Attaching to staticNode

I'm using jme physics2 everything was going smoothly until I decided to make the level static can anyone tell what exactly am i doing wrong??




package com.tps1.lvlLoader;

import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import trb.jme.imaging.TextureLoader;
import trb.jme.quake3.Quake3Converter;
import trb.jme.quake3.Quake3Loader;

import com.jme.input.FirstPersonHandler;
import com.jme.input.InputHandler;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.state.CullState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;
import com.jme.util.GameTaskQueueManager;
import com.jmex.game.StandardGame;
import com.jmex.game.state.GameStateManager;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.StaticPhysicsNode;
import com.tps1.GameState.Charactertype;
import com.tps1.GameState.DefineGameState;
import com.tps1.GameState.SkyBoxManager.SkyBoxGameState;
import com.tps1.util.ErrorHandler;

public class levelTester extends DefineGameState {
    Quake3Converter converter;
    Vector3f eyePos = new Vector3f();
   
    public levelTester(String act, String scene){   
       initLevel(act,scene);
    }
 
    protected void initLevel(String act, String scene) {   
        display.getRenderer().getQueue().setTwoPassTransparency(false);
        cam.setFrame(new Vector3f(-14, 1.5f, -2.5f), new Vector3f(0, 0, 1), new Vector3f(0, 1, 0), new Vector3f(-1, 0, 0));
        cam.update();
       
        CullState cullState = display.getRenderer().createCullState();
        cullState.setCullFace(CullState.Face.Front);
        getRootNode().setRenderState(cullState);

        // load quake 3 level
   TextureLoader.getInstance().registerPath("src/com/tps1/data/levels/act"+act+"/scene"+scene+"/");
        Quake3Loader loader = new Quake3Loader();
        try {
            loader.load("src/com/tps1/data/levels/act"+act+"/level.bsp");

        } catch (IOException e) {
            e.printStackTrace();
            ErrorHandler.reportError("Thier is an issue loading the level", e);
        }
       
        converter = new Quake3Converter();
        converter.convert(loader, display);
        //////////////////////////////THIS AREA///////////////////////////////////////
        /**sets up physics space*/
       setPhysicsSpace( PhysicsSpace.create() );
       
      this.getRootNode().attachChild(staticNode);
      
      staticNode=   getPhysicsSpace().createStaticNode();
      staticNode.attachChild(converter.getRoot());
      staticNode.generatePhysicsGeometry();
        /////////////////////////////////////////////////////////////////////////////
        GameTaskQueueManager.getManager().update(new Callable<Object>() {
            public Object call() throws Exception {
               getRootNode().lock(display.getRenderer());
                return null;
            }
        });
        setupZBuffer();
    }
    private void setupZBuffer(){
      ZBufferState buf = display.getRenderer().createZBufferState();
        buf.setEnabled(true);
        buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
        this.getRootNode().setRenderState(buf);         
   }
    @Override
   public void update(float tpf) {
       super.update(tpf);
        Vector3f camLoc = cam.getLocation();
        eyePos.set(camLoc);
        converter.setVisibility(eyePos, true);
    }


   
   @Override
   public void cleanup() {
      // TODO Auto-generated method stub
      
   }
   
    public static void main(String[] args){
       StandardGame standardGame = new StandardGame("GameControl", StandardGame.GameType.GRAPHICAL, null);
        standardGame.start();
 
       try {
         SkyBoxGameState.Manager().setActive(true);
         
          levelTester nex = new levelTester("Test","1");
              GameStateManager.getInstance().attachChild(nex);
              nex.setActive(true);
      } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
      Charactertype Avenger = new Charactertype("ninja");      
        Avenger.setActive(true);
        Avenger.getRootNode().getLocalTranslation().set(345f, 34f, 34f);
              
      }

}




as an error message I receive this repeated almost 30+ times



INFO: Child (null) attached to this node (null)
Mar 7, 2009 4:05:25 AM com.jmex.physics.PhysicsNode createPhysicsGeometry
WARNING: Skipped geometry:
java.lang.IllegalArgumentException: Extent cannot have a component that is 0 to generate collision geometries!
   at com.jmex.physics.PhysicsNode.createPhysicsGeometry(PhysicsNode.java:357)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:304)
   at com.jmex.physics.PhysicsNode.addPhysicsGeometries(PhysicsNode.java:202)
   at com.jmex.physics.PhysicsNode.addPhysicsGeometries(PhysicsNode.java:223)
   at com.jmex.physics.PhysicsNode.addPhysicsGeometries(PhysicsNode.java:223)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:172)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:147)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:132)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:119)
   at com.tps1.lvlLoader.levelTester.initLevel(levelTester.java:60)
   at com.tps1.lvlLoader.levelTester.<init>(levelTester.java:27)
   at com.tps1.lvlLoader.levelTester.main(levelTester.java:99)
