How to calculate the conversion matrix of two meshes

I have found the same questions on SO:

How to do this in babylon js for irregular mesh.

Use getWorldMatrix ro get the world matrix for each mesh.

wma and wmb

Multiply wma by an inverted wmb to get the conversion matrix from wma to wmb.

const conToB = Matrix.Identity();

ma.getWorldMatrix().multiplyToRef(Matrix.Invert(mb.getWorldMatrix()), conToB);

(Untested)

3 Likes

@adam
Thanks for your quick reply.

Is there a way to get out the position and rotation between the two mesh?

  1. The position we can use mesh.getBoundingInfo().boundingSphere.centerWorld to got.
  2. How to get the rotation value?

You can call decompose on the conversion matrix.

@adam
I prepared a PG:

Can you help me to understand the conversion matrix:

  1. how to transform the box1 to box2 (them should be align at the some position)
  2. how to decompose out the rotation and position value from the conversion matrix.

@jtcheng , when you use the following matrix:

box1.getWorldMatrix().multiplyToRef(BABYLON.Matrix.Invert(box2.getWorldMatrix()), conToB);

The conToB matrix will be a matrix that you can use to convert a position that is box1 local space to box2 local space. For example, if you have a TransformNode that is a child of box1 and you would like to know what its position would be if it was a child of box2 you could use the conToB to do it.

However, this will only be useful if you want to know where a position relative to box1 is relative to box2. For aligning the boxes you could the assign them the same world position and rotation, do you have an example of what you are trying to achieve?

  1. A transform matrix is capable of applying translation, rotation and scaling to a object in space. You can use the following code to decompose the matrix into these components:
var translation : BABYLON.Vector3;
var rotation : BABYLON.Quaternion;
var scale: BABYLON.Vector3;

conToB.decompose(scale, rotation, translation);

After decompose is called the translation, rotation and scale will have the values from the matrix.

The following documentation has more information and examples about coordinate systems:
Coordinate Transformation Examples | Babylon.js Documentation (babylonjs.com)

4 Likes

@srzerbetto
Thanks for your input!
(your question) do you have an example of what you are trying to achieve?
Yes, my case is like this:

  1. I have two STL (stl1, stl2) files for the same object (in fact, I have a dozen of this kind of stl file pair)
  2. I load them to Babylon JS scene (mesh1, mesh2) and found that their position and rotation are different (they are export from other software)
  3. I need to setup a animation to show the animation from mesh1 to mesh2
    a. I know the position value offset between the two mesh (use mesh.getBoundingInfo().boundingSphere.centerWorld to compute the position offset)
    b. I still need the rotation offset to make sure they can align to each other
  4. so my question is:
    a. how to compute the rotation offset between the two mesh? or
    b. is there a better way to implement this achieve?

@jtcheng , since you stl are been loaded with rotations that you do not control, you can use the bounding box axis information to get a relative rotation from one mesh to another.

Here is a playground example that show you to get the relative rotation for both meshes using this method: Box Examples | Babylon.js Playground (babylonjs.com)

The steps are pretty simple:

  • Use the bound box to get the rotation for mesh 1.
  • Use the bound box to get the rotation for mesh 2.
  • Calculate the inverse rotation for mesh 2.
  • Multiply it by the rotation for mesh 1.

This rotation quaternion will apply the inverse rotation for mesh 2 and than apply the mesh 1 rotation effectively rotation mesh 2 to mesh 1. You can use it to multiply any rotation relative to mesh 2 and make it relative to mesh 1.

1 Like

@srzerbetto
Thanks for your help:

But in my case, the loaded stl mesh always show the AABB boundingBox instead of OBB

    const directions = mesh.getBoundingInfo().boundingBox.directions;
    console.log(directions);
1. Array(3)
  1. 0: Vector3 {_isDirty: true, _x: 1, _y: 0, _z: 0}
  2. 1: Vector3 {_isDirty: true, _x: 0, _y: 1, _z: 0}
  3. 2: Vector3 {_isDirty: true, _x: 0, _y: 0, _z: 1}
  4. length: 3
  5. [[Prototype]]: Array(0)

@RaananW , do you know if it is possible to force boundingBox to be OBB ?

Will the directions array be enough for you to compute what you need?

@RaananW
My directions array always shows like this:

Got it.

Did you try force-computing the world matrix?

Box Examples | Babylon.js Playground (babylonjs.com)

If you are trying to use the bounding info on the same frame the box was created (like in this playground example), you will need to force the computation of the world matrix (and along with it update the bounding information), otherwise it will be correct to the time of mesh creation.

Rule of thumb, if you want to be sure that the world matrix is 100% correct and you need to use it, compute it yourself, or use the after-render loop, which will guarantee that babylon computed the world matrix.

Hello @jtcheng just checking in, was your question answered?