XModel stuff, unfinished.

This commit is contained in:
momo5502 2016-01-25 23:47:50 +01:00
parent ba3187ce9e
commit 86e1faabc3
11 changed files with 636 additions and 0 deletions

View File

@ -253,9 +253,13 @@ namespace Components
Utils::Hook(0x5BB650, AssetHandler::AddAssetStub, HOOK_JUMP).Install()->Quick();
// Register asset interfaces
AssetHandler::RegisterInterface(new Assets::IXModel());
AssetHandler::RegisterInterface(new Assets::IRawFile());
AssetHandler::RegisterInterface(new Assets::IGfxImage());
AssetHandler::RegisterInterface(new Assets::IMaterial());
AssetHandler::RegisterInterface(new Assets::IPhysPreset());
AssetHandler::RegisterInterface(new Assets::IPhysCollmap());
AssetHandler::RegisterInterface(new Assets::IXModelSurfs());
AssetHandler::RegisterInterface(new Assets::ILocalizedEntry());
AssetHandler::RegisterInterface(new Assets::IMaterialPixelShader());
AssetHandler::RegisterInterface(new Assets::IMaterialTechniqueSet());

View File

@ -56,9 +56,13 @@ namespace Components
};
}
#include "AssetInterfaces\IXModel.hpp"
#include "AssetInterfaces\IRawFile.hpp"
#include "AssetInterfaces\IGfxImage.hpp"
#include "AssetInterfaces\IMaterial.hpp"
#include "AssetInterfaces\IPhysPreset.hpp"
#include "AssetInterfaces\IPhysCollmap.hpp"
#include "AssetInterfaces\IXModelSurfs.hpp"
#include "AssetInterfaces\ILocalizedEntry.hpp"
#include "AssetInterfaces\IMaterialPixelShader.hpp"
#include "AssetInterfaces\IMaterialTechniqueSet.hpp"

View File

@ -0,0 +1,130 @@
#include <STDInclude.hpp>
namespace Assets
{
void IPhysCollmap::Save_BrushWrapper(Components::ZoneBuilder::Zone* builder, Game::BrushWrapper* brush)
{
Assert_Size(Game::BrushWrapper, 68);
Utils::Stream* buffer = builder->GetBuffer();
Game::BrushWrapper* destBrush = buffer->Dest<Game::BrushWrapper>();
buffer->Save(brush, sizeof(Game::BrushWrapper));
// Save_cbrushWrapper_t
{
Assert_Size(Game::cbrushWrapper_t, 36);
if (brush->brush.brushSide)
{
Assert_Size(Game::cbrushside_t, 8);
buffer->Align(Utils::Stream::ALIGN_4);
Game::cbrushside_t* destBrushSide = buffer->Dest<Game::cbrushside_t>();
buffer->SaveArray(brush->brush.brushSide, brush->brush.count);
// Save_cbrushside_tArray
for (short i = 0; i < brush->brush.count; ++i)
{
Game::cbrushside_t* destSide = &destBrushSide[i];
Game::cbrushside_t* side = &brush->brush.brushSide[i];
if (side->side)
{
if (builder->HasPointer(side->side))
{
destSide->side = builder->GetPointer(side->side);
}
else
{
buffer->Align(Utils::Stream::ALIGN_4);
builder->StorePointer(side->side);
buffer->Save(side->side, sizeof(Game::cplane_t));
destSide->side = reinterpret_cast<Game::cplane_t*>(-1);
}
}
}
destBrush->brush.brushSide = reinterpret_cast<Game::cbrushside_t*>(-1);
}
if (brush->brush.brushEdge)
{
buffer->Save(brush->brush.brushEdge, brush->totalEdgeCount);
destBrush->brush.brushEdge = reinterpret_cast<char*>(-1);
}
}
if (brush->planes)
{
Assert_Size(Game::cplane_t, 20);
if (builder->HasPointer(brush->planes))
{
destBrush->planes = builder->GetPointer(brush->planes);
}
else
{
buffer->Align(Utils::Stream::ALIGN_4);
builder->StorePointer(brush->planes);
buffer->Save(brush->planes, sizeof(Game::cplane_t));
destBrush->planes = reinterpret_cast<Game::cplane_t*>(-1);
}
}
}
void IPhysCollmap::Save_PhysGeomInfoArray(Components::ZoneBuilder::Zone* builder, Game::PhysGeomInfo* geoms, unsigned int count)
{
Assert_Size(Game::PhysGeomInfo, 68);
Utils::Stream* buffer = builder->GetBuffer();
Game::PhysGeomInfo* destGeoms = buffer->Dest<Game::PhysGeomInfo>();
buffer->SaveArray(geoms, count);
for (unsigned int i = 0; i < count; ++i)
{
Game::PhysGeomInfo* destGeom = &destGeoms[i];
Game::PhysGeomInfo* geom = &geoms[i];
if (geom->brush)
{
buffer->Align(Utils::Stream::ALIGN_4);
IPhysCollmap::Save_BrushWrapper(builder, geom->brush);
destGeom->brush = reinterpret_cast<Game::BrushWrapper*>(-1);
}
}
}
void IPhysCollmap::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Assert_Size(Game::XModel, 304);
Utils::Stream* buffer = builder->GetBuffer();
Game::PhysCollmap* asset = header.physCollmap;
Game::PhysCollmap* dest = buffer->Dest<Game::PhysCollmap>();
buffer->Save(asset, sizeof(Game::PhysCollmap));
buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL);
if (asset->name)
{
buffer->SaveString(builder->GetAssetName(this->GetType(), asset->name));
dest->name = reinterpret_cast<char*>(-1);
}
if (asset->geoms)
{
buffer->Align(Utils::Stream::ALIGN_4);
IPhysCollmap::Save_PhysGeomInfoArray(builder, asset->geoms, asset->count);
dest->geoms = reinterpret_cast<Game::PhysGeomInfo*>(-1);
}
buffer->PopBlock();
}
}

