Yet another Collision Problem

Hi all,



i've read round about 1.000 threads how to deal with the collision.

But I still can't get it…

That's the situation:



I've created a Map with MW3D. Added the Map as scene to rootNode.



Than I created a camNode. The camNode includes a sphereNode where

a sphere is attached to.



Now I want to set up a collision with my scene. But i can't figure it out.



This is how i tried to manage it:


  
            LocX = sphereNode.getLocalTranslation().getX();
            LocY = sphereNode.getLocalTranslation().getY();
            LocZ = sphereNode.getLocalTranslation().getZ();

            if (sphereNode.hasCollision(scene, true)){

            LocX = LocX * .99f;
            LocY = LocY * .99f;
            LocZ = LocZ * .99f;
            
            sphereNode.getLocalTranslation().setX(LocX);
            sphereNode.getLocalTranslation().setY(LocY);
            sphereNode.getLocalTranslation().setZ(LocZ);





And here the complete code:


import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;


import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.NodeHandler;
import com.jme.input.action.KeyNodeBackwardAction;
import com.jme.input.action.KeyNodeForwardAction;
import com.jme.input.action.KeyNodeRotateLeftAction;
import com.jme.input.action.KeyNodeRotateRightAction;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.CullState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.Savable;
import com.jme.util.export.binary.BinaryClassLoader;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.AbstractHeightMap;
import com.jmex.terrain.util.ImageBasedHeightMap;
import com.mw3d.terrain.model.TerrainAlphaLayer;
import com.mw3d.terrain.model.TerrainBaseLayer;
import com.mw3d.terrain.model.TerrainModel;
import com.mw3d.terrain.model.TerrainPropertiesBean;
import com.mw3d.terrain.model.binary.module.TerrainAlphaLayerModule;
import com.mw3d.terrain.model.binary.module.TerrainBaseLayerModule;
import com.mw3d.terrain.model.binary.module.TerrainModelModule;
import com.mw3d.terrain.model.binary.module.TerrainPropertiesBeanModule;


public class labyrinth extends SimpleGame {


    private String fileName = "mw3ddata/labyrinthmap.jme";
    private TerrainModel terrainPersistenceModel;
    public static final String HEIGHT_MAP_IMAGE = "mw3ddata/labyrinthmap-terrain-heightmapimage.png";
    private TerrainPage page;
    private Node scene;
    private CameraNode camNode;
    private Node sphereNode;
    private float LocX;
    private float LocY;
    private float LocZ;

  

    public static void main(String args[]) {
        labyrinth game = new labyrinth();
        game.start();
    }
  




    protected void simpleInitGame() {
        

        camNode();
        this.setupBinaryClassLoader();

       String terrainFileName = fileName.replaceAll(".jme", ".terrain");

        JMEImporter im = BinaryImporter.getInstance();
        try {
            File file = new File(terrainFileName);
            if (file.exists()) {
                Savable item = im.load(file);
                if (item != null) {
                    terrainPersistenceModel = (TerrainModel) item;
                }
            }
        } catch (IOException e) {
        } catch (Exception e) {
        }

        File file = null;
        AbstractHeightMap heightMap = null;


           String fn = "mw3ddata/labyrinthmap-terrain-heightmapimage.png";
        try {
            file = new File(fn);
            if (file != null) {
                heightMap = loadHeightMap(file.getAbsolutePath());
            }
        } catch (Exception e) {
        }

        if (terrainPersistenceModel != null) {
            if (terrainPersistenceModel.getProperties() != null) {
                TerrainPropertiesBean bean = terrainPersistenceModel
                        .getProperties();
                this.page = createHeightMapTerrain(heightMap, bean.getSize(),
                        bean.getBlockSize(), new Vector3f(bean.getXScale(),
                                bean.getYScale(), bean.getZScale()), false);
            }
        }

        try {
            File f = new File(this.fileName);
            scene = (Node) BinaryImporter.getInstance().load(f);
            rootNode.attachChild(scene);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (page != null) {
            rootNode.attachChild(page);
        }

        rootNode.updateGeometricState(0.1f, true);
        rootNode.updateRenderState();
        scene.updateGeometricState(0.1f, true);
        camNode.updateGeometricState(0.1f, true);
        sphereNode.updateGeometricState(0.1f, true);

        loadLayers();
    }


    public AbstractHeightMap loadHeightMap(String filepath) {
        AbstractHeightMap map = null;
        try {
            File file = new File(filepath);
            BufferedImage bufferedImage = ImageIO.read(file);
            map = new ImageBasedHeightMap(bufferedImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }




    public void setupBinaryClassLoader() {
        BinaryClassLoader.registerModule(new TerrainModelModule());
        BinaryClassLoader.registerModule(new TerrainPropertiesBeanModule());
        BinaryClassLoader.registerModule(new TerrainBaseLayerModule());
        BinaryClassLoader.registerModule(new TerrainAlphaLayerModule());
    }

    public static TerrainPage createHeightMapTerrain(AbstractHeightMap map,
            int size, int blockSize, Vector3f scale, boolean clod) {
        TerrainPage terrainPage = new TerrainPage("Terrain", blockSize,
                size + 1, scale, map.getHeightMap());
        CullState cs = DisplaySystem.getDisplaySystem().getRenderer().createCullState();

    
        cs.setCullFace(CullState.Face.Back );
        cs.setEnabled(true);
        terrainPage.setRenderState(cs);
        return terrainPage;
    }


    private void loadLayers() {
        TerrainBaseLayer layer = terrainPersistenceModel.getBaseLayer();
        if (page != null) {
            SimpleSplatManager manager = new SimpleSplatManager(page, rootNode);
            if (manager == null)
                return;
            if (layer != null) {
                try {
                    layer.loadFromJme(DisplaySystem.getDisplaySystem().getRenderer());
                    manager.registerBaseLayer(layer);
                } catch (Exception e) {
                }
            }

            ArrayList<TerrainAlphaLayer> alphaLayers = terrainPersistenceModel
                    .getAlphaLayers();

            for (TerrainAlphaLayer alphaLayer : alphaLayers) {
                alphaLayer.loadFromJme(DisplaySystem.getDisplaySystem().getRenderer());
                manager.registerAlphaLayer(alphaLayer);
            }
            
        }
    }



        private void camNode() {
        cam = display.getRenderer().getCamera();
        cam.setFrustum(1.0f, 1000.0f, -0.55f, 0.55f, 0.4125f, -0.4125f);
        camNode = new CameraNode("Camera Node", cam);
        camNode.setLocalTranslation(new Vector3f(230, 25, -220));
        camNode.hasCollision(scene, true);
        camNode.lookAt(new Vector3f(200, 25, 200), new Vector3f(0, 1, 0));
        camNode.updateWorldData(0);
        rootNode.attachChild(camNode);
        cam.update();
  

   Sphere camSphere=new Sphere("Camera Sphere",10,10,1f);
         camSphere.setModelBound(new BoundingBox());
         camSphere.setLocalScale(2.0f);
        camSphere.setLocalTranslation(new Vector3f(0, 3, 10));
        camSphere.updateModelBound();
          sphereNode = new Node("Sphere Node");
        sphereNode.attachChild(camSphere);
          camNode.attachChild(sphereNode);


            LocX = sphereNode.getLocalTranslation().getX();
            LocY = sphereNode.getLocalTranslation().getY();
            LocZ = sphereNode.getLocalTranslation().getZ();

            if (sphereNode.hasCollision(scene, true)){

            LocX = LocX * .99f;
            LocY = LocY * .99f;
            LocZ = LocZ * .99f;
            
            sphereNode.getLocalTranslation().setX(LocX);
            sphereNode.getLocalTranslation().setY(LocY);
            sphereNode.getLocalTranslation().setZ(LocZ);
            

            }

        




      
        input = new NodeHandler(camNode, 50, 10);
        input.removeAllActions();
        input.addAction(new KeyNodeForwardAction( camNode, 50 ), "forward", true);
        input.addAction(new KeyNodeBackwardAction( camNode, 50 ), "backward", true);
        KeyNodeRotateRightAction rotateRight = new KeyNodeRotateRightAction( camNode, 10 );
        rotateRight.setLockAxis( camNode.getLocalRotation().getRotationColumn( 1 ) );
        input.addAction( rotateRight, "strafeRight", true );
        KeyNodeRotateLeftAction rotateLeft = new KeyNodeRotateLeftAction( camNode, 10 );
        rotateLeft.setLockAxis( camNode.getLocalRotation().getRotationColumn( 1 ) );
        input.addAction( rotateLeft, "strafeLeft", true );
        input.update(1);
    }


      


}



You would do me a huge favour if u can help...

Thx so far!

collision-detection have to be done in the update-method. in your case as you use simpleGame

you have to override simpleupdate() additional you have to caluculate the collision before you

can use the hasCollision(…)-method. Try it like this(I copied it from jmetest.intersection.TestCollision:



private CollisionResult results;



protected void simpleInitGame() {

results = new BoundingCollisionResults() {

public void processCollisions() {

if (getNumber() > 0) {

text.print("Collision: YES");

} else {

text.print("Collision: NO");

}

}

};



      }



protected void simpleUpdate() {

results.clear();

n1.calculateCollisions(scene, results);



if(n1.hasCollision(scene, false)) {

//logger.info("hasCollision also reports true");

}

}



most important is to use simpeUpdate. Checking collisions in simpleInit() makes no sense (and

will be called only once) Hope that helped…