I'm trying to export object an animated hierarchy of objects from Cinema 4D's left coordinates (z+ = forward) with HPB rotations to Three.js's right-hand coordinates (z+ = backward) with XYZ rotations.

Unfortunately, I'm a bit beyond my depth with the matrix math and conversions involved. I'd like to take my C4D local coords write them out as local coords in this other system.

Any tips on how to approach this?

Thanks

Donovan

PS: Looks like we need an S22 tag in the tags option.

]]>I'm trying to export object an animated hierarchy of objects from Cinema 4D's left coordinates (z+ = forward) with HPB rotations to Three.js's right-hand coordinates (z+ = backward) with XYZ rotations.

Unfortunately, I'm a bit beyond my depth with the matrix math and conversions involved. I'd like to take my C4D local coords write them out as local coords in this other system.

Any tips on how to approach this?

Thanks

Donovan

PS: Looks like we need an S22 tag in the tags option.

]]>I ended up porting the Three.js Matrix4 and Euler classes from JS to python and using them in my script.

So, the final code (leaving out the ported methods) looked something like:

```
mg = self.op.GetMg()
parent_mg = self.op.GetUpMg()
c4d_to_three = c4d.Matrix(
off=c4d.Vector(0),
v1=c4d.Vector(1, 0, 0),
v2=c4d.Vector(0, 1, 0),
v3=c4d.Vector(0, 0, -1)
)
# Convert to new coordinate space
# http://www.techart3d.com/2016/02/convert-left-handed-to-right-handed-coordinates/
mg_three_coords = c4d_to_three * mg * c4d_to_three
parent_mg_three_coords = c4d_to_three * parent_mg * c4d_to_three
mg_mat4 = Matrix4(mg_three_coords)
parent_mg_mat4 = Matrix4(parent_mg_three_coords)
inv_parent_mg_mat4 = parent_mg_mat4.Clone()
inv_parent_mg_mat4 = inv_parent_mg_mat4.Inverse()
node_local = inv_parent_mg_mat4.Clone()
node_local = node_local.MultiplyMatrices(inv_parent_mg_mat4, mg_mat4)
position, scale, rotation = node_local.Decompose()
if position != c4d.Vector(0):
self.props["position"] = position
if scale != c4d.Vector(1):
self.props["scale"] = scale
if rotation != c4d.Vector(0):
self.props["rotation"] = rotation
```

]]>I do not quite understand the question. You cannot express other frame orientations than Cinema's builtin frame orientation with Cinema's matrices. When you write to one component in such way, that it would produce a malformed matrix, Cinema will silently rectify that matrix. See this script for demonstration:

```
import c4d
from c4d import gui
def main():
"""
"""
if not op:
return
mg = op.GetMg()
# Cinema will automatically rectify a matrix so that it does conform
# to its world frame. Which is why this will flip also the x-axis, not just
# the z-axis.
mg.v3 *= -1
op.SetMg(mg)
c4d.EvenatAdd()
if __name__=='__main__':
main()
```

I am not quite sure, what you are after. If you just want an axis tuple, then just grab it from the matrices and invert whatever you have to invert and construct the rest of the matrix with the cross product.

Cheers,

zipit

sound like you just have to switch the Z axis by multiplying it by -1.

Either you should go from local to global and back to local that's probably the problem, and with a hierarchy you will maybe hit some cases that i don't think right now.

If you could come with one simple example. A c4d scene with a simple animation and what you expect for three.js

(maybe the hierarchy isn't important there i don't know)

Cheers,

Manuel

I ended up porting the Three.js Matrix4 and Euler classes from JS to python and using them in my script.

So, the final code (leaving out the ported methods) looked something like:

```
mg = self.op.GetMg()
parent_mg = self.op.GetUpMg()
c4d_to_three = c4d.Matrix(
off=c4d.Vector(0),
v1=c4d.Vector(1, 0, 0),
v2=c4d.Vector(0, 1, 0),
v3=c4d.Vector(0, 0, -1)
)
# Convert to new coordinate space
# http://www.techart3d.com/2016/02/convert-left-handed-to-right-handed-coordinates/
mg_three_coords = c4d_to_three * mg * c4d_to_three
parent_mg_three_coords = c4d_to_three * parent_mg * c4d_to_three
mg_mat4 = Matrix4(mg_three_coords)
parent_mg_mat4 = Matrix4(parent_mg_three_coords)
inv_parent_mg_mat4 = parent_mg_mat4.Clone()
inv_parent_mg_mat4 = inv_parent_mg_mat4.Inverse()
node_local = inv_parent_mg_mat4.Clone()
node_local = node_local.MultiplyMatrices(inv_parent_mg_mat4, mg_mat4)
position, scale, rotation = node_local.Decompose()
if position != c4d.Vector(0):
self.props["position"] = position
if scale != c4d.Vector(1):
self.props["scale"] = scale
if rotation != c4d.Vector(0):
self.props["rotation"] = rotation
```

]]>