From 7d9c588e0e2dc18adc0f41b06f40d1b1ca32cf75 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 2 Jan 2017 22:35:55 +0100 Subject: [PATCH] [IXModel] Use correct XModel structure --- .../Modules/AssetInterfaces/IXModel.cpp | 140 +++++++++--------- src/Components/Modules/ModelSurfs.cpp | 10 +- src/Components/Modules/Zones.cpp | 8 +- src/Game/Structs.hpp | 76 +++++----- 4 files changed, 112 insertions(+), 122 deletions(-) diff --git a/src/Components/Modules/AssetInterfaces/IXModel.cpp b/src/Components/Modules/AssetInterfaces/IXModel.cpp index 78838581..28a1f13b 100644 --- a/src/Components/Modules/AssetInterfaces/IXModel.cpp +++ b/src/Components/Modules/AssetInterfaces/IXModel.cpp @@ -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(); - model->numColSurfs = reader.read(); + model->numsurfs = reader.read(); + model->numCollSurfs = reader.read(); model->numLods = static_cast(reader.read()); - model->collLod = reader.read(); + model->collLod = static_cast(reader.read()); // Read bone names - model->boneNames = builder->getAllocator()->allocateArray(model->numBones); + model->boneNames = builder->getAllocator()->allocateArray(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(boneCount); - model->tagAngles = reader.readArray(boneCount); - model->tagPositions = reader.readArray(boneCount); + model->quats = reader.readArray(boneCount * 4); + model->trans = reader.readArray(boneCount * 3); model->partClassification = reader.readArray(boneCount); - model->animMatrix = reader.readArray(boneCount); + model->baseMat = reader.readArray(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(model->numSurfaces); - surf.numSurfaces = model->numSurfaces; + std::memcpy(&surf, baseModel->lodInfo[0].modelSurfs, sizeof(Game::XModelSurfs)); + surf.surfaces = allocator.allocateArray(model->numsurfs); + surf.numSurfaces = model->numsurfs; for (int i = 0; i < 4; ++i) { - model->lods[i].dist = reader.read(); - model->lods[i].numsurfs = reader.read(); - model->lods[i].surfIndex = reader.read(); + model->lodInfo[i].dist = reader.read(); + model->lodInfo[i].numsurfs = reader.read(); + model->lodInfo[i].surfIndex = reader.read(); - model->lods[i].partBits[0] = reader.read(); - model->lods[i].partBits[1] = reader.read(); - model->lods[i].partBits[2] = reader.read(); - model->lods[i].partBits[3] = reader.read(); - model->lods[i].partBits[4] = 0; - model->lods[i].partBits[5] = 0; + model->lodInfo[i].partBits[0] = reader.read(); + model->lodInfo[i].partBits[1] = reader.read(); + model->lodInfo[i].partBits[2] = reader.read(); + model->lodInfo[i].partBits[3] = reader.read(); + 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(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(model->numSurfaces); - for (unsigned char i = 0; i < model->numSurfaces; ++i) + model->materialHandles = builder->getAllocator()->allocateArray(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(model->numColSurfs); + model->collSurfs = reader.readArray(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(model->colSurf[i].numCollTris); + model->collSurfs[i].collTris = reader.readArray(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(); - 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(); - buffer->saveArray(asset->colSurf, asset->numColSurfs); + Game::XModelCollSurf_s* destColSurfs = buffer->dest(); + 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) diff --git a/src/Components/Modules/ModelSurfs.cpp b/src/Components/Modules/ModelSurfs.cpp index cff3f685..9bf84eb6 100644 --- a/src/Components/Modules/ModelSurfs.cpp +++ b/src/Components/Modules/ModelSurfs.cpp @@ -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(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; diff --git a/src/Components/Modules/Zones.cpp b/src/Components/Modules/Zones.cpp index 940b646f..d294a8f4 100644 --- a/src/Components/Modules/Zones.cpp +++ b/src/Components/Modules/Zones.cpp @@ -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(&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(0xDEADC0DE); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index f328b46b..9764911d 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -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 {