Mar 7, 2009 4:05:25 AM com.jme.scene.Node attachChild



make sure your objects have a boundingbox before generatePhysicsGeometry()

Core-Dump said:

make sure your objects have a boundingbox before generatePhysicsGeometry()


I did


   converter.getRoot().setModelBound(new BoundingBox());
        /**sets up physics space*/
      setPhysicsSpace( PhysicsSpace.create() );
      
      staticNode=   getPhysicsSpace().createStaticNode();
      this.getRootNode().attachChild(staticNode);

      staticNode.attachChild(converter.getRoot());
      staticNode.generatePhysicsGeometry();
      



but get a long error message

it extends from definegamestate


package com.tps1.GameState;

import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.state.LightState;
import com.jme.system.DisplaySystem;
import com.jmex.game.state.GameState;
import com.jmex.game.state.GameStateNode;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.StaticPhysicsNode;
import com.tps1.aMain.Game;

public abstract class DefineGameState extends GameState {

   
   protected String name;
   protected Node rootNode;
   /**Returns the DisplaySystem*/
   protected DisplaySystem display =DisplaySystem.getDisplaySystem(Game.getSettings().getRenderer());
   /**Returns the Camera from the rendererer*/
   protected Camera cam = DisplaySystem.getDisplaySystem().getRenderer().getCamera();
   /**A static Node*/
   protected StaticPhysicsNode staticNode;
   /**A Dynamic Node*/
   protected DynamicPhysicsNode dynamicNode;

   public DefineGameState() {
        System.setProperty("jme.stats", "set");
       
      rootNode = new Node(name + ": RootNode");         
       
        KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);

    }
   /**
    * Empty.
    *
    * @see GameState#cleanup()
    */
   
   public abstract void cleanup();
   /**
    * Draws the rootNode.
    *
    * @see GameState#render(float)
    */
   @Override
   public void render(float tpf) {
      DisplaySystem.getDisplaySystem().getRenderer().draw(rootNode);
   }

   /**
    * Gets called every frame before render(float) by the parent
    * <code>GameStateNode</code>.
    *
    * @param tpf The elapsed time since last frame.
    */
   public void update(float tpf)
   {
    rootNode.updateGeometricState(tpf, true);      
      
      /**updates physics*/
      //getPhysicsSpace().update( tpf );   
   
       // check if ESC has been pressed, exit the application if needed
        if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit", false)) {
            System.out.println("Good Bye");
            System.exit(0);
            cleanup();} //OK, this is just a demo...
   }
   
   /**
     * physics space to do actual physics
   */
    protected PhysicsSpace physicsSpace;
   public PhysicsSpace getPhysicsSpace() {
       return physicsSpace;
   }
    /**
     * make sure physics space its relevant
    * @param physicsSpace The physics space for this simple game
    */
   protected void setPhysicsSpace(PhysicsSpace physicsSpace) {
      if ( physicsSpace != this.physicsSpace ) {
         if ( this.physicsSpace != null )
                this.physicsSpace.delete();
         this.physicsSpace = physicsSpace;
      }
   }
   
   //returns rootNode
   public Node getRootNode() {
      return rootNode;
   }

}



i'm apperantly getting the issue at

at com.tps1.lvlLoader.levelTester.update(levelTester.java:82)



and the line

      staticNode.generatePhysicsGeometry();

you need to update the bounding after setting them

converter.getRoot().setModelBound(new BoundingBox());

converter.getRoot().updateModelBound());

Core-Dump said:

you need to update the bounding after setting them
converter.getRoot().setModelBound(new BoundingBox());
converter.getRoot().updateModelBound());

I had tried it before but got the same issue

the error code is(copied and pasted what was different otherwise the limit was met because of repeating error code)


