PhysicsCharacterNode needed to move with a platform

I am trying to move player with a moving platform.Basically what I am doing is casting a ray to determine whether the player is standing on a particular type(named) object.Then I want to addLocal the player current position with the platforms current position.



Just like the player is standing on a moving platform and it it taking him to elsewhere.



This is in the simpleUpdate method

[java]

standingOnRayResults = new CollisionResults();



standingOnRay = new Ray(new Vector3f(pn_player.getLocalTranslation().getX(), pn_player.getLocalTranslation().getY()-.25f,pn_player.getLocalTranslation().getZ()), new Vector3f(0, -pn_player.getUpAxis(),0));



standingOnRay.setLimit(0.8f);



rootNode.collideWith(standingOnRay, standingOnRayResults);

if(standingOnRayResults.size() != 0){

standingOnObject = standingOnRayResults.getClosestCollision().getGeometry().getName();

reportGUIText.setText(standingOnObject);

if(standingOnObject.equals(“moving_platfrom-geom-1”) & pn_player.onGround()){



//Here goes the player position update code.

}

}

}[/java]



I have tried several ways but none of them produced what i wanted.Can somebody write this update line for me! :frowning:



here pn_player is the PhysicsCharacterNode and pn_movingPlatform is Physics Node for moving platform.

1 Like

Just attach the player node to the platform, that would be the easiest way.

It doesn’t work.I tried this first.

Well just use player.warp(plaform.getWorldTranslation().add(offVector)); then.

Normen, warp() has no javadoc yet, if you give me some details, i’l ladd it to the wiki.

What is offVector and how to get it?

Its to have the player not be at the position of the platform but above it.

Vector3f offVector=new Vector3f(0,1,0);

@ruth: Its simply a method to move the character node, its directly set in contrast to the setLocalTranslation(), which is only applied when the update is run.

Its not working too.The Player jumps up.When i deprecate “add(offVector)” part, nothing happens.



My world is scaled too low, can this cause this kind of weird behavior.



I am also facing lots of weird Physics behavioral.Like my PhysicsCharacterNode is going through the moving platform(MeshCompoundShape),when i first jump onto it, sometimes, when I start the app, i find my PlayerNode half buried in the ground…when I use BoxCompoundShape, the boxCollisionShape is in the wrong position(a bit lower from where it should be)

If its not deterministic theres something wrong in your code. You sure you do everything on the OpenGL thread?

ummm…I dont know. :frowning: How do I check it.



Here is the code.

[java]public class Main extends SimpleApplication implements AnimEventListener{



private AnimChannel animChannel;

private AnimControl animControl;



private BulletAppState bulletAppState;

private PhysicsNode pn_basicPlatform;

private PhysicsNode pn_movingPlatform;

private BitmapText reportGUIText;

private PhysicsCharacterNode pn_player;

private Vector3f walkDirection = new Vector3f();

private boolean left = false, right = false, up = false, down = false;



Ray standingOnRay = new Ray();

CollisionResults standingOnRayResults = new CollisionResults();

private String standingOnObject = “”;



public static void main(String[] args) {

Main app = new Main();

app.setShowSettings(false);



AppSettings newAppSettings = new AppSettings(true);

newAppSettings.put(“Width”, 800);

newAppSettings.put(“Height”, 600);

newAppSettings.put(“Title”, “SST”);

newAppSettings.put(“VSync”, false);

newAppSettings.put(“Samples”, 4);

//newAppSettings.put(“Fullscreen”, true);



app.setSettings(newAppSettings);

app.start();

}



@Override

public void simpleInitApp() {

// TODO: DEBUG : Work around of detaching previous Key binding

flyCam.setEnabled(false);

// inputManager.deleteMapping(“KEY_RIGHT”);

// inputManager.addMapping(“KEY_RIGHT”, new MouseAxisTrigger(0, true));



initGUIText();

initState();

initViewPortLight();

initPlatform();

initPlayer();

initMovingPlatform();

}



public void initMovingPlatform()

{

Spatial geo_movingPlatform = assetManager.loadModel(“Scenes/moving_platfrom.j3o”);

//geo_movingPlatform.setLocalScale(0.6f);

geo_movingPlatform.setLocalTranslation(0,-1.7f,1);



CompoundCollisionShape cs_movingPlatform = CollisionShapeFactory.createMeshCompoundShape((Node)geo_movingPlatform);

pn_movingPlatform = new PhysicsNode(cs_movingPlatform, 0f);

pn_movingPlatform.attachChild(geo_movingPlatform);

pn_movingPlatform.attachDebugShape(assetManager);

//pn_movingPlatform.applyContinuousForce(true, new Vector3f(0,9.7f,0));

bulletAppState.getPhysicsSpace().add(pn_movingPlatform);

rootNode.attachChild(pn_movingPlatform);

}



public void initPlayer()

{

//TODO Checking the capsule size that encapsulates Player Model

Spatial model_player = assetManager.loadModel(“Models/Oto/Oto.mesh.xml”);

model_player.setLocalScale(0.1f);

model_player.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.PI , new Vector3f(0,1,0)));

