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