Skip to content

Physics: streamed terrain tiles + sculpt edits don't update heightfield collision (follow-up to #428) #469

Description

@drsnuggles8

Is your feature request related to a problem? Please describe.
#428 (PR #468) wired Jolt HeightFieldShape collision into single-tile terrain, built once at OnPhysics3DStart from the terrain's CPU height field. Two cases are deliberately out of scope there and remain gaps:

  1. Streamed terrain (TerrainComponent::m_StreamingEnabled / TerrainStreamer) gets no collisionBuildTerrainCollisionBody early-returns for streaming terrains. Tiles add/remove their visual mesh as the camera moves, but no collision body is created/destroyed in step, so bodies fall through streamed worlds.
  2. Sculpt / erosion edits (TerrainBrush / TerrainErosion, which mutate TerrainData::m_Heights and report a DirtyRegion) update the GPU heightmap and chunk meshes but not the collision shape — the static heightfield body keeps the pre-edit surface.

Describe the solution you'd like

  • Streaming: create/destroy a static HeightFieldShape body per loaded tile, keyed on tile grid coords, hooked into the TerrainStreamer load (ProcessCompletedLoadsBuildGPUResources) and unload/evict (EvictOverBudget) lifecycle. Each tile's body uses its WorldOrigin (gridX·tileWorldSize, 0, gridZ·tileWorldSize) + per-tile TerrainData. Reuse JoltShapes::CreateTerrainHeightFieldShape + JoltScene::CreateTerrainBody/DestroyTerrainBody (already keyed by UUID — may need a per-tile key scheme).
  • Sculpt/erosion: on a DirtyRegion edit, update the affected collision region via JPH::HeightFieldShape::SetHeights(inX, inY, sizeX, sizeY, …). Note Jolt requires the region to be block-aligned (inX % mBlockSize == 0), so snap the dirty rect outward to the block grid. Debounce so a brush drag doesn't rebuild every frame.

Acceptance criteria

  • A character controller / vehicle rests on and traverses streamed terrain without falling through; collision tiles add/remove in step with the visual load/unload.
  • After a sculpt or erosion edit, a body dropped on the edited region rests on the new surface (collision matches the edited mesh).

Additional context
Foundation: #428 / PR #468. Conventions (scale/origin/padding, block-alignment for partial updates) are documented in that PR's JoltShapes::CreateTerrainHeightFieldShape and the JoltScene terrain-body lifecycle.

Score

capability: 5
craft: 3
stability: 3
decay: 1
effort: 5
confidence: 0.8
learning: 2
fun: 3
kano: table-stakes
blocked_by: []
blocks: []

Rated per issue-scoring · score = confidence × (capability + craft + stability + decay) / effort, derived by the picker.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions