Update terrain plan
This commit is contained in:
@@ -432,10 +432,9 @@ m_world.component<TerrainComponent>();
|
||||
|
||||
**In `EditorApp::setup()`** — construct after physics but before water/sun/skybox
|
||||
(terrain must exist before those systems try to interact with it):
|
||||
```cpp
|
||||
m_terrainSystem = std::make_unique<TerrainSystem>(
|
||||
m_world, m_sceneMgr, m_physicsSystem.get());
|
||||
```
|
||||
Ogre::Camera *cam = m_camera ? m_camera->getCamera() : nullptr;
|
||||
m_terrainSystem = std::make_unique<TerrainSystem>(
|
||||
m_world, m_sceneMgr, cam, m_physicsSystem->getPhysicsWrapper());
|
||||
|
||||
**In `EditorApp::frameRenderingQueued()`** — call update **before**
|
||||
static-world generation and **after** visual mesh setup. Insert right after
|
||||
@@ -1012,6 +1011,8 @@ Minimum controls:
|
||||
- Add/remove/split/join/select nodes.
|
||||
- Inspector for node position, offset, edge levels.
|
||||
- "Comply terrain to roads" button.
|
||||
- Physics debug: "Show Terrain Colliders" checkbox (off by default,
|
||||
toggles `TerrainBodyDrawFilter` via `TerrainSystem`).
|
||||
- Prefab spawn mode (uses `TerrainPrefabSpawnerComponent`):
|
||||
- Add/remove spawn points (snapped to terrain surface).
|
||||
- Pick prefab from existing prefab list.
|
||||
@@ -1145,15 +1146,63 @@ Definition of done: a paged terrain renders in the editor; terrain pages load
|
||||
and unload as the camera moves.
|
||||
|
||||
### Milestone 2 — Physics integration
|
||||
- Implement `ZigzagHeightfieldShape` as a `JPH::MeshShape` per page with zigzag
|
||||
triangulation matching Ogre.
|
||||
- Queue collider creation after page load and derived-data completion.
|
||||
- Maintain `mColliders` map; safe remove/re-add on scene clear or component
|
||||
removal.
|
||||
- Add raycast helper to `TerrainSystem` for gameplay/editor tools.
|
||||
|
||||
**Changes to TerrainSystem constructor**: Now takes `JoltPhysicsWrapper*` so
|
||||
it can create/destroy static terrain collider bodies directly in the Jolt world.
|
||||
|
||||
```cpp
|
||||
TerrainSystem(flecs::world &world, Ogre::SceneManager *sceneMgr,
|
||||
Ogre::Camera *camera, JoltPhysicsWrapper *physics);
|
||||
```
|
||||
|
||||
**EditorApp wiring change**: Update `setup()` to pass `m_physicsSystem->getPhysicsWrapper()`.
|
||||
|
||||
**Collider creation queue**: After `CustomTerrainDefiner::define()` finishes a
|
||||
page and `isDerivedDataUpdateInProgress()` is false, create a per-page
|
||||
`JPH::MeshShape` with zigzag triangulation (see section 3.3) and add a static
|
||||
body at the page's world position. Bodies go into `Layers::NON_MOVING`.
|
||||
|
||||
**mColliders map**: `std::unordered_map<uint64_t, TerrainCollider>` keyed by
|
||||
`packIndex(x, y)`. `TerrainCollider` holds `{pageX, pageY, JPH::BodyID,
|
||||
pendingRemove}`.
|
||||
|
||||
**Collider removal queue**: When a page unloads (detected via
|
||||
`DummyPageProvider::unloadProceduralPage`), mark its collider `pendingRemove`.
|
||||
In `update()`, only remove bodies when no derived data update is in progress.
|
||||
|
||||
**Zigzag triangulation** (see section 3.3): Build `JPH::MeshShape` from
|
||||
`terrain->getHeightData()` using the zigzag quad split matching Ogre's odd/even
|
||||
row parity.
|
||||
|
||||
**Debug drawing — TerrainBodyDrawFilter**:
|
||||
- Implement `class TerrainBodyDrawFilter : public JPH::BodyDrawFilter` in
|
||||
`TerrainSystem` that tracks terrain `BodyID`s in a `std::set`.
|
||||
- `ShouldDraw(const JPH::Body &)` returns `false` for terrain bodies when
|
||||
`m_showTerrainColliders == false` (the default).
|
||||
- Add `void setShowTerrainColliders(bool)` toggle.
|
||||
- Thread the filter into the physics wrapper: add a
|
||||
`JoltPhysicsWrapper::setBodyDrawFilter(BodyDrawFilter*)` setter and pass it
|
||||
to `BodyManager::DrawBodies(..., filter)`.
|
||||
- Terrain editor gets a **"Show Terrain Colliders"** checkbox (off by default).
|
||||
|
||||
**Raycast helper**: `TerrainSystem::getHeightAt(const Ogre::Vector3 &worldPos)`
|
||||
picks the right page, samples the height data bilinearly, and returns the
|
||||
world-space Y. Also add `raycastTerrain(const Ogre::Ray &ray, float &outT)`
|
||||
that casts a ray against all loaded terrain pages' Jolt bodies using
|
||||
`JPH::NarrowPhaseQuery::CastRay`.
|
||||
|
||||
**Testing**:
|
||||
- [ ] Drop a rigid body on terrain → rests flush (no sinking/floating).
|
||||
- [ ] Toggle "Show Terrain Colliders" → wireframe matches terrain surface.
|
||||
- [ ] Fly away and back → colliders for unloaded pages removed, new pages get colliders.
|
||||
- [ ] Remove terrain entity → all collider bodies removed, no dangling Jolt bodies.
|
||||
- [ ] Add/remove terrain repeated → stable memory (valgrind/ASan).
|
||||
- [ ] Raycast from above hits terrain at correct height.
|
||||
- [ ] Colliders are NOT visible in debug draw by default.
|
||||
|
||||
Definition of done: rigid bodies and characters collide flush with the visible
|
||||
terrain; removing/re-adding the terrain entity is leak-free.
|
||||
terrain; terrain collider debug draw is off by default with a toggle; removing
|
||||
and re-adding the terrain entity is leak-free.
|
||||
|
||||
### Milestone 3 — Serialization + heightmap editing + splat painting
|
||||
- Scene serialization for `TerrainComponent` (save/load JSON round-trip).
|
||||
|
||||
Reference in New Issue
Block a user