View File

@ -0,0 +1,13 @@
namespace Assets
{
class IPhysCollmap : public Components::AssetHandler::IAsset
{
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP; };
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
private:
void Save_PhysGeomInfoArray(Components::ZoneBuilder::Zone* builder, Game::PhysGeomInfo* geoms, unsigned int count);
void Save_BrushWrapper(Components::ZoneBuilder::Zone* builder, Game::BrushWrapper* brush);
};
}

View File

@ -0,0 +1,32 @@
#include <STDInclude.hpp>
namespace Assets
{
void IPhysPreset::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Assert_Size(Game::PhysPreset, 44);
Utils::Stream* buffer = builder->GetBuffer();
Game::PhysPreset* asset = header.physPreset;
Game::PhysPreset* dest = buffer->Dest<Game::PhysPreset>();
buffer->Save(asset, sizeof(Game::PhysPreset));
buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL);
// TODO: I think we have to write them, even if they are NULL
if (asset->name)
{
buffer->SaveString(builder->GetAssetName(this->GetType(), asset->name));
dest->name = reinterpret_cast<char*>(-1);
}
if (asset->sndAliasPrefix)
{
buffer->SaveString(asset->sndAliasPrefix);
dest->sndAliasPrefix = reinterpret_cast<const char*>(-1);
}
buffer->PopBlock();
}
}

View File

@ -0,0 +1,9 @@
namespace Assets
{
class IPhysPreset : public Components::AssetHandler::IAsset
{
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_PHYSPRESET; };
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
};
}

View File

