Lysa  0.0
Lysa 3D Engine
Rotation

RotatingAssetScene.cpp : onProcess

The rotation is implemented entirely in RotatingAssetScene::onProcess. The method is called once per rendered frame by the PROCESS event, which passes the elapsed time since the previous frame as alpha (in seconds).

void RotatingAssetScene::onProcess(const double alpha) {
rotationAngle += static_cast<float>(alpha) * ROTATION_SPEED;
if (rotationAngle > lysa::radians(360.0f)) {
rotationAngle -= lysa::radians(360.0f);
}
root.setTransform(lysa::float4x4::rotation_y(rotationAngle));
SceneTree::onProcess(alpha);
}

Frame-rate independence

rotationAngle is incremented by alpha * ROTATION_SPEED on each call. Because alpha is the actual elapsed time, the angular velocity is constant regardless of frame rate.

ROTATION_SPEED is 0.025f rad/s, giving a slow, deliberate rotation well-suited for inspecting a static asset.

Once rotationAngle exceeds 2π, the full circle is subtracted. Without this wrap, a float accumulating indefinitely would gradually lose sub-radian precision after several hours of runtime.

Math library overview

Lysa exposes a concise math library based on hlslpp. The types and free functions most commonly used for scene transforms:

Symbol Description
lysa::float4x4 Row-major 4×4 matrix
float4x4::identity() Returns the identity matrix
float4x4::rotation_x/y/z(radians) Single-axis rotation matrix
float4x4::translation(x, y, z) Translation matrix
float4x4::scale(s) Uniform scale matrix
lysa::mul(A, B) Matrix multiplication (A applied first, then B)
lysa::radians(degrees) Degrees-to-radians conversion
lysa::perspective(fov, aspect, near, far) Reversed-Z perspective projection
lysa::float3, lysa::float2, lysa::float4 Vector types with arithmetic operators
lysa::quaternion Quaternion type (useful for interpolated rotations)
lysa::euler_angles(q) Extracts Euler angles from a quaternion

Matrix multiplication order follows row-vector convention: in mul(localTransform, parentTransform), the local transform is applied first in object space, and then the result is transformed into the parent's space. This matches the SceneInstance::update() implementation.

Transform application

lysa::float4x4::rotation_y(rotationAngle) constructs a rotation matrix around the world Y-axis and assigns it as root's local transform. Because the loaded asset is a child of root, the rotation propagates to the entire imported hierarchy through the recursive root.update() call.

SceneTree::onProcess(alpha) is called last. It calls root.update() to recompute all global transforms in the tree, then updateInstance(root) to push the new transforms to the renderer (see Scene tree).

Note
The onProcess override always calls the base class last, after all mutations. Calling SceneTree::onProcess first and then mutating root would push stale transforms to the renderer for that frame.

Next : Application class