[SOLVED] Rotating Vector3f by angle

Hello guys , i’m new to Jmonkey , i have alredy red Beginners tutorial but i’m stucked with this problem.
I have a custom Java class called : Player with attributes like : healt , stamina … and a Vector3f field called direction that should store the current direction that the player is facing. My goal is to use right and left arrow to rotate a box and calculate the new direction it is facing.
I made a test case were :

  1. a player is rappresented by a simple box moving on a surface
  2. a player direction is rapresented by a red arrow starting from the center of the box
  3. mapping for arrow click were added
  4. when pressing arrow key the direction should change and the cube should rotate

this is what i did so far:
class Player { protected final Vector3f position; protected final Vector3f direction;
public Vector3f getPosition(){ return position;

public Vector3f getDirection(){ return direction;
}

public void Move(int i ){ switch(i){ case 0: //Move right case 1: //Move left

}

}
}

public class Test extends SimpleApplication implements ActionListener{

// Position at 0 0 0
// direction is equal to Z_Axis
Player player

@Override public void simpleInitApp() {

Geometry player_geom = new Geometry("player", new Box(1f, 1f, 1f)); Material player_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); player_mat.setColor("Color", ColorRGBA.randomColor()); player_geom.setMaterial(player_mat);

Geometry floor = new Geometry("floor", new Box(60f, 0.1f, 50f)); Material floor_material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); floor_material.setTexture("ColorMap", assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg")); floor.setMaterial(floor_material); floor.setLocalTranslation(60f, -1f, 0f);

Geometry player_direction = new Geometry("arrow",new Arrow(new Vector3f(10, 0f, 0f))); Material arrow_material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); arrow_material.setColor("Color", ColorRGBA.Red); player_direction.setMaterial(arrow_material); player_direction.setLocalTranslation(-1f, 0.15f, 0f);

Node n = new Node("player_node"); n.attachChild(player_geom); n.attachChild(player_direction); n.setLocalTranslation(player.getPosition()); }

@Override public void simpleUpdate(float tpf) {
.
.
.

// Here shoud rotate the box ``if(ROTATING){ rootNode.getChild("player_node").rotate(//Ho do i rotate facing the new direction ?); }

}

@Override public void onAction(String name, boolean isPressed, float tpf) {

if(name.equals("right") ){
ROTATION = isPressed;
if(isPressed)
player.move(0);
}else if (name.equals("left")){ if(isPressed){ p.move(0); } }

`}`

if somebody could help me understeand how to manage the move function ( how to get the new direction )
and how can i rotate the cube i will apreciate a lot

I am not quite what you want to achieve should the cube only turn around or also move?

Anyway a Vector can be rotated by multiplying it with a rotation matrix.

For example if you want to turn the vector around the y-axis this can be achieved by the following code:

Matrix3f m = new Matrix3f(); m.fromAngleAxis( some_angle_in_radians, new Vector3f(0f,1f,0f) ); direction = m.mult(direction);

1 Like

Use .rotate (float, float, float);

yea it should move to , but im having troubles with rotation .
this is what i did :
public void move (int i){ switch (i){ case 0 : Matrix rotation_matrix = new Matrix(); rotation_matrix.fromAngleAxis(1f, Vector3f.UNIT_Y)); direction.set(rotation.mult(direction)); }

in the simple update
@Override public void simpleUpdate(float tpf) {
.
.
.

// Here shoud rotate the box
if(ROTATING){ rootNode.getChild("player_node").rotate(0f,1f,0f); }

}

it’s weird … the cube rotate too fast and if i try to slow it down like :
m.fromAnglesAxis(0.0000001f , new Vector(0f,1f,0f)
direction became ~ 0 so the cube doesn’t rotate
how can i slow down the rotation but still use 1f as angle ?

its randian not degree. you will need something like this
.rotate(0, FastMath.DEG_TO_RAD20tpf, 0)

that way you have 20 degrees per second.

And did you work through the beginners section? I’m pretty sure there are samples/exercises which deal with rotation.

You might try just looking at the source for FlyByCamera as it does all of this sort of player movement.

In general, you probably want to use Quaternion instead of Matrix3f… or just use the code already built into spatial. (ie: your Node)

Which was is the player facing?
dir = node.getWorldRotation().mult(Vector3f.UNIT_Z);

Rotate the player around the Y axis?
node.rotate(0, someRadians, 0);

Yeah but im trying to separate logic from graphics so i felt like making moviment at core level could give me some nice feature , like i can change engine to test same code.
Also i couldn’t find any sample about rotating a character with keyboard manipulating data by myself.

If you look at this (CameraMovementState) class it is a bit more ‘readable’ than JME’s… just ignore the event processing stuff and you can see the logic of how the camera moves:

The camera doesn’t provide the smarter methods that Spatial does so you can more easily see how you might manage your own rotation and movement.

http://davidb.github.io/sandbox_wiki_jme/jme3/beginner/hello_main_event_loop.html
http://davidb.github.io/sandbox_wiki_jme/jme3/beginner/hello_input_system.html

are your friends. The first deals with the game loop where there is an example with rotating and the second deals with keyboard/mouse/whatever input.

Took me a while to adapt this to my situation but it worked! :smiley: