Clustered Mesh

Revision as of 05:11, 22 February 2024 by Burninrubber0 (talk | contribs) (Remove base class names generated by Ghidra.)
ClusteredMesh
aka CollisionMeshData

Track unit 203's clustered mesh.
Resource names Unknown
Type ID 0x24
Category Generic
Memory
distribution
Main Memory only
Imports Unknown
Imported by ID List
Editor
available?
Viewer only
Use Blender addons


Clustered Mesh resources were used for world collision (WORLDCOL) prior to the introduction of the Polygon Soup List resource type.

Development
Information on versions of the Clustered Mesh resource type used during development.

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 Base class

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 Base class
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 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

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
 
Hmmm...
To do:
Normals?
Vertex data
Unit data

Vertex data

Compression mode 0 (uncompressed)
Offset Length Type Name Description Comments
0x0
(repeating)
0x10 vpu::Vector3 ? Raw vector (mVertexCompressionGranularity unused)
Compression mode 1
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
Compression mode 2
Offset Length Type Name Description Comments
0x0
(repeating)
0xC int32_t[3] ? Multiply components by mVertexCompressionGranularity to get coordinate

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 - 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.