![]() |
Lysa Nodes
0.0
Lysa Nodes — Scene Graph for the Lysa Engine
|
Lysa Nodes is organized as a set of C++23 modules (.ixx interfaces paired with .cpp implementations) that live in the lysa::nodes namespace. The single top-level module lysa.nodes re-exports every public node type and serves as the only import needed by application code.
The library sits on top of the Lysa Engine and relies entirely on the engine context (lysa::ctx()) for rendering, physics, resource management, and event dispatch. It does not introduce any additional singletons.
lysa::nodes::SceneTree is the root of every scene. It extends the engine's lysa::Scene class and owns a flat list of root Node children. The SceneTree:
RenderingWindow or RenderTarget to receive render callbacks.PROCESS, PHYSICS_PROCESS, input, resize, pause, and resume events, and fans them out to its node tree.addChild / removeChild template methods to safely insert or remove nodes within the correct frame boundary.Virtual callbacks (onReady, onProcess, onPhysicsProcess, onInput, onResize, onPause, onResume, onAttach, onDetach) are intended to be overridden by application-level subclasses.
lysa::nodes::Node is the base of every scene object. Key responsibilities:
| Concern | Details |
|---|---|
| Identity | Unique unique_id, display name, Type enum, and optional group membership |
| Transform | Local and world-space float4x4 matrices; decomposed helpers for position, rotation (quaternion + Euler), and scale |
| Hierarchy | addChild / removeChild templates; findFirstChild, findAllChildren, getChildByPath, getRelativePath |
| Lifecycle | onReady, onEnterScene, onExitScene, onProcess, onPhysicsProcess, onInput virtual hooks |
| Visibility | setVisible / isVisible; propagated to mesh instances in VRAM |
| Duplication | duplicate() produces a deep copy of the subtree |
| Process mode | ProcessMode enum controls whether a node processes while the scene is paused |
The internal _process, _physicsProcess, _enterScene, _exitScene, _ready, _pause, _resume, and _input methods are called by the SceneTree and should not be invoked directly by application code.
lysa::nodes::Camera extends both Node and the engine's lysa::Camera resource. It supports perspective (FOV + near/far) and orthographic (left/right/top/bottom + near/far) projections. When attached to a scene, the camera registers a resize handler so the projection matrix is automatically updated when the render target changes size. The active camera is set on the SceneTree via setCamera().
lysa::nodes::MeshInstance wraps a lysa::MeshInstance GPU resource. Each surface can have an override Material that replaces the mesh's original material for that surface. Shadow casting is configurable per instance. The world-space AABB is kept up to date whenever the global transform changes.
lysa::nodes::Environment sets the ambient light color and intensity for the scene. Only one Environment node is active at a time; attaching it to the scene registers its values with the renderer.
lysa::nodes::Viewport overrides the renderer's viewport rectangle and scissor. If no Viewport node is present in the scene, the full render target surface is used.
All light nodes inherit from lysa::nodes::Light which manages color, intensity, shadow-map parameters, and registration with the engine's light pool (up to Light::MAX_LIGHTS per scene).
| Node | Description |
|---|---|
DirectionalLight | Parallel light (sun-like). Supports cascaded shadow maps (up to MAX_SHADOW_MAP_CASCADES = 3 cascades, configurable split lambda). |
OmniLight | Point light with configurable range and near-clip distance for shadow cube maps. |
SpotLight | Extends OmniLight with inner and outer cone cutoff angles. |
Physics nodes mirror the engine's collision-object hierarchy and delegate all physics work to the active backend (Jolt or PhysX). The backend is selected exclusively at compile time.
lysa::nodes::CollisionObject is the base for all physics nodes. It forwards position and rotation changes to the physics body, subscribes to the engine's contact/collision events, and routes them through the node's onEnterScene / onExitScene lifecycle.
lysa::nodes::CollisionArea is a passive sensor. It detects overlapping bodies (via CHARACTER_COLLISION_STARTS events) without generating reaction forces.
lysa::nodes::PhysicsBody is the base for active bodies:
| Class | Motion Type | Description |
|---|---|---|
StaticBody | Static | Immovable solid; other bodies collide with it |
KinematicBody | Kinematic | Moved by explicit velocity; ignores forces |
RigidBody | Dynamic | Fully simulated; responds to forces, impulses, and gravity |
RigidBody exposes density, mass, gravity factor, per-frame force application (addForce, addImpulse), and linear velocity read/write.
lysa::nodes::Character uses a virtual capsule controller (Jolt CharacterVirtual or PhysX PxCapsuleController). It provides:
isOnGround, isGround, getGroundVelocity).getCollisions().CharacterEventType::ON_COLLISION event fired on each contact.lysa::nodes::RayCast performs a layer-filtered ray query each physics tick from its world-space position toward a local-space target point. The result is available via getCollider().
lysa::nodes::AnimationPlayer manages one or more AnimationLibrary instances. Each library contains named Animation objects composed of AnimationTrack keyframe channels (position, rotation, scale). Playback features include:
play(name) / playBackwards(name) / stop(keepState) / seek(seconds).AnimationPlayerEvent::START and FINISH events dispatched through the engine event system.setTargetPath to redirect all track targets to a different node path.The lysa::nodes module provides two free functions that instantiate node trees from Lysa asset packs (.lys files exported by the Blender add-on):
| Function | Description |
|---|---|
load(URI) | Synchronous load; blocks until the node tree is ready |
loadAsync(URI, callback) | Loads on a background thread; invokes callback at the start of the next frame |
Both functions return a std::shared_ptr<Node> pointing to the root of the loaded subtree.
When the engine is compiled with LUA_BINDINGS=ON, every node type inherits from LuaScript and exposes its full public API to Lua via LuaBridge. Lua callbacks integrate with the same EventManager::on() mechanism used by C++ listeners, enabling hybrid C++/Lua scene hierarchies.