Files
2026-01-26 01:39:04 -08:00

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