i needed advices, i'd like to make movements relative to the direction the camera is facing.
for example, i use keys W,A,S,D to move. W is used to go forward.
but W is alway moving in same direction… if i look behind me by rotating camera, and then press W, i will now move in same direction as before, thus making me move backward…
how can i make movement relative to the direction the camera is facing so the W key will alway make me move forward (the direction the cam is facing) … like it's done on almost all FPS out there…
here's the code i use so far:
// if no collision do move
if (oldData.getTargetTris().size()==0){
lastPosition.set(b.getLocalTranslation());
// the boolean at the end is for keypress repeat
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveFwd", true))
{
b.getLocalTranslation().x += boxSpeed* timer.getTimePerFrame();
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveBwd", true))
{
b.getLocalTranslation().x -= boxSpeed* timer.getTimePerFrame();
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveLeft", true))
{
b.getLocalTranslation().z -= boxSpeed* timer.getTimePerFrame();
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveRight", true))
{
b.getLocalTranslation().z += boxSpeed* timer.getTimePerFrame();
}
}
// if collision go back to last known valid position
if (oldData.getTargetTris().size()>0)
{
b.getLocalTranslation().set(lastPosition);
}
I've kind of half-way sorted the problem, W and S keys now work.
if i press W key it will go forward according to the direction camera is facing.
same for S key .. going backward depending direction the camera is facing.
so far so good or so it look like, but
i can't figure how to make A and D key to strafe left or right depending direction camera is facing ?
//boxNode = new Node("box node");
b = new Box("box", new Vector3f(0,5,0), 1, 1 ,1);
b.setLocalScale(.4f);
b.setModelBound(new BoundingBox());
b.updateModelBound();
rootNode.attachChild(b);
rootNode.attachChild(m);
} catch (Exception e) { // Just in case anything happens
System.out.println("Damn exceptions! O_o n" + e);
e.printStackTrace();
System.exit(0);
}
// change the direction camera is looking at
cam.setAxes(new Vector3f(0,0,-1), new Vector3f(0,1,0), new Vector3f(1,0,0));
//put the cam at the box position
cam.setLocation(new Vector3f(
b.getLocalTranslation().getX(),
b.getLocalTranslation().getY()+1,
b.getLocalTranslation().getZ()
));
if (results.getNumber() <= 0) {
System.out.printf("don't go out dammitn");
System.exit(0);
}
oldData = results.getCollisionData(0);
if (oldData.getTargetTris().size()==0){
lastPosition.set(b.getLocalTranslation());
// the boolean at the end is for keypress repeat
// Movement for W key (go forward depending the direction camera is facing)
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveFwd", true))
{
b.getLocalTranslation().x += cam.getDirection().x * timer.getTimePerFrame();
b.getLocalTranslation().z += cam.getDirection().z * timer.getTimePerFrame();
}
// Movement for S key (go backward depending the direction camera is facing)
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveBwd", true))
{
b.getLocalTranslation().x -= cam.getDirection().x * timer.getTimePerFrame();
b.getLocalTranslation().z -= cam.getDirection().z * timer.getTimePerFrame();
}
// Movement for A key (not working)
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveLeft", true))
{
b.getLocalTranslation().z -= cam.getDirection().z * timer.getTimePerFrame();
}
// Movement for D key (not working)
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveRight", true))
{
b.getLocalTranslation().z += cam.getDirection().z * timer.getTimePerFrame();
}
}
if (oldData.getTargetTris().size()>0)
{
b.getLocalTranslation().set(lastPosition);
}
}
}
BTW, http://www.euclideanspace.com/ is a great resource for anything related to 3d graphics math.
@hevee and others
thanks for the help!
i tryed getting the sideway vector by calcultating the cross product of the cam,
it mostly works , at least it's now much better and i can strafe left or right,
but there's a little problem left:
strafe works only when camera is facing world X axis.
if i turn my cam 90deg left or right and then try to strafe it move veeery slowly. i have to turn the camera a bit toward world X axis to get more speed or turn it back completely toward X axis (i mean here: X or -X (looking forward or backward the player)) to have strafe to work normaly.
here's the code i used:
if (oldData.getTargetTris().size()==0){ // if *no* collision then do:
lastPosition.set(b.getLocalTranslation()); // first save last position
// the boolean at the end is for keypress repeat
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveFwd", true))
{
//b.getLocalTranslation().x += boxSpeed* timer.getTimePerFrame();
b.getLocalTranslation().x += cam.getDirection().x * timer.getTimePerFrame();
b.getLocalTranslation().z += cam.getDirection().z * timer.getTimePerFrame();
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveBwd", true))
{
b.getLocalTranslation().x += cam.getDirection().x * timer.getTimePerFrame();
b.getLocalTranslation().z += cam.getDirection().z * timer.getTimePerFrame();
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveLeft", true))
{
// strafe left (partialy works depending if the cam faces world X or not)
Vector3f sideways = cam.getDirection().cross(Vector3f.UNIT_Y);
b.getLocalTranslation().z -= sideways.z * timer.getTimePerFrame();
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveRight", true))
{
// strafe right (partialy works depending if the cam faces world X or not)
Vector3f sideways = cam.getDirection().cross(Vector3f.UNIT_Y);
b.getLocalTranslation().z += sideways.z * timer.getTimePerFrame();
}
}
if (oldData.getTargetTris().size()>0) // if collision happened then do:
{
b.getLocalTranslation().set(lastPosition);
}
the cross product is not normalized ... call vector.normalize() or .normalizeLocal() so it will be a normalized vector.
that vector can then be multiplied by the speed of your movement and it will always strafe with the same speed.
@dhdd
tnx but, i think it's not about variable speed, it's about axis..
when i'm (the camera) facing an axis other than X (say if i look left) the strafe don't work.
as soon as i rotate even just a bit the camera toward X strafe start to works progressively..
i made a webstart : http://keisangi.free.fr/dungeon/dungeon.jnlp
(i have a problem with texture, they couldn't be found on the webstart version i dunno why yet.
so, there's only the default "missing texture" displayed. but the rest works ok, you can test moving around in the dungeon)
you can move using key W,A,S,D and mouse look, as in most FPS.
you'll see what i mean about strafe left or right ...try facing the wall on your sides and press A or D.
i tryed and it doesn't work..
it does roughly the same as the previous code.
*update:
to be clear it work only when facing straight forward or backward.
as soon as you look around , and try to strafe, it doesn't work as expected.
the best to see the problem is to look at the walls on your side.
like this:
when the webstart run, do a 90deg rotation to look at the wall on your left or your right and try to strafe: it doesn't work.
then rotate back to normal (facing forward) and try to strafe: it works.
so it does works *only* when looking toward 2 directions: forward and backward: i think it's because it's the same axis..
you can test the webstart to see what i'm poorly trying to explain.
//boxNode = new Node("box node");
b = new Box("box", new Vector3f(0,5,0), 1, 1 ,1);
b.setLocalScale(.4f);
b.setModelBound(new BoundingBox());
b.updateModelBound();
rootNode.attachChild(b);
rootNode.attachChild(m);
} catch (Exception e) { // Just in case anything happens
System.out.println("Damn exceptions! O_o n" + e);
e.printStackTrace();
System.exit(0);
}
// change the direction camera is looking at
cam.setAxes(new Vector3f(0,0,-1), new Vector3f(0,1,0), new Vector3f(1,0,0));
//put the cam at the box position
cam.setLocation(new Vector3f(
b.getLocalTranslation().getX(),
b.getLocalTranslation().getY()+1,
b.getLocalTranslation().getZ()
));
if (results.getNumber() <= 0) {
System.out.printf("don't go out dammitn");
System.exit(0);
}
oldData = results.getCollisionData(0);
if (oldData.getTargetTris().size()==0){
lastPosition.set(b.getLocalTranslation());
// the boolean at the end is for keypress repeat
if (KeyBindingManager.getKeyBindingManager().isValidCommand("moveFwd", true))
{
b.getLocalTranslation().x += cam.getDirection().x * playerSpeed * timer.getTimePerFrame();
b.getLocalTranslation().z += cam.getDirection().z * playerSpeed * timer.getTimePerFrame();