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