Machmed / jmonkeyengine

Automatically exported from code.google.com/p/jmonkeyengine
0 stars 0 forks source link

WireBox.fromBoundingBox doesn't center on BoundingBox #635

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago

The method "fromBoundingBox" at "WireBox" class doesn’t center the cube to 
the BoundingBox origin/center. The center of the drawn cube is always at 0,0,0. 
The BoundingBox-Size is always correct.

Four unknown reasons the drawn cube is on the wrong position, but the 
"intersects"-Function works fine.

Here some Code (note the comments):

package default;

import com.jme3.app.SimpleApplication;
import com.jme3.collision.MotionAllowedListener;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.debug.WireBox;
import com.jme3.system.AppSettings;
import com.jme3.util.BufferUtils;
import com.jme3.bounding.BoundingBox;
import com.jme3.material.RenderState;
import com.jme3.scene.shape.Box;

/**
 *
 * @author me
 */
public class TestOctree extends SimpleApplication implements AnalogListener, 
ActionListener {

    PointLight lamp = new PointLight();
    Material debugMat1;
    Material debugMat2;
    Material debugMat3;
    final Vector3f homeView = new Vector3f(0f, 0.4f, 3.0f);
    boolean onRotate = false;
    private Vector3f initUp;
    private float rotationSpeed = 1f;
    private float moveSpeed = 2f;
    private MotionAllowedListener motionAllowed = null;

    public static void main(String[] args) {
        TestOctree app = new TestOctree();
        AppSettings s = new AppSettings(true);
        s.setFrameRate(60);
        app.setSettings(s);
        app.start();
    }

    @Override
    public void simpleInitApp() {    
        flyCam.setEnabled(false);
        camSetHome();
        initUp = cam.getUp().clone();

        registerInput();

        this.setDisplayFps(true);
        this.setDisplayStatView(true);
        this.setPauseOnLostFocus(false);

        //some Materials for debugging
        debugMat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        debugMat1.setColor("Color", ColorRGBA.Cyan);

        debugMat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        debugMat2.setColor("Color", ColorRGBA.Blue);

        debugMat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        debugMat3.setColor("Color", new ColorRGBA(1,.5f,.5f,.5f) );
        debugMat3.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
        debugMat3.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
        debugMat3.getAdditionalRenderState().setWireframe(true);

        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Green);

        BoundingBox b0 = new BoundingBox();
        b0.setCenter(new Vector3f(1,1,1));
        b0.setXExtent(.1f);
        b0.setYExtent(.1f);
        b0.setZExtent(.1f);
        if (b0.intersects(new Vector3f(1,1,1))){
            System.out.println("Vector is inside BoundingBox b0");
        }

        // WireBox0 at wrong position
        WireBox wireBox0 = new WireBox();
        wireBox0.fromBoundingBox(b0);
        Geometry wireG0 = new Geometry("wireBox0", wireBox0);
        wireG0.setMaterial(debugMat1);
        wireG0.updateModelBound();
        rootNode.attachChild(wireG0);

        // Box0 at right position
        Box box0 = new Box(b0.getCenter(), b0.getXExtent() * .5f, b0.getYExtent() * .5f, b0.getZExtent() * .5f);
        Geometry boxGeom0 = new Geometry("Box", box0);  
        boxGeom0.setMaterial(debugMat3);
        rootNode.attachChild(boxGeom0);

        BoundingBox b1 = new BoundingBox(new Vector3f(-0.5f,-0.5f,-0.5f), .2f, .2f, .2f);    
        if (b1.intersects(new Vector3f(-0.6f,-0.6f,-0.6f))){
            System.out.println("Vector is inside BoundingBox b1");
        }

        // WireBox1 at wrong position
        WireBox wireBox1 = new WireBox(); 
        wireBox1.fromBoundingBox(b1);
        Geometry wireG1 = new Geometry("wireBox1", wireBox1);
        wireG1.setMaterial(debugMat2);
        rootNode.attachChild(wireG1);

        // Box1 on right position
        Box box1 = new Box(b1.getCenter(), b1.getXExtent() * .5f, b1.getYExtent() * .5f, b1.getZExtent() * .5f);
        Geometry boxGeom1 = new Geometry("Box", box1);  
        boxGeom1.setMaterial(debugMat3);
        rootNode.attachChild(boxGeom1);

        // some points for a better debugging
        Vector3f[] somePoints = {
            new Vector3f(.51f, .51f, .51f),
            new Vector3f(.2f, .2f, .2f),
            new Vector3f(.8f, .8f, .8f),
            new Vector3f(.01f, .01f, .01f),
            new Vector3f(.99f, .99f, .99f),
            new Vector3f(-.5f,-.5f,-.5f)
        };

        Mesh mesh = new Mesh();
        mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(somePoints));
        mesh.setMode(Mesh.Mode.Points);
        mesh.setPointSize(5.0f);
        mesh.updateBound();
        mesh.updateCounts();

        Geometry dots = new Geometry("dots", mesh);
        dots.setMaterial(mat);
        rootNode.attachChild(dots);

        /**
         * A white ambient light source.
         */
        AmbientLight ambient = new AmbientLight();
        ambient.setColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1f));
        rootNode.addLight(ambient);

        viewPort.setBackgroundColor(ColorRGBA.DarkGray);
    }

    @Override
    public void simpleUpdate(float tpf) {
        //TODO: add update code
        if (!onRotate) {
            Vector3f origin = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);
            Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);
            direction.subtractLocal(origin).normalizeLocal();
        }
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }

    void camSetHome() {
        cam.setLocation(homeView);
        cam.lookAt(new Vector3f(0, homeView.getY(), 0), homeView);
        //cam.setFrame(homeView, new Vector3f(-2f,0,0), new Vector3f(0,-1f,0), new Vector3f(0,0,-2f));
    }

    public void registerInput() {
        String[] mappings = new String[]{
            "FLYCAM_Left",
            "FLYCAM_Right",
            "FLYCAM_Up",
            "FLYCAM_Down",
            "FLYCAM_StrafeLeft",
            "FLYCAM_StrafeRight",
            "FLYCAM_Forward",
            "FLYCAM_Backward",
            "FLYCAM_ZoomIn",
            "FLYCAM_ZoomOut",
            "FLYCAM_RotateDrag",
            "FLYCAM_Rise",
            "FLYCAM_Lower",
        };

        inputManager.addMapping("FLYCAM_Lower", new KeyTrigger(KeyInput.KEY_Y));
        inputManager.addListener(this, mappings);
    }

    private void rotateCamera(float value, Vector3f axis) {
        if (!onRotate) {
            return;
        }

        Matrix3f mat = new Matrix3f();
        mat.fromAngleNormalAxis(rotationSpeed * value, axis);

        Vector3f up = cam.getUp();
        Vector3f left = cam.getLeft();
        Vector3f dir = cam.getDirection();

        mat.mult(up, up);
        mat.mult(left, left);
        mat.mult(dir, dir);

        Quaternion q = new Quaternion();
        q.fromAxes(left, up, dir);
        q.normalizeLocal();

        cam.setAxes(q);
    }

    private void zoomCamera(float value) {
        float h = cam.getFrustumTop();
        float w = cam.getFrustumRight();
        float aspect = w / h;

        float near = cam.getFrustumNear();

        float fovY = FastMath.atan(h / near)
                / (FastMath.DEG_TO_RAD * .5f);
        fovY += value * 0.1f;

        h = FastMath.tan(fovY * FastMath.DEG_TO_RAD * .5f) * near;
        w = h * aspect;

        cam.setFrustumTop(h);
        cam.setFrustumBottom(-h);
        cam.setFrustumLeft(-w);
        cam.setFrustumRight(w);
    }

    private void riseCamera(float value) {
        Vector3f vel = new Vector3f(0, value * moveSpeed, 0);
        Vector3f pos = cam.getLocation().clone();

        if (motionAllowed != null) {
            motionAllowed.checkMotionAllowed(pos, vel);
        } else {
            pos.addLocal(vel);
        }
        cam.setLocation(pos);
    }

    private void moveCamera(float value, boolean sideways) {
        Vector3f vel = new Vector3f();
        Vector3f pos = cam.getLocation().clone();

        if (sideways) {
            cam.getLeft(vel);
        } else {
            cam.getDirection(vel);
        }
        vel.multLocal(value * moveSpeed);

        if (motionAllowed != null) {
            motionAllowed.checkMotionAllowed(pos, vel);
        } else {
            pos.addLocal(vel);
        }
        cam.setLocation(pos);
    }

    @Override
    public void onAnalog(String name, float value, float tpf) {
        if (name.equals("FLYCAM_Left")) {
            rotateCamera(value, initUp);
        } else if (name.equals("FLYCAM_Right")) {
            rotateCamera(-value, initUp);
        } else if (name.equals("FLYCAM_Up")) {
            rotateCamera(-value, cam.getLeft());
        } else if (name.equals("FLYCAM_Down")) {
            rotateCamera(value, cam.getLeft());
        } else if (name.equals("FLYCAM_Forward")) {
            moveCamera(value, false);
        } else if (name.equals("FLYCAM_Backward")) {
            moveCamera(-value, false);
        } else if (name.equals("FLYCAM_StrafeLeft")) {
            moveCamera(value, true);
        } else if (name.equals("FLYCAM_StrafeRight")) {
            moveCamera(-value, true);
        } else if (name.equals("FLYCAM_Rise")) {
            riseCamera(value);
        } else if (name.equals("FLYCAM_Lower")) {
            riseCamera(-value);
        } else if (name.equals("FLYCAM_ZoomIn")) {
            zoomCamera(value);
        } else if (name.equals("FLYCAM_ZoomOut")) {
            zoomCamera(-value);
        }
    }

    @Override
    public void onAction(String name, boolean isPressed, float tpf) {
        if (name.equals("FLYCAM_RotateDrag") && isPressed) {
            onRotate = true;
            inputManager.setCursorVisible(false);
        } else if (name.equals("FLYCAM_RotateDrag") && !isPressed) {
            onRotate = false;
            inputManager.setCursorVisible(true);
        }

    }
}

Original issue reported on code.google.com by florianb...@googlemail.com on 9 Mar 2014 at 10:48

GoogleCodeExporter commented 8 years ago
I'll handle this one.

Original comment by sg...@sonic.net on 14 Mar 2014 at 4:38

GoogleCodeExporter commented 8 years ago
Oops!  I only meant to take ownership, not to mark it as Fixed.

Original comment by sg...@sonic.net on 14 Mar 2014 at 4:51

GoogleCodeExporter commented 8 years ago
Per suggestions at 
http://hub.jmonkeyengine.org/forum/topic/proposed-fix-for-issue-635/ I changed 
the semantics of WireBox.fromBoundingBox() to return a Geometry.

https://code.google.com/p/jmonkeyengine/source/detail?r=11087

https://code.google.com/p/jmonkeyengine/source/detail?r=11088

Original comment by sg...@sonic.net on 15 Mar 2014 at 7:19