Sign in to follow this  
Herbert

Change rotation when the physic is enabled

Recommended Posts

I have a box and a ground with physicsImpostor, how can I keep the rotation of the ground up to date with the rotation of the box. here is the playground
https://www.babylonjs-playground.com/#T310H5
If I use "ground.rotation = box.rotation", then the ground rotate but the box do not.
If I use "ground.rotation.x = box.rotation.x", then the ground will keep rotating.

Share this post


Link to post
Share on other sites

You can't rotate a mesh using rotation when it has a physicsImpostor.  You can mesh.physicsImpostor.sleep(), then rotate, and then mesh.physicsImpostor.wakeUp(), but inbetween those sleep/awake it does not maintain physics properties.  To maintain physics you could apply forces/impulses. Read the post from Mackey titled "Physics Movement" - lots of good info in there.

Share this post


Link to post
Share on other sites

sleep and wakeUp does not work as I tested 
 

scene.registerBeforeRender(() => {
    ground.physicsImpostor.sleep();
    ground.rotation.x = box.rotation.x;
    ground.physicsImpostor.wakeUp();
});

What I want is to keep the ground having the same rotation as the box, I think it will be complicated to implement it by applying forces/impulses.
Thanks for your recommended post, I will read it tomorrow~

Share this post


Link to post
Share on other sites

oh, I found what I was missing when I tried to reproduce it, so I have to set the rotationQuaternion for my box first.

https://www.babylonjs-playground.com/#T310H5#4

box.rotationQuaternion = new BABYLON.Quaternion();

and it turns out after this both calling rotate function or setting rotation.x directly work, while setting the whole rotation still not work.

scene.registerBeforeRender(() => {
    box.rotation.x -= -0.001;
    console.log(box.rotation.x);

    // not work
    // ground.rotation = box.rotation;

    // works
    ground.rotation.x = box.rotation.x;

    // works
    // ground.rotate(new BABYLON.Vector3(1, 0, 0), box.rotation.x);
});

I think there might be a setter function when I set rotation.x directly, which will actually check rotationQuaternion?
I log the value of  box.rotation.x right after I change it, but it shows 0.001 constantly, does that mean once rotationQuaternion exists the value of rotation doesn't mean much anymore?

Share this post


Link to post
Share on other sites

Once a rotationQuaternion exists, the rotation variable is being ignored and should not be used.

The rotate function will set a rotationQuaternion for you, if it doesn't already exist (of couse, taking your current rotation in account). Setting a physicsImpostor to your mesh will do the same. afterwards, the rotation should not be used.

Hint regarding .rotate, the first variable is an Axis. If you need either X, Y or Z, you can use the static BABYLON.Axis.X (or Y or Z :) ) instead of creating a new vector. Will save you a few microseconds per frame.

Share this post


Link to post
Share on other sites

As you said, I shouldn't use rotation once a rotationQuaternion exists, then I am confused how my playground still work(I actually think it shouldn't be working since box.rotation.x is constantly 0.001).

and if rotation is not referable, what can I be used to pass to the second variable of rotate function?

Share this post


Link to post
Share on other sites

About the 2nd variable to the rotate function, it is an angle, expressed in radians. Pretty straight forward.

Regarding the rotation update when quaternion already exists - a few months ago I added a code to the AbstractMesh's computeWorldMatrix that updates the mesh's rotationQuaternion, if rotation was used. This is to keep people from changing habits, but is relatively discouraged, mainly due to the conversion between euler units and quaternion. that's the code, if you are interested - https://github.com/BabylonJS/Babylon.js/blob/master/src/Mesh/babylon.abstractMesh.ts#L1258 

Share this post


Link to post
Share on other sites

Thanks for being patient and your very detailed answers, it helps a lot:)
I know the 2nd variable's meaning~ just curious is there any other attribute of the box that I can just take and pass to the second variable to keep their rotation the same(since taking rotation.x is relatively discouraged ).
If no such attribute exists, I will do it another way or just set the rotationQuaternion instead.

 

 

Share this post


Link to post
Share on other sites

The reason it works (in case anyone is interested) is those few lines of code in AbstractMesh i mentioned earlier.

Each time the computeWorldMatrix is called, the rotation variable is being inspected. if it is not only 0,0,0, it is being added to the rotationQuaternion and being reset. So, you either add -0.001 and then reset to 0, or set it to be -0.001 and reset it back to 0. As simple as that :)

Why it is not accumulated, you ask? it is practically impossible to go back to rotation from rotationQuaternion. So in order to prevent users from thinking rotation === rotationQuaternion, I reset the variable.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.