Mar 7, 2009 6:44:40 AM com.jmex.physics.PhysicsNode createPhysicsGeometry
WARNING: Skipped geometry:
java.lang.IllegalArgumentException: Extent cannot have a component that is 0 to generate collision geometries!
   at com.jmex.physics.PhysicsNode.createPhysicsGeometry(PhysicsNode.java:357)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:304)
   at com.jmex.physics.PhysicsNode.addPhysicsGeometries(PhysicsNode.java:202)
   at com.jmex.physics.PhysicsNode.addPhysicsGeometries(PhysicsNode.java:223)
   at com.jmex.physics.PhysicsNode.addPhysicsGeometries(PhysicsNode.java:223)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:172)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:147)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:132)
   at com.jmex.physics.PhysicsNode.generatePhysicsGeometry(PhysicsNode.java:119)
   at com.tps1.lvlLoader.levelTester.initLevel(levelTester.java:63)
   at com.tps1.lvlLoader.levelTester.<init>(levelTester.java:28)
   at com.tps1.lvlLoader.levelTester.main(levelTester.java:105)






SEVERE: Main game loop broken by uncaught exception
java.lang.IllegalArgumentException: scale must not have 0 as a component (geom 'tm: 3979')!
   at com.jmex.physics.impl.ode.geometry.OdeBox.updateWorldVectors(OdeBox.java:69)
   at com.jme.scene.Spatial.updateWorldData(Spatial.java:552)
   at com.jme.scene.Spatial.updateGeometricState(Spatial.java:517)
   at com.jme.scene.Node.updateWorldData(Node.java:395)
   at com.jme.scene.Spatial.updateGeometricState(Spatial.java:517)
   at com.jme.scene.Node.updateWorldData(Node.java:395)
   at com.jme.scene.Spatial.updateGeometricState(Spatial.java:517)
   at com.tps1.GameState.DefineGameState.update(DefineGameState.java:66)
   at com.tps1.lvlLoader.levelTester.update(levelTester.java:83)
   at com.jmex.game.state.GameStateNode.update(GameStateNode.java:71)
   at com.jmex.game.StandardGame.update(StandardGame.java:381)
   at com.jmex.game.StandardGame.run(StandardGame.java:250)
   at java.lang.Thread.run(Thread.java:619)



am I missing something

if anything the DefinegameState extends gamestate can anyone try on their system and tell if its maybe my set up because i can't figure it out at all

"Extent cannot have a component that is 0 to generate collision geometries!"



do any of your geometries have a width, height or length of zero?

Guedez said:

"Extent cannot have a component that is 0 to generate collision geometries!"

do any of your geometries have a width, height or length of zero?


None that i know of this is an odd issue that i can't seem to figure out

the javadoc on it states

void com.jmex.physics.PhysicsNode.generatePhysicsGeometry()
This method generates physics geometry bounds for detecting collision from the graphical representation in this PhysicsNode.

See Also:
PhysicsCollisionGeometry
Throws:
IllegalStateException - if no graphical representation is present (no Geometries within this Node)



but the level does show so...


[EDIT]
I got it to compile and run with problems though

PhysicsNode.generatePhysicsGeometry(converter.getRoot(), staticNode, true);


or

PhysicsNode.generatePhysicsGeometry(getRoot(), staticNode, true);



it also seems to work when I do

staticNode.generatePhysicsGeometry(true);


but not when i do

staticNode.generatePhysicsGeometry(false);



However the character falls through the mesh regardless of what I do

I'm loading a .bsp map btw

should this be yielding the proper result that I want do i really need triangle accuracy(its a level)

I looked through simplePhysics super classes and found nothing that was even similar to the above statement when they implemented the simple surface

could it be an issue between bsp and jme physics 2 or I didn't properly solve the issue

should I change my characters dynamicNodes class to include the above isntead of the below??


dynamicNode.generatePhysicsGeometry();


i've also recently added

/**sets up physics space*/
       setPhysicsSpace( PhysicsSpace.create() );


in the constructor of the define class and I also found the below doesn't seem to work unless i add it into the playerGameState class which is suppose to only load my character and extends from the DefineGameState class as well this is very odd if i create a copy of level tester delete all the code related to bsp loading and add the code below the character falls through the mesh.


// first we will create the floor
        // as the floor can't move we create a _static_ physics node
        staticNode = getPhysicsSpace().createStaticNode();

        // attach the node to the root node to have it updated each frame
        rootNode.attachChild( staticNode );

        // now we do not create a collision geometry but a visual box
        final Box visualFloorBox = new Box( "floor", new Vector3f(), 5, 0.25f, 5 );
        // note: we have used the constructor (name, center, xExtent, yExtent, zExtent)
        //       thus our box is centered at (0,0,0) and has size (10, 0.5f, 10)

        // we have to attach it to our node
        staticNode.attachChild( visualFloorBox );

        // now we let jME Physics 2 generate the collision geometry for our box
        staticNode.generatePhysicsGeometry();





