Clustered Mesh
ClusteredMesh | |||
---|---|---|---|
aka CollisionMeshData | |||
Type ID | 0x24 | ||
Category | Generic | ||
Memory distribution |
Main Memory only | ||
Imported by | ID List |
Development Information on versions of the Clustered Mesh resource type used during development. |
Clustered Mesh resources were used for world collision (WORLDCOL) prior to the introduction of the Polygon Soup List resource type.
Structures[edit | edit source]
CgsPhysics::CollisionMeshData[edit | edit source]
32-bit[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x4 | Volume* | mpCollisionVolume | ||
0x4 | 0xC | Padding | |||
0x10 | 0x10 | Vector3Plus | mBoundingSphere |
rw::collision::VolRef::Volume[edit | edit source]
32-bit[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x40 | Matrix44Affine | transform | ||
0x40 | 0x4 | Volume::VTable* | vTable | When written to file, this actually represents an rw::collision::VolumeType instead rather than a pointer. This is always VOLUMETYPEAGGREGATE , which has a value of 6.
| |
0x44 | 0x4 | ClusteredMesh* | This is actually implemented as a 12-byte union accepting multiple types, including three floats representing triangles or boxes. The union type used is defined by the VolumeType in the vTable. The Clustered Mesh resource type however only accepts a ClusteredMesh pointer here (represented by the aggregate volume type), and will cause undefined behaviour if other types are used instead.
| ||
0x48 | 0x8 | Union padding | |||
0x50 | 0x4 | float32_t | radius | ||
0x54 | 0x4 | uint32_t | groupID | ||
0x58 | 0x4 | uint32_t | surfaceID | ||
0x5C | 0x4 | uint32_t | m_flags | List of flags is unknown |
rw::collision::Aggregate[edit | edit source]
32-bit[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x20 | AABBox | m_AABB | ||
0x20 | 0x4 | Aggregate::VTable* | m_vTable | Garbage data in the file - always replaced on read | |
0x24 | 0x4 | uint32_t | m_numTagBits | ||
0x28 | 0x4 | uint32_t | m_numVolumes | ||
0x2C | 0x4 | uint32_t | pad |
rw::collision::Procedural[edit | edit source]
32-bit[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x30 | Aggregate | super_Aggregate |
rw::collision::ClusteredMesh[edit | edit source]
The base pointer resets here - all pointer offsets here are relative to the start of this struct.
32-bit[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x30 | Procedural | super_Procedural | ||
0x30 | 0x4 | KDTree* | mKDTree | ||
0x34 | 0x4 | uint32_t* | mCluster | Effectively a ClusteredMeshCluster** | |
0x38 | 0x8 | ClusterParams | mClusterParams | ||
0x40 | 0x4 | uint32_t | mNumClusters | ||
0x44 | 0x4 | uint32_t | mMaxClusters | ||
0x48 | 0x4 | uint32_t | mNumUnits | ||
0x4C | 0x4 | uint32_t | mMaxUnits | ||
0x50 | 0x4 | uint32_t | mSizeOfThis | ||
0x54 | 0x2 | uint16_t | mDefaultGroupId | ||
0x56 | 0x2 | uint16_t | mDefaultSurfaceId | ||
0x58 | 0x1 | uint8_t | mDefaultEdgeAngle | ||
0x59 | 0x7 | Padding |
rw::collision::AALineClipper::AABBox[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x10 | vpu::Vector3 | m_min | ||
0x10 | 0x10 | vpu::Vector3 | m_max |
rw::collision::ClusterParams[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x4 | float32_t | mVertexCompressionGranularity | Relevant for cluster compression modes 1 and 2 | |
0x4 | 0x2 | uint16_t | mFlags | List of flags is unknown | |
0x6 | 0x1 | uint8_t | mGroupIdSize | Number of bytes | 1 or 2 |
0x7 | 0x1 | uint8_t | mSurfaceIdSize | Number of bytes | 1 or 2 |
rw::collision::KDTree[edit | edit source]
The base pointer resets here - all pointer offsets here are relative to the start of this struct.
32-bit[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x4 | BranchNode* | m_branchNodes | ||
0x4 | 0x4 | uint32_t | m_numBranchNodes | ||
0x8 | 0x4 | uint32_t | m_numEntries | ||
0xC | 0x4 | Padding | |||
0x10 | 0x20 | AABBox | m_bbox |
rw::collision::KDTree::BranchNode[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x4 | uint32_t | m_parent | ||
0x4 | 0x4 | uint32_t | m_axis | ||
0x8 | 0x10 | NodeRef[2] | m_childRefs | ||
0x18 | 0x8 | float32_t[2] | m_extents |
rw::collision::KDTree::NodeRef[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x4 | uint32_t | m_content | ||
0x4 | 0x4 | uint32_t | m_index |
rw::collision::ClusteredMeshCluster[edit | edit source]
Offset | Length | Type | Name | Description | Comments | ||
---|---|---|---|---|---|---|---|
0x0 | 0x2 | uint16_t | unitCount | ||||
0x2 | 0x2 | uint16_t | unitDataSize | ||||
0x4 | 0x2 | uint16_t | unitDataStart | The index of the vertex array where unit data starts | |||
0x6 | 0x2 | uint16_t | normalStart | The index of the vertex array where normal data starts | |||
0x8 | 0x2 | uint16_t | totalSize | ||||
0xA | 0x1 | uint8_t | vertexCount | ||||
0xB | 0x1 | uint8_t | normalCount | ||||
0xC | 0x1 | uint8_t | compressionMode | 0, 1 or 2 | |||
0xD | 0x3 | uint8_t[3] | padding | ||||
0x10 | 0x10 | vpu::Vector3[1] | vertexArray | Variable size data |
Unit data |
Vertex data[edit | edit source]
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 (repeating) |
0x10 | vpu::Vector3 | ? | Raw vector (mVertexCompressionGranularity unused) |
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0xC | int32_t[3] | ? | Component base | |
0xC (repeating) |
0x6 | uint16_t[3] | ? | Add to initial int32_t components and then multiply components by mVertexCompressionGranularity to get coordinate |
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 (repeating) |
0xC | int32_t[3] | ? | Multiply components by mVertexCompressionGranularity to get coordinate |
Unit data[edit | edit source]
This is a byte stream. Exact offsets are variable and depends on several factors, as detailed below.
Length | Type | Description | Comments |
---|---|---|---|
0x1 | uint8_t | Lower nibble (type) 1 - Triangles 2 - Quads 3 - Variable? Upper nibble Flag 1 - ? Flag 2 - Has edge cosine? data Flag 4 - Has a group ID Flag 8 - Has a surface ID |
|
0x1 | uint8_t | Only present if type == 3 The number of points minus two |
|
Point count | uint8_t | Vertex index | 3 points for type 1, 4 points for type 2, and specified by the previous byte plus 2 for type 3 |
Point count | uint8_t | Only present with flag 2 Edge cosines? Mask with 0x1F and flags above that? | |
Group ID size (see ClusterParams) | uint8_t or uint16_t | Only present with flag 4 Group ID |
This is always little endian. |
Surface ID size (see ClusterParams) | uint8_t or uint16_t | Only present with flag 8 Surface ID |
This is always little endian. |