Visibility Decoupled from Logic
Added
- `node.SetBodyEnabled(bool)` / `node.BodyEnabled()` pause a physics body without releasing it.
- Removes the body and its shape from the cp space; the `*PhysicsBody` wrapper stays attached to the node.
- Position, rotation, velocity, mass, moment, friction, elasticity, and shape geometry are preserved across the toggle.
- Re-enabling adds the body back to the same space and it resumes from the preserved state.
- Distinct from `RemoveBody`, which releases the body back to the pool and clears `node.Body` to nil.
- `EmitterConfig.SimulateWhileHidden` opts a particle emitter out of the default visibility pause.
- Default false: emitters tick only when their node (and every ancestor) is visible.
- Set true for effects whose state must persist while briefly off-screen (long smoke trails, etc).
Changed
- `SetVisible(false)` now only pauses rendering and hit-testing.
- `OnUpdate` callbacks, tweens, physics simulation, and world-transform recomputation continue to run on hidden subtrees.
- Gameplay logic on hidden nodes sees up-to-date world coordinates, and physics bodies keep simulating in their parent space.
- To pause a single body, use `SetBodyEnabled(false)`. To pause an entire subtree, detach with `RemoveFromParent()` and re-attach later.
- Particle emitters still pause by default when invisible; opt out via `SimulateWhileHidden`.
Fixed
- World transforms now recompute on invisible subtrees.
- Previously, the transform walk early-returned on invisible nodes, leaving stale `WorldTransform` matrices for the whole subtree.
- Physics-driven bodies on hidden nodes could drift because the parent inverse used to map world space back to local space was stale.
- `UpdateWorldTransform` now recurses through invisible subtrees; the render and hit-test paths apply their own visibility gate so hidden nodes still do not draw or receive input.
- `PhysicsParent.RemoveBody` is now idempotent: removing an already-detached body is a safe no-op. This lets `DisablePhysics` tear down subtrees containing a mix of enabled and disabled bodies without panicking.
- New `Node` instances initialize `WorldTransform` to the identity matrix instead of a degenerate zero matrix, so spatial queries on a never-walked node return sensible values.