Rotating A Bone Via Code?

Hi,
I have a car with wheels rigged to the bone.
I can import it fine, but when I take control over a wheel with setUserControl method, the bone gets moved to (0,0,0). How can I make it stay in place? I just want to rotate the bone, to make the wheels turn, without having to export turning wheels as an animation.
Thanks!

Please look at the examples, specifically “jmetest.model.anim.TestCustomAnim”

1 Like

I see how the example works, but my car wheel moves to position 0,0,0 when I take control of the bone. Why does it do that? I want it to stay in place, then to be rotated along its own axis. Like I could do in Blender, by pressing ‘R’ (rotate) then selecting an axis. So the only issue is figuring out how to make it STAY where it was before it moved.

So you do something wrong when you “take control of the wheel”.

Everything works until I take control of the bone that the wheel is attached to. The bone then acts as if it was never attached to a bone.

That further hints at you doing something wrong. Before we continue this game, check out this: http://www.mikeash.com/getting_answers.html

Okay.
My car consists of a chassis made of bones. The wheels are one mesh, properly weight painted to be controlled by each bone.
The body of the car, and the chassis, are connected to a node called car, inside the Car class.
So I want to rotate the wheel bone, to make my wheel spin.
Here is my car class

public Car(String name, String colour, int tires)
{
car = new Node();
wheels = new Node();
wheels = (Node) Game.app.getAssetManager().loadModel(“Models/Cars/”+name+"/Tires.mesh.xml");
treads = new Material(Game.app.getAssetManager(),“Common/MatDefs/Misc/Unshaded.j3md”);
treads.setTexture(“ColorMap”, Game.app.getAssetManager().loadTexture(new TextureKey(“Textures/Tires/Tire”+tires+".png",false)));
wheels.setMaterial(treads);

    body = new Node();
    body = (Node) Game.app.getAssetManager().loadModel("Models/Cars/"+name+"/Body.mesh.xml");
    paint = new Material(Game.app.getAssetManager(),"Common/MatDefs/Misc/Unshaded.j3md");
    paint.setTexture("ColorMap", Game.app.getAssetManager().loadTexture(new   TextureKey("Textures/Paint/"+colour+".png",false)));
    body.setMaterial(paint);
    
    chassis = wheels.getControl(SkeletonControl.class);
    
    car.attachChild(body);
    car.attachChild(wheels);
}
public void setTurnRotation(float rotation) { Bone rWheel = chassis.getSkeleton().getBone("FRight"); rWheel.setUserControl(true); rWheel.setUserTransforms(Vector3f.ZERO, new Quaternion(0,rotation,0,0), Vector3f.ZERO); } public Node getCarNode() { return car; }

So, that is the car class, minus the variable declarations etc.
So, in my main class, when I call the setTurnRotation method, the wheel disappears. If I comment our the ‘setUserTransforms’ line, the wheel appears at the position (0,0,0).

Any ideas?

Well you set it to zero here:
rWheel.setUserTransforms(Vector3f.ZERO, new Quaternion(0,rotation,0,0), Vector3f.ZERO);

But when I comment out that line, and leave just setUserControl(true)
the wheel still goes to zero.

Its because you took user control and its not controlled by the animation anymore.

However there never was an animation, so shouldn’t it stay in it’s default position?
I’m going to assume the answer to that is no.
So, new question, how can I make it go where it was?

Get the transforms before setting user control mode.

Actually, I can just reposition the entire skeleton to fix that.
How about making one specific bone rotate on its scale.
I had my line of code posted above, how can I make it stay in the same position that it was-but rotate on a single axis?

:? As I said, before setting user control mode, get the transforms, in your code:

[java]Bone rWheel = chassis.getSkeleton().getBone(“FRight”);
Vector3f loc = rWheel.getLocation();
Quaternion rot = rWheel.getRotation();
Vector3f scale = rWheel.getScale();
rWheel.setUserControl(true);
rWheel.setUserTransforms(loc, rot, scale);[/java]

If the location hasn’t been applied yet (that is you enable the user control before the animation sets the rest pose) you have to do this one frame late, so e.g. in simpleUpdate.

The car wheel now appears above the car, instead of below it.
I made some code to make it not set on the first frame, not sure how to do that, I just made it set the user control and rotations, once it wasn’t the first frame (after frame 1)
I didn’t find getLocation, etc, I found getLocal_______, and used that. The wheel still isn’t in place however. Should I convert it to world…?

Still not moving into position.
I used

Bone rWheel = chassis.getSkeleton().getBone(“FRight”);
Vector3f loc = rWheel.getLocalPosition();
Quaternion rot = rWheel.getLocalRotation();
Vector3f scale = rWheel.getLocalScale();
rWheel.setUserControl(true);
rWheel.setUserTransforms(loc, rot, scale);

And the wheel now appears above the car. Still not in place.

I know this thread is old but it is necessary to make a copy of the references (loc, rot and scale)

for example:

Vector3f loc = rWheel.getLocalPosition().clone();