@@ -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