Taxi demo update with sedan
This commit is contained in:
@@ -127,6 +127,10 @@ cmake --build build --target Procedural # Procedural test (legacy)
|
||||
cmake --build build --target TerrainTest # Terrain test (legacy)
|
||||
cmake --build build --target TerrainTest # Terrain test (legacy)
|
||||
cmake --build build --target editSceneEditor # Current executable for scene editor and game
|
||||
cmake --build build --target demoLuaSceneScript # Demo: game-mode inline scene/prefab Lua scripts
|
||||
cmake --build build --target demoSceneSwitchingExtra # Demo: scene switching with CellGrid interior
|
||||
cmake --build build --target demoSokoban # Demo: forklift sokoban activity (vehicle + crates + quest HUD)
|
||||
cmake --build build --target demoTaxi # Demo: taxi driver (procedural town, sedans, NPC traffic, fare chain)
|
||||
```
|
||||
|
||||
### Build Outputs
|
||||
@@ -135,6 +139,11 @@ cmake --build build --target editSceneEditor # Current executable for scene e
|
||||
- `build/Procedural` - Procedural generation test (legacy)
|
||||
- `build/TerrainTest` - Terrain system test (legacy)
|
||||
- `build//src/features/editScene/editSceneEditor` - current executable
|
||||
- `build//src/features/editScene/demos/demo-lua-scene-script/demoLuaSceneScript` - SceneScriptComponent demo (game mode, inline Lua); self-contained runtime staged in the same directory
|
||||
- `build//src/features/editScene/demos/demo-scene-switching-extra/demoSceneSwitchingExtra` - Scene-switching demo with a CellGrid interior (own-entity ProceduralMaterial/ProceduralTexture); self-contained runtime staged in the same directory
|
||||
- `build//src/features/editScene/demos/demo-interior-exterior-dynamics/demoInteriorExteriorDynamics` - Same scene-switching demo, but the exterior scene has a streaming terrain (baseNoise archipelago - a large island at the content site amid an ocean with more islands) + sky + water instead of the flat floor; self-contained runtime staged in the same directory
|
||||
- `build//src/features/editScene/demos/demo-sokoban/demoSokoban` - Forklift sokoban activity demo (drivable Jolt VehicleConstraint forklift, pushable crates, target pads, completion HUD); based on demo-interior-exterior-dynamics, see demos/demo-sokoban/PLAN.md; self-contained runtime staged in the same directory
|
||||
- `build//src/features/editScene/demos/demo-taxi/demoTaxi` - Taxi driver demo (procedurally generated town, drivable sedans, passenger/foot-traffic/vehicle-traffic NPCs, chained timed fares with doubling payout); based on demo-interior-exterior-dynamics with vehicle ideas from demo-sokoban, see demos/demo-taxi/PLAN.md; self-contained runtime staged in the same directory
|
||||
- `build/resources/` - Staged game resources
|
||||
- `build/characters/` - Processed character models
|
||||
- `build/water/` - Water assets (legacy)
|
||||
@@ -224,13 +233,17 @@ The editor/game mode executable adds its own ECS modules:
|
||||
|--------|---------|
|
||||
| CharacterSlotSystem | Catalog-driven multi-slot character mesh builder |
|
||||
| CharacterSpawnerSystem | Distance-based spawn/despawn of registry characters |
|
||||
| TerrainPrefabSpawnerSystem | Distance-based terrain prefab spawn/despawn, terrain snap and compliance flattening |
|
||||
| PlayerControllerSystem | Player input, camera, locomotion and animation state |
|
||||
| ActuatorSystem | Player interaction prompts and smart-object/item actions |
|
||||
| DoorSystem | Swing animation and collider toggle for CellGrid door entities |
|
||||
| EditorUISystem | ImGui property panels and scene management |
|
||||
| ProceduralTextureSystem | Runtime procedural texture generation |
|
||||
| ProceduralMaterialSystem | Runtime procedural material creation |
|
||||
| AnimationTreeRegistry | Global named animation tree definitions |
|
||||
| AnimationTreeSystem | Runtime evaluation of registry-referenced animation trees |
|
||||
| SceneScriptSystem | Execute-once scene/prefab Lua scripts (SceneScriptComponent) and scene_loaded/prefab_loaded events |
|
||||
| VehicleSystem | Jolt VehicleConstraint vehicles (VehicleComponent): chassis constraint lifetime, driver input, wheel visual nodes |
|
||||
|
||||
#### PlayerControllerSystem
|
||||
|
||||
@@ -245,6 +258,11 @@ When a controller's `targetCharacterName` points at an entity with
|
||||
immediate spawn; the actual controlled entity is the spawned character
|
||||
instance, not the spawner.
|
||||
|
||||
The TPS camera boom is collision-clamped via a physics raycast from the
|
||||
pivot to the desired camera position (instant pull-in, eased recovery), and
|
||||
the character geometry is hidden when the clamped camera gets too close to
|
||||
the body — see `src/features/editScene/AGENTS.md` for details.
|
||||
|
||||
#### Player Character Resolution
|
||||
|
||||
Systems that need the live player character (inventory UI, character sheet,
|
||||
@@ -268,7 +286,9 @@ inside `keyPressed`/`keyReleased` by `keysym.sym`. Repeated `KEYDOWN` events
|
||||
(`evt.repeat != 0`) are ignored for movement keys, because releasing `Shift`
|
||||
while `W`/`A`/`S`/`D` is held can generate a repeated keydown with a different
|
||||
symbol after the physical release, which would otherwise leave the key stuck.
|
||||
One-shot actions (`E`, `F`, `I`, `Escape`) are still matched by `keysym.sym`.
|
||||
One-shot actions (`E`, `F`, `I`, `Space`) are also matched by `keysym.sym`,
|
||||
and their `*Pressed` edges ignore repeats too — otherwise holding `E` (e.g.
|
||||
the hold-E-to-exit a vehicle) re-fires the door actuators and re-enters.
|
||||
|
||||
#### CharacterSpawnerComponent
|
||||
|
||||
@@ -286,6 +306,30 @@ The spawner uses the entity's `TransformComponent` for spawn position/rotation.
|
||||
|
||||
The actual tree definition (node hierarchy, state machines, animations) lives in the `AnimationTreeRegistry`, persisted to `animation_tree.json`. Trees are authored in the registry editor (**Tools -> Animation Tree Registry**), where each entry can also select a skeleton source from the `Characters` resource group (one representative mesh per skeleton) to populate animation-name dropdowns. Old scenes and prefabs that stored the tree inline or referenced an `AnimationTreeTemplate` are migrated automatically on load.
|
||||
|
||||
#### Road Region Streaming (M5)
|
||||
|
||||
When the terrain has `streamingEnabled`, `RoadSystem` persists the road graph per terrain page in `heightmaps/<terrainId>/roads/<px>_<py>.json` (managed by `RoadRegionStore`) instead of inline in the scene JSON — `SceneSerializer::serializeTerrain` then skips `roadNodes`/`roadEdges` and keeps only `roadConfig`. Region files store absolute world-space doubles; a cross-page edge is written to the region file of each endpoint page with the foreign endpoint repeated inline. On the first sync a non-empty inline graph is migrated to region files automatically. Merges match nodes by world XZ (0.01 eps) so reloaded pages never duplicate nodes; `EditorUISystem::saveScene` calls `RoadSystem::flushRegionStore()` before writing the scene. Page mesh rebuilds are gated by a rebase-invariant FNV-1a content signature (world positions quantized to cm), so a render-origin rebase shifts node render positions without re-dirtying pages; navmesh dirtying is debounced (~15 quiet frames) while streaming.
|
||||
|
||||
#### Terrain Streaming Architecture
|
||||
|
||||
The terrain can span up to 40,000,000 x 40,000,000 units (`TerrainComponent::worldSizeUnits`, default; 20000 x 20000 pages at the default 2000-unit page size, clamped to 32768 per axis for TerrainGroup's signed 16-bit slot packing). Streaming is opt-in per terrain via `TerrainComponent::streamingEnabled`.
|
||||
|
||||
**Coordinate spaces.** Three spaces coexist (see `TerrainSystem.hpp` "Coordinate spaces"):
|
||||
|
||||
- **WORLD** space — absolute double-precision coordinates; authoritative. `TransformComponent::worldX/Y/Z`, region files, bookmarks and the Navigation panel all use it.
|
||||
- **RENDER** space — floats relative to the floating render origin: `render = world - renderOrigin`. Scene nodes, mouse rays and the editor camera live here. `RenderOriginSystem` (singleton, `RenderOriginSystem::getInstance()`) owns the origin and rebases when the camera moves further than `REBASE_THRESHOLD` (8192 render units) from it: the origin snaps to integer world coordinates near the camera and every render-space position shifts by the exact negated delta. Convert with `RenderOriginSystem::worldToRender(x,y,z)` / `renderToWorld(Ogre::Vector3)`.
|
||||
- **PHYSICS** space — Jolt `DVec3`/`RVec3` in absolute world coordinates via `physics/physics.h`; terrain colliders live here, so `TerrainSystem::raycastTerrain` converts its render-space ray to world space for the collider query.
|
||||
|
||||
`TerrainSystem` additionally exposes `renderToWorldX/Y/Z`, `worldToRender`, and `visualToPhysicalX/Z` / `physicalToVisualX/Z` for the physical heightmap space (physical X shifted by half a page, physical Z mirrored within each page).
|
||||
|
||||
**Page streaming window.** With `streamingEnabled`, pages are not defined up front; `TerrainSystem::updateStreamingWindow()` loads a square window of `pageLoadRadius` pages around the camera page each frame (2 loads/frame cap) and unloads pages beyond `pageHoldRadius` (4 unloads/frame cap), all synchronously to avoid WorkQueue shutdown hangs. Base heights come from procedural `TerrainComponent::baseNoise` (FastNoiseLite, double precision) instead of the legacy heightmap buffer; `setHeightAt` writes through the LRU-capped fixup chunk layer. Pages are indexed in PHYSICAL page coords `[0, N-1]`; the Ogre TerrainGroup slot for physical page `(x, y)` is `(x, -y)` because `ALIGN_X_Z` negates Z. The world is bounded — page indices and teleports clamp to `[0, N-1]`.
|
||||
|
||||
**Region storage.** Per-page data lives under `heightmaps/<terrainId>/`: painted blend maps, aux maps, fixup chunks, plus the streamed content stores `spawners/<px>_<py>.json` (prefab spawner defs, see below) and `roads/<px>_<py>.json` (road graph, see "Road Region Streaming (M5)" above).
|
||||
|
||||
**Editor navigation tools (M3).** `EditorCamera` supports mouse-wheel zoom (`handleMouseWheel`), Shift boost (x10) and a configurable fly speed (`setFlySpeed`, 1..100000 units/s). **Tools -> Navigation** opens `NavigationPanel` (teleport by world X/Y/Z or by page index, clamped to world bounds; named world bookmarks stored in the scene JSON top-level `bookmarks` array, tolerated when missing on load). **Tools -> World Map** opens `WorldMapPanel` (ImGui canvas over `WorldMapData`: coarse heights, loaded pages, roads, spawners, bookmarks and camera overlays; drag pan, wheel zoom, double-click teleport). `TerrainEditor` also has a compact "Navigation" section sharing the same static teleport backend.
|
||||
|
||||
**Streamed vs always-loaded spawners (M4).** Scene-embedded `TerrainPrefabSpawnerComponent` entities behave as always-loaded spawners for small/non-streaming scenes. When the terrain streams, spawner definitions persist per page in `heightmaps/<terrainId>/spawners/<px>_<py>.json` (via `SpawnerRegionStore`); `TerrainPrefabSpawnerSystem::syncStreamedSpawners()` polls `TerrainGroup::getTerrainSlots()` and creates a region spawner entity (tagged `StreamedSpawnerTag{pageX,pageY,defId}`, excluded from scene JSON) when a page loads, destroying it and writing edits back (including page-boundary crossings) when it unloads. The editor "prefab spawn mode" click-to-place writes to the region store when streaming.
|
||||
|
||||
### Physics System
|
||||
|
||||
Uses Jolt Physics with custom wrapper (legacy - `src/physics/physics.h`, current - `src/features/editScene/physics/physics.h`):
|
||||
@@ -311,7 +355,22 @@ JPH::BodyID body = physics->createBody(shape, 1.0f, position, rotation,
|
||||
2. **Export**: Python scripts in `assets/blender/scripts/`
|
||||
- `export_buildings.py` - Building export to glTF
|
||||
- `export_characters_ogre.py` - Character export to OGRE format
|
||||
- `export_vehicles.py` - Vehicle export
|
||||
- `export_vehicles.py` - Vehicle export (car modeling contract:
|
||||
`assets/blender/vehicles/CAR_MODELING.md`)
|
||||
- `gen_sokoban_assets.py` - One-shot generator for the demo-sokoban
|
||||
`forklift`/`crate`/`pad` .blend files (blender2ogre names .mesh
|
||||
files after mesh *data* names — set both object and data names)
|
||||
- `gen_taxi_assets.py` - Generator for the demo-taxi `sedan-a` /
|
||||
`sedan-taxi` .blend files (body + hinge-local door/hood/trunk
|
||||
parts, shared wheel meshes; body colors baked as material
|
||||
variants)
|
||||
- `gen_vehicle.py` - Convention-based vehicle pipeline for
|
||||
hand-modeled cars (`sedan-v2.blend` is the reference): classifies
|
||||
parts by name (`* Tire`, `* Door`, `* hood`/`* trunk`,
|
||||
`* Steering`, `seat_*` empties), normalizes wheel/steering axes,
|
||||
unpacks texture atlases, and emits a ready-to-merge
|
||||
`<name>.vehicle.json` scene entity (contract:
|
||||
`assets/blender/vehicles/CAR_MODELING.md`)
|
||||
- `import_vrm.py` - VRM character import
|
||||
3. **Build**: CMake processes assets during build
|
||||
4. **Runtime**: Assets loaded from `resources.cfg` paths
|
||||
|
||||
Reference in New Issue
Block a user