diff options
Diffstat (limited to 'src/collision')
-rw-r--r-- | src/collision/ColBox.h | 10 | ||||
-rw-r--r-- | src/collision/ColLine.h | 4 | ||||
-rw-r--r-- | src/collision/ColModel.cpp | 138 | ||||
-rw-r--r-- | src/collision/ColModel.h | 4 | ||||
-rw-r--r-- | src/collision/ColPoint.h | 4 | ||||
-rw-r--r-- | src/collision/ColSphere.h | 5 | ||||
-rw-r--r-- | src/collision/ColStore.cpp | 176 | ||||
-rw-r--r-- | src/collision/ColStore.h | 18 | ||||
-rw-r--r-- | src/collision/ColTriangle.h | 1 | ||||
-rw-r--r-- | src/collision/Collision.cpp | 18 | ||||
-rw-r--r-- | src/collision/TempColModels.cpp | 87 | ||||
-rw-r--r-- | src/collision/TempColModels.h | 15 |
12 files changed, 384 insertions, 96 deletions
diff --git a/src/collision/ColBox.h b/src/collision/ColBox.h index 0df55925..721756b4 100644 --- a/src/collision/ColBox.h +++ b/src/collision/ColBox.h @@ -19,4 +19,12 @@ struct CColBox : public CBox using CBox::Set; CColBox& operator=(const CColBox &other); -};
\ No newline at end of file +}; + +// no name for this +// bounds for a number of triangles +struct CColTriBBox : public CBox +{ + int32 first; + int32 last; +}; diff --git a/src/collision/ColLine.h b/src/collision/ColLine.h index 21587a06..a2cb9a0b 100644 --- a/src/collision/ColLine.h +++ b/src/collision/ColLine.h @@ -4,9 +4,9 @@ struct CColLine { // NB: this has to be compatible with two CVuVectors CVector p0; - int pad0; +// int pad0; CVector p1; - int pad1; +// int pad1; CColLine(void) { }; CColLine(const CVector &p0, const CVector &p1) { this->p0 = p0; this->p1 = p1; }; diff --git a/src/collision/ColModel.cpp b/src/collision/ColModel.cpp index 2224a804..944f76d8 100644 --- a/src/collision/ColModel.cpp +++ b/src/collision/ColModel.cpp @@ -1,4 +1,5 @@ #include "common.h" +#include "main.h" #include "ColModel.h" #include "Collision.h" #include "Game.h" @@ -7,6 +8,10 @@ CColModel::CColModel(void) { + boundingSphere.Set(0.0001f, CVector(0.0f, 0.0f, 0.0f)); + boundingBox.Set(CVector(0.0f, 0.0f, 0.0f), CVector(0.0f, 0.0f, 0.0f)); + numTriBBoxes = 0; + triBBoxes = nil; numSpheres = 0; spheres = nil; numLines = 0; @@ -18,14 +23,18 @@ CColModel::CColModel(void) triangles = nil; trianglePlanes = nil; level = LEVEL_GENERIC; // generic col slot - ownsCollisionVolumes = true; +// ownsCollisionVolumes = true; } CColModel::~CColModel(void) { - RemoveCollisionVolumes(); + if(!gNASTY_NASTY_MEM_SHUTDOWN_HACK){ + RemoveTrianglePlanes(); + RemoveCollisionVolumes(); + } } +//--LCS: no pool used, but maybe we better keep it? void* CColModel::operator new(size_t) throw() { @@ -43,19 +52,28 @@ CColModel::operator delete(void *p, size_t) throw() void CColModel::RemoveCollisionVolumes(void) { - if(ownsCollisionVolumes){ - RwFree(spheres); - RwFree(lines); - RwFree(boxes); - RwFree(vertices); - RwFree(triangles); - CCollision::RemoveTrianglePlanes(this); +#ifdef FIX_BUGS + // why is this missing? + if(ownsCollisionVolumes) +#endif + if(!gUseChunkFiles){ + delete[] triBBoxes; + delete[] spheres; + delete[] lines; + delete[] boxes; + delete[] vertices; + delete[] triangles; } + CCollision::RemoveTrianglePlanes(this); numSpheres = 0; + numTriBBoxes = 0; numLines = 0; numBoxes = 0; numTriangles = 0; spheres = nil; +#ifdef FIX_BUGS + triBBoxes = nil; +#endif lines = nil; boxes = nil; vertices = nil; @@ -68,7 +86,7 @@ CColModel::CalculateTrianglePlanes(void) PUSH_MEMID(MEMID_COLLISION); // HACK: allocate space for one more element to stuff the link pointer into - trianglePlanes = (CColTrianglePlane*)RwMalloc(sizeof(CColTrianglePlane) * (numTriangles+1)); + trianglePlanes = new CColTrianglePlane[numTriangles+1]; REGISTER_MEMPTR(&trianglePlanes); for(int i = 0; i < numTriangles; i++) trianglePlanes[i].Set(vertices, triangles[i]); @@ -79,8 +97,10 @@ CColModel::CalculateTrianglePlanes(void) void CColModel::RemoveTrianglePlanes(void) { - RwFree(trianglePlanes); - trianglePlanes = nil; + if(trianglePlanes){ + delete[] trianglePlanes; + trianglePlanes = nil; + } } void @@ -112,20 +132,33 @@ CColModel::operator=(const CColModel &other) boundingSphere = other.boundingSphere; boundingBox = other.boundingBox; + // copy tri bboxes + if(other.numTriBBoxes){ + if(numTriBBoxes != other.numTriBBoxes){ + numTriBBoxes = other.numTriBBoxes; + delete[] triBBoxes; + triBBoxes = new CColTriBBox[numTriBBoxes]; + } + for(i = 0; i < numTriBBoxes; i++) + triBBoxes[i] = other.triBBoxes[i]; + }else{ + numTriBBoxes = 0; + delete[] triBBoxes; + triBBoxes = nil; + } + // copy spheres if(other.numSpheres){ if(numSpheres != other.numSpheres){ numSpheres = other.numSpheres; - if(spheres) - RwFree(spheres); - spheres = (CColSphere*)RwMalloc(numSpheres*sizeof(CColSphere)); + delete[] spheres; + spheres = new CColSphere[numSpheres]; } for(i = 0; i < numSpheres; i++) spheres[i] = other.spheres[i]; }else{ numSpheres = 0; - if(spheres) - RwFree(spheres); + delete[] spheres; spheres = nil; } @@ -133,16 +166,14 @@ CColModel::operator=(const CColModel &other) if(other.numLines){ if(numLines != other.numLines){ numLines = other.numLines; - if(lines) - RwFree(lines); - lines = (CColLine*)RwMalloc(numLines*sizeof(CColLine)); + delete[] lines; + lines = new CColLine[numLines]; } for(i = 0; i < numLines; i++) lines[i] = other.lines[i]; }else{ numLines = 0; - if(lines) - RwFree(lines); + delete[] lines; lines = nil; } @@ -150,23 +181,21 @@ CColModel::operator=(const CColModel &other) if(other.numBoxes){ if(numBoxes != other.numBoxes){ numBoxes = other.numBoxes; - if(boxes) - RwFree(boxes); - boxes = (CColBox*)RwMalloc(numBoxes*sizeof(CColBox)); + delete[] boxes; + boxes = new CColBox[numBoxes]; } for(i = 0; i < numBoxes; i++) boxes[i] = other.boxes[i]; }else{ numBoxes = 0; - if(boxes) - RwFree(boxes); + delete[] boxes; boxes = nil; } // copy mesh if(other.numTriangles){ // copy vertices - numVerts = 0; + numVerts = -1; for(i = 0; i < other.numTriangles; i++){ if(other.triangles[i].a > numVerts) numVerts = other.triangles[i].a; @@ -176,10 +205,9 @@ CColModel::operator=(const CColModel &other) numVerts = other.triangles[i].c; } numVerts++; - if(vertices) - RwFree(vertices); + delete[] vertices; if(numVerts){ - vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector)); + vertices = new CompressedVector[numVerts]; for(i = 0; i < numVerts; i++) vertices[i] = other.vertices[i]; } @@ -187,20 +215,54 @@ CColModel::operator=(const CColModel &other) // copy triangles if(numTriangles != other.numTriangles){ numTriangles = other.numTriangles; - if(triangles) - RwFree(triangles); - triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle)); + delete[] triangles; + triangles = new CColTriangle[numTriangles]; } for(i = 0; i < numTriangles; i++) triangles[i] = other.triangles[i]; }else{ numTriangles = 0; - if(triangles) - RwFree(triangles); + delete[] triangles; triangles = nil; - if(vertices) - RwFree(vertices); + delete[] vertices; vertices = nil; } return *this; } + +bool +CColModel::Write(base::cRelocatableChunkWriter &writer, bool allocSpace) +{ + int numVerts = -1; + for(int i = 0; i < numTriangles; i++){ + if(triangles[i].a > numVerts) + numVerts = triangles[i].a; + if(triangles[i].b > numVerts) + numVerts = triangles[i].b; + if(triangles[i].c > numVerts) + numVerts = triangles[i].c; + } + numVerts++; + + if(allocSpace) + writer.AllocateRaw(this, sizeof(*this), 16, false, true); + writer.AllocateRaw(spheres, sizeof(*spheres)*numSpheres, 16, false, true); + writer.AddPatch(&spheres); + writer.AllocateRaw(lines, sizeof(*lines)*numLines, 16, false, true); + writer.AddPatch(&lines); + writer.AllocateRaw(boxes, sizeof(*boxes)*numBoxes, 16, false, true); + writer.AddPatch(&boxes); + if(triBBoxes && numTriBBoxes != 0){ + writer.AllocateRaw(triBBoxes, sizeof(*triBBoxes)*numTriBBoxes, 16, false, true); + writer.AddPatch(&triBBoxes); + }else + triBBoxes = nil; + if(numTriangles != 0){ + writer.AllocateRaw(vertices, sizeof(*vertices)*numVerts, 2, false, true); + writer.AddPatch(&vertices); + writer.AllocateRaw(triangles, sizeof(*triangles)*numTriangles, 2, false, true); + writer.AddPatch(&triangles); + RemoveTrianglePlanes(); + } + return 1; +} diff --git a/src/collision/ColModel.h b/src/collision/ColModel.h index 64f05f76..ce6dcd6d 100644 --- a/src/collision/ColModel.h +++ b/src/collision/ColModel.h @@ -15,11 +15,13 @@ struct CColModel int16 numBoxes; int16 numTriangles; int8 numLines; + int8 numTriBBoxes; uint8 level; // colstore slot but probably still named level bool ownsCollisionVolumes; CColSphere *spheres; CColLine *lines; CColBox *boxes; + CColTriBBox *triBBoxes; CompressedVector *vertices; CColTriangle *triangles; CColTrianglePlane *trianglePlanes; @@ -36,4 +38,6 @@ struct CColModel void *operator new(size_t) throw(); void operator delete(void *p, size_t) throw(); CColModel& operator=(const CColModel& other); + + bool Write(base::cRelocatableChunkWriter &writer, bool allocSpace); };
\ No newline at end of file diff --git a/src/collision/ColPoint.h b/src/collision/ColPoint.h index a15b2345..36801efc 100644 --- a/src/collision/ColPoint.h +++ b/src/collision/ColPoint.h @@ -3,15 +3,13 @@ struct CColPoint { CVector point; - int pad1; + float depth; // the surface normal on the surface of point CVector normal; - int pad2; uint8 surfaceA; uint8 pieceA; uint8 surfaceB; uint8 pieceB; - float depth; const CVector &GetNormal() { return normal; } float GetDepth() { return depth; } diff --git a/src/collision/ColSphere.h b/src/collision/ColSphere.h index f86b282a..3f18d8c0 100644 --- a/src/collision/ColSphere.h +++ b/src/collision/ColSphere.h @@ -2,10 +2,11 @@ #include "SurfaceTable.h" -struct CSphere +// TODO(LCS): maybe this was in a union with CVuVector? or is the alignment manual? +struct TYPEALIGN(16) CSphere { // NB: this has to be compatible with a CVuVector - CVector center; + RwV3d center; float radius; void Set(float radius, const CVector ¢er) { this->center = center; this->radius = radius; } }; diff --git a/src/collision/ColStore.cpp b/src/collision/ColStore.cpp index c74bf5ba..c50e6cbd 100644 --- a/src/collision/ColStore.cpp +++ b/src/collision/ColStore.cpp @@ -1,5 +1,7 @@ #include "common.h" +#include "main.h" +#include "smallHeap.h" #include "templates.h" #include "General.h" #include "ModelInfo.h" @@ -8,6 +10,9 @@ #include "Script.h" #include "Timer.h" #include "Camera.h" +#include "World.h" +#include "Zones.h" +#include "Garages.h" #include "Frontend.h" #include "Physical.h" #include "ColStore.h" @@ -15,16 +20,55 @@ #include "Pools.h" CPool<ColDef,ColDef> *CColStore::ms_pColPool; +bool CColStore::m_onlyBB; #ifndef MASTER bool bDispColInMem; #endif +// LCS: file done except unused: +// CColStore::LoadCol(int,char const*) +// CColStore::LoadAllBoundingBoxes(void) +// CColStore::Write(base::cRelocatableChunkWriter &) + +const CVector& +LevelPos(eLevelName level) +{ + static CVector pos[4] = { + CVector(1060.0f, -800.0f, 0.0f), + CVector(1060.0f, -800.0f, 0.0f), + CVector(350.0f, -624.0f, 0.0f), + CVector(-670.0f, -511.0f, 0.0f) + }; + return pos[level]; +}; + +static eLevelName +PosLevel(const CVector &pos) +{ + static eLevelName lastPlayerLevel = LEVEL_INDUSTRIAL; + static eLevelName lastOtherLevel = LEVEL_INDUSTRIAL; + + if(Abs(FindPlayerCoors().x - pos.x) < 5.0f && + Abs(FindPlayerCoors().y - pos.y) < 5.0f && + Abs(FindPlayerCoors().z - pos.z) < 5.0f){ + if(CGame::currLevel != LEVEL_GENERIC) + lastPlayerLevel = CGame::currLevel; + return lastPlayerLevel; + }else{ + eLevelName lvl = CTheZones::GetLevelFromPosition(&pos); + if(lvl != LEVEL_GENERIC) + lastOtherLevel = lvl; + return lastOtherLevel; + } +} + void CColStore::Initialise(void) { - if(ms_pColPool == nil) + if(ms_pColPool == nil){ ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles"); - AddColSlot("generic"); // slot 0. not streamed + AddColSlot("generic"); // slot 0. not streamed + } #ifndef MASTER VarConsole.Add("Display collision in memory", &bDispColInMem, true); #endif @@ -38,7 +82,9 @@ CColStore::Shutdown(void) RemoveColSlot(i); if(ms_pColPool) delete ms_pColPool; +#ifdef FIX_BUGS ms_pColPool = nil; +#endif } int @@ -119,11 +165,34 @@ CColStore::LoadCol(int32 slot, uint8 *buffer, int32 bufsize) return success; } +struct ColChunkEntry +{ + int32 modelId; // -1 marks end + CColModel *colModel; +}; + +void +CColStore::LoadColCHK(int32 slot, void *data, void *chunk) +{ + ColDef *def = GetSlot(slot); + def->chunk = chunk; + CStreaming::RegisterPointer(&def->chunk, 1, true); + for(ColChunkEntry *entry = (ColChunkEntry*)data; entry->modelId != -1; entry++){ + CBaseModelInfo *mi = CModelInfo::GetModelInfo(entry->modelId); + mi->SetColModel(entry->colModel, true); // we own this? can that work? + CStreaming::RegisterPointer(&mi->m_colModel, 1, true); + } + def->isLoaded = true; +} + +CColModel nullCollision; + void CColStore::RemoveCol(int32 slot) { int id; - GetSlot(slot)->isLoaded = false; + ColDef *def = GetSlot(slot); + def->isLoaded = false; for(id = 0; id < MODELINFOSIZE; id++){ CBaseModelInfo *mi = CModelInfo::GetModelInfo(id); if(mi){ @@ -132,6 +201,23 @@ CColStore::RemoveCol(int32 slot) col->RemoveCollisionVolumes(); } } + if(gUseChunkFiles){ + for(id = 0; id < MODELINFOSIZE; id++){ + CBaseModelInfo *mi = CModelInfo::GetModelInfo(id); + if(mi){ + CColModel *col = mi->GetColModel(); + if(col && col->level == slot){ + mi->SetColModel(&nullCollision); + CStreaming::UnregisterPointer(&mi->m_colModel, 1); + } + } + } + if(def->chunk){ + CStreaming::UnregisterPointer(&def->chunk, 1); + cSmallHeap::msInstance.Free(def->chunk); + def->chunk = nil; + } + } } void @@ -156,29 +242,49 @@ CColStore::RemoveAllCollision(void) } static bool bLoadAtSecondPosition; -static CVector2D secondPosition; +static CVector secondPosition; void -CColStore::AddCollisionNeededAtPosn(const CVector2D &pos) +CColStore::AddCollisionNeededAtPosn(const CVector &pos) { bLoadAtSecondPosition = true; secondPosition = pos; } void -CColStore::LoadCollision(const CVector2D &pos) +CColStore::LoadCollision(const CVector &pos, eLevelName level) { int i; if(CStreaming::ms_disableStreaming) return; + if(level == LEVEL_GENERIC) + level = PosLevel(pos); + + eLevelName allowedLevel = (eLevelName)CTheScripts::AllowedCollision[0]; + if(allowedLevel == LEVEL_GENERIC) + allowedLevel = (eLevelName)CTheScripts::AllowedCollision[1]; + + bool requestedSomething = false; + for(i = 1; i < COLSTORESIZE; i++){ - if(GetSlot(i) == nil) + if(GetSlot(i) == nil || !DoScriptsWantThisIn(i)) continue; bool wantThisOne = false; + if(strcmp(GetColName(i), "indust") == 0){ + if(allowedLevel != LEVEL_GENERIC && level != LEVEL_INDUSTRIAL) + wantThisOne = allowedLevel == LEVEL_INDUSTRIAL; + else + wantThisOne = level == LEVEL_INDUSTRIAL; + }else if(GetBoundingBox(i).IsPointInside(LevelPos(level))) + wantThisOne = true; + else if(allowedLevel != LEVEL_GENERIC && GetBoundingBox(i).IsPointInside(LevelPos(allowedLevel))) + wantThisOne = true; + +/* // LCS: removed if(GetBoundingBox(i).IsPointInside(pos) || bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) || strcmp(GetColName(i), "yacht") == 0){ @@ -203,28 +309,38 @@ CColStore::LoadCollision(const CVector2D &pos) } } } +*/ - if(wantThisOne) + if(wantThisOne){ CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY); - else + requestedSomething = true; + }else CStreaming::RemoveCol(i); } + if(requestedSomething){ + CTimer::Suspend(); + // BUG? request was done with priority but now loading non-priority? + CStreaming::LoadAllRequestedModels(false); + CGarages::SetupAnyGaragesForThisIsland(); + CTimer::Resume(); + } bLoadAtSecondPosition = false; } void -CColStore::RequestCollision(const CVector2D &pos) +CColStore::RequestCollision(const CVector &pos) { int i; for(i = 1; i < COLSTORESIZE; i++) - if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f)) + if(GetSlot(i) && DoScriptsWantThisIn(i) && GetBoundingBox(i).IsPointInside(LevelPos(PosLevel(pos)), -115.0f)) CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY); } void -CColStore::EnsureCollisionIsInMemory(const CVector2D &pos) +CColStore::EnsureCollisionIsInMemory(const CVector &pos) { +/* // LCS: removed int i; if(CStreaming::ms_disableStreaming) @@ -240,16 +356,48 @@ CColStore::EnsureCollisionIsInMemory(const CVector2D &pos) CStreaming::LoadAllRequestedModels(false); CTimer::Resume(); } +*/ } bool -CColStore::HasCollisionLoaded(const CVector2D &pos) +CColStore::DoScriptsWantThisIn(int32 slot) +{ + if(slot == 0) + return false; + ColDef *coldef = GetSlot(slot); + if(coldef == nil) + return false; + if(strcmp(coldef->name, "fortstaunton") == 0) + return !CTheScripts::IsFortStauntonDestroyed(); + if(strcmp(coldef->name, "fortdestroyed") == 0) + return CTheScripts::IsFortStauntonDestroyed(); + return true; +} + +bool +CColStore::HasCollisionLoaded(eLevelName level) { int i; + const CVector &pos = LevelPos(level); for(i = 1; i < COLSTORESIZE; i++) - if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f) && + if(GetSlot(i) && DoScriptsWantThisIn(i) && + (!CGeneral::faststricmp(GetColName(i), "indust") && level == LEVEL_INDUSTRIAL || + GetBoundingBox(i).IsPointInside(pos)) && !GetSlot(i)->isLoaded) return false; return true; } + +bool +CColStore::HasCollisionLoaded(const CVector &pos) +{ + return HasCollisionLoaded(PosLevel(pos)); +} + +void +CColStore::Load(bool onlyBB, CPool<ColDef> *pool) +{ + ms_pColPool = pool; + m_onlyBB = onlyBB; +} diff --git a/src/collision/ColStore.h b/src/collision/ColStore.h index 8e2a3a70..c66a67ed 100644 --- a/src/collision/ColStore.h +++ b/src/collision/ColStore.h @@ -9,11 +9,13 @@ struct ColDef { // made up name char name[20]; int16 minIndex; int16 maxIndex; + void *chunk; }; class CColStore { static CPool<ColDef,ColDef> *ms_pColPool; + static bool m_onlyBB; public: static void Initialise(void); @@ -25,14 +27,18 @@ public: static CRect &GetBoundingBox(int32 slot); static void IncludeModelIndex(int32 slot, int32 modelIndex); static bool LoadCol(int32 storeID, uint8 *buffer, int32 bufsize); + static void LoadColCHK(int32 slot, void *data, void *chunk); static void RemoveCol(int32 slot); - static void AddCollisionNeededAtPosn(const CVector2D &pos); + static void AddCollisionNeededAtPosn(const CVector &pos); static void LoadAllCollision(void); static void RemoveAllCollision(void); - static void LoadCollision(const CVector2D &pos); - static void RequestCollision(const CVector2D &pos); - static void EnsureCollisionIsInMemory(const CVector2D &pos); - static bool HasCollisionLoaded(const CVector2D &pos); + static void LoadCollision(const CVector &pos, eLevelName level = LEVEL_GENERIC); + static void RequestCollision(const CVector &pos); + static void EnsureCollisionIsInMemory(const CVector &pos); + static bool DoScriptsWantThisIn(int32 slot); + static bool HasCollisionLoaded(eLevelName level); + static bool HasCollisionLoaded(const CVector &pos); + static void Load(bool, CPool<ColDef> *pool); static ColDef *GetSlot(int slot) { assert(slot >= 0); @@ -41,3 +47,5 @@ public: return ms_pColPool->GetSlot(slot); } }; + +const CVector& LevelPos(eLevelName level); diff --git a/src/collision/ColTriangle.h b/src/collision/ColTriangle.h index a2580c58..5ce543b5 100644 --- a/src/collision/ColTriangle.h +++ b/src/collision/ColTriangle.h @@ -62,6 +62,7 @@ struct CColTrianglePlane } #endif #else + // TODO(LCS): LCS actually uses CompressedVector too CVector normal; float dist; uint8 dir; diff --git a/src/collision/Collision.cpp b/src/collision/Collision.cpp index f39f3f35..946513d3 100644 --- a/src/collision/Collision.cpp +++ b/src/collision/Collision.cpp @@ -24,6 +24,10 @@ #include "Camera.h" #include "ColStore.h" +// gotta figure out how they handled CSphere exactly +// so using this to remind me to look into it again. +#define CVECTORHACK(rwv3d) CVector(rwv3d) + #ifdef VU_COLLISION #include "VuCollision.h" @@ -398,7 +402,7 @@ CCollision::TestLineSphere(const CColLine &line, const CColSphere &sph) // The length of the tangent would be this: Sqrt((c-p0)^2 - r^2). // Negative if p0 is inside the sphere! This breaks the test! float tansq = 4.0f * linesq * - (sph.center.MagnitudeSqr() - 2.0f*DotProduct(sph.center, line.p0) + line.p0.MagnitudeSqr() - sph.radius*sph.radius); + (CVECTORHACK(sph.center).MagnitudeSqr() - 2.0f*DotProduct(sph.center, line.p0) + line.p0.MagnitudeSqr() - sph.radius*sph.radius); float diffsq = projline*projline - tansq; // if diffsq < 0 that means the line is a passant, so no intersection if(diffsq < 0.0f) @@ -477,9 +481,9 @@ CCollision::TestSphereTriangle(const CColSphere &sphere, case 2: // closest to an edge // looks like original game as DistToLine manually inlined - if(!insideAB) dist = DistToLine(&va, &vb, &sphere.center); - else if(!insideAC) dist = DistToLine(&va, &vc, &sphere.center); - else if(!insideBC) dist = DistToLine(&vb, &vc, &sphere.center); + if(!insideAB) dist = DistToLine(&va, &vb, &CVECTORHACK(sphere.center)); + else if(!insideAC) dist = DistToLine(&va, &vc, &CVECTORHACK(sphere.center)); + else if(!insideBC) dist = DistToLine(&vb, &vc, &CVECTORHACK(sphere.center)); else assert(0); break; case 3: @@ -1295,9 +1299,9 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere, case 2: // closest to an edge // looks like original game as DistToLine manually inlined - if(!insideAB) dist = DistToLine(&va, &vb, &sphere.center, p); - else if(!insideAC) dist = DistToLine(&va, &vc, &sphere.center, p); - else if(!insideBC) dist = DistToLine(&vb, &vc, &sphere.center, p); + if(!insideAB) dist = DistToLine(&va, &vb, &CVECTORHACK(sphere.center), p); + else if(!insideAC) dist = DistToLine(&va, &vc, &CVECTORHACK(sphere.center), p); + else if(!insideBC) dist = DistToLine(&vb, &vc, &CVECTORHACK(sphere.center), p); else assert(0); break; case 3: diff --git a/src/collision/TempColModels.cpp b/src/collision/TempColModels.cpp index 0c0d4376..148b86fe 100644 --- a/src/collision/TempColModels.cpp +++ b/src/collision/TempColModels.cpp @@ -1,22 +1,25 @@ #include "common.h" +#include "main.h" #include "TempColModels.h" #include "Game.h" -CColModel CTempColModels::ms_colModelPed1; +// LCS: haven't yet checked the numbers but they probably haven't changed + CColModel CTempColModels::ms_colModelPed2; -CColModel CTempColModels::ms_colModelBBox; CColModel CTempColModels::ms_colModelBumper1; CColModel CTempColModels::ms_colModelWheel1; CColModel CTempColModels::ms_colModelPanel1; CColModel CTempColModels::ms_colModelBodyPart2; CColModel CTempColModels::ms_colModelBodyPart1; -CColModel CTempColModels::ms_colModelCutObj[5]; +CColModel CTempColModels::ms_colModelCutObj[10]; CColModel CTempColModels::ms_colModelPedGroundHit; CColModel CTempColModels::ms_colModelBoot1; CColModel CTempColModels::ms_colModelDoor1; CColModel CTempColModels::ms_colModelBonnet1; -CColModel CTempColModels::ms_colModelWeapon; +CColModel CTempColModels::ms_colModelFerryDocked; + +CTempColModels *gpTempColModels; CColSphere s_aPedSpheres[3]; @@ -34,6 +37,7 @@ CColSphere s_aBootSpheres[4]; CColSphere s_aWheelSpheres[2]; CColSphere s_aBodyPartSpheres1[2]; CColSphere s_aBodyPartSpheres2[2]; +CColBox S_aFerryDockedBoxes[1]; void CTempColModels::Initialise(void) @@ -44,11 +48,26 @@ CTempColModels::Initialise(void) colmodel.level = LEVEL_GENERIC;\ colmodel.ownsCollisionVolumes = false; - int i; + if(gMakeResources){ + if(gpTempColModels == nil){ + gpTempColModels = new CTempColModels; + gpTempColModels->Initialise(); + return; + } + + ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f)); + ms_colModelBBox.level = LEVEL_GENERIC; - ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); - ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f)); - ms_colModelBBox.level = LEVEL_GENERIC; + ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f)); + SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres); + + ms_colModelWeapon.boundingSphere.Set(0.25f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelWeapon.boundingBox.Set(CVector(-0.25f, -0.25f, -0.25f), CVector(0.25f, 0.25f, 0.25f)); + } + + int i; for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) { ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); @@ -74,10 +93,6 @@ CTempColModels::Initialise(void) s_aPedSpheres[i].piece = 0; } - ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f)); - ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f)); - SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres); - // Ped 2 Spheres s_aPed2Spheres[0].radius = 0.3f; @@ -294,13 +309,47 @@ CTempColModels::Initialise(void) SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2); - ms_colModelWeapon.boundingSphere.radius = 0.25f; - ms_colModelWeapon.boundingBox.min.x = -0.25f; - ms_colModelWeapon.boundingBox.min.y = -0.25f; - ms_colModelWeapon.boundingBox.min.z = -0.25f; - ms_colModelWeapon.boundingBox.max.x = 0.25f; - ms_colModelWeapon.boundingBox.max.y = 0.25f; - ms_colModelWeapon.boundingBox.max.z = 0.25f; + // Ferry Docked + + S_aFerryDockedBoxes[0].Set(CVector(-6.3f, -22.78f, -2.0f), CVector(6.3f, 22.78f, 2.8f), SURFACE_THICK_METAL_PLATE, SURFACE_DEFAULT); + + ms_colModelFerryDocked.boundingSphere.Set(35.0f, CVector(0.0f, -0.0f, 0.0f)); + ms_colModelFerryDocked.boundingBox.Set(S_aFerryDockedBoxes[0].min, S_aFerryDockedBoxes[0].max); + ms_colModelFerryDocked.spheres = nil; + ms_colModelFerryDocked.numSpheres = 0; + ms_colModelFerryDocked.boxes = S_aFerryDockedBoxes; + ms_colModelFerryDocked.numBoxes = ARRAY_SIZE(S_aFerryDockedBoxes); + ms_colModelFerryDocked.level = LEVEL_GENERIC; + #undef SET_COLMODEL_SPHERES } + +void +CTempColModels::Write(base::cRelocatableChunkWriter &writer) +{ + writer.AllocateRaw(this, sizeof(*this), 0x10, false, true); + + ms_colModelBBox.Write(writer, false); + writer.AddPatch(&ms_colModelBBox); + + ms_colModelPed1.Write(writer, false); + writer.AddPatch(&ms_colModelPed1); + + ms_colModelWeapon.Write(writer, false); + writer.AddPatch(&ms_colModelWeapon); + + for(int i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) + ms_colModelCutObj[i].Write(writer, true); + ms_colModelPed2.Write(writer, true); + ms_colModelPedGroundHit.Write(writer, true); + ms_colModelDoor1.Write(writer, true); + ms_colModelBumper1.Write(writer, true); + ms_colModelPanel1.Write(writer, true); + ms_colModelBonnet1.Write(writer, true); + ms_colModelBoot1.Write(writer, true); + ms_colModelWheel1.Write(writer, true); + ms_colModelBodyPart1.Write(writer, true); + ms_colModelBodyPart2.Write(writer, true); + ms_colModelFerryDocked.Write(writer, true); +} diff --git a/src/collision/TempColModels.h b/src/collision/TempColModels.h index 1a888723..0f1f06c3 100644 --- a/src/collision/TempColModels.h +++ b/src/collision/TempColModels.h @@ -5,20 +5,25 @@ class CTempColModels { public: - static CColModel ms_colModelPed1; + CColModel ms_colModelPed1; + CColModel ms_colModelBBox; + CColModel ms_colModelWeapon; + static CColModel ms_colModelPed2; - static CColModel ms_colModelBBox; static CColModel ms_colModelBumper1; static CColModel ms_colModelWheel1; static CColModel ms_colModelPanel1; static CColModel ms_colModelBodyPart2; static CColModel ms_colModelBodyPart1; - static CColModel ms_colModelCutObj[5]; + static CColModel ms_colModelCutObj[10]; static CColModel ms_colModelPedGroundHit; static CColModel ms_colModelBoot1; static CColModel ms_colModelDoor1; static CColModel ms_colModelBonnet1; - static CColModel ms_colModelWeapon; + static CColModel ms_colModelFerryDocked; - static void Initialise(void); + void Initialise(void); + void Write(base::cRelocatableChunkWriter &writer); }; + +extern CTempColModels *gpTempColModels; |