Commit Graph
7 Commits
Author SHA1 Message Date
atdunbg b6d0868e15 feat(ecs): per-component enable/disable + inspector rework
Add `active` flag to the 8 behavior components (Unity enabled / UE
SetActive semantics; structural Id/Name/Transform excluded). Consumers
skip disabled components: renderer (mesh/light/anim), primary camera
election, physics reconciliation (body/constraint/character destroyed
and rebuilt on toggle), scripts keep instance but stop ticking.

Inspector: component headers now carry an enable checkbox and a remove
button, Add-Component menu greys out attached entries, and conflict
hints added (RigidBody <-> CharacterController mutual exclusion, Joint
requires RigidBody, Animation requires MeshRenderer, unregistered
script name). Scenes persist Active per component (default true).
2026-10-03 18:45:03 +08:00
atdunbg 3403822a52 feat(engine): C++ native script system (ScriptBehavior + registry)
ScriptComponent stores only a script name string (POD, serializable);
instances are reconciled by ScriptRuntime each frame (PhysicsWorld
pattern): orphan/rename cleanup with OnDestroy, per-name instantiation
from a file-level self-registering registry (ENGINE_REGISTER_SCRIPT),
OnCreate on bind, OnUpdate after physics step on scaled dt. Engine
framerate loop only sees the base interface, so future Lua/C# behaviors
plug in as foreign ScriptBehavior implementations with zero engine
changes. Ships a Spinner sample script and Inspector script picker.
2026-10-03 18:02:49 +08:00
atdunbg e1cef53158 physics: character controller (Jolt CharacterVirtual)
- CharacterControllerComponent: capsule params (radius/halfHeight, mass,
  max slope, step height); entity origin = feet via shape offset
- CharacterController per-entity wrapper: gravity integration + grounded
  clamp, ExtendedUpdate (sweep/slide + stick-to-floor + walk-stairs),
  SetLinearVelocity/Jump/IsGrounded facade
- PhysicsWorld: SyncCharacters reconcile (create/rebuild on param
  change, editor-drag teleport), UpdateCharacters after physics Update
  (Jolt recommended order), writes back to Transform
- Inspector: params + grounded/velocity telemetry + jump debug button
- Serialization: params only, state rebuilt by reconcile
2026-10-03 16:34:20 +08:00
atdunbg 82910c41e8 physics: joint constraints (fixed/hinge/ball)
- JointComponent: type, target UUID, per-body local anchors, hinge axis
  + angle limits (data only, zero Jolt deps)
- PhysicsWorld::SyncConstraints: create/remove/rebuild on snapshot
  change; body rebuild contagion via invalidated-bits list; target
  resolved lazily by UUID each sync (no two-pass load needed)
- Jolt FixedConstraint/HingeConstraint/PointConstraint in
  LocalToBodyCOM space (anchors minus shape COM); fixed frames lock
  creation-time relative pose; hinge axis aligned across bodies
- Inspector: Joint section with target entity name dropdown
- Serialization: Joint map with UUID target, as<T> fallbacks
2026-10-03 16:26:20 +08:00
atdunbg a744b332eb physics: capsule/cylinder/compound collider shapes
- ColliderType + Capsule/Cylinder/Compound; CompoundChild list (Box/
  Sphere/Capsule, local pos/quat, non-recursive)
- CreateBody: CapsuleShape/CylinderShape (ctor param orders differ) +
  StaticCompoundShape; empty/failed compound falls back to Box
- BodyRecord caches radius/halfHeight/compound; SyncScene rebuilds on
  change (per-collider param extraction)
- Inspector: combo entries + shape params + compound child list editor
- Serialization: new fields with as<T> fallback, compound seq round-trip
2026-10-03 16:17:44 +08:00
atdunbg e2a9c21e68 fix(serialization): load failure on hardened yaml-cpp + flow-style arrays
yaml-cpp master hardens zombie nodes: operator=, size(), Type() and
chained operator[] all throw InvalidNode instead of silently passing.
Storing per-component nodes via Node::operator= threw for every key
that was absent, so all 7 entities were skipped on load (0 loaded).
Reads are now level-by-level guarded (copy-init + IsDefined), which
only uses the safe surface (as<T>(fallback), begin(), IsDefined).

Save side switched from node-tree streaming to a manual Emitter:
vector/quat fields emit as single-line flow arrays ([0, 1.2, -6])
and model refs as inline maps, with 9-digit float precision for
lossless float32 round-trips.

Verified offline against the previously saved scene: 7/7 entities
parse with correct component counts; emitter output round-trips.
2026-10-03 15:30:36 +08:00
atdunbg 007d175314 serialization: scene save/load (Unity-style YAML + UE-style GUID registry)
Engine-layer SceneSerializer (yaml-cpp submodule): entities/components
to versioned YAML, atomic clear-and-rebuild on load with per-entity
fault tolerance, missing-field defaults, unknown-component skip and
UUID dedup. Asset references are {Guid, Path} pairs resolved through
the new AssetManager GUID registry (assets/asset_registry.yaml) with
path fallback; procedural:// pseudo-paths rebuild from parameters.
Editor File menu gets Save/Load Scene modals; app re-resolves stale
entity handles via onSceneLoaded callback.
2026-10-03 14:47:02 +08:00