@ -0,0 +1,184 @@
#include <STDInclude.hpp>
namespace Assets
{
void IXModel::Mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Game::XModel* asset = header.model;
if (asset->boneNames)
{
for (char i = 0; i < asset->numBones; ++i)
{
builder->AddScriptString(asset->boneNames[i]);
}
}
for (int i = 0; i < 4; ++i)
{
if (asset->lods[i].surfaces)
{
builder->LoadAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces->name);
}
}
if (asset->physPreset)
{
builder->LoadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->physPreset->name);
}
if (asset->physPreset)
{
builder->LoadAsset(Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP, asset->physCollmap->name);
}
}
void IXModel::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Assert_Size(Game::XModel, 304);
Utils::Stream* buffer = builder->GetBuffer();
Game::XModel* asset = header.model;
Game::XModel* dest = buffer->Dest<Game::XModel>();
buffer->Save(asset, sizeof(Game::XModel));
buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL);
if (asset->name)
{
buffer->SaveString(builder->GetAssetName(this->GetType(), asset->name));
dest->name = reinterpret_cast<char*>(-1);
}
if (asset->boneNames)
{
buffer->Align(Utils::Stream::ALIGN_2);
unsigned short* destBoneNames = buffer->Dest<unsigned short>();
buffer->SaveArray(asset->boneNames, asset->numBones);
for (char i = 0; i < asset->numBones; ++i)
{
builder->MapScriptString(&destBoneNames[i]);
}
dest->boneNames = reinterpret_cast<short*>(-1);
}
if (asset->parentList)
{
buffer->Save(asset->parentList, asset->numBones - asset->numRootBones);
dest->parentList = reinterpret_cast<char*>(-1);
}
if (asset->tagAngles)
{
Assert_Size(Game::XModelAngle, 8);
buffer->Align(Utils::Stream::ALIGN_2);
buffer->Save(asset->tagAngles, sizeof(Game::XModelAngle), asset->numBones - asset->numRootBones);
dest->tagAngles = reinterpret_cast<Game::XModelAngle*>(-1);
}
if (asset->tagPositions)
{
Assert_Size(Game::XModelTagPos, 12);
buffer->Align(Utils::Stream::ALIGN_4);
buffer->Save(asset->tagPositions, sizeof(Game::XModelTagPos), asset->numBones - asset->numRootBones);
dest->tagPositions = reinterpret_cast<Game::XModelTagPos*>(-1);
}
if (asset->partClassification)
{
buffer->Save(asset->partClassification,asset->numBones);
dest->partClassification = reinterpret_cast<char*>(-1);
}
if (asset->animMatrix)
{
Assert_Size(Game::DObjAnimMat, 32);
buffer->Align(Utils::Stream::ALIGN_4);
buffer->Save(asset->animMatrix, sizeof(Game::DObjAnimMat), asset->numBones);
dest->animMatrix = reinterpret_cast<Game::DObjAnimMat*>(-1);
}
if (asset->materials)
{
buffer->Align(Utils::Stream::ALIGN_4);
Game::Material** destMaterials = buffer->Dest<Game::Material*>();
buffer->Save(asset->materials, sizeof(Game::Material*), asset->numSurfaces);
for (char i = 0; i < asset->numSurfaces; ++i)
{
if (asset->materials[i])
{
destMaterials[i] = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materials[i]->name).material;
}
}
dest->materials = reinterpret_cast<Game::Material**>(-1);
}
// Save_XModelLodInfoArray()
{
Assert_Size(Game::XModelLodInfo, 44);
for (int i = 0; i < 4; ++i)
{
if (asset->lods[i].surfaces)
{
dest->lods[i].surfaces = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces->name).surfaces;
}
}
}
// Save_XModelCollSurfArray
if (asset->colSurf)
{
Assert_Size(Game::XModelCollSurf, 44);
buffer->Align(Utils::Stream::ALIGN_4);
Game::XModelCollSurf* destColSurfs = buffer->Dest<Game::XModelCollSurf>();
buffer->Save(asset->colSurf, asset->numColSurfs);
for (int i = 0; i < asset->numColSurfs; ++i)
{
Game::XModelCollSurf* destColSurf = &destColSurfs[i];
Game::XModelCollSurf* colSurf = &asset->colSurf[i];
if (colSurf->tris)
{
buffer->Align(Utils::Stream::ALIGN_4);
buffer->Save(colSurf->tris, 48, colSurf->count);
destColSurf->tris = reinterpret_cast<void*>(-1);
}
}
dest->colSurf = reinterpret_cast<Game::XModelCollSurf*>(-1);
}
if (asset->boneInfo)
{
buffer->Align(Utils::Stream::ALIGN_4);
buffer->Save(asset->boneInfo, 28, asset->numBones);
dest->boneInfo = reinterpret_cast<char*>(-1);
}
if (asset->physPreset)
{
dest->physPreset = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->physPreset->name).physPreset;
}
if (asset->physPreset)
{
dest->physPreset = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP, asset->physCollmap->name).physPreset;
}
buffer->PopBlock();
}
}

View File

@ -0,0 +1,10 @@
namespace Assets
{
class IXModel : public Components::AssetHandler::IAsset
{
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_XMODEL; };
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
virtual void Mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
};
}

View File

