[SOLVED] How to rotate a meshInstance on a specific axis?

My scene has a car, and I want to make the wheels running.
The wheels are meshInstances of the car, and their transform matrix are all identity.

图片

To make the wheels running, I need to rotate them on their axis.
I make a demo to do this: PlayCanvas | HTML5 Game Engine
and the main logic is here: PlayCanvas | HTML5 Game Engine

But the result is not good, as it is rotate on the world’s X axis.
You can go to the launch page to see what is going wrong.

图片

Can anyone help me ?

If the pivot point of the wheel is done correctly, you can use the local rotation to rotate on it’s local axis.

TBH, it be easier to separate the wheels from the rest of the car model (so two separate FBXs) and make the wheels separate entities. This will give you more control of where and how they rotate.

Thanks for your quick reply!

So, do you mean there is no way to rotate the wheels correctly if they are “meshInstances” ?

It depends on how they’ve been modelled and where the pivot point/origin is. As they are part of the single model, you have no control on changing it if it is wrong hence why it be a lot easier to work with them if they are separate meshes and entities.

1 Like

I am wondering if there is a workaround for my issue ?

I would first work out where the pivot/origin for the wheel meshInstances are. The easiest way I can think of doing this is to create several visible entities into the scene (one for each wheel) and move them to the meshInstance node world position of each wheel.

The meshes for the wheels may also be rotated in the model at an odd angle which is something to take into account.

I would take a proper look at it but the model is killing my browser. It’s too high poly :frowning:

OMG, my macbook air 2013 still works fine (both chrome and firefox) for this 140k triangles model.

I would first work out where the pivot/origin for the wheel meshInstances are.

As theire world transform matrix are identity, so the pivot/origin are all at [0, 0, 0] ?

The easiest way I can think of doing this is to create several visible entities into the scene (one for each wheel) and move them to the meshInstance node world position of each wheel.

And what is next step ?

Are you 100% sure that the origin of the mesh Instances are at the world 0, 0, 0? If so, you can’t get around this easily.

Just had a quick look, yes all the parts have their origin as the middle of the whole model (0, 0, 0) which means that everything will be rotating around the center of the car.

Maybe you can try to do this:

  • calculate the wheels’ aabb (you did it)
  • translate your wheels to -aabb.center
  • rotate it
  • translate the wheels to the origin position.

I just see this way from https://gamedev.stackexchange.com/a/61479
But I am not sure if this will work.

2 Likes

@yaustar @scarlex
I’ve updated the demo and use the way mentioned above. The implementation is here:

for (var i = 0; i < this.wheelInstances.length; i++) {
    var mesh = this.wheelInstances[i];
    matA.copy(mesh.node.getWorldTransform());
    vecA.copy(this.aabb.center).scale(-1);
    vecB.copy(this.aabb.center);
    quatA.copy(mesh.node.getRotation());
    quatB.setFromAxisAngle(pc.Vec3.RIGHT, this.speed);
    quatC.mul2(quatB, quatA);

    matB.setTRS(vecA, pc.Quat.IDENTITY, pc.Vec3.ONE);
    matC.mul2(matB, matA);
    matA.setTRS(pc.Vec3.ZERO, quatC, pc.Vec3.ONE).mul(matC);
    matB.setTRS(vecB, pc.Quat.IDENTITY, pc.Vec3.ONE).mul(matA);
    mesh.node.setPosition(matB.getTranslation());
    mesh.node.setEulerAngles(matB.getEulerAngles());
    mesh.node.setLocalScale(matB.getScale());
}

It works indeed. But I can’t control the speed anymore, and it will rotate reversely sometime …
What’s wrong with it ?

It is possible for something to spin so fast that it looks like it is going backwards https://www.google.co.uk/amp/s/io9.gizmodo.com/why-do-wheels-sometimes-appear-to-spin-backwards-1593807400/amp

Try at lower speeds to be sure.

But I can’t control the speed anymore

I mean whatever the speed is, the wheel is always moving very fast…

This is what I get when I with:

quatB.setFromAxisAngle(pc.Vec3.RIGHT, 0);

Untitled

The wheel should not run, but it is still running. :face_with_raised_eyebrow:

Not too sure of the math but I think you might be applying the current rotation on itself on this line:

    quatA.copy(mesh.node.getRotation());

As you are getting the current rotation and then applying to the node again.

What happens when you change that to identity?

1 Like

Yes, I think so. The problem is

quatA.copy(mesh.node.getRotation());
quatB.setFromAxisAngle(pc.Vec3.RIGHT, this.speed);
quatC.mul2(quatB, quatA);
matA.setTRS(pc.Vec3.ZERO, quatC, pc.Vec3.ONE).mul(matC);

quatC is the final quaternion of the mesh, and it should not set into the matA.

Try to replace the quatC with quatB:

matA.setTRS(pc.Vec3.ZERO, quatB, pc.Vec3.ONE)
1 Like

@yaustar @scarlex
It works after I replace quatC with quatB!
Thanks!:smile: