Skip to content

Commit ba773a5

Browse files
author
Yuri Pourre
committed
Handle Cameras and Lights
1 parent 39a5c67 commit ba773a5

File tree

1 file changed

+63
-22
lines changed

1 file changed

+63
-22
lines changed

editor/src/editor/layout/graph.tsx

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -901,36 +901,77 @@ export class EditorGraph extends Component<IEditorGraphProps, IEditorGraphState>
901901
}
902902

903903
private _setParentPreservingWorldTransform(node: Node, newParent: Node | null): void {
904-
if (!(node instanceof TransformNode)) {
905-
// For non-transform nodes, just set the parent directly
904+
// TransformNodes (including Meshes) support full world transform preservation
905+
if (node instanceof TransformNode) {
906+
// Store the current world transform
907+
const worldPosition = node.getAbsolutePosition();
908+
const worldRotation = node.rotationQuaternion || node.rotation.toQuaternion();
909+
const worldScaling = node.absoluteScaling.clone();
910+
911+
// Set the new parent
906912
node.parent = newParent;
907-
return;
908-
}
909913

910-
// Store the current world transform
911-
const worldPosition = node.getAbsolutePosition();
912-
const worldRotation = node.rotationQuaternion || node.rotation.toQuaternion();
913-
const worldScaling = node.absoluteScaling.clone();
914+
// Restore the world transform
915+
node.position.copyFrom(worldPosition);
914916

915-
// Set the new parent
916-
node.parent = newParent;
917+
// Compute the local rotation based on the parent's rotation
918+
let localRotation = worldRotation;
919+
if (newParent instanceof TransformNode) {
920+
const parentRotation = newParent.absoluteRotationQuaternion;
921+
localRotation = parentRotation.conjugate().multiply(worldRotation);
922+
}
917923

918-
// Restore the world transform
919-
node.setAbsolutePosition(worldPosition);
924+
if (node.rotationQuaternion) {
925+
node.rotationQuaternion.copyFrom(localRotation);
926+
} else {
927+
node.rotation.copyFrom(localRotation.toEulerAngles());
928+
}
920929

921-
// Compute the local rotation based on the parent's rotation
922-
let localRotation = worldRotation;
923-
if (newParent instanceof TransformNode) {
924-
const parentRotation = newParent.absoluteRotationQuaternion;
925-
localRotation = parentRotation.conjugate().multiply(worldRotation);
930+
node.scaling.copyFrom(worldScaling);
931+
return;
926932
}
927933

928-
if (node.rotationQuaternion) {
929-
node.rotationQuaternion.copyFrom(localRotation);
930-
} else {
931-
node.rotation.copyFrom(localRotation.toEulerAngles());
934+
// Cameras and Lights have position and rotation but not the full transform methods
935+
if (isCamera(node) || isLight(node)) {
936+
// Store current world position and rotation
937+
const worldPosition = (node as any).position.clone();
938+
const worldRotation = (node as any).rotationQuaternion || (node as any).rotation.toQuaternion();
939+
940+
// Set the new parent
941+
node.parent = newParent;
942+
943+
// For cameras and lights, we need to compute local position manually
944+
if (newParent instanceof TransformNode) {
945+
// Compute local position from world position
946+
const localPosition = worldPosition.subtract(newParent.getAbsolutePosition());
947+
const parentRotationInverse = newParent.absoluteRotationQuaternion.conjugate();
948+
localPosition.applyRotationQuaternionInPlace(parentRotationInverse);
949+
localPosition.divideInPlace(newParent.absoluteScaling);
950+
(node as any).position.copyFrom(localPosition);
951+
952+
// Compute local rotation
953+
const parentRotation = newParent.absoluteRotationQuaternion;
954+
const localRotation = parentRotation.conjugate().multiply(worldRotation);
955+
956+
if ((node as any).rotationQuaternion) {
957+
(node as any).rotationQuaternion.copyFrom(localRotation);
958+
} else {
959+
(node as any).rotation.copyFrom(localRotation.toEulerAngles());
960+
}
961+
} else {
962+
// No parent, world position/rotation equals local position/rotation
963+
(node as any).position.copyFrom(worldPosition);
964+
965+
if ((node as any).rotationQuaternion) {
966+
(node as any).rotationQuaternion.copyFrom(worldRotation);
967+
} else {
968+
(node as any).rotation.copyFrom(worldRotation.toEulerAngles());
969+
}
970+
}
971+
return;
932972
}
933973

934-
node.scaling.copyFrom(worldScaling);
974+
// For other node types, just set the parent directly
975+
node.parent = newParent;
935976
}
936977
}

0 commit comments

Comments
 (0)