Odd results

I’ve been trying to set up a movement physics handler similar to the one momoko has which was based off of http://www.ogre3d.org/wiki/index.php/OgreOde_Walking_Character however i’ve run into a few issues. I’ve restarted twice and even copied part of the code provided by momoko to a point and still end up with a similar issues in the characterGamestate I call


private void init(DefineGameState base) {      
      //sets up lighting
      setupLight(base, rootNode);
      DynamicPhysicsNode feetNode=base.getPhysicsSpace().createDynamicNode();feetNode.setName("feetNode");      
      DynamicPhysicsNode physNode=base.getPhysicsSpace().createDynamicNode();physNode.setName("physNode");
       rootNode.attachChild(feetNode);
       rootNode.attachChild(physNode);
      //Loads Inital Model//////////////////////////////////
      ogre charModel = new ogre(name);
      charNode = charModel.newClone();   
      charNode.setName(name);
      /////////////////////////////////////////      
      //sets up model to be deployed
      charNode.setModelBound(new BoundingBox());
        charNode.updateModelBound();
       
        physNode.attachChild(charNode);
        rootNode.updateGeometricState(0, false);
       
      //temporary reduction in size
      float N=1;
      BoundingBox bb = (BoundingBox) rootNode.getWorldBound();
      
      float wantedScale = Math.min(N/bb.xExtent, N/bb.yExtent);
      wantedScale = Math.min(N/bb.zExtent, wantedScale);
      rootNode.setLocalScale(wantedScale);


       rootNode.updateModelBound();
      
   

      //initializes movement
        rootNode.addController(new PlayerController(rootNode, charNode,base.getPhysicsSpace())); 
       
      rootNode.updateGeometricState(0, true);
      rootNode.updateWorldBound();
      rootNode.updateRenderState();
       
   }   



and within the cotnroller I have

public class PlayerController extends Controller{
InputHandler input;
private DynamicPhysicsNode feetNode,physNode;
private Node rootNode, charNode;
private PhysicsSpace physicsSpace;
private static Material characterMaterial = null;

/**
 * This is the character material. Density should be balanced to prevent character from flying
 * too far, but not too high at the same time to prevent large forces. Bouncing should be
 *  disabled in most cases. Mu should be low enough to prevent character from sliding, but not
 *  high enough to prevent walking on walls.
 */
static {
    characterMaterial = new Material( "Character Material" );
    characterMaterial.setDensity( 1f );
    MutableContactInfo contactDetails = new MutableContactInfo();
    contactDetails.setBounce(0);
    contactDetails.setMu(1);
    contactDetails.setMuOrthogonal(1);
    contactDetails.setDampingCoefficient(10);
    characterMaterial.putContactHandlingDetails( Material.DEFAULT, contactDetails );
}
/**
 * Constructor: Constructs a Controller to handle movement
 * @param rootNode the rootNode
 * @param charNode the direct node that contains the model
 * @param physicsSpace the relevant physicsSpace of the system
 */
   public PlayerController(Node rootNode, Node charNode, PhysicsSpace physicsSpace)
   {
      this.rootNode=rootNode;
      this.charNode=charNode;
      this.physicsSpace = physicsSpace;
      feetNode =((DynamicPhysicsNode) this.rootNode.getChild("feetNode"));
      physNode =((DynamicPhysicsNode) this.rootNode.getChild("physNode"));
      
      createCharacterPhysics();

        input = new FirstPersonHandler(DisplaySystem.getDisplaySystem().getRenderer().getCamera(),8,1);
        physNode.generatePhysicsGeometry();
      feetNode.generatePhysicsGeometry();
     //   ((FirstPersonHandler)handler).getKeyboardLookHandler().setMoveSpeed(10);
     
   }
   RotationalJointAxis feetWalkAxis;
    InputHandler contactDetect;
   boolean onGround, allowFall;
    public void createCharacterPhysics(){
       // here we compute the radius of a virtual cylinder
        // that would totally contain the character
        BoundingBox bbox = (BoundingBox) charNode.getWorldBound();
        float cRadius = bbox.xExtent > bbox.zExtent ? bbox.zExtent : bbox.xExtent;
        float cHeight = bbox.yExtent * 2f;
       
       
        // create the feet physics object
        // it's a sphere on the floor
        PhysicsSphere feetGeom = feetNode.createSphere("Feet");
        feetGeom.setLocalScale(cRadius);
        feetNode.setMaterial(characterMaterial);
        feetNode.computeMass();
        // Aligns character to floor
       charNode.setLocalTranslation(0, -cRadius / charNode.getLocalScale().y, 0);
       
       
       
     // create the capsule physics object
        // it's a capsule and its going to be attached to the feet
        physNode.setAffectedByGravity(false);
        PhysicsCapsule torsoGeom = physNode.createCapsule("Torso");
        torsoGeom.setLocalScale(new Vector3f(cRadius, cHeight-4*cRadius, cHeight));
        torsoGeom.setLocalTranslation(0, cHeight - ((torsoGeom.getLocalScale().y)/2f+2f*cRadius), 0);
        Quaternion rot = new Quaternion();
        rot.fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X);
        torsoGeom.setLocalRotation(rot);
        physNode.computeMass();
       
     
     // create a joint to keep the capsule locked to the rolling sphere
        Joint joint = physicsSpace.createJoint();
        JointAxis axis = joint.createRotationalAxis();
        axis.setDirection(Vector3f.UNIT_X);
        joint.attach(physNode, feetNode);
        feetWalkAxis = joint.createRotationalAxis();
        feetWalkAxis.setDirection(new Vector3f( 0, 0, 1 ));
        feetWalkAxis.setAvailableAcceleration(10);
        feetWalkAxis.setRelativeToSecondObject(true);
       

       
       
       
       