FULL class


package com.tps1.lvlLoader;

import java.io.IOException;
import java.util.concurrent.Callable;

import trb.jme.imaging.TextureLoader;
import trb.jme.quake3.Quake3Converter;
import trb.jme.quake3.Quake3Loader;

import com.jme.bounding.BoundingBox;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jme.scene.state.CullState;
import com.jme.scene.state.ZBufferState;
import com.jme.util.GameTaskQueueManager;
import com.jmex.game.StandardGame;
import com.jmex.game.state.GameStateManager;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.StaticPhysicsNode;
import com.tps1.GameState.Charactertype;
import com.tps1.GameState.DefineGameState;
import com.tps1.GameState.SkyBoxManager.SkyBoxGameState;
import com.tps1.util.ErrorHandler;

public class levelTester2 extends DefineGameState {
    Quake3Converter converter;
    Vector3f eyePos = new Vector3f();
   
    public levelTester2(String act, String scene){   
       this.name = "act "+act+"scene "+scene;
      
       initLevel();
       
        GameStateManager.getInstance().attachChild(this);
    }
 
    protected void initLevel() {   

        // first we will create the floor
        // as the floor can't move we create a _static_ physics node
        staticNode = getPhysicsSpace().createStaticNode();

        // attach the node to the root node to have it updated each frame
        rootNode.attachChild( staticNode );

        // now we do not create a collision geometry but a visual box
        final Box visualFloorBox = new Box( "floor", new Vector3f(), 5, 0.25f, 5 );
        // note: we have used the constructor (name, center, xExtent, yExtent, zExtent)
        //       thus our box is centered at (0,0,0) and has size (10, 0.5f, 10)

        // we have to attach it to our node
        staticNode.attachChild( visualFloorBox );

        // now we let jME Physics 2 generate the collision geometry for our box
        staticNode.generatePhysicsGeometry();
        this.getRootNode().updateGeometricState(0, true);
        this.getRootNode().updateWorldBound();
        this.getRootNode().updateRenderState();

    }
 
    @Override
    public void update(float tpf)
    {
       super.update(tpf);               
    }

   
   @Override
   public void cleanup() {
      // TODO Auto-generated method stub
      
   }
   
    public static void main(String[] args){
       StandardGame standardGame = new StandardGame("GameControl", StandardGame.GameType.GRAPHICAL, null);
        standardGame.start();
 
       try {
      //   SkyBoxGameState.Manager().setActive(true);
         
          levelTester2 nex = new levelTester2("Test","1");
              nex.setActive(true);
      } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
       Charactertype Avenger = new Charactertype("ninja");      
        Avenger.setActive(true);
   //     Avenger.getRootNode().getLocalTranslation().set(345f, 34f, 34f);
              
      }

}




to run i use

   public static void main(String[] args){
       StandardGame standardGame = new StandardGame("GameControl", StandardGame.GameType.GRAPHICAL, null);
        standardGame.start();
 
          levelTester2 nex = new levelTester2("Test","1");
              nex.setActive(true);
      
       Charactertype Avenger = new Charactertype("ninja");      
        Avenger.setActive(true);
   //     Avenger.getRootNode().getLocalTranslation().set(345f, 34f, 34f);
              
      }

