You've already forked PrimeRemasterStructs
mirror of
https://github.com/PrimeDecomp/PrimeRemasterStructs.git
synced 2026-03-31 14:23:23 -07:00
618 lines
15 KiB
Plaintext
618 lines
15 KiB
Plaintext
#ifndef _CGRAPHICSMODEL
|
|
#define _CGRAPHICSMODEL
|
|
#include "CAABox.bt"
|
|
#include "CEvalSystem.bt"
|
|
#include "CVector4i.bt"
|
|
#include "CColor4f.bt"
|
|
#include "CRenderOctree.bt"
|
|
#include "NGraphicsMaterial.bt"
|
|
#include "CMaterialInstanceResource.bt"
|
|
|
|
struct SModelAnimatedUVData {
|
|
CEvalSystem evalSystem;
|
|
uint evalIdCount;
|
|
CEvalId evalId[evalIdCount];
|
|
uint vec4iCount;
|
|
CVector4i vec4is[vec4iCount];
|
|
uint unkCount;
|
|
char unk[unkCount];
|
|
if (!isDKCTF)
|
|
{
|
|
uchar unk2;
|
|
}
|
|
};
|
|
|
|
struct SModelWindData {
|
|
uint32 windSets;
|
|
struct WindSet
|
|
{
|
|
CVector3f WindMin;
|
|
CVector3f WindMax;
|
|
float unk;
|
|
} windset[windSets];
|
|
uint32 unkD;
|
|
byte unkData[unkD];
|
|
};
|
|
|
|
struct SCausticData {
|
|
uint32 unkD;
|
|
uint32 unkData[unkD];
|
|
};
|
|
|
|
// CModelDataSource
|
|
struct DataSourceLoader {
|
|
if (ReadByte() == 0) //Type for WiiU is an I32
|
|
{
|
|
uint32 tmpFormatI32;
|
|
switch (tmpFormatI32)
|
|
{
|
|
case 0:
|
|
local FourCC type = "ANUV";
|
|
break;
|
|
case 1:
|
|
local FourCC type = "WIND";
|
|
break;
|
|
case 2:
|
|
local FourCC type = "CAUS";
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FourCC type;
|
|
}
|
|
switch (type) {
|
|
case "ANUV":
|
|
// NModelCustomData::sAnimUvDataSourceLoader
|
|
SModelAnimatedUVData animatedUvs;
|
|
break;
|
|
case "WIND":
|
|
// NModelCustomData::sWindModelDataSourceLoader
|
|
SModelWindData wind;
|
|
break;
|
|
case "CAUS":
|
|
// NModelCustomData::sCausticDataSourceLoader
|
|
SCausticData caustic;
|
|
break;
|
|
}
|
|
// NModelCustomData::sSkinnedModelAnimUvDataSourceLoader
|
|
// NModelCustomData::sVertAnimModelDataSourceLoader
|
|
};
|
|
|
|
struct CustomDataLoader {
|
|
FourCC type;
|
|
// CModelCustomDataMPT
|
|
// byte b;
|
|
// if (b) CModelSurfaceMetaDataMPT
|
|
};
|
|
|
|
struct ModelHeader {
|
|
if (isDKCTF == 1)
|
|
{
|
|
uint opaqueMeshes;
|
|
uint onePassTransMeshes;
|
|
uint TwoPassTransMeshes;
|
|
uint oneBitMeshes;
|
|
uint additiveMeshes;
|
|
}
|
|
else
|
|
{
|
|
uint unk1;
|
|
}
|
|
CAABox bounds;
|
|
uint dataSourceCount;
|
|
local int i;
|
|
for (i = 0; i < dataSourceCount; ++i) {
|
|
DataSourceLoader dataSource;
|
|
}
|
|
if (isDKCTF == 0)
|
|
{
|
|
uchar unk2;
|
|
if (unk2) {
|
|
CustomDataLoader customData;
|
|
}
|
|
}
|
|
};
|
|
|
|
typedef struct(int readerVersion, int writerVersion) {
|
|
FourCC id <read=ReadMaterialDataId>;
|
|
FourCC type <read=ReadMaterialDataType>;
|
|
} MaterialType <read=(Str("%s %s", id, type))>;
|
|
|
|
|
|
struct SSkinnedModelHeader {
|
|
uint unk;
|
|
if (!isDKCTF)
|
|
{
|
|
uint unk;
|
|
uint unk;
|
|
uint unk;
|
|
uint uintsCount;
|
|
uint uints[uintsCount];
|
|
uint dataCount;
|
|
char data[dataCount];
|
|
}
|
|
};
|
|
|
|
struct SWorldModelHeader {
|
|
uchar unk;
|
|
};
|
|
|
|
enum <uint32> ECachedGraphicsTransform
|
|
{
|
|
XF_MODEL_TO_WORLD_MTX = 0, // uc_modelToWorldMatrix
|
|
XF_WORLD_TO_MODEL_MTX = 1, // uc_worldToModelMatrix
|
|
XF_WORLD_TO_VIEW_MTX = 2, // uc_worldToViewMatrix
|
|
XF_PROJECTION_MTX = 3, // uc_projectionMatrix
|
|
XF_MODEL_VIEW_MTX = 4, // uc_modelViewMatrix
|
|
XF_MODEL_VIEW_PROJECTION_MTX = 5, // uc_modelViewProjectionMatrix
|
|
XF_PROJECTION_INVERSE_MTX = 6, // uc_projectionInverseMatrix
|
|
XF_NORMAL_MTX = 7, // uc_normalMatrix
|
|
XF_CUSTOM_MTX_0 = 8, // uc_customMatrix0
|
|
};
|
|
|
|
enum <uint32> EVertexComponent
|
|
{
|
|
VTX_POSITION = 0, // in_position
|
|
VTX_NORMAL = 1, // in_normal
|
|
VTX_TANGENT0 = 2, // in_tangent[0]
|
|
VTX_TANGENT1 = 3, // in_tangent[1]
|
|
VTX_TANGENT2 = 4, // in_tangent[2]
|
|
VTX_TEXCOORD0 = 5, // in_texCoord[0]
|
|
VTX_TEXCOORD1 = 6, // in_texCoord[1]
|
|
VTX_TEXCOORD2 = 7, // in_texCoord[2]
|
|
VTX_TEXCOORD3 = 8, // in_texCoord[3]
|
|
VTX_COLOR = 9, // in_color
|
|
VTX_BONE_INDICES = 10, // in_boneIndices
|
|
VTX_BONE_WEIGHTS = 11, // in_boneWeights
|
|
VTX_BAKED_LIGHTING_COORD = 12, // in_bakedLightingCoord
|
|
VTX_BAKED_LIGHTING_TANGENT = 13, // in_bakedLightingTangent
|
|
VTX_VERT_INSTANCE_PARAMS = 14, // in_vertInstanceParams
|
|
VTX_VERT_INSTANCE_COLOR = 15, // in_vertInstanceColor
|
|
VTX_VERT_TRANSFORM0 = 16, // in_vertTransform[0]
|
|
VTX_VERT_TRANSFORM1 = 17, // in_vertTransform[1]
|
|
VTX_VERT_TRANSFORM2 = 18, // in_vertTransform[2]
|
|
VTX_CURRENT_POSITION = 19, // in_currentPosition
|
|
VTX_VERT_INSTANCE_OPACITY_PARAMS = 20, // in_vertInstanceOpacityParams
|
|
VTX_VERT_INSTANCE_COLOR_INDEXING_PARAMS = 21, // in_vertInstanceColorIndexingParams
|
|
VTX_VERT_INSTANCE_OPACITY_INDEXING_PARAMS = 22, // in_vertInstanceOpacityIndexingParams
|
|
VTX_VERT_INSTANCE_PAINT_PARAMS = 23, // in_vertInstancePaintParams
|
|
VTX_BAKED_LIGHTING_LOOKUP = 24, // in_bakedLightingLookup
|
|
VTX_MATERIAL_CHOICE0 = 25, // in_materialChoice[0]
|
|
VTX_MATERIAL_CHOICE1 = 26, // in_materialChoice[1]
|
|
VTX_MATERIAL_CHOICE2 = 27, // in_materialChoice[2]
|
|
VTX_MATERIAL_CHOICE3 = 28, // in_materialChoice[3]
|
|
};
|
|
|
|
enum <uint32> EMaterialDataType
|
|
{
|
|
DATA_TYPE_NONE = 0,
|
|
DATA_TYPE_TEXTURE = 1, // TXTR
|
|
DATA_TYPE_COLOR = 2, // COLR
|
|
DATA_TYPE_SCALAR = 3, // SCLR
|
|
DATA_TYPE_INT1 = 4, // INT1
|
|
DATA_TYPE_COMPLEX = 5, // CPLX
|
|
DATA_TYPE_INT4 = 6, // INT4
|
|
DATA_TYPE_MAT4 = 7, // MAT4
|
|
};
|
|
|
|
EMaterialDataType MapMaterialDataType(FourCC value)
|
|
{
|
|
switch (value) {
|
|
case "TXTR":
|
|
return DATA_TYPE_TEXTURE;
|
|
case "COLR":
|
|
return DATA_TYPE_COLOR;
|
|
case "SCLR":
|
|
return DATA_TYPE_SCALAR;
|
|
case "INT1":
|
|
return DATA_TYPE_INT1;
|
|
case "CPLX":
|
|
return DATA_TYPE_COMPLEX;
|
|
case "INT4":
|
|
return DATA_TYPE_INT4;
|
|
case "MAT4":
|
|
return DATA_TYPE_MAT4;
|
|
default:
|
|
return DATA_TYPE_NONE;
|
|
}
|
|
}
|
|
|
|
string ReadMaterialDataType(FourCC value)
|
|
{
|
|
EMaterialDataType type = MapMaterialDataType(value);
|
|
return EnumToString(type);
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
GUID id;
|
|
if (id != GUIDZero || isDKCTF) { STextureUsageInfo usage; } //Detect isDKCTF to force it on NS models
|
|
} CMaterialTextureTokenData <optimize=false>;
|
|
|
|
enum <uint32> EBlendControl {
|
|
// TODO
|
|
};
|
|
|
|
struct SBlendRegs {
|
|
CColor4f colors[3];
|
|
};
|
|
|
|
struct CLayeredTextureBaseData
|
|
{
|
|
EBlendControl blendControl;
|
|
SBlendRegs regs;
|
|
byte flags;
|
|
};
|
|
|
|
struct CLayeredTextureData
|
|
{
|
|
CLayeredTextureBaseData base;
|
|
CMaterialTextureTokenData textures[3];
|
|
};
|
|
|
|
typedef struct(int readerVersion, int writerVersion) {
|
|
FourCC id <read=ReadMaterialDataId>;
|
|
if (ReadByte() == 0) //Fix DKCTF WiiU models
|
|
{
|
|
uint32 tmpFormatI32; //Do this so we can get the fancy struct names
|
|
switch (tmpFormatI32)
|
|
{
|
|
case 0:
|
|
local FourCC type = "TXTR";
|
|
CMaterialTextureTokenData texture;
|
|
break;
|
|
case 1:
|
|
local FourCC type = "COLR";
|
|
float color[4];
|
|
break;
|
|
case 2:
|
|
local FourCC type = "SCLR";
|
|
float scalar;
|
|
break;
|
|
case 3:
|
|
local FourCC type = "INT1"; //Not sure if in DKCTF but need to dcheck
|
|
int int1;
|
|
break;
|
|
case 4:
|
|
local FourCC type = "CPLX";
|
|
byte unk[141];
|
|
break;
|
|
case 5:
|
|
local FourCC type = "INT4";
|
|
int int4[4];
|
|
break;
|
|
case 6:
|
|
local FourCC type = "MAT4"; //Not sure if in DKCTF but need to dcheck
|
|
float mtx[16];
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FourCC type <read=ReadMaterialDataType>;
|
|
switch (MapMaterialDataType(type)) {
|
|
case DATA_TYPE_TEXTURE:
|
|
CMaterialTextureTokenData texture;
|
|
break;
|
|
case DATA_TYPE_COLOR:
|
|
CColor4f color;
|
|
break;
|
|
case DATA_TYPE_SCALAR:
|
|
float scalar;
|
|
break;
|
|
case DATA_TYPE_INT1:
|
|
int int1;
|
|
break;
|
|
case DATA_TYPE_INT4:
|
|
CVector4i int4;
|
|
break;
|
|
case DATA_TYPE_MAT4:
|
|
float mtx[16]; // CMatrix4f
|
|
break;
|
|
case DATA_TYPE_COMPLEX:
|
|
if (isDKCTF)
|
|
{
|
|
byte unk[141];
|
|
}
|
|
else
|
|
{
|
|
local EMaterialDataId dataId <hidden=true> = MapMaterialDataId(id);
|
|
if (IsTextureLayeredMaterialDataId(dataId)) {
|
|
CLayeredTextureData data;
|
|
} else if (IsTextureMaterialDataId(dataId)) {
|
|
// TODO
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
} CMaterialData <read=CMaterialDataRead>;
|
|
|
|
string CMaterialDataRead(CMaterialData &mat) {
|
|
switch (MapMaterialDataType(mat.type)) {
|
|
case DATA_TYPE_TEXTURE:
|
|
return Str("Texture %s = %s", mat.id, GUIDToString(mat.texture.id));
|
|
case DATA_TYPE_COLOR:
|
|
return Str("Color %s = %s", mat.id, ColorToString(mat.color));
|
|
case DATA_TYPE_SCALAR:
|
|
return Str("Scalar %s = %f", mat.id, mat.scalar);
|
|
case DATA_TYPE_INT1:
|
|
return Str("Int %s = %f", mat.id, mat.int1);
|
|
case DATA_TYPE_INT4:
|
|
return Str("Int4 %s = %s", mat.id, Vec4iToString(mat.int4));
|
|
case DATA_TYPE_COMPLEX:
|
|
return Str("Complex %s", mat.id);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
typedef struct(int readerVersion, int writerVersion) {
|
|
if (readerVersion != 163 && readerVersion != 177) {
|
|
if (ReadByte() == 0 || !isDKCTF) //NS, use anti isDKCTF so MP1R models don't break
|
|
{
|
|
local uint useMaterialTypeChunk <hidden=true> = 1;
|
|
CStringFixed name;
|
|
}
|
|
else
|
|
{
|
|
local uint useMaterialTypeChunk <hidden=true> = 0;
|
|
CString name;
|
|
}
|
|
GUID shaderID;
|
|
if (isDKCTF)
|
|
{
|
|
local uint traitCount <hidden=true> = 1; //Hack it to 1
|
|
}
|
|
else if (readerVersion != 163 && readerVersion != 177)
|
|
{
|
|
GUID guid2; //unsure
|
|
uint unk1;
|
|
uint unk2;
|
|
uint traitCount;
|
|
}
|
|
if (traitCount != 0) {
|
|
struct { FourCC value; } traits[traitCount] <read=(ReadTrait(value))>;
|
|
}
|
|
if (isDKCTF == 1)
|
|
{
|
|
uint flags;
|
|
}
|
|
else if (readerVersion != 163 && readerVersion != 177)
|
|
{
|
|
uint variableDescCount;
|
|
if (variableDescCount != 0) {
|
|
CVariableDesc variableDescs[variableDescCount];
|
|
}
|
|
}
|
|
|
|
//material data types
|
|
uint dataCount;
|
|
if (useMaterialTypeChunk || !isDKCTF)
|
|
{
|
|
MaterialType dataTypes(readerVersion, writerVersion)[dataCount];
|
|
}
|
|
CMaterialData materialData(readerVersion, writerVersion)[dataCount]<optimize = false>;
|
|
} else if (parentof(this).unkFcc != "LEGA") {
|
|
uint unk1;
|
|
uint unk2;
|
|
GUID unkGuid1;
|
|
GUID unkGuid2;
|
|
GUID unkGuid3;
|
|
uint unk3;
|
|
} else {
|
|
uint dataCount;
|
|
CMaterialData materialData(readerVersion, writerVersion)[dataCount]<optimize = false>;
|
|
}
|
|
|
|
// data parse
|
|
} CMaterialCache;// <name=(Str("%s %s", this.name.text, GUIDToString(this.shaderID)))>;
|
|
|
|
typedef struct {
|
|
if (isDKCTF)
|
|
{
|
|
uint32 PrimitiveMode;
|
|
}
|
|
ushort MaterialIndex;
|
|
byte VertexBufferIndex;
|
|
byte IndexBufferIndex;
|
|
uint IndexStart;
|
|
uint IndexCount;
|
|
uint Flags;
|
|
if (isDKCTF)
|
|
{
|
|
byte unk;
|
|
}
|
|
} CRenderMesh;
|
|
|
|
struct SMeshLoadInformation {
|
|
uint meshCount;
|
|
CRenderMesh meshes[meshCount] <optimize=false>;
|
|
byte unk[(meshCount + 3) / 4];
|
|
byte unk2[(meshCount + 7) / 8];
|
|
uint shortCount;
|
|
if (shortCount > 0) {
|
|
uint16 shorts[shortCount];
|
|
}
|
|
byte lodCount;
|
|
struct {
|
|
struct {
|
|
uint32 a;
|
|
uint32 b;
|
|
} inner[5];
|
|
} outer[lodCount];
|
|
uint32 hasLodRule;
|
|
if (hasLodRule == 1) {
|
|
float lodRule[lodCount];
|
|
}
|
|
};
|
|
|
|
enum <uint32> EVertexDataFormat {
|
|
FMT_R8_UNORM = 0,
|
|
FMT_R8_UINT = 1,
|
|
FMT_R8_SNORM = 2,
|
|
FMT_R8_SINT = 3,
|
|
FMT_R16_UNORM = 4,
|
|
FMT_R16_UINT = 5,
|
|
FMT_R16_SNORM = 6,
|
|
FMT_R16_SINT = 7,
|
|
FMT_R16_FLOAT = 8,
|
|
FMT_RG8_UNORM = 9,
|
|
FMT_RG8_UINT = 10,
|
|
FMT_RG8_SNORM = 11,
|
|
FMT_RG8_SINT = 12,
|
|
FMT_R32_UINT = 13,
|
|
FMT_R32_SINT = 14,
|
|
FMT_R32_FLOAT = 15,
|
|
FMT_RG16_UNORM = 16,
|
|
FMT_RG16_UINT = 17,
|
|
FMT_RG16_SNORM = 18,
|
|
FMT_RG16_SINT = 19,
|
|
FMT_RG16_FLOAT = 20,
|
|
FMT_RGBA8_UNORM = 21,
|
|
FMT_RGBA8_UINT = 22,
|
|
FMT_RGBA8_SNORM = 23,
|
|
FMT_RGBA8_SINT = 24,
|
|
FMT_RGB10A2_UNORM = 25,
|
|
FMT_RGB10A2_UINT = 26,
|
|
FMT_RG32_UINT = 27,
|
|
FMT_RG32_SINT = 28,
|
|
FMT_RG32_FLOAT = 29,
|
|
FMT_RGBA16_UNORM = 30,
|
|
FMT_RGBA16_UINT = 31,
|
|
FMT_RGBA16_SNORM = 32,
|
|
FMT_RGBA16_SINT = 33,
|
|
FMT_RGBA16_FLOAT = 34,
|
|
FMT_RGB32_UINT = 35,
|
|
FMT_RGB32_SINT = 36,
|
|
FMT_RGB32_FLOAT = 37,
|
|
FMT_RGBA32_UINT = 38,
|
|
FMT_RGBA32_SINT = 39,
|
|
FMT_RGBA32_FLOAT = 40,
|
|
};
|
|
|
|
struct SVertexDataComponent {
|
|
uint32 bufferIndex;
|
|
uint32 offset;
|
|
uint32 stride;
|
|
EVertexDataFormat format;
|
|
EVertexComponent component;
|
|
};
|
|
|
|
struct SVertexBufferInfo {
|
|
uint32 vertexCount;
|
|
uint32 numAttributes;
|
|
SVertexDataComponent component[numAttributes];
|
|
if (!isDKCTF)
|
|
{
|
|
byte unk;
|
|
}
|
|
};
|
|
|
|
struct CGraphicsVertexBufferToken {
|
|
uint32 count;
|
|
SVertexBufferInfo info[count] <optimize=false>;
|
|
};
|
|
|
|
enum <uint32> EBufferType {
|
|
INDEX_U8 = 0, // ?
|
|
INDEX_U16 = 1,
|
|
INDEX_U32 = 2,
|
|
};
|
|
|
|
struct CGraphicsIndexBufferToken {
|
|
uint32 count;
|
|
EBufferType type[count];
|
|
};
|
|
|
|
typedef struct(int readerVersion, int writerVersion) {
|
|
ChunkDescriptor chunk;
|
|
|
|
local uint pos<format = hex, hidden = true> = FTell();
|
|
switch (chunk.id) {
|
|
case "WDHD":
|
|
SWorldModelHeader worldHeader;
|
|
CRenderOctree renderOctree;
|
|
uint aaboxCount;
|
|
CAABox aaboxes[aaboxCount];
|
|
if (form.readerVersion > 52 && form.writerVersion > 52)
|
|
{
|
|
uint floatCount;
|
|
float floats[floatCount];
|
|
}
|
|
if (!isDKCTF)
|
|
{
|
|
ushort unk;
|
|
uint shortCount;
|
|
ushort shorts[shortCount];
|
|
}
|
|
break;
|
|
case "HEAD":
|
|
ModelHeader header;
|
|
break;
|
|
case "SKHD":
|
|
SSkinnedModelHeader skinnedModelHeader;
|
|
break;
|
|
case "MTRL":
|
|
if (isDKCTF == 0)
|
|
{
|
|
if (readerVersion == 163 || readerVersion == 177) {
|
|
FourCC unkFcc;// LEGA?
|
|
} else {
|
|
uint unk;
|
|
}
|
|
}
|
|
uint numMaterials;
|
|
CMaterialCache materials(readerVersion, writerVersion)[numMaterials]<optimize = false>;
|
|
break;
|
|
case "MESH":
|
|
SMeshLoadInformation loadInformation;
|
|
break;
|
|
case "VBUF":
|
|
CGraphicsVertexBufferToken data;
|
|
break;
|
|
case "IBUF":
|
|
CGraphicsIndexBufferToken data;
|
|
break;
|
|
}
|
|
FSeek(pos + chunk.size);
|
|
} ModelChunk <name=(Str("%s chunk", chunk.id))>;
|
|
|
|
typedef struct(uint64 size, int readerVersion, int writerVersion) {
|
|
local uint64 start <format=hex, hidden=true> = FTell();
|
|
while (FTell() < start + size) {
|
|
ModelChunk chunk(readerVersion, writerVersion);
|
|
}
|
|
} ModelFile <name="Model chunks">;
|
|
|
|
// NModelFormat::SReadBufferInfo
|
|
struct SModelReadBufferInfo
|
|
{
|
|
uint32 size <format=hex>;
|
|
uint32 offset <format=hex>;
|
|
};
|
|
|
|
// NModelFormat::SBufferInfo
|
|
struct SModelBufferInfo
|
|
{
|
|
uint32 index; // SModelReadBufferInfo index
|
|
uint32 offset <format=hex>;
|
|
uint32 size <format=hex>;
|
|
uint32 destSize <format=hex>;
|
|
};
|
|
|
|
// NModelFormat::SMetaData
|
|
struct SModelMetaData(uint64 fileStart)
|
|
{
|
|
uint32 unk;
|
|
uint32 gpuOffset <format=hex>;
|
|
uint32 readInfoCount;
|
|
SModelReadBufferInfo readInfo[readInfoCount];
|
|
uint32 vtxInfoCount;
|
|
SModelBufferInfo vtxBufferInfo[vtxInfoCount];
|
|
uint32 idxInfoCount;
|
|
SModelBufferInfo idxBufferInfo[idxInfoCount];
|
|
};
|
|
|
|
#endif// _CGRAPHICSMODEL
|