@ -0,0 +1,39 @@
#include <STDInclude.hpp>
namespace Assets
{
void IXModelSurfs::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Assert_Size(Game::XModelSurfs, 36);
Utils::Stream* buffer = builder->GetBuffer();
Game::XModelSurfs* asset = header.surfaces;
Game::XModelSurfs* dest = buffer->Dest<Game::XModelSurfs>();
buffer->Save(asset, sizeof(Game::PhysPreset));
buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL);
if (asset->name)
{
buffer->SaveString(builder->GetAssetName(this->GetType(), asset->name));
dest->name = reinterpret_cast<char*>(-1);
}
if (asset->surfaces)
{
Assert_Size(Game::XSurface, 64);
buffer->Align(Utils::Stream::ALIGN_4);
buffer->SaveArray(asset->surfaces, asset->numSurfaces);
for (int i = 0; i < asset->numSurfaces; ++i)
{
}
dest->surfaces = reinterpret_cast<Game::XSurface*>(-1);
}
buffer->PopBlock();
}
}

View File

@ -0,0 +1,9 @@
namespace Assets
{
class IXModelSurfs : public Components::AssetHandler::IAsset
{
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_XMODELSURFS; };
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
};
}

View File

@ -1226,6 +1226,204 @@ 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
{
char pad[24];
int numNode;
char* node; // el size 16
int numLeaf;
short* leaf;
};
struct XRigidVertList
{
int pad;
int pad2;
XSurfaceCollisionTree* entry;
};
struct GfxPackedVertex
{
float x;
float y;
float z;
DWORD color;
WORD texCoords[2];
float normal[3];
};
struct Face
{
unsigned short v1;
unsigned short v2;
unsigned short v3;
};
struct XSurface
{
short pad; // +0
unsigned short numVertices; // +2
unsigned short numPrimitives; // +4
unsigned char streamHandle; // something to do with buffers, +6
char pad2; // +7
int pad3; // +8
Face* indexBuffer; // +12
short blendNum1; // +16
short blendNum2; // +18
short blendNum3; // +20
short blendNum4; // +22
char* blendInfo; // +24
GfxPackedVertex* vertexBuffer; // +28
int numCT; // +32
XRigidVertList* ct; // +36
char pad5[24]; // +40
// pad5 matches XModelSurfaces pad
// total size, 64
};
struct XModelSurfs
{
const char* name;
XSurface* surfaces;
int numSurfaces;
char pad[24];
};
struct XModelLodInfo
{
char pad[8];
XModelSurfs* surfaces;
char pad2[32];
};
struct cplane_t
{
vec3_t a;
float dist;
int type;
};
struct cbrushside_t
{
cplane_t* side;
short texInfo;
short dispInfo;
};
struct cbrushWrapper_t
{
short count;
cbrushside_t* brushSide;
char * brushEdge;
char pad[24];
};
#pragma pack(push, 4)
struct BrushWrapper
{
float mins[3];
float maxs[3];
cbrushWrapper_t brush;
int totalEdgeCount;
cplane_t *planes;
};
#pragma pack(pop)
struct PhysGeomInfo
{
BrushWrapper *brush;
int type;
float orientation[3][3];
float offset[3];
float halfLengths[3];
};
struct PhysMass
{
float centerOfMass[3];
float momentsOfInertia[3];
float productsOfInertia[3];
};
struct PhysCollmap
{
const char * name;
unsigned int count;
PhysGeomInfo *geoms;
char unknown[0x18];
PhysMass mass;
};
struct DObjAnimMat
{
float quat[4];
float trans[3];
float transWeight;
};
struct XModelCollSurf
{
void* tris; // +0, sizeof 48
int count; // +4
char pad[36]; // +8
}; // +44
struct PhysPreset
{
const char *name;
int type;
float mass;
float bounce;
float friction;
float bulletForceScale;
float explosiveForceScale;
const char *sndAliasPrefix;
float piecesSpreadFraction;
float piecesUpwardVelocity;
bool tempDefaultToCylinder;
};
struct XModel
{
char* name; // +0
char numBones; // +4
char numRootBones; // +5
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
int pad4; // +240
XModelCollSurf* colSurf; // +244
int numColSurfs; // +248
int pad6;
char* boneInfo; // bone count, +256, element size 28
char pad5[36];
PhysPreset* physPreset;
PhysCollmap* physCollmap;
}; // total size 304
union XAssetHeader
{
void *data;
@ -1244,6 +1442,10 @@ namespace Game
MaterialVertexShader *vertexShader;
MaterialPixelShader *pixelShader;
structuredDataDef_t* structuredData;
XModel* model;
PhysPreset* physPreset;
PhysCollmap* physCollmap;
XModelSurfs* surfaces;
};
struct XAsset