Ver código fonte

Merge pull request #2559 from zzuegg/worldToLocal

Added convenience method worldToLocal(Quaternion) to spatial.
Ryan McDonough 2 semanas atrás
pai
commit
a63ea7b9e9

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

@@ -998,6 +998,28 @@ 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);
+        }else{
+            store.set(in);
+        }
+        TempVars tempVars = TempVars.get();
+        Quaternion worldRotation = tempVars.quat1.set(getWorldRotation());
+        worldRotation.inverseLocal();
+        store.multLocal(worldRotation);
+        tempVars.release();
+        return store;
+    }
+
     /**
      * <code>getParent</code> retrieves this node's parent. If the parent is
      * null this is the root node.

+ 32 - 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,33 @@ 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.assertTrue(worldTranslation.isSimilar(testNode.getWorldTranslation(),1e-6f));
+        Assert.assertTrue(worldRotation.isSimilar(testNode.getWorldRotation(),1e-6f));
+
+        nodeB.attachChild(testNode);
+
+        Assert.assertFalse(worldTranslation.isSimilar(testNode.getWorldTranslation(),1e-6f));
+        Assert.assertFalse(worldRotation.isSimilar(testNode.getWorldRotation(),1e-6f));
+
+        testNode.setLocalTranslation(nodeB.worldToLocal(worldTranslation,null));
+        Assert.assertTrue(worldTranslation.isSimilar(testNode.getWorldTranslation(),1e-6f));
+
+        testNode.setLocalRotation(nodeB.worldToLocal(worldRotation,null));
+        System.out.println(testNode.getWorldRotation());
+        Assert.assertTrue(worldRotation.isSimilar(testNode.getWorldRotation(),1e-6f));
+    }
 }