update method
Called once per frame while the component is mounted, enabled, and
loaded. deltaSeconds is the elapsed time since the previous tick.
A traversal visits each component at most once. Removing this component
or an earlier sibling is safe. A component inserted before the current
traversal position starts on the next frame. Reordering component or
child lists during traversal is unsupported.
Implementation
@override
void update(double deltaSeconds) {
if (timeSpeed != 0.0 && deltaSeconds > 0.0) {
timeOfDay = (timeOfDay + timeSpeed * deltaSeconds) % 24.0;
}
final sunDir = sunDirection;
if (skySource != null) {
skySource!.sunDirection = sunDir;
}
final targetNode =
sunLightNode ??
node.children.cast<Node?>().firstWhere(
(c) => c?.getComponent<DirectionalLightComponent>() != null,
orElse: () => null,
);
if (targetNode == null) return;
final eye = sunDir * 100.0;
final target = vm.Vector3.zero();
// In flutter_scene, DirectionalLightComponent travels along local +Z
final forward = (target - eye).normalized();
var up = vm.Vector3(0, 1, 0);
if (up.cross(forward).length2 < 1e-6) {
up = vm.Vector3(0, 0, 1);
}
final right = up.cross(forward).normalized();
final actualUp = forward.cross(right).normalized();
final worldMat = vm.Matrix4.columns(
vm.Vector4(right.x, right.y, right.z, 0.0),
vm.Vector4(actualUp.x, actualUp.y, actualUp.z, 0.0),
vm.Vector4(forward.x, forward.y, forward.z, 0.0),
vm.Vector4(eye.x, eye.y, eye.z, 1.0),
);
final parent = targetNode.parent;
if (parent != null) {
final invParent = parent.globalTransform.clone()..invert();
targetNode.localTransform = invParent * worldMat;
} else {
targetNode.localTransform = worldMat;
}
if (applyLightingToTarget) {
final lighting = evaluateLighting();
final lightComp = targetNode.getComponent<DirectionalLightComponent>();
if (lightComp != null) {
lightComp.light.color = lighting.sunColor;
lightComp.light.intensity = lighting.sunIntensity;
lightComp.light.castsShadow = lighting.shadowDarkness > 0.0;
lightComp.light.shadowAmbientStrength = (1.0 - lighting.shadowDarkness)
.clamp(0.0, 1.0);
}
if (targetScene != null) {
targetScene!.environmentIntensity = lighting.environmentIntensity;
}
}
}