# On quaternion rotation problem

I need to rotate my model,
Every time I press the w key the model turns to the direction of the camera.

`````` private Vector3f viewDirUP = new Vector3f(0,0,1);
targetQua.set((simpleApp.getRootNode().getChild("model")).getWorldRotation()).nlerp(cam.getRotation(), 0.1f);
viewDirection.set(targetQua.mult(viewDirUP));
viewDirection.setY(0);

``````

I don’t know much about the concept of quaternions,So I don’t know if I’m doing the right thing.

Because minie CharacterControl was used,So the end result is going to be a vector.
The above code completes the interpolation rotation conversion to vectors,
I don’t know if I have any mathematical problems with this piece of code,The results look good.

I hit the “s” key, The character model should face the camera,
I got an error when I multiplied targetQua by viewDirUP.negate() and you can see the result in the video

It’s obvious that the model should be facing the camera when the back button S is pressed instead of spinning around(Here I guess I must have used the wrong parameters to cause this,But I’m not sure what).
But I found a function in javadoc Quaternion.opposite(), And then I changed the code for the S key

`````` private Vector3f viewDirUP = new Vector3f(0,0,1);
targetQua.set((simpleApp.getRootNode().getChild("model")).getWorldRotation().opposite()).nlerp(cam.getRotation(), 0.1f);
viewDirection.set(targetQua.mult(viewDirUP.negate()));
viewDirection.setY(0);

``````

So now the S bond works pretty well,But I don’t know why…

Here’s the problem:

• I want to know how to turn left and right?

• And hopefully, to correct my thinking

Turn what, exactly? If you want to rotate your character’s view direction, that is done with `mult` or `multLocal`.

``````character.setViewDirection(
new Quaternion(angleToRotate, Vector3f.UNIT_Y)
.mult(character.getViewDirection()));
``````
1 Like
``````           targetQua.set((simpleApp.getRootNode().getChild("model")).getWorldRotation().opposite()).nlerp(cam.getRotation(), 0.1f);
//simpleApp.getRootNode().getChild("model").setLocalRotation(targetQua);
viewDirection.set(targetQua.mult(viewDirUP.negate()));
viewDirection.setY(0);
``````

I found that I added.opposite() and then converted to v3 f as normal.This will make the backward normal instead of jitter

I would like to ask you how should I rotate the model from side to side?

``````targetQua.set((simpleApp.getRootNode().getChild("model")).getWorldRotation()).nlerp(cam.getRotation().fromAngleAxis(90* FastMath.DEG_TO_RAD, Vector3f.UNIT_Y), 0.1f);
``````

`.fromAngleAxis(90* FastMath.DEG_TO_RAD, Vector3f.UNIT_Y)`

This is how I try,But it didn’t seem to work

I think this is what you’re looking for.

``````Quaternion rotation = spatial.getLocalRotation();
Vector3f direction = camera.getLocation().subtractLocal(spatial.getWorldTranslation());
direction.setY(0f).normalizeLocal();
Quaternion target = new Quaternion().lookAt(direction, Vector3f.UNIT_Y);
rotation.nlerp(target, .1f);
spatial.setLocalRotation(rotation);
``````

Bonus: the model will face the camera regardless of the camera’s direction.

The reason your code does not work as expected is because `fromAngleAxis` sets the quaternion. So in essence, you are completely overwriting the camera rotation and replacing it with 90 degrees around the y axis. So I would expect `targetQua` to always turn to the same direction.

2 Likes

Can you tell me how you finally converted quaternions into vectors?

1 Like

Where does this parameter come from?

Uh uh… What I really want to say is how do I turn this into a vector3f

`rotation`What do I multiply by to get the vector?

Multiply the vector by the quaternion.

``````Vector3f vec1 = ...
Quaternion quaternion = ...
Vector3f vec2 = quaternion.mult(vec1);
``````
``````Quaternion   rotation = spatial.getLocalRotation();
Vector3f direction = camera.getLocation().subtractLocal(spatial.getWorldTranslation());
direction.setY(0f).normalizeLocal();
Quaternion target = new Quaternion().lookAt(direction, Vector3f.UNIT_Y);
rotation.nlerp(target, .1f);

rotation.mult(?????);

``````

vec1=direction？

I seem to be asking a strange question , but I think you should be able to understand what I mean

I want to turn “rotation” into a vector3f.
rotation.mult(???);

Quaternions are based off the z axis, so multiply with `Vector3f.UNIT_Z`.

Edit: sorry, didn’t realize that was what you were confused about.

1 Like

In jMonkeyEngine, the default “look” direction or “facing” is the Z axis. Vector3f.UNIT_Z.

So any default quaternion (new Quaternion()) is considered to be “looking” down UNIT_Z until changed.

Camera looks down its local Z axis, spatials look down their local Z axis, etc…

3 Likes
`````` @Override
public void update(float tpf) {
camDir.set(cam.getDirection().mult(1f));
camLeft.set(cam.getLeft().mult(1f));
walkDirection.set(0, 0, 0);

camDir.setY(0).normalizeLocal();
camLeft.setY(0).normalizeLocal();
//System.err.println(camDir.y+","+camLeft.y);
//viewDirection.set(camDir);
// 计算运动方向

boolean changed = false;
if(up){

Quaternion rotation = simpleApp.getRootNode().getChild("model").getLocalRotation().clone();
Vector3f direction = camDir;//.subtractLocal(simpleApp.getRootNode().getChild("model").getWorldTranslation())
targetQua.lookAt(direction, Vector3f.UNIT_Y);
rotation.nlerp(targetQua, 0.5f);
viewDirection.set(rotation.mult(Vector3f.UNIT_Z));

System.err.println(viewDirection);
changed = true;
}
if(down){

changed = true;
}else if(left){

changed = true;
}else if(right){
changed = true;
}else if(changed){
}

player.setViewDirection(viewDirection);

}

``````

I hope you can tell me why viewDirection.set(rotation.mult(Vector3f.UNIT_Z)); Have no effect(Maybe not without effect).

set `rotation.nlerp(targetQua, 0.5f);` Obviously the blue box is facing the wrong way

If I set rotation.nlerp(targetQua, 1f); Then everything will be fine but there will be no interpolation

This means that the rotation will only be correct if there is no interpolation.

I don’t understand why this is and what other key elements I am missing?

This code works as intended for me. There is probably something wrong in the code I can’t see that is causing the behavior you’re seeing.

1 Like