pn_player = new PhysicsCharacterNode(new CapsuleCollisionShape(.35f,.32f), 0.05f);

pn_player.attachChild(model_player);

pn_player.setGravity(17);

pn_player.setFallSpeed(17);

pn_player.setJumpSpeed(8);

pn_player.setLocalTranslation(0,35,8);



//DEBUG SHAPE

pn_player.attachDebugShape(assetManager);



animControl = model_player.getControl(AnimControl.class);

animControl.addListener(this);

animChannel = animControl.createChannel();

animChannel.setAnim(“stand”);



inputManager.addMapping(“CharLeft”, new KeyTrigger(KeyInput.KEY_LEFT));

inputManager.addMapping(“CharRight”, new KeyTrigger(KeyInput.KEY_RIGHT));

inputManager.addMapping(“CharForw”, new KeyTrigger(KeyInput.KEY_UP));

inputManager.addMapping(“CharBack”, new KeyTrigger(KeyInput.KEY_DOWN));

inputManager.addMapping(“CharJump”, new KeyTrigger(KeyInput.KEY_SPACE));

inputManager.addMapping(“CharShoot”, new MouseButtonTrigger(MouseInput.BUTTON_LEFT) );



inputManager.addListener(actionListener, “CharLeft”);

inputManager.addListener(actionListener, “CharRight”);

inputManager.addListener(actionListener, “CharForw”);

inputManager.addListener(actionListener, “CharBack”);

inputManager.addListener(actionListener, “CharJump”);

inputManager.addListener(actionListener, “CharShoot”);



bulletAppState.getPhysicsSpace().add(pn_player);

rootNode.attachChild(pn_player);

}



public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {

if (!right & animName.equals(“Walk”)) //if walk animation comes to the end

// and still the Right button not pressed → User dont want to move any further.

// Then it starts blending the standing animation

{

channel.setAnim(“stand”, 0.5f);

// channel.setLoopMode(LoopMode.DontLoop);

// channel.setSpeed(1f);

}

}



public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {

// unused

}



private ActionListener actionListener = new ActionListener() {

public void onAction(String binding, boolean isPressed, float tpf)

{

if (binding.equals(“CharLeft”))

{

if (isPressed)

left = true;

else

left = false;

}



else if (binding.equals(“CharRight”))

{

if (isPressed)

{

right = true;

if (!animChannel.getAnimationName().equals(“Walk”)) {

animChannel.setAnim(“Walk”, 0.5f);

animChannel.setSpeed(0.75f);

//animChannel.setLoopMode(LoopMode.Loop);

}

}

else

right = false;

}



else if (binding.equals(“CharForw”))

{

if (isPressed)

up = true;

else

up = false;

}



else if (binding.equals(“CharBack”))

{

if (isPressed)

down = true ;

else

down = false;

}



else if(binding.equals(“CharJump”))

{

pn_player.jump();

}



else if(binding.equals(“CharShoot”))

{

//

}

}

};



public void initViewPortLight() {

DirectionalLight sun = new DirectionalLight();

sun.setDirection(new Vector3f(-3f, -5f, 5f));

sun.setColor(ColorRGBA.White);

rootNode.addLight(sun);



Spatial sky = SkyFactory.createSky(assetManager, “Textures/FullskiesBlueClear03.dds”, false);

sky.setLocalScale(1000);

rootNode.attachChild(sky);

}



public void initPlatform() {

Spatial basicPlatform = assetManager.loadModel(“Scenes/platform.j3o”);



CompoundCollisionShape cs_basicPlatform = CollisionShapeFactory.createMeshCompoundShape((Node)basicPlatform);

pn_basicPlatform = new PhysicsNode(cs_basicPlatform, 0f);

pn_basicPlatform.attachChild((Node)basicPlatform);

pn_basicPlatform.attachDebugShape(assetManager);



bulletAppState.getPhysicsSpace().add(pn_basicPlatform);

rootNode.attachChild(pn_basicPlatform);

}



private void initState() {

bulletAppState = new BulletAppState();

bulletAppState.setThreadingType(BulletAppState.ThreadingType.SEQUENTIAL);

stateManager.attach(bulletAppState);

}



protected void initGUIText() {

guiNode.detachAllChildren();

guiFont = assetManager.loadFont(“Interface/Fonts/Default.fnt”);



reportGUIText = new BitmapText(guiFont, false);

reportGUIText.setSize(guiFont.getCharSet().getRenderedSize());

reportGUIText.setLocalTranslation(100,75,0);

guiNode.attachChild(reportGUIText);

}



@Override

public void simpleUpdate(float tpf) {

//TODO These two are a quick-fix for PhysicsCharacterNode Jitter

rootNode.updateLogicalState(tpf);

rootNode.updateGeometricState();



updateStandingOnRay();



cam.setDirection(new Vector3f(-.7f,-.2f,-1f));

cam.setLocation(new Vector3f(pn_player.getLocalTranslation().getX()+3, pn_player.getLocalTranslation().getY()+1,pn_player.getLocalTranslation().getZ()+3f));



pn_player.setWalkDirection(Vector3f.ZERO);



//TODO : DEBUG

pn_movingPlatform.move(0, 0, 0.002f);



//if(animChannel.getAnimationName().equals(“stand”))pn_player.setWalkDirection(new Vector3f(0, 0, -0.005f));

if(animChannel.getAnimationName().equals(“Walk”)) pn_player.setWalkDirection(new Vector3f(0, 0, -0.02f));

}



@Override

public void simpleRender(RenderManager rm) {

}



private void updateStandingOnRay(){

standingOnRayResults = new CollisionResults();



//TODO : PlayerDEPENDENT

standingOnRay = new Ray(new Vector3f(pn_player.getLocalTranslation().getX(), pn_player.getLocalTranslation().getY()-.25f,pn_player.getLocalTranslation().getZ()), new Vector3f(0, -pn_player.getUpAxis(),0));

standingOnRay.setLimit(0.8f);



rootNode.collideWith(standingOnRay, standingOnRayResults);

if(standingOnRayResults.size() != 0){

standingOnObject = standingOnRayResults.getClosestCollision().getGeometry().getName();

reportGUIText.setText(standingOnObject);

if(standingOnObject.equals(“moving_platfrom-geom-1”) & pn_player.onGround()){

reportGUIText.setText(pn_player.getLocalTranslation() + " tt " + standingOnRayResults.getClosestCollision().getContactPoint());



pn_player.warp(pn_movingPlatform.getWorldTranslation().add(new Vector3f(0,1f,0)));

//pn_player.setLocalTranslation(pn_player.getLocalTranslation().addLocal(new Vector3f(0,0,1)));

}

}

}



}[/java]

I dont know, looks ok. Still, I feel like I am asking each time what your nebulous “move” method does. Maybe the problem is there, like you do this.updateGeometricState() (I’d have to cross you if you do) in it…

I thought the PhysicsNode movement, this is not going to affect the object on top of it.Cause, I am just calculating the movement of the platform,It really doesnt matter, what is making it move.



If I try to use Physics Force, the I have to enable mass.If I enable mass then it is not possible to balance it while a the player is moving on top of it. As the player moves on a side of the platform, it starts tilting.I tried some like setting gravity zero, applying continuous force, Vector3f(0,9.8,0), but none of then are able to maintain a constant platform-ic motion.I asked how to set the Mass of PhysicsCharacterNode to zero, you said, it dont have any.But, why its helping to tilt a physics object, if it dont have any mass?



So, for simple movement, i was thinking about animating it or moving with simple move methods.But, as you are saying now, this might cause inaccurate physical calculations.But, I have checked by displaying the physics debug shape, it is moving as it should.



Now, anymore idea about how can i Move my character with the moving platform.



another question, How do I create force of magnitude less then 1.My world scale is small so, pn_movingPlatform.applyContinuousForce(true ,new Vector3f(0,0,1f)); this force is reacting extreme.I want something like Vector3f(0,0,0.01f), how to get it?

The character is an obstacle, so the platform tilts.

iamcreasy said:
My world scale is small so, pn_movingPlatform.applyContinuousForce(true ,new Vector3f(0,0,1f)); this force is reacting extreme.I want something like Vector3f(0,0,0.01f), how to get it?

Huh? Exactly as you write it..
Huh? Exactly as you write it..

Anything less then Vector3f(0,0,0.3967f) dont move the platform.Even, Vector3f(0,0,0.3966f) vibrates the platform, but it dont move it.Vector3f(0,0,0.01f) is far away.But, 0.3967 is too strong force for the scale of the current game world.

The character is an obstacle, so the platform tilts.

So, how I am going to solve this problem :(

Replace the characternode with a physicsnode or just attach the model to the elevator instead of the character node while its moving, then attach the model to the character again when its up and warp the character to the top position.