      //Creates a synthetic button that is triggered when this node collides with another node.
contactDetect=new InputHandler();
        SyntheticButton collButton = feetNode.getCollisionEventHandler();
        contactDetect.addAction( new InputAction() {
            @Override
            public void performAction( InputActionEvent evt ) {
                ContactInfo contactInfo = (ContactInfo) evt.getTriggerData();
                Vector3f vec = contactInfo.getContactNormal(null);
                if (vec.dot(Vector3f.UNIT_Y) > 0.5f){
                    onGround = true;
                }
                Vector3f vel = contactInfo.getContactVelocity(null);
                if (vel.length() > 10){
                    System.out.println("POWERFUL CONTACT: "+vel.length());
                }
            }
        }, collButton, false );
    }

   
   @Override
   public void update(float time) {
      // TODO Auto-generated method stub
       if (!allowFall){
               preventFall();
           }
           resetFeetRotation();
      input.update( time );
        contactDetect.update(time);
        onGround = false;

   }
   
     /**This method should be called every frame to prevent the character from tripping over.*/
    private void preventFall(){
        Quaternion q = physNode.getLocalRotation();
        Vector3f[] axes = new Vector3f[3];
        q.toAxes(axes);

        q.fromAxes(axes[0], Vector3f.UNIT_Y, axes[2]);
        physNode.setLocalRotation(q);
        physNode.setAngularVelocity(Vector3f.ZERO);
        physNode.updateWorldVectors();
    }
   
    /**Don't remember what this does. It's possible its for 2D physics only.*/
    private void resetFeetRotation(){
        Quaternion q = feetNode.getLocalRotation();
        Vector3f[] axes = new Vector3f[3];
        q.toAxes(axes);

        q.fromAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, axes[2]);
        feetNode.setLocalRotation(q);
    }
   
   
   
   


However I run into ocasional ODE lock bounds error sometimes something about a line at :60 and others at 71 though if i run it again after the first fail It works also sometimes the camera turns on an angle i'm unsure y?

I get these results