hmm this is odd i’ve found that if hash the codes and bring the important part of playerGameState to the levelGameState then colliding works however if i initiate them as seperate gamestates they fall through each other are they not accessing the same rootNode that they inherit from the same class or what could be the issue here  :’(

every Gamestate has usually its own root Node

Core-Dump said:

every Gamestate has usually its own root Node


so i have to make another class and load everything that is collidable in it and make it another gamestate??
or create a root Node in the main class and pass it to the constructor of every gamestate that will need to be collidable btw i make the rootNode in DefineGamestate and declare it their as well.

EDIT
underlined method doesn't work

you use jmephysics for collissions, right ?

Make sure you don't create multiple physic spaces, i think that could be your problem.

Core-Dump said:

you use jmephysics for collissions, right ?
Make sure you don't create multiple physic spaces, i think that could be your problem.


hmm well i implement physicsSpace in DefineState with

setPhysicsSpace( PhysicsSpace.create() );


DefineState is extended by both playerGameState and levelGameState could this be y


   
    /**
     * @return the physics space for this simple game
     */
    protected PhysicsSpace physicsSpace;
   public PhysicsSpace getPhysicsSpace() {
       return physicsSpace;
   }
    /**
     * make sure physics space its relevant
    * @param physicsSpace The physics space for this simple game
    */
   protected void setPhysicsSpace(PhysicsSpace physicsSpace) {
      if ( physicsSpace != this.physicsSpace ) {
         if ( this.physicsSpace != null )
                this.physicsSpace.delete();
         this.physicsSpace = physicsSpace;
      }
   }



edit
hmm if i implement it in either playergamestate or lvlgamestate i get an error

I always used PhysicsGameState from jmephysics and only one of it.

If you use multiple Gamestate which need to create physics entities, then maybe you should create the PhysicsSpace outside the Gamestate, and pass a reference to the PhysicsSpace to the GameStates constructor.



That way only one PhysicsSpace exists and things from different GameStates can collide with each other.

Core-Dump said:

I always used PhysicsGameState from jmephysics and only one of it.
If you use multiple Gamestate which need to create physics entities, then maybe you should create the PhysicsSpace outside the Gamestate, and pass a reference to the PhysicsSpace to the GameStates constructor.

That way only one PhysicsSpace exists and things from different GameStates can collide with each other.


okay thank you for the reply would it work if i made another gamestate extended from physicsGameState that created the physics space?? and activated it before everything else or is it easier just to call DefineGameState.setPhysicsSpace( PhysicsSpace.create() ); in the main class??

hmm I wonder how PhysicsGameState makes it so that no matter how many new Gamestates you extended from it the PhysicsSpace is the same through out...

it seems as though i should construct DefineGameState not extend from it and get the rootNode from thier. I guess I can then pass the theRootNode to the constructors of the other two gamestates
or maybe to make it cleaner I could make the class static and send directly to the gamestates could these ideas work
DefineGamestate is where i create the physicsSpace and i'm guessing that since they extend from it when I construct the two gamestates it creates two seperate physicsSpace when it constructs the DefineGameState.

thx i'll try when i get home...
I wonder how PhysicsGameState makes it so that no matter how many new Gamestates you extended from it the PhysicsSpace is the same through out...

it will also create one physics space per gamestate.

what you can do is:


PhysicsSpace space = PhysicsSpace.create();
GameState gs1 = new GameState1(space);
or
GameState gs2 = new GameState2();
gs2.setPhysicsSpace(gs2);



That way both Gamestates use the same space.

But only one GameState should update the physicsSpace (otherwise physics would be updated multiple times per update cycle).

You could also wrap the PhysicsSpace in a Singleton class so you can access it from everywhere, then you dont have to pass references around.

There are many ways to set up your classes.
Core-Dump said:

I wonder how PhysicsGameState makes it so that no matter how many new Gamestates you extended from it the PhysicsSpace is the same through out...

it will also create one physics space per gamestate.

what you can do is:


PhysicsSpace space = PhysicsSpace.create();
GameState gs1 = new GameState1(space);
or
GameState gs2 = new GameState2();
gs2.setPhysicsSpace(gs2);



That way both Gamestates use the same space.

But only one GameState should update the physicsSpace (otherwise physics would be updated multiple times per update cycle).

You could also wrap the PhysicsSpace in a Singleton class so you can access it from everywhere, then you dont have to pass references around.

There are many ways to set up your classes.


man core your the best I changed all References of the DefineGameState in the classes to receive a them in static form and made the sub classes extend GameState instead of DefineGameState


and also for some odd reason now when the objects are constructed thier falling from a prety high place



       DefineGameState game = new DefineGameState("");
       game.setActive(true);
       
      levelTester2 nex = new levelTester2("Test","1");
       nex.setActive(true);      
       Charactertype Avenger = new Charactertype("ninja");      
        Avenger.setActive(true);


with this thx to coredump I am back to my original problems generating geometry

the first issue i'm actually faced with is when i call I lock the rootNode that has the character as well and everything is frozen when i run it

GameTaskQueueManager.getManager().update(new Callable<Object>() {
            public Object call() throws Exception {
               getRootNode().lock(display.getRenderer());
                return null;
            }
        });

make sure StandardGame has already started before calling lock

Core-Dump said:

make sure StandardGame has already started before calling lock


lol of course I think i fixed it of course now i get console output that i'm zooming around the clusters though the map is now magically invisible


by making a new rootNode in the actual class maybe i should do this for the playerGamestate as well as make a new displaysystem and camera which i originally received at DefineGameState.

EDIT

okay i'm going to make everything using PhysicsGameState instead and see my results using this do i still have to make a physicsGameState and pass it to each node or it would just work?