Update terrain plan

This commit is contained in:
2026-06-27 00:13:04 +03:00
parent 52de5cef44
commit 4b46b1a8e0
+60 -11
View File
@@ -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).