Skip to content

RealTree meshes

AnvilVegetationApplies toSWS

The trees of Shaun White Skateboarding are not ordinary meshes. A RealTreeMesh object (0xCD0D35E6, the CRC-32 of its name) holds a skeleton of nodes, branches and leaf records that the vertex shader expands into trunk, branches and leaf cards. The game’s executable embeds the RealTreeLib code of Ubisoft’s technology group, whose source file names (RTRenderDataNode.cpp, RTSimulation.cpp, RTSkeletal.cpp, RTRegenSimple.h, RTDestruction.cpp) and an ActivateRealTreeGrowthEvent appear in its strings. Observed · SWS

Level 01 places 30 tree meshes through Visual components, and 29 RealTreeComponent objects are alive in the running level. In the grey Ministry state 36 entities carry both a tree mesh and a sibling ordinary mesh, a metal pole with a bare crown. Observed · level 01

The body of a tree mesh begins with the marker bytes 30 7E 5E 5E, a size, the words 154 and 12345, and the blob is the last size bytes of the body. Pointers inside the blob are stored as 0x72300000 plus an offset and are relocated in place by the loader (0xA38870 of the recorded build, which takes a header of 0x45 integers, an auxiliary block and the blob). Observed

The tree structure is at blob offset 0xF4. Observed

Tree structure (at blob offset 0xF4)variableSWS67% known

Little-endian. Offsets relative to the tree structure; counts N, M and L are the node, branch and leaf counts.

ProvenObservedSourcedInferredUnknownNot described
OffsetSizeTypeFieldConfidenceNotes
0x104u32node count NObserved
0x144pointernodes AObservedN records of 0x50 bytes
0x184pointerbackup tableObserved
0x1C4u32branch count MObservedthe trunk is the first branch
0x204pointerbranchesObservedM records of 0x2C bytes
0x244pointerbackup tableObserved
0x284u32leaf count LObserved
0x2C4pointerleaves CObservedL records of 0x5C bytes

The blob header from offset 0x350 holds the pointers of four tables (F, G, R and E). A node’s radius is the entry R[k − 1]; the last node of a branch is a sentinel and is dropped. The branch and trunk vertex builders are at 0xA621B0 (vertices) and 0xA63790 (indices) and the vertex declarations at 0xA38EE0. Observed

The last node record (branch 65535, a dummy) of the thin and the urban tree trunks holds (−0.004, 0.004, 0.23 or 0.41, the first node's z); its meaning is not established. The trunks of the thin and urban trees start at z 2.6 and 3.5 m above the entity origin, so the trunk begins above the ground (the rule that joins it to the ground is not established), and the small urban tree has a three-node root stub below the ground as branch 0. Observed · level 01

Leaf record92 bytesSWS65% known

Little-endian. The 418 leaves of level 01 give 394 cards; 24 are sentinel or clamped records and are dropped.

ProvenObservedSourcedInferredUnknownNot described
OffsetSizeTypeFieldConfidenceNotes
0x01u8kindObservedselects an entry of the kind table: runs of three words 0x3F008081 at blob offsets 0x300 to 0x4A0
0x33u8[3]UV corner permutationObserved
0x204f32sizeObserved
0x284f32scaleObserved
0x2C48f32[3][4]vertex vectorsObservedvertex = leaf centre + size × vector

A leaf with code 100 or more has three UV corners and a parallelogram; a lower code has four. The four points of a card are coplanar (median volume 0.001 to 0.003). In the small urban tree 91% of the cards are thin (minor over major axis under 0.15) against 15% for the thin tree and 2% for the urban tree. Observed · level 01

The leaf shading normal is the normalised direction from a density sphere’s centre to the leaf, with z raised to at least 0.6 and renormalised, the same on both faces; the colour is the diffuse colour times a light attenuation and the composite lighting. The blob header word at 0x1D4 holds a centre and radius that matches the leaf centroid to within 0.07 to 0.55 m on three level-01 trees and one palm, and 1.5 m on a cherry tree; it is read as the density sphere. Inferred · from the fit to leaf centroids

How is the far crown generated?

The vertex shader scales a leaf by LeavesEquations[scaleOut] (ring distances of 4, 8, 15, 20, 25 and 100 m at blob 0x314 to 0x328) and blends toward camera-facing cards except for scale codes above 99. 149 of 150 leaves of one tree carry code 100 and 141 have ring byte 4, so by this rule they would shrink to zero by 25 m, yet the game shows a dense crown at 37 m. The far-view leaf generation is not in the blob and is not decoded. Unknown

The grey and the restored state use the same tree, and the crowns appear when the game raises an ActivateRealTreeGrowthEvent (0xCB394D43, factory at 0x10DBC50, vtable 0x196ED44, 16 bytes). The RealTreeComponent (0x7338CDF5, runtime vtable 0x1964690) installs a listener at offset 0x3C (vtable 0x19647D8, owner pointer at 0x40, callback at 0x44, the receiver 0xFDE7B0). If the component’s loaded-tree pointer at 0x4C is non-null the receiver sets the byte at 0x6D to 1 and the float at 0x1C to 1.0 and does nothing else. The component’s update (0xFE7958) tests the byte, calls the tree manager (global at 0x1C71AB8, function 0xA3D1C0) with the tree and 1.0, and clears the byte. Observed

Setting those two fields on all 29 components of level 01 by hand, which has the receiver’s effect, made all 29 read 1.0 afterwards, the game consumed every request, and grown branch and leaf canopies appeared at the same camera position where the bare trees had been. Observed · 29 loaded components

The tree materials store the influence hide mode HideNone, so neither the sibling metal mesh nor the tree is discarded by the influence kill; see influence. Observed