Plane.reflect(point, store) returns different results when point == store jme3 r7281

This is the original code, com.jme3.math.Plane.reflect(Vector3f, Vector3f)

[java]public Vector3f reflect(Vector3f point, Vector3f store){

if (store == null)

store = new Vector3f();



float d = pseudoDistance(point);

store.set(normal).negateLocal().multLocal(d * 2f);

store.addLocal(point);

return store;

}[/java]



When called like plane.reflect(x, x); where x is used both as input and also as store the results are different (obviously if you read the above code), therefore the caller must be aware/on guard when doing this call, also Note similar methods that use in and store do work well when in == store (aka same reference)



testcase (search for “XXX:” to get to the relevant code) [used @alfinete 's code]:

[java]package org.jme3.forum;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Plane;

import com.jme3.math.Quaternion;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.shape.Box;



public class CopyOfMain extends SimpleApplication {

public static void main(String args) {

CopyOfMain app = new CopyOfMain();

app.start();

}



Node cosmos;

Node farAway;

Vector3f translationVector, translationUnityVector;

float myTimer = 0.0f;

Quaternion fromCameraRotation;



@Override

public void simpleInitApp() {

Box b = new Box(new Vector3f(620, 80, -300), 100, 100, 100);

Geometry geom = new Geometry("Box", b);

Material mat = new Material(assetManager,

"Common/MatDefs/Misc/SolidColor.j3md");

mat.setColor("m_Color", ColorRGBA.Blue);

geom.setMaterial(mat);

cosmos = new Node("cosmos");

farAway = new Node("farAway");

farAway.attachChild(geom);

cosmos.attachChild(farAway);

rootNode.attachChild(cosmos);

rootNode.setLocalScale(2, 3, 4);

rootNode.setLocalTranslation(2900f, -189f, 7718f);

rootNode.setLocalRotation(new Quaternion().fromAngles(

FastMath.DEG_TO_RAD * 81, FastMath.DEG_TO_RAD * 320,

FastMath.DEG_TO_RAD * 139));

translationVector = new Vector3f(-1200.0f, 1000.0f, 1600.0f);

farAway.setLocalTranslation(translationVector);

translationUnityVector = new Vector3f(translationVector.normalize());

cam.setFrustumFar(115000.0f);

Quaternion cameraRotation = new Quaternion();

cameraRotation.lookAt(translationUnityVector, Vector3f.UNIT_Y);

// COMMENT OUT ONE OF THESE TWO LINES TO TEST ONE METHOD OR THE OTHER.

// cam.setRotation(cameraRotation);

cam.lookAt(geom.localToWorld(b.getCenter(), null), Vector3f.UNIT_Y);

System.out.println(" Var translationUnityVector = "

  • translationUnityVector);

    System.out.println("Camera Direction (cam.getDirection) = "
  • cam.getDirection());

    System.out.println("Quaternion to be sent to the camera = "
  • cameraRotation.toString());

    System.out.println(" Quaternion retrieved from Camera = "
  • cam.getRotation().toString());

    Vector3f x = translationVector.clone();

    Vector3f y = translationVector.clone();

    // geom.localToWorld(x, x);

    // y = geom.localToWorld(y, null);

    // System.out.println(x + "n" + y);

    // geom.worldToLocal(x, x);

    // y = geom.worldToLocal(y, null);

    System.out.println("Initially: x=" + x + "nInitially: y=" + y);

    // XXX:

    Plane p = new Plane();

    p.setNormal(translationUnityVector);

    p.reflect(x, x);

    y = p.reflect(y, null);

    System.out.println("After: x=" + x + "nAfter: y=" + y);

    }



    @Override

    public void simpleUpdate(float tpf) {

    }



    @Override

    public void simpleRender(RenderManager rm) {

    // TODO: add render code

    }

    }[/java]



    output (on console):
Initially: x=(-1200.0, 1000.0, 1600.0)
Initially: y=(-1200.0, 1000.0, 1600.0)
After: x=(4800.0, -4000.0, -6400.0)
After: y=(1200.0, -1000.0, -1600.0)

When it is possible to use in == store then its mentioned in the javadoc.