[IXModel] Use correct XModel structure
This commit is contained in:
parent
85c9488c2a
commit
7d9c588e0e
@ -29,16 +29,18 @@ namespace Assets
|
||||
Components::Logger::Error(0, "Reading model '%s' failed, expected version is %d, but it was %d!", name.data(), IW4X_MODEL_VERSION, version);
|
||||
}
|
||||
|
||||
ZeroMemory(model->noScalePartBits, sizeof model->noScalePartBits);
|
||||
|
||||
model->name = reader.readCString();
|
||||
model->numBones = reader.readByte();
|
||||
model->numRootBones = reader.readByte();
|
||||
model->numSurfaces = reader.read<unsigned char>();
|
||||
model->numColSurfs = reader.read<int>();
|
||||
model->numsurfs = reader.read<unsigned char>();
|
||||
model->numCollSurfs = reader.read<int>();
|
||||
model->numLods = static_cast<char>(reader.read<short>());
|
||||
model->collLod = reader.read<short>();
|
||||
model->collLod = static_cast<char>(reader.read<short>());
|
||||
|
||||
// Read bone names
|
||||
model->boneNames = builder->getAllocator()->allocateArray<short>(model->numBones);
|
||||
model->boneNames = builder->getAllocator()->allocateArray<unsigned short>(model->numBones);
|
||||
for (int i = 0; i < model->numBones; ++i)
|
||||
{
|
||||
model->boneNames[i] = Game::SL_GetString(reader.readCString(), 0);
|
||||
@ -49,32 +51,32 @@ namespace Assets
|
||||
|
||||
// Read bone data
|
||||
model->parentList = reader.readArray<char>(boneCount);
|
||||
model->tagAngles = reader.readArray<Game::XModelAngle>(boneCount);
|
||||
model->tagPositions = reader.readArray<Game::XModelTagPos>(boneCount);
|
||||
model->quats = reader.readArray<short>(boneCount * 4);
|
||||
model->trans = reader.readArray<float>(boneCount * 3);
|
||||
model->partClassification = reader.readArray<char>(boneCount);
|
||||
model->animMatrix = reader.readArray<Game::DObjAnimMat>(boneCount);
|
||||
model->baseMat = reader.readArray<Game::DObjAnimMat>(boneCount);
|
||||
|
||||
// Prepare surfaces
|
||||
Game::XModelSurfs surf;
|
||||
Utils::Memory::Allocator allocator;
|
||||
Game::XSurface* baseSurface = &baseModel->lods[0].modelSurfs[0].surfaces[0];
|
||||
Game::XSurface* baseSurface = &baseModel->lodInfo[0].modelSurfs[0].surfaces[0];
|
||||
|
||||
std::memcpy(&surf, baseModel->lods[0].modelSurfs, sizeof(Game::XModelSurfs));
|
||||
surf.surfaces = allocator.allocateArray<Game::XSurface>(model->numSurfaces);
|
||||
surf.numSurfaces = model->numSurfaces;
|
||||
std::memcpy(&surf, baseModel->lodInfo[0].modelSurfs, sizeof(Game::XModelSurfs));
|
||||
surf.surfaces = allocator.allocateArray<Game::XSurface>(model->numsurfs);
|
||||
surf.numSurfaces = model->numsurfs;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
model->lods[i].dist = reader.read<float>();
|
||||
model->lods[i].numsurfs = reader.read<unsigned short>();
|
||||
model->lods[i].surfIndex = reader.read<unsigned short>();
|
||||
model->lodInfo[i].dist = reader.read<float>();
|
||||
model->lodInfo[i].numsurfs = reader.read<unsigned short>();
|
||||
model->lodInfo[i].surfIndex = reader.read<unsigned short>();
|
||||
|
||||
model->lods[i].partBits[0] = reader.read<int>();
|
||||
model->lods[i].partBits[1] = reader.read<int>();
|
||||
model->lods[i].partBits[2] = reader.read<int>();
|
||||
model->lods[i].partBits[3] = reader.read<int>();
|
||||
model->lods[i].partBits[4] = 0;
|
||||
model->lods[i].partBits[5] = 0;
|
||||
model->lodInfo[i].partBits[0] = reader.read<int>();
|
||||
model->lodInfo[i].partBits[1] = reader.read<int>();
|
||||
model->lodInfo[i].partBits[2] = reader.read<int>();
|
||||
model->lodInfo[i].partBits[3] = reader.read<int>();
|
||||
model->lodInfo[i].partBits[4] = 0;
|
||||
model->lodInfo[i].partBits[5] = 0;
|
||||
}
|
||||
|
||||
// Read surfaces
|
||||
@ -139,42 +141,42 @@ namespace Assets
|
||||
// Usually, a binary representation is used for the index, but meh.
|
||||
realSurf->name = builder->getAllocator()->duplicateString(fmt::sprintf("%s_lod%d", model->name, i & 0xFF));
|
||||
|
||||
realSurf->numSurfaces = model->lods[i].numsurfs;
|
||||
realSurf->numSurfaces = model->lodInfo[i].numsurfs;
|
||||
realSurf->surfaces = builder->getAllocator()->allocateArray<Game::XSurface>(realSurf->numSurfaces);
|
||||
|
||||
std::memcpy(realSurf->surfaces, &surf.surfaces[model->lods[i].surfIndex], sizeof(Game::XSurface) * realSurf->numSurfaces);
|
||||
std::memcpy(realSurf->partBits, model->lods[i].partBits, sizeof(realSurf->partBits));
|
||||
std::memcpy(realSurf->surfaces, &surf.surfaces[model->lodInfo[i].surfIndex], sizeof(Game::XSurface) * realSurf->numSurfaces);
|
||||
std::memcpy(realSurf->partBits, model->lodInfo[i].partBits, sizeof(realSurf->partBits));
|
||||
|
||||
model->lods[i].modelSurfs = realSurf;
|
||||
model->lods[i].surfs = realSurf->surfaces;
|
||||
model->lodInfo[i].modelSurfs = realSurf;
|
||||
model->lodInfo[i].surfs = realSurf->surfaces;
|
||||
|
||||
// Store surfs for later writing
|
||||
Components::AssetHandler::StoreTemporaryAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, { realSurf });
|
||||
}
|
||||
|
||||
// Read materials
|
||||
model->materials = builder->getAllocator()->allocateArray<Game::Material*>(model->numSurfaces);
|
||||
for (unsigned char i = 0; i < model->numSurfaces; ++i)
|
||||
model->materialHandles = builder->getAllocator()->allocateArray<Game::Material*>(model->numsurfs);
|
||||
for (char i = 0; i < model->numsurfs; ++i)
|
||||
{
|
||||
model->materials[i] = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MATERIAL, reader.readString(), builder).material;
|
||||
model->materialHandles[i] = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MATERIAL, reader.readString(), builder).material;
|
||||
}
|
||||
|
||||
// Read collision surfaces
|
||||
if (reader.readByte())
|
||||
{
|
||||
model->colSurf = reader.readArray<Game::XModelCollSurf>(model->numColSurfs);
|
||||
model->collSurfs = reader.readArray<Game::XModelCollSurf_s>(model->numCollSurfs);
|
||||
|
||||
for (int i = 0; i < model->numColSurfs; ++i)
|
||||
for (int i = 0; i < model->numCollSurfs; ++i)
|
||||
{
|
||||
if (model->colSurf[i].collTris)
|
||||
if (model->collSurfs[i].collTris)
|
||||
{
|
||||
model->colSurf[i].collTris = reader.readArray<Game::XModelCollTri_s>(model->colSurf[i].numCollTris);
|
||||
model->collSurfs[i].collTris = reader.readArray<Game::XModelCollTri_s>(model->collSurfs[i].numCollTris);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model->colSurf = nullptr;
|
||||
model->collSurfs = nullptr;
|
||||
}
|
||||
|
||||
// Read bone info
|
||||
@ -208,22 +210,22 @@ namespace Assets
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->materials)
|
||||
if (asset->materialHandles)
|
||||
{
|
||||
for (unsigned char i = 0; i < asset->numSurfaces; ++i)
|
||||
for (unsigned char i = 0; i < asset->numsurfs; ++i)
|
||||
{
|
||||
if (asset->materials[i])
|
||||
if (asset->materialHandles[i])
|
||||
{
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materials[i]);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materialHandles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (asset->lods[i].modelSurfs)
|
||||
if (asset->lodInfo[i].modelSurfs)
|
||||
{
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].modelSurfs);
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lodInfo[i].modelSurfs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,22 +278,18 @@ namespace Assets
|
||||
Utils::Stream::ClearPointer(&dest->parentList);
|
||||
}
|
||||
|
||||
if (asset->tagAngles)
|
||||
if (asset->quats)
|
||||
{
|
||||
AssertSize(Game::XModelAngle, 8);
|
||||
|
||||
buffer->align(Utils::Stream::ALIGN_2);
|
||||
buffer->saveArray(asset->tagAngles, asset->numBones - asset->numRootBones);
|
||||
Utils::Stream::ClearPointer(&dest->tagAngles);
|
||||
buffer->saveArray(asset->quats, (asset->numBones - asset->numRootBones) * 4);
|
||||
Utils::Stream::ClearPointer(&dest->quats);
|
||||
}
|
||||
|
||||
if (asset->tagPositions)
|
||||
if (asset->trans)
|
||||
{
|
||||
AssertSize(Game::XModelTagPos, 12);
|
||||
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(asset->tagPositions, asset->numBones - asset->numRootBones);
|
||||
Utils::Stream::ClearPointer(&dest->tagPositions);
|
||||
buffer->saveArray(asset->trans, (asset->numBones - asset->numRootBones) * 3);
|
||||
Utils::Stream::ClearPointer(&dest->trans);
|
||||
}
|
||||
|
||||
if (asset->partClassification)
|
||||
@ -300,31 +298,31 @@ namespace Assets
|
||||
Utils::Stream::ClearPointer(&dest->partClassification);
|
||||
}
|
||||
|
||||
if (asset->animMatrix)
|
||||
if (asset->baseMat)
|
||||
{
|
||||
AssertSize(Game::DObjAnimMat, 32);
|
||||
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(asset->animMatrix, asset->numBones);
|
||||
Utils::Stream::ClearPointer(&dest->animMatrix);
|
||||
buffer->saveArray(asset->baseMat, asset->numBones);
|
||||
Utils::Stream::ClearPointer(&dest->baseMat);
|
||||
}
|
||||
|
||||
if (asset->materials)
|
||||
if (asset->materialHandles)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
|
||||
Game::Material** destMaterials = buffer->dest<Game::Material*>();
|
||||
buffer->saveArray(asset->materials, asset->numSurfaces);
|
||||
buffer->saveArray(asset->materialHandles, asset->numsurfs);
|
||||
|
||||
for (unsigned char i = 0; i < asset->numSurfaces; ++i)
|
||||
for (unsigned char i = 0; i < asset->numsurfs; ++i)
|
||||
{
|
||||
if (asset->materials[i])
|
||||
if (asset->materialHandles[i])
|
||||
{
|
||||
destMaterials[i] = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materials[i]).material;
|
||||
destMaterials[i] = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materialHandles[i]).material;
|
||||
}
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->materials);
|
||||
Utils::Stream::ClearPointer(&dest->materialHandles);
|
||||
}
|
||||
|
||||
// Save_XModelLodInfoArray
|
||||
@ -333,38 +331,38 @@ namespace Assets
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (asset->lods[i].modelSurfs)
|
||||
if (asset->lodInfo[i].modelSurfs)
|
||||
{
|
||||
dest->lods[i].modelSurfs = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].modelSurfs).surfaces;
|
||||
dest->lodInfo[i].modelSurfs = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lodInfo[i].modelSurfs).surfaces;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save_XModelCollSurfArray
|
||||
if (asset->colSurf)
|
||||
if (asset->collSurfs)
|
||||
{
|
||||
AssertSize(Game::XModelCollSurf, 44);
|
||||
AssertSize(Game::XModelCollSurf_s, 44);
|
||||
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
|
||||
Game::XModelCollSurf* destColSurfs = buffer->dest<Game::XModelCollSurf>();
|
||||
buffer->saveArray(asset->colSurf, asset->numColSurfs);
|
||||
Game::XModelCollSurf_s* destColSurfs = buffer->dest<Game::XModelCollSurf_s>();
|
||||
buffer->saveArray(asset->collSurfs, asset->numCollSurfs);
|
||||
|
||||
for (int i = 0; i < asset->numColSurfs; ++i)
|
||||
for (int i = 0; i < asset->numCollSurfs; ++i)
|
||||
{
|
||||
Game::XModelCollSurf* destColSurf = &destColSurfs[i];
|
||||
Game::XModelCollSurf* colSurf = &asset->colSurf[i];
|
||||
Game::XModelCollSurf_s* destCollSurf = &destColSurfs[i];
|
||||
Game::XModelCollSurf_s* collSurf = &asset->collSurfs[i];
|
||||
|
||||
if (colSurf->collTris)
|
||||
if (collSurf->collTris)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
|
||||
buffer->save(colSurf->collTris, 48, colSurf->numCollTris);
|
||||
Utils::Stream::ClearPointer(&destColSurf->collTris);
|
||||
buffer->save(collSurf->collTris, 48, collSurf->numCollTris);
|
||||
Utils::Stream::ClearPointer(&destCollSurf->collTris);
|
||||
}
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->colSurf);
|
||||
Utils::Stream::ClearPointer(&dest->collSurfs);
|
||||
}
|
||||
|
||||
if (asset->boneInfo)
|
||||
|
@ -152,7 +152,7 @@ namespace Components
|
||||
|
||||
for (char i = 0; i < model->numLods; ++i)
|
||||
{
|
||||
Game::XModelSurfs* surfs = model->lods[i].modelSurfs;
|
||||
Game::XModelSurfs* surfs = model->lodInfo[i].modelSurfs;
|
||||
|
||||
if (!surfs->surfaces)
|
||||
{
|
||||
@ -163,12 +163,12 @@ namespace Components
|
||||
surfs->surfaces = newSurfs->surfaces;
|
||||
surfs->numSurfaces = newSurfs->numSurfaces;
|
||||
|
||||
model->lods[i].surfs = newSurfs->surfaces;
|
||||
std::memcpy(&model->lods[i].partBits, &newSurfs->partBits, 24);
|
||||
model->lodInfo[i].surfs = newSurfs->surfaces;
|
||||
std::memcpy(&model->lodInfo[i].partBits, &newSurfs->partBits, 24);
|
||||
|
||||
short numSurfs = static_cast<short>(newSurfs->numSurfaces);
|
||||
model->lods[i].numsurfs = numSurfs;
|
||||
model->lods[i].surfIndex = surfCount;
|
||||
model->lodInfo[i].numsurfs = numSurfs;
|
||||
model->lodInfo[i].surfIndex = surfCount;
|
||||
surfCount += numSurfs;
|
||||
|
||||
changed = true;
|
||||
|
@ -89,19 +89,19 @@ namespace Components
|
||||
Game::XModel model[2]; // Allocate 2 models, as we exceed the buffer
|
||||
|
||||
std::memcpy(model, xmodel, 36);
|
||||
std::memcpy(&model->pad3[0x1C], &xmodel[44], 28);
|
||||
std::memcpy(&model->boneNames, &xmodel[44], 28);
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
AssertOffset(Game::XModelLodInfo, partBits, 12);
|
||||
|
||||
std::memcpy(&model->lods[i], &xmodel[72 + (i * 56)], 12);
|
||||
std::memcpy(&model->lods[i].partBits, &xmodel[72 + (i * 56) + 16], 32);
|
||||
std::memcpy(&model->lodInfo[i], &xmodel[72 + (i * 56)], 12);
|
||||
std::memcpy(&model->lodInfo[i].partBits, &xmodel[72 + (i * 56) + 16], 32);
|
||||
|
||||
std::memcpy(reinterpret_cast<char*>(&model) + (size - 4) - (i * 4), &xmodel[72 + (i * 56) + 12], 4);
|
||||
}
|
||||
|
||||
std::memcpy(&model->lods[3].pad4[0], &xmodel[292], (size - 292 - 4)/*68*/);
|
||||
std::memcpy(&model->lodInfo[3].lod, &xmodel[292], (size - 292 - 4)/*68*/);
|
||||
std::memcpy(&model->physPreset, &xmodel[(size - 8)], 8);
|
||||
|
||||
model[1].name = reinterpret_cast<char*>(0xDEADC0DE);
|
||||
|
@ -1517,21 +1517,6 @@ namespace Game
|
||||
int error;
|
||||
} structuredDataFindState_t;
|
||||
|
||||
struct XModelAngle
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
short z;
|
||||
short base; // defines the 90-degree point for the shorts
|
||||
};
|
||||
|
||||
struct XModelTagPos
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
struct XSurfaceCollisionTree
|
||||
{
|
||||
float trans[3];
|
||||
@ -1605,7 +1590,10 @@ namespace Game
|
||||
XModelSurfs *modelSurfs;
|
||||
int partBits[6];
|
||||
XSurface *surfs;
|
||||
char pad4[4];
|
||||
char lod;
|
||||
char smcBaseIndexPlusOne;
|
||||
char smcSubIndexMask;
|
||||
char smcBucket;
|
||||
};
|
||||
|
||||
struct cplane_t
|
||||
@ -1683,12 +1671,11 @@ namespace Game
|
||||
float tvec[4];
|
||||
};
|
||||
|
||||
struct XModelCollSurf
|
||||
struct XModelCollSurf_s
|
||||
{
|
||||
XModelCollTri_s *collTris;
|
||||
int numCollTris;
|
||||
float mins[3];
|
||||
float maxs[3];
|
||||
Bounds bounds;
|
||||
int boneIdx;
|
||||
int contents;
|
||||
int surfFlags;
|
||||
@ -1718,31 +1705,36 @@ namespace Game
|
||||
|
||||
struct XModel
|
||||
{
|
||||
const char* name; // +0
|
||||
char numBones; // +4
|
||||
char numRootBones; // +5
|
||||
unsigned char numSurfaces; // +6
|
||||
char pad2; // +7
|
||||
char pad3[28]; // +8
|
||||
short* boneNames; // +36
|
||||
char* parentList; // +40
|
||||
XModelAngle* tagAngles; // +44, element size 8
|
||||
XModelTagPos* tagPositions; // +48, element size 12
|
||||
char* partClassification; // +52
|
||||
DObjAnimMat* animMatrix; // +56, element size 32
|
||||
Material** materials; // +60
|
||||
XModelLodInfo lods[4]; // +64
|
||||
char pad4;
|
||||
const char *name;
|
||||
char numBones;
|
||||
char numRootBones;
|
||||
char numsurfs;
|
||||
char lodRampType;
|
||||
float scale;
|
||||
unsigned int noScalePartBits[6];
|
||||
unsigned __int16 *boneNames;
|
||||
char *parentList;
|
||||
__int16 *quats;
|
||||
float *trans;
|
||||
char *partClassification;
|
||||
DObjAnimMat *baseMat;
|
||||
Material **materialHandles;
|
||||
XModelLodInfo lodInfo[4];
|
||||
char maxLoadedLod;
|
||||
char numLods;
|
||||
short collLod;
|
||||
XModelCollSurf* colSurf; // +244
|
||||
int numColSurfs; // +248
|
||||
char collLod;
|
||||
char flags;
|
||||
XModelCollSurf_s *collSurfs;
|
||||
int numCollSurfs;
|
||||
int contents;
|
||||
XBoneInfo* boneInfo; // bone count, +256, element size 28
|
||||
char pad7[36];
|
||||
PhysPreset* physPreset;
|
||||
PhysCollmap* physCollmap;
|
||||
}; // total size 304
|
||||
XBoneInfo *boneInfo;
|
||||
float radius;
|
||||
Bounds bounds;
|
||||
int memUsage;
|
||||
bool bad;
|
||||
PhysPreset *physPreset;
|
||||
PhysCollmap *physCollmap;
|
||||
};
|
||||
|
||||
struct CModelAllocData
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user