WDR
Материал из GTAModding.ru
Версия объекта: |
| |||
---|---|---|---|---|
Расширение файла: |
| |||
Содержащийся объект: | ::gtaDrawable |
WDR – Windows Drawable ('XDR – Xenon Drawable, CTD - Cell Drawable) – статические модели.
Ресурс Drawable содержит один экземпляр класса rage::gtaDrawable, является одним из самых распространённых ресурсов в GTA IV. В нем хранятся все статические модели, такие как здания, различные объекты и оружие. Также служит для хранения «частей» моделей персонажей.
Сложность ресурса Drawable заключается в том, что помимо непосредственно информации о модели (геометриях), также содержит достаточно много дополнительной информации.
В общем виде, ресурс состоит из 4-х групп информации:
- ShaderGroup – Информация о шейдерах используемых для рендеринга геометрий модели. Также может содержать непосредственно текстуры (объект rage::pgDictionary<rage::grcTexture>, по сути вложенный WTD файл) используемые в шейдерах.
- Skeleton – Содержит информацию о костях и суставах, отвечающих за то, как части модели могут перемещаться относительно друг друга и прочая инверсная кинематика.
- LodGroup – Непосредственно информация о модели, в каждом объекте rage::gtaDrawable может храниться до 4-х уровней детализации. В каждый уровень детализации может входить несколько «объектов моделей», которые в свою очередь могут состоять из нескольких геометрий (каждая геометрия может содержать до 4-х индексных/вертексных буферов). Для каждой отдельной геометрии указывается какой именно щейдр используется для её рендеринга и указан какой именно формат вектексов используется в геометрии.
- lightAttrs – Информация об освещении модели.
Вывод структуры в 010 Editor
//--------------------------------------
//--- 010 Editor v3.0.5 Binary Template
// File: wdr.bt
// Version: 0.1
// Author: Dageron
// Site: www.GTAModding.ru
//--------------------------------------
struct pgPtr {
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
byte DataStart;
FSeek(doffset);
}
};
struct pgPtr_OffsetMap {
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
DWORD OffsetMap[132];
FSeek(doffset);
}
};
struct PointerCollection {
pgPtr OffsetToThePointers;
short NumberOfPointers;
short unknown;
};
struct VertexBuffer { // BlockSize 0x40
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
LONG VTable;// 0xD8BA6B00
short VertexCount;
short Unknown1;// Usually 0
pgPtr DataOffsetToVertexData;
LONG VertexStride;// 36 without normal map, 52 with normal map
pgPtr VertexDeclarationOffset;
LONG Unknown2;// Usually 0
pgPtr DataOffsetToVertexData1;// Again
LONG Unknown3;// Usually 0
byte Padding[32];
FSeek(doffset);
}
};
struct IndexBuffer{ // BlockSize 0x40
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
LONG VTable;// 0x70B86B00
LONG IndexCount;
pgPtr DataOffsetToIndexData;
LONG Unknown1;// Usually 0
byte Padding[32];
FSeek(doffset);
}
};
struct Geometry {
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
LONG VTable;// 0xF4486B00
LONG Unknown1;// Usually 0
LONG Unknown2;// Usually 0
VertexBuffer m_VertexBuffer;
LONG Unknown3;// Usually 0
LONG Unknown4;// Usually 0
LONG Unknown5;// Usually 0
IndexBuffer m_IndexBuffer;
LONG Unknown6;// Usually 0
LONG Unknown7;// Usually 0
LONG Unknown8;// Usually 0
LONG IndexCount;
LONG FaceCount;
short VertexCount;
short PrimitiveType;
LONG Unknown9;// Usually 0
short VertexStride;// 36 without normal map, 52 with normal map
short Unknown10;// Usually 0
LONG Unknown11;// Usually 0
LONG Unknown12;// Usually 0
LONG Unknown13;// Usually 0
byte Padding[4];
FSeek(doffset);
}
};
struct PtrCollectionGeometrys {
int offset:28;
int type:4;
short NumberOfPointers;
short unknown;
local uint doffset = FTell();
FSeek(offset);
Geometry m_Geometry[NumberOfPointers] <optimize=true>;
FSeek(doffset);
};
struct pgPtr_Model {
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
LONG VTable;// 0x34026B00
PtrCollectionGeometrys m_PtrCollectionGeometrys;
pgPtr SimpleArrayVector4;// Unknown Vectors
pgPtr SimpleArrayInteger;// Material Mappings
short Unknown1;// Usually 0
short Unknown2;
short Unknown3;
short GeometryCount;
byte Padding[8];
FSeek(doffset);
}
};
struct pgPtr_ModelCollection {
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
int offset1:28;
int type1:4;
short NumberOfPointers;
short Unknown;
byte Padding[8];
{
if (type1 == 5) { // RAM location
local uint doffset1 = FTell();
FSeek(offset1);
pgPtr_Model m_pgPtr_Model[NumberOfPointers]<optimize=true>;
FSeek(doffset1);
}
}
FSeek(doffset);
}
};
struct SimpleCollection {
pgPtr OffsetToTheData;
short DataCount;
short DataSize;
};
struct pgPtr_String{
int offset:28;
int type:4;
if (type == 5) {
local uint doffset = FTell();
FSeek(offset);
string data;
FSeek(doffset);
}
};
struct ShaderFX {
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
LONG VTable;// 0x3C226B00
LONG BlockMapAdress;
short Unknown1;
byte Unknown2;
byte Unknown3;
LONG Unknown4;
LONG Unknown5;
pgPtr ShaderParamsOffsetsOffset;
LONG Unknown6;
LONG ShaderParamCount;
LONG Unknown8;
pgPtr ShaderParamTypesOffset;
LONG UnknownHash;
LONG Unknown9;
LONG Unknown10;
pgPtr ShaderParamNameOffset;
LONG Unknown11;
LONG Unknown12;
LONG Unknown13;
pgPtr_String ShaderNamePointer; // Pointer to null terminated String
pgPtr_String ShaderSPSPointer; // Pointer to null terminated String
LONG Unknown14;
LONG Unknown15;
LONG Unknown16;
LONG Unknown17;
}
FSeek(doffset);
};
struct PtrPointerCollectionShaderFXObjects {
int offset:28;
int type:4;
short NumberOfPointers;
short unknown;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
ShaderFX m_ShaderFX[NumberOfPointers]<optimize=true>;
FSeek(doffset);
}
};
struct ShaderGroupData {
int offset:28;
int type:4;
if (type == 5) { // RAM location
local uint doffset = FTell();
FSeek(offset);
LONG VTable;// 0x44166B00
pgPtr TextureDictionairy;// 0 = no Embedded textures
PtrPointerCollectionShaderFXObjects m_PointerCollectionToShaderFXobjects;
int zeros[12];
SimpleCollection VertexDeclarationUsageFlags;
SimpleCollection UnknownInts;
FSeek(doffset);
}
};
struct gtaDrawable {
int VTable;
pgPtr_OffsetMap m_pgPtr_OffsetMap;
ShaderGroupData m_ShaderGroupData;
pgPtr SkeletonData;
float CenterX;
float CenterY;
float CenterZ;
float CenterW;
float BoundsMinX;
float BoundsMinY;
float BoundsMinZ;
float BoundsMinW;
float BoundsMaxX;
float BoundsMaxY;
float BoundsMaxZ;
float BoundsMaxW;
pgPtr_ModelCollection m_pgPtr_ModelCollection;//0=Non existing
pgPtr PointerLODmodels1;//0=Non existing
pgPtr PointerLODmodels2;//0=Non existing
pgPtr PointerLODmodels3;//0=Non existing
float MaxVectorX;//Usually 9999.0)
float MaxVectorY;//Usually 9999.0)
float MaxVectorZ;//Usually 9999.0)
float MaxVectorW;//Usually 9999.0)
int ObjectCount;
int Unknown1;//Usually 0xFFFFFFFF
int Unknown2;//Usually 0xFFFFFFFF
int Unknown3;//Usually 0xFFFFFFFF
int Unknown4;
byte Unknown[20];//Usually all zeros
byte UnassignedData[8];//0xCDCDCDCDCDCDCDCD
byte EndOfHeader[4];//Usually 0x00000000
};
LittleEndian();
struct
{
gtaDrawable m_gtaDrawable;
} wdr;
Заголовок WDR
ид секции (7691129) оффсет 1 (секция 1) оффсет 2 (секция 2) ...
секция 1
0 неизвестно
секция 2
ид секции (52114138) оффсет 21 (секция 21) оффсет 22 (секция 22) количество контейнеров моделей для секции 22 ...
секция 21
ид секции (76173129) 0 0 1 оффсет 211 (секция 211) количество контейнеров текстур для секции 211 оффсет 212 (секция 212) количество контейнеров текстур для секции 212
секция 211
массив, длинна строки: 4 байт. Количество элементов массива = количество контейнеров текстур внутри WDR
секция 212
массив оффсетов на заголовки контейнеров текстур, длинна строки: 4 байт. Количество элементов массива = количество контейнеров текстур внутри WDR.
секция 22
массив оффсетов на заголовки контейнеров моделей, длинна строки: 4 байт. Количество элементов массива = количество контейнеров моделей внутри WDR.