Matrix
Matrix math is widely used for various DCC to represent position, rotation and scale. Cinema4D provides a comprehensive introduction on its own implemention.
Gotchas
- For matrices, there is no such thing as division
Code Snippets
# Retrieved from https://gist.github.com/andreberg/888507/f653bdb58299ca0efe198f4ff14525ca033c286a
def getGlobalPosition(obj):
return obj.GetMg().off
def getGlobalRotation(obj):
return MatrixToHPB(obj.GetMg()) # Use c4d.utils.RadtoDeg() to convert to degrees.
def getGlobalScale(obj):
m = obj.GetMg()
return c4d.Vector(m.v1.GetLength(),
m.v2.GetLength(),
m.v3.GetLength())
@staticmethod
def setGlobalPosition(obj, pos):
m = obj.GetMg()
m.off = pos
obj.SetMg(m)
@staticmethod
def setGlobalRotation(obj, rot):
"""
Please remember, CINEMA 4D handles rotation in radians.
Example for H=10, P=20, B=30:
import c4d
from c4d import utils
#...
hpb = c4d.Vector(utils.Rad(10), utils.Rad(20), utils.Rad(30))
SetGlobalRotation(obj, hpb) #object's rotation is 10, 20, 30
"""
m = obj.GetMg()
pos = m.off
scale = c4d.Vector( m.v1.GetLength(),
m.v2.GetLength(),
m.v3.GetLength())
m = HPBToMatrix(rot)
m.off = pos
m.v1 = m.v1.GetNormalized() * scale.x
m.v2 = m.v2.GetNormalized() * scale.y
m.v3 = m.v3.GetNormalized() * scale.z
obj.SetMg(m)
@staticmethod
def setGlobalScale(obj, scale):
m = obj.GetMg()
m.v1 = m.v1.GetNormalized() * scale.x
m.v2 = m.v2.GetNormalized() * scale.y
m.v3 = m.v3.GetNormalized() * scale.z
obj.SetMg(m)
def _GlobalToLocal(self, obj, global_pos) :
""" Returns a point in global coordinate in local space. """
obj_mg = obj.GetMg()
return ~obj_mg * global_pos
def get_points_global_matrix(obj, point_idx):
obj_local_pos = obj.GetPoint(idx)
obj_world_pos = obj.GetMg() * obj_local_pos