majidarif - 9 months ago 43

Python Question

I am trying to calculate transforms in Three.JS and honestly I'm new to 3D math.

In Three.JS there is a 3x3 and 4x4 matrix class but no 4x3.

**Goal**: I want to understand how to do multiplication on a 4x3*4x3 matrix.

I have a set of the inputs and the correct outputs. I got it by using python, because there is a library called

`Noesis`

The problem is that the library calls from a python binary, so I can't see the source code.

The code in python is simply:

`modelSpaceMat = boneMat * frameMat`

Here is a sample of the

`boneMat= (`

(0.0, 0.0, 1.0),

(0.0, 1.0, 0.0),

(-1.0, 0.0, 0.0),

(0.0, 32.29199981689453, -3.2665998935699463)

)

frameMat= (

(0.6425124406814575, -0.06018795818090439, 0.7639083862304688),

(-0.003379624802619219, 0.9966778755187988, 0.08136376738548279),

(-0.7662678360939026, -0.05486864596605301, 0.640174925327301),

(4.438972473144531, -1.4769394397735596, 3.863013744354248)

)

modelSpaceMat=(

(-0.7639083862304688, -0.06018795818090439, 0.6425124406814575),

(-0.08136376738548279, 0.9966778755187988, -0.003379624802619219),

(-0.640174925327301, -0.05486864596605301, -0.7662678360939026),

(-1.1457012760729413e-07, 30.441999435424805, 9.592490357590577e-08)

)

boneMat= (

(1.0, 0.0, 0.0),

(0.0, 1.0, 0.0),

(0.0, 0.0, 1.0),

(0.0, 0.007000000216066837, -3.2665998935699463)

)

frameMat= (

(1.0000004768371582, 2.3320662876358256e-06, -1.4419805665966123e-05),

(2.817355607476202e-06, 0.9999991059303284, -3.3202520626218757e-06),

(1.5038006495160516e-05, -2.133270072590676e-06, 1.0000003576278687),

(-0.0015083501348271966, 0.02300064079463482, 3.266691207885742)

)

modelSpaceMat= (

(1.0000004768371582, 2.3320662876358256e-06, -1.4419805665966123e-05),

(2.817355607476202e-06, 0.9999991059303284, -3.3202520626218757e-06),

(1.5038006495160516e-05, -2.133270072590676e-06, 1.0000003576278687),

(-0.0014612301019951701, 0.030011480674147606, 9.013115777634084e-05)

)

Now I want to be able to do it with javascript.

- Is there any library available?
- What is the formula?

The python module, Noesis, has this line:

`def __mul__(self, other):`

if isinstance(other, (NoeMat43, list, tuple)):

return noesis.mat43Mul(self, other)

elif isinstance(other, NoeVec3):

return noesis.mat43TransformPoint(self, other)

elif isinstance(other, NoeVec4):

return noesis.mat43TransformVec4(self, other)

else:

return NoeMat43([self.mat43[0]*other, self.mat43[1]*other, self.mat43[2]*other, self.mat43[3]*other])

I can't find the source code for

`noesis.mat43Mul`

Testing-out

`var boneMat = new THREE.Matrix4().copy(_bone.userData.modelMatrix);`

var frameMat = new THREE.Matrix4();

frameMat.set(

bone.rotationMatrix[0], bone.rotationMatrix[1], bone.rotationMatrix[2], bone.positionVector[0],

bone.rotationMatrix[3], bone.rotationMatrix[4], bone.rotationMatrix[5], bone.positionVector[1],

bone.rotationMatrix[6], bone.rotationMatrix[7], bone.rotationMatrix[8], bone.positionVector[2],

0.0, 0.0, 0.0, 1.0

);

var modelSpaceMat = new THREE.Matrix4();

modelSpaceMat.multiplyMatrices(boneMat, frameMatrix);

console.log(boneMat, frameMat, modelSpaceMat);

But the result of this

`modelSpaceMat`

`modelSpaceMat`

`(-1.1457012760729413e-07, 30.441999435424805, 9.592490357590577e-08)`

`3.863013744354248, 30.815059661865234, -7.705572128295898`

Why is that?

For reference here are the outputs of the

`console.log`

Answer Source

From a mathematical point of view, you cannot multiply 4x3 matrices.

When its about affine transformations, graphics libraries use a special subset of square matrices in the homogeneous space to describe the transformation:

```
a b c 0
d e f 0
g h i 0
x y z 1
```

The last column is chosen to be `0 0 0 1`

so the transformation is not a perspective projection.

Some graphics libraries only store the interesting 4x3 portion of that transformation, but multiplication must be done as it was in the 4x4 form.

Threejs has a builtin `Matrix4`

class, which implements multiplication.