Clustered Mesh
Clustered Mesh resources were used for world collision (WORLDCOL) prior to the introduction of the Polygon Soup List resource type.
Structures
CgsPhysics::CollisionMeshData
32-bit
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x4 | Volume* | mpCollisionVolume | ||
0x4 | 0xC | Padding | |||
0x10 | 0x10 | Vector3Plus | mBoundingSphere |
rw::collision::VolRef::Volume
32-bit
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
32-bit
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
32-bit
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x30 | Aggregate | super_Aggregate |
rw::collision::ClusteredMesh
The base pointer resets here - all pointer offsets here are relative to the start of this struct.
32-bit
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
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x10 | vpu::Vector3 | m_min | ||
0x10 | 0x10 | vpu::Vector3 | m_max |
rw::collision::ClusterParams
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x4 | float32_t | mVertexCompressionGranularity | ||
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
The base pointer resets here - all pointer offsets here are relative to the start of this struct.
32-bit
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
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
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0x4 | uint32_t | m_content | ||
0x4 | 0x4 | uint32_t | m_index |
rw::collision::ClusteredMeshCluster
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
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 (repeating) |
0x10 | vpu::Vector3? | ? |
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 | 0xC | float[3] | ? | ||
0xC (repeating) |
0x6 | ? | ? | Add this to initial 3-float vector and multiply components by mVertexCompressionGranularity? |
Offset | Length | Type | Name | Description | Comments |
---|---|---|---|---|---|
0x0 (repeating) |
0xC | ? | ? | Multiply components by mVertexCompressionGranularity? |
Unit data
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 - ? 2 - ? 3 - ? Upper nibble Flag 1 - ? Flag 2 - ? Flag 4 - Has a group ID Flag 8 - Has a surface ID |
|
0x1 | uint8_t | Only present if type == 3 The size of ? |
|
Variable | ? | Size is 1 for type 1, 2 for type 2, and specified by the previous byte for type 3. | |
0x2 | ? | ? | ? |
2 + variable size again | ? | Only present with flag 2 | ? |
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. |