1
0
Fork 0
mirror of https://git.rip/DMCA_FUCKER/re3.git synced 2024-12-23 10:00:01 +00:00

CColModel

This commit is contained in:
aap 2021-02-09 17:35:41 +01:00
parent 410eb19ce6
commit 031df36935
8 changed files with 167 additions and 49 deletions

View file

@ -20,3 +20,11 @@ struct CColBox : public CBox
CColBox& operator=(const CColBox &other); CColBox& operator=(const CColBox &other);
}; };
// no name for this
// bounds for a number of triangles
struct CColTriBBox : public CBox
{
int32 first;
int32 last;
};

View file

@ -1,4 +1,5 @@
#include "common.h" #include "common.h"
#include "main.h"
#include "ColModel.h" #include "ColModel.h"
#include "Collision.h" #include "Collision.h"
#include "Game.h" #include "Game.h"
@ -9,6 +10,8 @@ CColModel::CColModel(void)
{ {
boundingSphere.Set(0.0001f, CVector(0.0f, 0.0f, 0.0f)); 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)); boundingBox.Set(CVector(0.0f, 0.0f, 0.0f), CVector(0.0f, 0.0f, 0.0f));
numTriBBoxes = 0;
triBBoxes = nil;
numSpheres = 0; numSpheres = 0;
spheres = nil; spheres = nil;
numLines = 0; numLines = 0;
@ -25,9 +28,13 @@ CColModel::CColModel(void)
CColModel::~CColModel(void) CColModel::~CColModel(void)
{ {
RemoveCollisionVolumes(); if(!gNASTY_NASTY_MEM_SHUTDOWN_HACK){
RemoveTrianglePlanes();
RemoveCollisionVolumes();
}
} }
//--LCS: no pool used, but maybe we better keep it?
void* void*
CColModel::operator new(size_t) CColModel::operator new(size_t)
{ {
@ -45,19 +52,28 @@ CColModel::operator delete(void *p, size_t)
void void
CColModel::RemoveCollisionVolumes(void) CColModel::RemoveCollisionVolumes(void)
{ {
if(ownsCollisionVolumes){ #ifdef FIX_BUGS
RwFree(spheres); // why is this missing?
RwFree(lines); if(ownsCollisionVolumes)
RwFree(boxes); #endif
RwFree(vertices); if(!gUseChunkFiles){
RwFree(triangles); delete[] triBBoxes;
CCollision::RemoveTrianglePlanes(this); delete[] spheres;
delete[] lines;
delete[] boxes;
delete[] vertices;
delete[] triangles;
} }
CCollision::RemoveTrianglePlanes(this);
numSpheres = 0; numSpheres = 0;
numTriBBoxes = 0;
numLines = 0; numLines = 0;
numBoxes = 0; numBoxes = 0;
numTriangles = 0; numTriangles = 0;
spheres = nil; spheres = nil;
#ifdef FIX_BUGS
triBBoxes = nil;
#endif
lines = nil; lines = nil;
boxes = nil; boxes = nil;
vertices = nil; vertices = nil;
@ -70,7 +86,7 @@ CColModel::CalculateTrianglePlanes(void)
PUSH_MEMID(MEMID_COLLISION); PUSH_MEMID(MEMID_COLLISION);
// HACK: allocate space for one more element to stuff the link pointer into // 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); REGISTER_MEMPTR(&trianglePlanes);
for(int i = 0; i < numTriangles; i++) for(int i = 0; i < numTriangles; i++)
trianglePlanes[i].Set(vertices, triangles[i]); trianglePlanes[i].Set(vertices, triangles[i]);
@ -81,8 +97,10 @@ CColModel::CalculateTrianglePlanes(void)
void void
CColModel::RemoveTrianglePlanes(void) CColModel::RemoveTrianglePlanes(void)
{ {
RwFree(trianglePlanes); if(trianglePlanes){
trianglePlanes = nil; delete[] trianglePlanes;
trianglePlanes = nil;
}
} }
void void
@ -114,20 +132,33 @@ CColModel::operator=(const CColModel &other)
boundingSphere = other.boundingSphere; boundingSphere = other.boundingSphere;
boundingBox = other.boundingBox; 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 // copy spheres
if(other.numSpheres){ if(other.numSpheres){
if(numSpheres != other.numSpheres){ if(numSpheres != other.numSpheres){
numSpheres = other.numSpheres; numSpheres = other.numSpheres;
if(spheres) delete[] spheres;
RwFree(spheres); spheres = new CColSphere[numSpheres];
spheres = (CColSphere*)RwMalloc(numSpheres*sizeof(CColSphere));
} }
for(i = 0; i < numSpheres; i++) for(i = 0; i < numSpheres; i++)
spheres[i] = other.spheres[i]; spheres[i] = other.spheres[i];
}else{ }else{
numSpheres = 0; numSpheres = 0;
if(spheres) delete[] spheres;
RwFree(spheres);
spheres = nil; spheres = nil;
} }
@ -135,16 +166,14 @@ CColModel::operator=(const CColModel &other)
if(other.numLines){ if(other.numLines){
if(numLines != other.numLines){ if(numLines != other.numLines){
numLines = other.numLines; numLines = other.numLines;
if(lines) delete[] lines;
RwFree(lines); lines = new CColLine[numLines];
lines = (CColLine*)RwMalloc(numLines*sizeof(CColLine));
} }
for(i = 0; i < numLines; i++) for(i = 0; i < numLines; i++)
lines[i] = other.lines[i]; lines[i] = other.lines[i];
}else{ }else{
numLines = 0; numLines = 0;
if(lines) delete[] lines;
RwFree(lines);
lines = nil; lines = nil;
} }
@ -152,23 +181,21 @@ CColModel::operator=(const CColModel &other)
if(other.numBoxes){ if(other.numBoxes){
if(numBoxes != other.numBoxes){ if(numBoxes != other.numBoxes){
numBoxes = other.numBoxes; numBoxes = other.numBoxes;
if(boxes) delete[] boxes;
RwFree(boxes); boxes = new CColBox[numBoxes];
boxes = (CColBox*)RwMalloc(numBoxes*sizeof(CColBox));
} }
for(i = 0; i < numBoxes; i++) for(i = 0; i < numBoxes; i++)
boxes[i] = other.boxes[i]; boxes[i] = other.boxes[i];
}else{ }else{
numBoxes = 0; numBoxes = 0;
if(boxes) delete[] boxes;
RwFree(boxes);
boxes = nil; boxes = nil;
} }
// copy mesh // copy mesh
if(other.numTriangles){ if(other.numTriangles){
// copy vertices // copy vertices
numVerts = 0; numVerts = -1;
for(i = 0; i < other.numTriangles; i++){ for(i = 0; i < other.numTriangles; i++){
if(other.triangles[i].a > numVerts) if(other.triangles[i].a > numVerts)
numVerts = other.triangles[i].a; numVerts = other.triangles[i].a;
@ -178,10 +205,9 @@ CColModel::operator=(const CColModel &other)
numVerts = other.triangles[i].c; numVerts = other.triangles[i].c;
} }
numVerts++; numVerts++;
if(vertices) delete[] vertices;
RwFree(vertices);
if(numVerts){ if(numVerts){
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector)); vertices = new CompressedVector[numVerts];
for(i = 0; i < numVerts; i++) for(i = 0; i < numVerts; i++)
vertices[i] = other.vertices[i]; vertices[i] = other.vertices[i];
} }
@ -189,19 +215,16 @@ CColModel::operator=(const CColModel &other)
// copy triangles // copy triangles
if(numTriangles != other.numTriangles){ if(numTriangles != other.numTriangles){
numTriangles = other.numTriangles; numTriangles = other.numTriangles;
if(triangles) delete[] triangles;
RwFree(triangles); triangles = new CColTriangle[numTriangles];
triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle));
} }
for(i = 0; i < numTriangles; i++) for(i = 0; i < numTriangles; i++)
triangles[i] = other.triangles[i]; triangles[i] = other.triangles[i];
}else{ }else{
numTriangles = 0; numTriangles = 0;
if(triangles) delete[] triangles;
RwFree(triangles);
triangles = nil; triangles = nil;
if(vertices) delete[] vertices;
RwFree(vertices);
vertices = nil; vertices = nil;
} }
return *this; return *this;
@ -210,6 +233,36 @@ CColModel::operator=(const CColModel &other)
bool bool
CColModel::Write(base::cRelocatableChunkWriter &writer, bool allocSpace) CColModel::Write(base::cRelocatableChunkWriter &writer, bool allocSpace)
{ {
assert(0 && "TODO(LCS)"); 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; return 1;
} }

View file

@ -15,11 +15,13 @@ struct CColModel
int16 numBoxes; int16 numBoxes;
int16 numTriangles; int16 numTriangles;
int8 numLines; int8 numLines;
int8 numTriBBoxes;
uint8 level; // colstore slot but probably still named level uint8 level; // colstore slot but probably still named level
bool ownsCollisionVolumes; bool ownsCollisionVolumes;
CColSphere *spheres; CColSphere *spheres;
CColLine *lines; CColLine *lines;
CColBox *boxes; CColBox *boxes;
CColTriBBox *triBBoxes;
CompressedVector *vertices; CompressedVector *vertices;
CColTriangle *triangles; CColTriangle *triangles;
CColTrianglePlane *trianglePlanes; CColTrianglePlane *trianglePlanes;

View file

@ -3,15 +3,13 @@
struct CColPoint struct CColPoint
{ {
CVector point; CVector point;
int pad1; // this is stupid float depth;
// the surface normal on the surface of point // the surface normal on the surface of point
CVector normal; CVector normal;
//int pad2;
uint8 surfaceA; uint8 surfaceA;
uint8 pieceA; uint8 pieceA;
uint8 surfaceB; uint8 surfaceB;
uint8 pieceB; uint8 pieceB;
float depth;
const CVector &GetNormal() { return normal; } const CVector &GetNormal() { return normal; }
float GetDepth() { return depth; } float GetDepth() { return depth; }

View file

@ -291,7 +291,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
{ {
int i; int i;
model.boundingSphere.radius = *(float*)(buf); model.boundingSphere.radius = Max(*(float*)(buf), 0.1f);
model.boundingSphere.center.x = *(float*)(buf+4); model.boundingSphere.center.x = *(float*)(buf+4);
model.boundingSphere.center.y = *(float*)(buf+8); model.boundingSphere.center.y = *(float*)(buf+8);
model.boundingSphere.center.z = *(float*)(buf+12); model.boundingSphere.center.z = *(float*)(buf+12);
@ -304,10 +304,13 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
model.numSpheres = *(int16*)(buf+40); model.numSpheres = *(int16*)(buf+40);
buf += 44; buf += 44;
if(model.numSpheres > 0){ if(model.numSpheres > 0){
model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere)); model.spheres = new CColSphere[model.numSpheres];
REGISTER_MEMPTR(&model.spheres); REGISTER_MEMPTR(&model.spheres);
for(i = 0; i < model.numSpheres; i++){ for(i = 0; i < model.numSpheres; i++){
model.spheres[i].Set(*(float*)buf, *(CVector*)(buf+4), buf[16], buf[17]); float radius = *(float*)buf;
if(radius > model.boundingSphere.radius)
model.boundingSphere.radius = radius + 0.01f;
model.spheres[i].Set(radius, *(CVector*)(buf+4), buf[16], buf[17]);
buf += 20; buf += 20;
} }
}else }else
@ -316,7 +319,8 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
model.numLines = *(int16*)buf; model.numLines = *(int16*)buf;
buf += 4; buf += 4;
if(model.numLines > 0){ if(model.numLines > 0){
//model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine)); //model.lines = new CColLine[model.numLines];;
REGISTER_MEMPTR(&model.lines);
for(i = 0; i < model.numLines; i++){ for(i = 0; i < model.numLines; i++){
//model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12)); //model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
buf += 24; buf += 24;
@ -329,7 +333,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
model.numBoxes = *(int16*)buf; model.numBoxes = *(int16*)buf;
buf += 4; buf += 4;
if(model.numBoxes > 0){ if(model.numBoxes > 0){
model.boxes = (CColBox*)RwMalloc(model.numBoxes*sizeof(CColBox)); model.boxes = new CColBox[model.numBoxes];
REGISTER_MEMPTR(&model.boxes); REGISTER_MEMPTR(&model.boxes);
for(i = 0; i < model.numBoxes; i++){ for(i = 0; i < model.numBoxes; i++){
model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]); model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]);
@ -341,7 +345,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
int32 numVertices = *(int16*)buf; int32 numVertices = *(int16*)buf;
buf += 4; buf += 4;
if(numVertices > 0){ if(numVertices > 0){
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector)); model.vertices = new CompressedVector[numVertices];
REGISTER_MEMPTR(&model.vertices); REGISTER_MEMPTR(&model.vertices);
for(i = 0; i < numVertices; i++){ for(i = 0; i < numVertices; i++){
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8)); model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
@ -359,14 +363,64 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
model.numTriangles = *(int16*)buf; model.numTriangles = *(int16*)buf;
buf += 4; buf += 4;
if(model.numTriangles > 0){ if(model.numTriangles > 0){
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle)); model.triangles = new CColTriangle[model.numTriangles];
REGISTER_MEMPTR(&model.triangles); REGISTER_MEMPTR(&model.triangles);
for(i = 0; i < model.numTriangles; i++){ for(i = 0; i < model.numTriangles; i++){
model.triangles[i].Set(*(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12]); model.triangles[i].Set(*(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12]);
buf += 16; buf += 16;
// skip small triangles
CVector vA = model.vertices[model.triangles[i].a].Get();
CVector vB = model.vertices[model.triangles[i].b].Get();
CVector vC = model.vertices[model.triangles[i].c].Get();
float area = CrossProduct(vA - vB, vA - vC).Magnitude();
if(area < 0.001f || vA == vB || vA == vB || vB == vC){
i--;
model.numTriangles--;
}
} }
}else }else
model.triangles = nil; model.triangles = nil;
SplitColTrianglesIntoSections(model);
}
void
CFileLoader::SplitColTrianglesIntoSections(CColModel &model)
{
if(model.triangles == nil || model.numTriangles == 0)
return;
model.numTriBBoxes = 1;
model.triBBoxes = new CColTriBBox[1];
model.triBBoxes[0].first = 0;
model.triBBoxes[0].last = model.numTriangles-1;
CVector v = model.vertices[model.triangles[0].a].Get();
model.triBBoxes[0].Set(v, v);
for(int i = 0; i < model.numTriangles; i++){
CVector vA = model.vertices[model.triangles[i].a].Get();
CVector vB = model.vertices[model.triangles[i].b].Get();
CVector vC = model.vertices[model.triangles[i].c].Get();
model.triBBoxes[0].min.x = Min(vA.x, model.triBBoxes[0].min.x);
model.triBBoxes[0].min.y = Min(vA.y, model.triBBoxes[0].min.y);
model.triBBoxes[0].min.z = Min(vA.z, model.triBBoxes[0].min.z);
model.triBBoxes[0].min.x = Min(vB.x, model.triBBoxes[0].min.x);
model.triBBoxes[0].min.y = Min(vB.y, model.triBBoxes[0].min.y);
model.triBBoxes[0].min.z = Min(vB.z, model.triBBoxes[0].min.z);
model.triBBoxes[0].min.x = Min(vC.x, model.triBBoxes[0].min.x);
model.triBBoxes[0].min.y = Min(vC.y, model.triBBoxes[0].min.y);
model.triBBoxes[0].min.z = Min(vC.z, model.triBBoxes[0].min.z);
model.triBBoxes[0].max.x = Max(vA.x, model.triBBoxes[0].max.x);
model.triBBoxes[0].max.y = Max(vA.y, model.triBBoxes[0].max.y);
model.triBBoxes[0].max.z = Max(vA.z, model.triBBoxes[0].max.z);
model.triBBoxes[0].max.x = Max(vB.x, model.triBBoxes[0].max.x);
model.triBBoxes[0].max.y = Max(vB.y, model.triBBoxes[0].max.y);
model.triBBoxes[0].max.z = Max(vB.z, model.triBBoxes[0].max.z);
model.triBBoxes[0].max.x = Max(vC.x, model.triBBoxes[0].max.x);
model.triBBoxes[0].max.y = Max(vC.y, model.triBBoxes[0].max.y);
model.triBBoxes[0].max.z = Max(vC.z, model.triBBoxes[0].max.z);
}
} }
static void static void

View file

@ -11,6 +11,7 @@ public:
static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot); static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot);
static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot); static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot);
static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name); static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name);
static void SplitColTrianglesIntoSections(CColModel &model);
static void LoadModelFile(const char *filename); static void LoadModelFile(const char *filename);
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data); static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
static void LoadClumpFile(const char *filename); static void LoadClumpFile(const char *filename);

View file

@ -88,6 +88,7 @@ bool gUseChunkFiles = false;
bool gSecondExportPass; bool gSecondExportPass;
bool gUseModelResources; bool gUseModelResources;
bool gUseResources; bool gUseResources;
bool gNASTY_NASTY_MEM_SHUTDOWN_HACK; // rather unused
float FramesPerSecond = 30.0f; float FramesPerSecond = 30.0f;

View file

@ -30,6 +30,7 @@ extern bool gUseChunkFiles;
extern bool gSecondExportPass; extern bool gSecondExportPass;
extern bool gUseModelResources; extern bool gUseModelResources;
extern bool gUseResources; extern bool gUseResources;
extern bool gNASTY_NASTY_MEM_SHUTDOWN_HACK;
class CSprite2d; class CSprite2d;