2
0
Эх сурвалжийг харах

Added `worldToLocal` method to `Spatial` for quaternion transformations and corresponding test

zzuegg 3 сар өмнө
parent
commit
234545d39e

+ 16 - 0
jme3-core/src/main/java/com/jme3/scene/Spatial.java

@@ -986,6 +986,22 @@ public abstract class Spatial implements Savable, Cloneable, Collidable,
         return worldTransform.transformInverseVector(in, store);
     }
 
+    /**
+     * Transforms the given quaternion from world space to local space relative to this object's transform.
+     *
+     * @param in the input quaternion in world space that needs to be transformed
+     * @param store an optional Quaternion to store the result; if null, a new Quaternion will be created
+     * @return the transformed quaternion in local space, either stored in the provided Quaternion or a new one
+     */
+    public Quaternion worldToLocal(final Quaternion in, Quaternion store){
+        checkDoTransformUpdate();
+        if(store == null){
+            store=new Quaternion(in);
+        }
+        store.multLocal(worldTransform.getRotation().inverse());
+        return store;
+    }
+
     /**
      * <code>getParent</code> retrieves this node's parent. If the parent is
      * null this is the root node.

+ 31 - 0
jme3-core/src/test/java/com/jme3/scene/SpatialTest.java

@@ -31,6 +31,9 @@
  */
 package com.jme3.scene;
 
+import com.jme3.math.FastMath;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
 import com.jme3.scene.control.UpdateControl;
 import org.junit.Assert;
 import org.junit.Test;
@@ -119,4 +122,32 @@ public class SpatialTest {
         Assert.assertEquals(testSpatial, control1.getSpatial());
         Assert.assertEquals(testSpatial, control2.getSpatial());
     }
+
+    @Test
+    public void testTransferToOtherNode(){
+        Node nodeA = new Node("nodeA");
+        Node nodeB = new Node("nodeB");
+        Node testNode=new Node("testNode");
+        nodeA.setLocalTranslation(-1,0,0);
+        nodeB.setLocalTranslation(1,0,0);
+        nodeB.rotate(0,90* FastMath.DEG_TO_RAD,0);
+        testNode.setLocalTranslation(1,0,0);
+        nodeA.attachChild(testNode);
+        Vector3f worldTranslation = testNode.getWorldTranslation().clone();
+        Quaternion worldRotation = testNode.getWorldRotation().clone();
+
+        Assert.assertEquals(worldTranslation,testNode.getWorldTranslation());
+        Assert.assertEquals(worldRotation,testNode.getWorldRotation());
+
+        nodeB.attachChild(testNode);
+
+        Assert.assertNotEquals(worldTranslation,testNode.getWorldTranslation());
+        Assert.assertNotEquals(worldRotation,testNode.getWorldRotation());
+
+        testNode.setLocalTranslation(nodeB.worldToLocal(worldTranslation,null));
+        Assert.assertEquals(worldTranslation,testNode.getWorldTranslation());
+
+        testNode.setLocalRotation(nodeB.worldToLocal(worldRotation,null));
+        Assert.assertEquals(worldRotation,testNode.getWorldRotation());
+    }
 }