also If I try to get the boundingBox extent values at differnt times i get the same value if i but it right after i make the boundingbox bb if i put it after i scale the model or inside the playerController class
I also recieve a null pointer error if i don't call        rootNode.updateGeometricState(0, false);
after i attach the charNode to physNode before anything is done with bounding boxes


x=30.5345 y=95.824585 z=48.746696
x=30.5345 y=95.824585 z=48.746696
x=30.5345 y=95.824585 z=48.746696

I think i'm close to figuring it out but first i'm having an issue i've found that if i comment out the line feetNode.computerMass() then it seems to work however if i don't the character falls through the floor after it is spawned extremly high up for some odd reason. the most i did was call the feetNode in the controller instead of the gameState class and i fell into issues however by commenting out computeMass i'm bac at square 1 which is actually were i wanted to be when i declared feetNode in the controller instead can anyone reply as 2 y?



Through some debugging i've found that at

       charNode.setLocalTranslation(0, -cRadius / charNode.getLocalScale().y, 0);


the feetGeom sphere is extremly large proobably getting the original scale from the character before he's scaled somehow even though i do the scaling before i call the playerControllerConstructor

EDIT
if i call

        rootNode.updateGeometricState(0, false);


before i call        rootNode.addController(new PlayerController(rootNode, charNode,base.getPhysicsSpace()));  it seems to work even after compueMass() is uncommented however the feetGeom i'm assuming thats what it is is incredibly small whats going on??

i've found that if i do below instead i get the same results as if the updateworldData was updategeometricstate but y do i have to call it so many times?



charNode.setModelBound(new BoundingBox());
        charNode.updateModelBound();
       
        physNode.attachChild(charNode);
        rootNode.updateWorldData(0);
       
      //temporary reduction in size
      float N=1;
      BoundingBox bb = (BoundingBox) charNode.getWorldBound();
      
      float wantedScale = Math.min(N/bb.xExtent, N/bb.yExtent);
      wantedScale = Math.min(N/bb.zExtent, wantedScale);
      rootNode.setLocalScale(wantedScale);   
        rootNode.updateWorldData(0);
      //initializes movement
        rootNode.addController(new PlayerController(rootNode, charNode,base.getPhysicsSpace())); 
       
      //rootNode.updateGeometricState(0, false);
      rootNode.updateWorldBound();
      rootNode.updateRenderState();





should say i belive this to be the feetGeom

i get the picture above if i do below however in the ogre example it was (below) any suggestions I think i'm getting closer




// here we compute the radius of a virtual cylinder
        // that would totally contain the character
        BoundingBox bbox = (BoundingBox) charNode.getWorldBound();
       
        System.out.println(bbox.xExtent+" "+bbox.yExtent+" "+bbox.zExtent);
        float cRadius = bbox.xExtent > bbox.zExtent ? bbox.zExtent : bbox.xExtent;
        float cHeight = bbox.yExtent * 2f;
       
       
        // create the feet physics object
        // it's a sphere on the floor
        feetNode = physicsSpace.createDynamicNode();
        feetNode.setName("feetNode");
        PhysicsSphere feetGeom = feetNode.createSphere("Feet");
        feetGeom.setLocalScale(cRadius);
        feetNode.setMaterial(characterMaterial);
       feetNode.computeMass();
        // Aligns character to floor
       charNode.setLocalTranslation(0, -cRadius / charNode.getLocalScale().y, 0);
       rootNode.attachChild(feetNode);




EDIT
I've also found through println-ing bbox values, that after i call updateWorldData(0); the values are drasitcally reduced. However if i don't call it the model falls from an unprecedented height

also the rootNode isn't the actual rootnode its only the rootNode for that class the rootNode is attached to a baseNode which is the actual rootNode. In this i've created the boundingbox and scaled the rootNode not the charNode which actually has the model geometry data could this be an issue

Does making the 'terrain' out of smaller triangles help?



(I think I read some where that there can be issues with really small triangles intersecting with really big…)



I use a similar system (of my own making) but it doesn't use a ball for the feet, just a single cylinder; but I have yet to encounter the issues you are describing…