How to rotate a bone with the camera?

Hello,
I am developing a multiplayer first person shooter. Now I want that the arm bones of the character rotate with the cameras up/down movements. I did the same with the head before: if the player looks up, the head is following him.
That’s the relevant code I wrote for the head movement (in init):

neckBone = playerModel.getControl(AnimControl.class).getSkeleton().getBone("neck");

And this in update …

 neckBoneRotation.fromAngleAxis(cam.getDirection().y * (-1), Vector3f.UNIT_X);
 neckBone.setUserTransforms(Vector3f.ZERO, neckBoneRotation, Vector3f.UNIT_XYZ);

That works for me. But in that case the relevant values from the localRotation of the head are zero. So I can easily rotate this with the camera. But the ‘default’ localRotation of the arms aren’t 0. So the arms don’t look like as they should :grinning:

I tried to use a node which contains the attachment nodes from the shoulder bones. But I can’t rotate the bones by rotating the parentNode, even if I set shoulderRight.setUserControl(true);

So how can I compute the correct rotation of the bones with the camera movement?

Thank you in advance.

I think you want to do something like that

try to use the below for example with static values to insure

Quaternion quat = new Quaternion().fromAngles(FastMath.HALF_PI, y, z);
neckBone.setLocalRotation(quat);

after that we need to be careful with dealing with cam direction

in my case I need to calculate the arc between player view direction and camera direction

I am not sure if my solution is the best but it might help you

Thank you for your answer.
But in my case I write a firstPerson shooter.
Now, look at these screenshoots:
The lower the camera looks, the closer get the two hands together.



I looked at the model in blender and there, all values (x,y,z,w) are changed just by rotating the shoulder bone at the x-axis. I guess I don’t do that in my game.
I’m a bit confused. I am hanging on this problem for days now. :confused:

I JUST WANT THE ARMS FOLLOWING THE CAMERA !

You know how to use quaternions?

Find the bones you need (two shoulders, elbows etc…), and initialize them properly with rotations like Ahmad_Sayed proposed.

Once initialized, save the angle between your camera and the shoulder bone.

When that is done, just rotate the right bones along with the camera each frame.

If the shoulders are not parallel to the body, you will have to rotate more then one bone.

I used this to rotate a players head with the camera angle, I hope it will help you

pos is player position
q is player camera rotation

public void UpdateGeometry(Vector3f pos, Quaternion q){
    
    node.setLocalTranslation(pos.subtract(new Vector3f(0,ConstPlayer.PLAYER_HEIGHT,0)));
    
    if(!oldRot.equals(q)){
        //Make sure the character node is facing right position
        node.getLocalRotation().lookAt(q.clone().getRotationColumn(2).mult(new Vector3f(1,0,1)), new Vector3f(0,1,0));
        
        float[] angles = new float[3];
        
        q.toAngles(angles);
        float n = angles[0];           
        
        for(int i = 0; i<anims.size();i++){            
            Bone b = anims.get(i).getSkeleton().getBone("Head");
            b.setUserControl(true);  

            //startRots the initial value I was talking about (in rads)
            Quaternion qu = new Quaternion().fromAngles(n+startRots.get(i),0,0);

            //System.out.println(String.valueOf(qu.getY()));
            b.setUserTransforms(Vector3f.ZERO, qu, Vector3f.UNIT_XYZ);
        }
        oldRot = q.clone(); //Storing old rotations to only move head when player is moving mouse
    }
    oldPos = pos.clone();            
}

for first person shooter only hands, why not saving yourself messing with quaternions and skeleton, you could rotate the whole body it may give you the same effect

I agree with @Eric_Bourque Quaternion is a bit tricky, to reach the effect I demonstrate in the video it took me about 4 hours, of neuron training for my brain to get adapted with it :blush:

I even did a trial with IK but It partially work but not as expected

Jeah, but I am developing a multiplayer! So the other players should see what I am aiming at. (Hope, that’s correct English :D)
Do you know a solution of that Problem, if I would rotate the hole Charakter?

if you found the effect I did in my video useful I could give you a temp access to my project at bitbucket , but do not share a lot it contains a lot of messy code, and it works great in case of right and left but it up and down works with some issue.

do not worry about english I am not native English speaker too :smile:

EDIT : check this as well it is really useful http://wiki.jmonkeyengine.org/doku.php/jme3:math_for_dummies

Okay, I will have a look and try it again.

Domenic,

Quaternions are not hard, just think of it as a black box. After you play around with them for a while they get easy. Plus they are the only accurate way of rotating bones and stuff.

In multiplayer, the head moves, the arms usually dont unless for reloading and stuff.

Rotate the whole character with this:

http://wiki.jmonkeyengine.org/doku.php/jme3:rotate

You need to send the remote players camera position, rotate the whole character along the xz axis and the head (and arms) along the y axis. (Body rotates left to right, arms and head go up and down)

The bones rotate local to the character, so when you rotate the character, the bones move with.

Again, that code I posted does exactly what you want, but for the head. Throw it in your code, play around with it and you will succeed.

Hey guys, I got it!
Okay, now it’s more clearly to me. In the next days I am going to adjust all this and extend my knowledge about Quaternions and all that stuff :grinning:

Now, please look at my results :relaxed: (I am so happy now :smiley:


Thank you very much, guys !!!

3 Likes

You are very welcome