1
0
Fork 0
mirror of https://git.rip/DMCA_FUCKER/re3.git synced 2024-11-06 05:25:55 +00:00

CSimpleModelInfo

This commit is contained in:
aap 2021-01-24 13:40:33 +01:00
parent c1a7ded1e4
commit 8cbae5d62a
8 changed files with 300 additions and 44 deletions

View file

@ -607,11 +607,14 @@ CFileLoader::LoadObjectTypes(const char *filename)
int section; int section;
int pathIndex; int pathIndex;
int id, pathType; int id, pathType;
int minID, maxID; //int minID, maxID;
for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
m_sTempIdeData[i].id = -1;
section = NONE; section = NONE;
minID = INT32_MAX; //minID = INT32_MAX;
maxID = -1; //maxID = -1;
pathIndex = -1; pathIndex = -1;
debug("Loading object types from %s...\n", filename); debug("Loading object types from %s...\n", filename);
@ -635,13 +638,13 @@ CFileLoader::LoadObjectTypes(const char *filename)
}else switch(section){ }else switch(section){
case OBJS: case OBJS:
id = LoadObject(line); id = LoadObject(line);
if(id > maxID) maxID = id; //if(id > maxID) maxID = id;
if(id < minID) minID = id; //if(id < minID) minID = id;
break; break;
case TOBJ: case TOBJ:
id = LoadTimeObject(line); id = LoadTimeObject(line);
if(id > maxID) maxID = id; //if(id > maxID) maxID = id;
if(id < minID) minID = id; //if(id < minID) minID = id;
break; break;
case WEAP: case WEAP:
LoadWeaponObject(line); LoadWeaponObject(line);
@ -678,10 +681,10 @@ CFileLoader::LoadObjectTypes(const char *filename)
} }
CFileMgr::CloseFile(fd); CFileMgr::CloseFile(fd);
for(id = minID; id <= maxID; id++){ for(id = 0; id < MODELINFOSIZE; id++){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi && mi->IsBuilding()) if(mi && mi->IsBuilding())
mi->SetupBigBuilding(minID, maxID); mi->SetupBigBuilding();
} }
} }
@ -714,6 +717,13 @@ CFileLoader::LoadObject(const char *line)
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4) if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
return 0; // game returns return value return 0; // game returns return value
for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
if(m_sTempIdeData[i].id == -1){
m_sTempIdeData[i].id = id;
strcpy(m_sTempIdeData[i].name, model);
break;
}
switch(numObjs){ switch(numObjs){
case 1: case 1:
sscanf(line, "%d %s %s %d %f %d", sscanf(line, "%d %s %s %d %f %d",
@ -762,6 +772,13 @@ CFileLoader::LoadTimeObject(const char *line)
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4) if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
return 0; // game returns return value return 0; // game returns return value
for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
if(m_sTempIdeData[i].id < 0){
m_sTempIdeData[i].id = id;
strcpy(m_sTempIdeData[i].name, model);
break;
}
switch(numObjs){ switch(numObjs){
case 1: case 1:
sscanf(line, "%d %s %s %d %f %d %d %d", sscanf(line, "%d %s %s %d %f %d %d %d",

14
src/core/Leeds.cpp Normal file
View file

@ -0,0 +1,14 @@
#include "common.h"
#include "Leeds.h"
void LoadResource(RpAtomic *atomic) {}
void LoadResource(RpClump *clump) {}
void SaveResource(RwTexture *tex, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RwTexDictionary *txd, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpMaterial *mat, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpMaterialList *matlist, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpGeometry *geo, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpAtomic *atomic, base::cRelocatableChunkWriter &writer) {}
void SaveResource(RpClump *clump, base::cRelocatableChunkWriter &writer) {}

36
src/core/Leeds.h Normal file
View file

@ -0,0 +1,36 @@
#pragma once
/*
PatchElementModelInfo(RslElement *,void *)
ChunkName(char const*)
DestroyAndFreeResourceImage(void)
WriteOrder(char const*)
UnpatchTextures(void)
IsChunked(int)
SaveResourceImage(void)
LoadResourceImage(void)
SaveResource(RslNode *,base::cRelocatableChunkWriter &)
SaveResource(RslTAnimTree *,base::cRelocatableChunkWriter &)
SaveResource(RslSkin *,base::cRelocatableChunkWriter &)
SaveResource(CAnimBlendTree *,base::cRelocatableChunkWriter &)
PatchElementTextures(RslElement *)
PatchElementGroupTextures(RslElementGroup *)
*/
void LoadResource(RpAtomic *atomic);
void LoadResource(RpClump *clump);
/*
cRelocatableChunkWriterGTA::Save(char const*,uint,uint,bool)
cRelocatableChunkGTA::cRelocatableChunkGTA(char const*,uint,uint,bool)
SaveAnimBlock(int)
SaveModel(int,bool)
*/
void SaveResource(RwTexture *tex, base::cRelocatableChunkWriter &writer);
void SaveResource(RwTexDictionary *txd, base::cRelocatableChunkWriter &writer);
void SaveResource(RpMaterial *mat, base::cRelocatableChunkWriter &writer);
void SaveResource(RpMaterialList *matlist, base::cRelocatableChunkWriter &writer);
void SaveResource(RpGeometry *geo, base::cRelocatableChunkWriter &writer);
void SaveResource(RpAtomic *atomic, base::cRelocatableChunkWriter &writer);
void SaveResource(RpClump *clump, base::cRelocatableChunkWriter &writer);

View file

@ -13,6 +13,7 @@
//struct RpMaterial; //struct RpMaterial;
typedef rw::Material RpMaterial; typedef rw::Material RpMaterial;
typedef rw::MaterialList RpMaterialList;
typedef RpMaterial *(*RpMaterialCallBack)(RpMaterial *material, void *data); typedef RpMaterial *(*RpMaterialCallBack)(RpMaterial *material, void *data);

View file

@ -19,6 +19,8 @@ namespace base
void* Shrink(void* data); void* Shrink(void* data);
}; };
#define VTABLE_ADDR(obj) ((void*)obj) // TODO: make this portable
class cRelocatableChunkClassInfo class cRelocatableChunkClassInfo
{ {
public: public:

View file

@ -57,10 +57,13 @@ public:
virtual void ConvertAnimFileIndex(void) {} virtual void ConvertAnimFileIndex(void) {}
virtual int GetAnimFileIndex(void) { return -1; } virtual int GetAnimFileIndex(void) { return -1; }
virtual void LoadModel(void *,void const*) {}; // = 0; virtual void LoadModel(void *model, const void *chunk) {}; // = 0;
virtual void DeleteChunk(void); virtual void DeleteChunk(void);
// this writes the modelinfo struct, possibly including actual RW models
virtual void Write(base::cRelocatableChunkWriter &writer); virtual void Write(base::cRelocatableChunkWriter &writer);
virtual void WriteModel(base::cRelocatableChunkWriter &writer) {} // = 0; // this writes the RW models
virtual void *WriteModel(base::cRelocatableChunkWriter &writer) { return nil; } // = 0; // this is not in the vtable for some reason???
// these allocate the space for a modelinfo struct and patch the vtable pointer
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer) {} // = 0; virtual void RcWriteThis(base::cRelocatableChunkWriter &writer) {} // = 0;
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer) {} // = 0; virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer) {} // = 0;

View file

@ -1,18 +1,29 @@
#include "common.h" #include "common.h"
#include "main.h"
#include "General.h" #include "General.h"
#include "Renderer.h"
#include "Camera.h" #include "Camera.h"
#include "ModelInfo.h" #include "ModelInfo.h"
#include "AnimManager.h" #include "AnimManager.h"
#include "custompipes.h" #include "custompipes.h"
#include "Streaming.h"
#include "smallHeap.h"
#include "Leeds.h"
#define LOD_DISTANCE (300.0f) TempIdeData m_sTempIdeData[800];
base::cRelocatableChunkClassInfo CSimpleModelInfo::msClassInfo("CSimpleModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
CSimpleModelInfo CSimpleModelInfo::msClassInstance;
void void
CSimpleModelInfo::DeleteRwObject(void) CSimpleModelInfo::DeleteRwObject(void)
{ {
int i; int i;
RwFrame *f; RwFrame *f;
if(m_atomics == nil)
return;
if(!gUseChunkFiles){
for(i = 0; i < m_numAtomics; i++) for(i = 0; i < m_numAtomics; i++)
if(m_atomics[i]){ if(m_atomics[i]){
f = RpAtomicGetFrame(m_atomics[i]); f = RpAtomicGetFrame(m_atomics[i]);
@ -23,16 +34,27 @@ CSimpleModelInfo::DeleteRwObject(void)
if(GetAnimFileIndex() != -1) if(GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex()); CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
} }
}else if(m_chunk){
CStreaming::UnregisterPointer(&m_atomics, 2);
for(i = 0; i < m_numAtomics; i++)
CStreaming::UnregisterAtomic(m_atomics[i], nil);
DeleteChunk();
RemoveTexDictionaryRef();
if(GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
}
m_atomics = nil;
} }
RwObject* RwObject*
CSimpleModelInfo::CreateInstance(void) CSimpleModelInfo::CreateInstance(void)
{ {
RpAtomic *atomic; RpAtomic *atomic;
if(m_atomics[0] == nil) if(m_atomics && m_atomics[0] == nil)
return nil; return nil;
atomic = RpAtomicClone(m_atomics[0]); atomic = RpAtomicClone(m_atomics[0]);
RpAtomicSetFrame(atomic, RwFrameCreate()); RpAtomicSetFrame(atomic, RwFrameCreate());
CStreaming::RegisterInstance(atomic, nil);
return (RwObject*)atomic; return (RwObject*)atomic;
} }
@ -42,21 +64,20 @@ CSimpleModelInfo::CreateInstance(RwMatrix *matrix)
RpAtomic *atomic; RpAtomic *atomic;
RwFrame *frame; RwFrame *frame;
if(m_atomics[0] == nil) if(m_atomics && m_atomics[0] == nil)
return nil; return nil;
atomic = RpAtomicClone(m_atomics[0]); atomic = RpAtomicClone(m_atomics[0]);
frame = RwFrameCreate(); frame = RwFrameCreate();
*RwFrameGetMatrix(frame) = *matrix; *RwFrameGetMatrix(frame) = *matrix;
RpAtomicSetFrame(atomic, frame); RpAtomicSetFrame(atomic, frame);
CStreaming::RegisterInstance(atomic, nil);
return (RwObject*)atomic; return (RwObject*)atomic;
} }
void void
CSimpleModelInfo::Init(void) CSimpleModelInfo::Init(void)
{ {
m_atomics[0] = nil; m_atomics = new RpAtomic*[3];
m_atomics[1] = nil;
m_atomics[2] = nil;
m_numAtomics = 0; m_numAtomics = 0;
m_firstDamaged = 0; m_firstDamaged = 0;
m_wetRoadReflection = 0; m_wetRoadReflection = 0;
@ -72,21 +93,30 @@ CSimpleModelInfo::Init(void)
m_ignoreDrawDist = 0; m_ignoreDrawDist = 0;
m_isCodeGlass = 0; m_isCodeGlass = 0;
m_isArtistGlass = 0; m_isArtistGlass = 0;
m_relatedModel = nil;
} }
void void
CSimpleModelInfo::SetAtomic(int n, RpAtomic *atomic) CSimpleModelInfo::SetAtomic(int n, RpAtomic *atomic)
{ {
AddTexDictionaryRef(); if(m_atomics == nil){
m_atomics = new RpAtomic*[3];
m_atomics[0] = nil;
m_atomics[1] = nil;
m_atomics[2] = nil;
}
m_atomics[n] = atomic; m_atomics[n] = atomic;
AddTexDictionaryRef();
if(GetAnimFileIndex() != -1) if(GetAnimFileIndex() != -1)
CAnimManager::AddAnimBlockRef(GetAnimFileIndex()); CAnimManager::AddAnimBlockRef(GetAnimFileIndex());
RpGeometry *geo = RpAtomicGetGeometry(atomic); RpGeometry *geo = RpAtomicGetGeometry(atomic);
if(m_ignoreLight) if(m_ignoreLight)
RpGeometrySetFlags(geo, RpGeometryGetFlags(geo) & ~rpGEOMETRYLIGHT); RpGeometrySetFlags(geo, RpGeometryGetFlags(geo) & ~rpGEOMETRYLIGHT);
/*
if(RpGeometryGetFlags(geo) & rpGEOMETRYNORMALS && if(RpGeometryGetFlags(geo) & rpGEOMETRYNORMALS &&
RpGeometryGetNumTriangles(geo) > 200) RpGeometryGetNumTriangles(geo) > 200)
debug("%s has %d polys\n", m_name, RpGeometryGetNumTriangles(geo)); debug("%s has %d polys\n", m_name, RpGeometryGetNumTriangles(geo));
*/
#ifdef EXTENDED_PIPELINES #ifdef EXTENDED_PIPELINES
if(m_wetRoadReflection) if(m_wetRoadReflection)
@ -136,6 +166,40 @@ CSimpleModelInfo::GetLargestLodDistance(void)
return d * TheCamera.LODDistMultiplier; return d * TheCamera.LODDistMultiplier;
} }
RpAtomic*
CSimpleModelInfo::GetLodAtomic(int n)
{
if(m_atomics == nil || n >= m_numAtomics)
return nil;
return m_atomics[n];
}
RpAtomic*
CSimpleModelInfo::GetLastAtomic(void)
{
if(m_atomics == nil)
return nil;
if(m_firstDamaged == 0 || m_isDamaged)
return m_atomics[m_numAtomics-1];
else
return m_atomics[m_firstDamaged-1];
}
RpAtomic*
CSimpleModelInfo::GetLastAtomic(float dist)
{
int n;
if(m_atomics == nil)
return nil;
if(m_firstDamaged == 0 || m_isDamaged)
n = m_numAtomics-1;
else
n = m_firstDamaged-1;
if(dist < m_lodDistances[n] * TheCamera.LODDistMultiplier)
return m_atomics[n];
return nil;
}
RpAtomic* RpAtomic*
CSimpleModelInfo::GetAtomicFromDistance(float dist) CSimpleModelInfo::GetAtomicFromDistance(float dist)
{ {
@ -152,20 +216,40 @@ CSimpleModelInfo::GetAtomicFromDistance(float dist)
RpAtomic* RpAtomic*
CSimpleModelInfo::GetFirstAtomicFromDistance(float dist) CSimpleModelInfo::GetFirstAtomicFromDistance(float dist)
{ {
// HACk until we figure out what's going on
if(m_atomics == nil) return nil;
if(dist < m_lodDistances[0] * TheCamera.LODDistMultiplier) if(dist < m_lodDistances[0] * TheCamera.LODDistMultiplier)
return m_atomics[0]; return m_atomics[0];
return nil; return nil;
} }
void void
CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID) CSimpleModelInfo::FindRelatedModel(void)
{ {
int i;
CBaseModelInfo *mi; CBaseModelInfo *mi;
for(i = minID; i <= maxID; i++){ int thisIndex, otherIndex;
mi = CModelInfo::GetModelInfo(i);
// find our own index in temp data
for(thisIndex = 0; thisIndex < ARRAY_SIZE(m_sTempIdeData); thisIndex++){
if(m_sTempIdeData[thisIndex].id == -1)
break;
if(this == CModelInfo::GetModelInfo(m_sTempIdeData[thisIndex].id))
goto found;
}
thisIndex = -1;
found:
#ifdef FIX_BUGS
if(thisIndex == -1)
return;
#endif
for(otherIndex = 0; otherIndex < ARRAY_SIZE(m_sTempIdeData); otherIndex++){
if(m_sTempIdeData[otherIndex].id == -1)
break;
mi = CModelInfo::GetModelInfo(m_sTempIdeData[otherIndex].id);
if(mi && mi != this && if(mi && mi != this &&
!CGeneral::faststrcmp(GetModelName()+3, mi->GetModelName()+3)){ !CGeneral::faststrcmp(m_sTempIdeData[thisIndex].name+3, m_sTempIdeData[otherIndex].name+3)){
assert(mi->IsSimple()); assert(mi->IsSimple());
this->SetRelatedModel((CSimpleModelInfo*)mi); this->SetRelatedModel((CSimpleModelInfo*)mi);
return; return;
@ -176,12 +260,14 @@ CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID)
#define NEAR_DRAW_DIST 100.0f // 0.0f in vice city #define NEAR_DRAW_DIST 100.0f // 0.0f in vice city
void void
CSimpleModelInfo::SetupBigBuilding(int32 minID, int32 maxID) CSimpleModelInfo::SetupBigBuilding(void)
{ {
CSimpleModelInfo *related; CSimpleModelInfo *related;
if(m_lodDistances[0] > LOD_DISTANCE && GetRelatedModel() == nil){ if(m_lodDistances[0] < 0.0f)
m_lodDistances[0] = -m_lodDistances[0]; // what?
else if(m_lodDistances[0] > LOD_DISTANCE && GetRelatedModel() == nil){
m_isBigBuilding = 1; m_isBigBuilding = 1;
FindRelatedModel(minID, maxID); FindRelatedModel();
related = GetRelatedModel(); related = GetRelatedModel();
if(related){ if(related){
m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier; m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier;
@ -193,3 +279,79 @@ CSimpleModelInfo::SetupBigBuilding(int32 minID, int32 maxID)
m_lodDistances[2] = NEAR_DRAW_DIST; m_lodDistances[2] = NEAR_DRAW_DIST;
} }
} }
void
CSimpleModelInfo::LoadModel(void *atomics, const void *chunk)
{
int i;
m_chunk = (void*)chunk;
m_atomics = (RpAtomic**)atomics;
CStreaming::RegisterPointer(m_chunk, 2, true);
CStreaming::RegisterPointer(m_atomics, 2, true);
for(i = 0; i < m_numAtomics; i++){
LoadResource(m_atomics[i]);
CStreaming::RegisterAtomic(m_atomics[i], nil);
}
}
void
CSimpleModelInfo::Write(base::cRelocatableChunkWriter &writer)
{
CBaseModelInfo::Write(writer);
if(WriteModel(writer))
writer.AddPatch(&m_atomics);
else
m_atomics = nil;
if(m_isBigBuilding)
writer.AddPatch(&m_relatedModel);
}
void*
CSimpleModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
{
int i;
if(m_atomics == nil || m_atomics[0] == nil)
return nil;
// remove empty atomics
int numAtomics = 0;
for(i = 0; i < m_numAtomics; i++)
if(m_atomics[i]){
m_atomics[numAtomics] = m_atomics[i];
#ifdef FIX_BUGS
m_lodDistances[numAtomics] = m_lodDistances[i];
#endif
numAtomics++;
}
if(m_firstDamaged){
int firstDam = m_firstDamaged - m_numAtomics + numAtomics;
if(firstDam < numAtomics)
m_firstDamaged = firstDam;
else
m_firstDamaged = 0;
}
m_numAtomics = numAtomics;
// write the actual models
writer.AllocateRaw(m_atomics, m_numAtomics*sizeof(void*), sizeof(void*), false, true);
for(i = 0; m_numAtomics; i++){
writer.AddPatch(&m_atomics[i]);
SaveResource(m_atomics[i], writer);
}
return m_atomics;
}
void
CSimpleModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), 0x10, false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}
void
CSimpleModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
{
writer.AllocateRaw(this, sizeof(*this), 0x10, false, true);
writer.Class(VTABLE_ADDR(this), msClassInfo);
}

View file

@ -2,11 +2,18 @@
#include "BaseModelInfo.h" #include "BaseModelInfo.h"
// For linking up models by name
struct TempIdeData
{
char name[24];
int16 id;
};
extern TempIdeData m_sTempIdeData[800];
class CSimpleModelInfo : public CBaseModelInfo class CSimpleModelInfo : public CBaseModelInfo
{ {
public: public:
// atomics[2] is often a pointer to the non-LOD modelinfo RpAtomic **m_atomics;
RpAtomic *m_atomics[3];
// m_lodDistances[2] holds the near distance for LODs // m_lodDistances[2] holds the near distance for LODs
float m_lodDistances[3]; float m_lodDistances[3];
uint8 m_numAtomics; uint8 m_numAtomics;
@ -31,15 +38,26 @@ public:
uint16 m_isCodeGlass : 1; uint16 m_isCodeGlass : 1;
uint16 m_isArtistGlass : 1; uint16 m_isArtistGlass : 1;
CSimpleModelInfo *m_relatedModel;
static base::cRelocatableChunkClassInfo msClassInfo;
static CSimpleModelInfo msClassInstance;
CSimpleModelInfo(void) : CBaseModelInfo(MITYPE_SIMPLE) {} CSimpleModelInfo(void) : CBaseModelInfo(MITYPE_SIMPLE) {}
CSimpleModelInfo(ModelInfoType id) : CBaseModelInfo(id) {} CSimpleModelInfo(ModelInfoType id) : CBaseModelInfo(id) {}
~CSimpleModelInfo() {} ~CSimpleModelInfo() {}
void DeleteRwObject(void); void DeleteRwObject(void);
RwObject *CreateInstance(void); RwObject *CreateInstance(void);
RwObject *CreateInstance(RwMatrix *); RwObject *CreateInstance(RwMatrix *);
RwObject *GetRwObject(void) { return (RwObject*)m_atomics[0]; } RwObject *GetRwObject(void) { return m_atomics ? (RwObject*)m_atomics[0] : nil; }
virtual void SetAtomic(int n, RpAtomic *atomic); virtual void LoadModel(void *atomics, const void *chunk);
virtual void Write(base::cRelocatableChunkWriter &writer);
virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
virtual void SetAtomic(int n, RpAtomic *atomic); // TODO: remove this
void Init(void); void Init(void);
void IncreaseAlpha(void); void IncreaseAlpha(void);
@ -47,15 +65,18 @@ public:
float GetLodDistance(int i); float GetLodDistance(int i);
float GetNearDistance(void); float GetNearDistance(void);
float GetLargestLodDistance(void); float GetLargestLodDistance(void);
RpAtomic *GetLodAtomic(int n);
RpAtomic *GetLastAtomic(void);
RpAtomic *GetLastAtomic(float dist);
RpAtomic *GetAtomicFromDistance(float dist); RpAtomic *GetAtomicFromDistance(float dist);
RpAtomic *GetFirstAtomicFromDistance(float dist); RpAtomic *GetFirstAtomicFromDistance(float dist);
void FindRelatedModel(int32 minID, int32 maxID); void FindRelatedModel(void);
void SetupBigBuilding(int32 minID, int32 maxID); void SetupBigBuilding(void);
void SetNumAtomics(int n) { m_numAtomics = n; } void SetNumAtomics(int n) { m_numAtomics = n; }
CSimpleModelInfo *GetRelatedModel(void){ CSimpleModelInfo *GetRelatedModel(void){
return (CSimpleModelInfo*)m_atomics[2]; } return m_relatedModel; }
void SetRelatedModel(CSimpleModelInfo *m){ void SetRelatedModel(CSimpleModelInfo *m){
m_atomics[2] = (RpAtomic*)m; } m_relatedModel = m; }
}; };
//static_assert(sizeof(CSimpleModelInfo) == 0x4C, "CSimpleModelInfo: error"); //static_assert(sizeof(CSimpleModelInfo) == 0x4C, "CSimpleModelInfo: error");