[IXModel] Correct model loading
This commit is contained in:
parent
75158227fb
commit
2c7b7f6d87
@ -1,6 +1,6 @@
|
|||||||
#include <STDInclude.hpp>
|
#include <STDInclude.hpp>
|
||||||
|
|
||||||
#define IW4X_MODEL_VERSION 2
|
#define IW4X_MODEL_VERSION 3
|
||||||
|
|
||||||
namespace Assets
|
namespace Assets
|
||||||
{
|
{
|
||||||
@ -34,6 +34,8 @@ namespace Assets
|
|||||||
model->numRootBones = reader.readByte();
|
model->numRootBones = reader.readByte();
|
||||||
model->numSurfaces = reader.read<unsigned char>();
|
model->numSurfaces = reader.read<unsigned char>();
|
||||||
model->numColSurfs = reader.read<int>();
|
model->numColSurfs = reader.read<int>();
|
||||||
|
model->numLods = static_cast<char>(reader.read<short>());
|
||||||
|
model->collLod = reader.read<short>();
|
||||||
|
|
||||||
// Read bone names
|
// Read bone names
|
||||||
model->boneNames = builder->getAllocator()->allocateArray<short>(model->numBones);
|
model->boneNames = builder->getAllocator()->allocateArray<short>(model->numBones);
|
||||||
@ -53,41 +55,32 @@ namespace Assets
|
|||||||
model->animMatrix = reader.readArray<Game::DObjAnimMat>(boneCount);
|
model->animMatrix = reader.readArray<Game::DObjAnimMat>(boneCount);
|
||||||
|
|
||||||
// Prepare surfaces
|
// Prepare surfaces
|
||||||
Game::XSurface* baseSurface = &baseModel->lods[0].surfaces[0].surfaces[0];
|
Game::XModelSurfs surf;
|
||||||
Game::XModelSurfs* surf = builder->getAllocator()->allocate<Game::XModelSurfs>();
|
Utils::Memory::Allocator allocator;
|
||||||
|
Game::XSurface* baseSurface = &baseModel->lods[0].modelSurfs[0].surfaces[0];
|
||||||
|
|
||||||
std::memcpy(surf, baseModel->lods[0].surfaces, sizeof(Game::XModelSurfs));
|
std::memcpy(&surf, baseModel->lods[0].modelSurfs, sizeof(Game::XModelSurfs));
|
||||||
surf->name = builder->getAllocator()->duplicateString(fmt::sprintf("%s_lod1", model->name));
|
surf.surfaces = allocator.allocateArray<Game::XSurface>(model->numSurfaces);
|
||||||
surf->surfaces = builder->getAllocator()->allocateArray<Game::XSurface>(model->numSurfaces);
|
surf.numSurfaces = model->numSurfaces;
|
||||||
surf->numSurfaces = model->numSurfaces;
|
|
||||||
|
|
||||||
// Store surfs for later writing
|
for (int i = 0; i < 4; ++i)
|
||||||
Components::AssetHandler::StoreTemporaryAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, { surf });
|
|
||||||
|
|
||||||
// Reset surfaces in remaining lods
|
|
||||||
for (unsigned int i = 1; i < 4; ++i)
|
|
||||||
{
|
{
|
||||||
ZeroMemory(&model->lods[i], sizeof(Game::XModelLodInfo));
|
model->lods[i].dist = reader.read<float>();
|
||||||
|
model->lods[i].numsurfs = reader.read<unsigned short>();
|
||||||
|
model->lods[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->lods[0].dist = reader.read<float>();
|
|
||||||
model->lods[0].numSurfs = reader.read<short>();
|
|
||||||
model->lods[0].maxSurfs = reader.read<short>();
|
|
||||||
|
|
||||||
model->lods[0].partBits[0] = reader.read<int>();
|
|
||||||
model->lods[0].partBits[1] = reader.read<int>();
|
|
||||||
model->lods[0].partBits[2] = reader.read<int>();
|
|
||||||
model->lods[0].partBits[3] = reader.read<int>();
|
|
||||||
|
|
||||||
model->lods[0].numSurfs = model->numSurfaces; // This is needed in case we have more than 1 LOD
|
|
||||||
model->lods[0].surfaces = surf;
|
|
||||||
model->lods[0].surfs = surf->surfaces;
|
|
||||||
model->numLods = 1;
|
|
||||||
|
|
||||||
// Read surfaces
|
// Read surfaces
|
||||||
for (int i = 0; i < surf->numSurfaces; ++i)
|
for (int i = 0; i < surf.numSurfaces; ++i)
|
||||||
{
|
{
|
||||||
Game::XSurface* surface = &surf->surfaces[i];
|
Game::XSurface* surface = &surf.surfaces[i];
|
||||||
std::memcpy(surface, baseSurface, sizeof(Game::XSurface));
|
std::memcpy(surface, baseSurface, sizeof(Game::XSurface));
|
||||||
|
|
||||||
surface->tileMode = reader.read<char>();
|
surface->tileMode = reader.read<char>();
|
||||||
@ -98,6 +91,8 @@ namespace Assets
|
|||||||
surface->partBits[1] = reader.read<int>();
|
surface->partBits[1] = reader.read<int>();
|
||||||
surface->partBits[2] = reader.read<int>();
|
surface->partBits[2] = reader.read<int>();
|
||||||
surface->partBits[3] = reader.read<int>();
|
surface->partBits[3] = reader.read<int>();
|
||||||
|
surface->partBits[4] = 0;
|
||||||
|
surface->partBits[5] = 0;
|
||||||
|
|
||||||
surface->baseTriIndex = reader.read<unsigned __int16>();
|
surface->baseTriIndex = reader.read<unsigned __int16>();
|
||||||
surface->baseVertIndex = reader.read<unsigned __int16>();
|
surface->baseVertIndex = reader.read<unsigned __int16>();
|
||||||
@ -136,6 +131,27 @@ namespace Assets
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When all surfaces are loaded, split them up.
|
||||||
|
for (char i = 0; i < model->numLods; ++i)
|
||||||
|
{
|
||||||
|
Game::XModelSurfs* realSurf = builder->getAllocator()->allocate<Game::XModelSurfs>();
|
||||||
|
|
||||||
|
// 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->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));
|
||||||
|
|
||||||
|
model->lods[i].modelSurfs = realSurf;
|
||||||
|
model->lods[i].surfs = realSurf->surfaces;
|
||||||
|
|
||||||
|
// Store surfs for later writing
|
||||||
|
Components::AssetHandler::StoreTemporaryAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, { realSurf });
|
||||||
|
}
|
||||||
|
|
||||||
// Read materials
|
// Read materials
|
||||||
model->materials = builder->getAllocator()->allocateArray<Game::Material*>(model->numSurfaces);
|
model->materials = builder->getAllocator()->allocateArray<Game::Material*>(model->numSurfaces);
|
||||||
for (unsigned char i = 0; i < model->numSurfaces; ++i)
|
for (unsigned char i = 0; i < model->numSurfaces; ++i)
|
||||||
@ -205,9 +221,9 @@ namespace Assets
|
|||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
if (asset->lods[i].surfaces)
|
if (asset->lods[i].modelSurfs)
|
||||||
{
|
{
|
||||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces);
|
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].modelSurfs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,9 +333,9 @@ namespace Assets
|
|||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
if (asset->lods[i].surfaces)
|
if (asset->lods[i].modelSurfs)
|
||||||
{
|
{
|
||||||
dest->lods[i].surfaces = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces).surfaces;
|
dest->lods[i].modelSurfs = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].modelSurfs).surfaces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ namespace Components
|
|||||||
|
|
||||||
for (char i = 0; i < model->numLods; ++i)
|
for (char i = 0; i < model->numLods; ++i)
|
||||||
{
|
{
|
||||||
Game::XModelSurfs* surfs = model->lods[i].surfaces;
|
Game::XModelSurfs* surfs = model->lods[i].modelSurfs;
|
||||||
|
|
||||||
if (!surfs->surfaces)
|
if (!surfs->surfaces)
|
||||||
{
|
{
|
||||||
@ -164,12 +164,11 @@ namespace Components
|
|||||||
surfs->numSurfaces = newSurfs->numSurfaces;
|
surfs->numSurfaces = newSurfs->numSurfaces;
|
||||||
|
|
||||||
model->lods[i].surfs = newSurfs->surfaces;
|
model->lods[i].surfs = newSurfs->surfaces;
|
||||||
std::memcpy(&model->lods[i].partBits, &newSurfs->partBits, 16);
|
std::memcpy(&model->lods[i].partBits, &newSurfs->partBits, 24);
|
||||||
std::memcpy(&model->lods[i].pad3, &newSurfs->pad, 8);
|
|
||||||
|
|
||||||
short numSurfs = static_cast<short>(newSurfs->numSurfaces);
|
short numSurfs = static_cast<short>(newSurfs->numSurfaces);
|
||||||
model->lods[i].numSurfs = numSurfs;
|
model->lods[i].numsurfs = numSurfs;
|
||||||
model->lods[i].maxSurfs = surfCount;
|
model->lods[i].surfIndex = surfCount;
|
||||||
surfCount += numSurfs;
|
surfCount += numSurfs;
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -1586,10 +1586,7 @@ namespace Game
|
|||||||
GfxPackedVertex* vertexBuffer; // +28
|
GfxPackedVertex* vertexBuffer; // +28
|
||||||
int numCT; // +32
|
int numCT; // +32
|
||||||
XRigidVertList* ct; // +36
|
XRigidVertList* ct; // +36
|
||||||
int partBits[4];
|
int partBits[6];
|
||||||
char pad5[8]; // +40
|
|
||||||
// pad5 matches XModelSurfaces pad
|
|
||||||
// total size, 64
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XModelSurfs
|
struct XModelSurfs
|
||||||
@ -1597,19 +1594,17 @@ namespace Game
|
|||||||
const char* name;
|
const char* name;
|
||||||
XSurface* surfaces;
|
XSurface* surfaces;
|
||||||
int numSurfaces;
|
int numSurfaces;
|
||||||
int partBits[4];
|
int partBits[6];
|
||||||
char pad[8];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XModelLodInfo
|
struct XModelLodInfo
|
||||||
{
|
{
|
||||||
float dist;
|
float dist;
|
||||||
short numSurfs; // +4
|
unsigned __int16 numsurfs;
|
||||||
short maxSurfs;// +6
|
unsigned __int16 surfIndex;
|
||||||
XModelSurfs* surfaces; // +8
|
XModelSurfs *modelSurfs;
|
||||||
int partBits[4]; // +12
|
int partBits[6];
|
||||||
char pad3[8];
|
XSurface *surfs;
|
||||||
XSurface* surfs;
|
|
||||||
char pad4[4];
|
char pad4[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user