def String2MAvatarPosture(lines, avatarID = "Avatar"): parent_map = {None : None} joints = [] name = "" pos = None rot = None channels = [] parentJointName = None for i in range(len(lines)): line = lines[i].strip().split(" ") if line[0] == "ROOT" or line[0] == "JOINT": name = lines[i].strip().split(" ")[1] if name == "PelvisCenter": name = "PelvisCentre" elif line[0] == "OFFSET": pos = MVector3(float(line[1]), float(line[2]), float(line[3])) elif line[0] == "ROTATION": rot = MQuaternion(float(line[4]), float(line[1]), float(line[2]), float(line[3])) elif line[0] == "CHANNELS": channels = [MChannel._NAMES_TO_VALUES[line[j]] for j in range(1, len(line))] joint = MJoint(name, MJointType._NAMES_TO_VALUES[name], pos, rot, channels, parentJointName) parent_map[name] = parentJointName parentJointName = name joints.append(joint) if line[0] == "}": name = parentJointName parentJointName = parent_map[parentJointName] return MAvatarPosture(avatarID, joints)
def NewJson2MAvatarPosture(data, avatarID = "Avatar"): joints = [] for j in data["Joints"]: name = j["ID"] type = j["Type"] pos = MVector3(j["Position"]["X"], j["Position"]["Y"], j["Position"]["Z"]) #rot = MQuaternion(j["Rotation"]["X"], j["Rotation"]["Y"], j["Rotation"]["Z"], j["Rotation"]["W"]) rot = MQuaternion(0,0,0,1) joints.append(MJoint(name, type, pos, rot)) return MAvatarPosture(avatarID, joints)
def position_from_json(v): x = 0 if "X" in v: x = v["X"] y = 0 if "Y" in v: y = v["Y"] z = 0 if "Z" in v: z = v["Z"] return MVector3(x, y, z)
def VMultiply(quat : MQuaternion, vec : MVector3): num = quat.X * 2.0 #round(quat.X, 2) num2 = quat.Y * 2.0 #round(quat.Y, 2) num3 = quat.Z * 2.0 #round(quat.Z, 2) num4 = quat.X * num num5 = quat.Y * num2 num6 = quat.Z * num3 num7 = quat.X * num2 num8 = quat.X * num3 num9 = quat.Y * num3 num10 = quat.W * num num11 = quat.W * num2 num12 = quat.W * num3 result = MVector3() result.X = (1.0 - (num5 + num6)) * vec.X + (num7 - num12) * vec.Y + (num8 + num11) * vec.Z result.Y = (num7 + num12) * vec.X + (1.0 - (num4 + num6)) * vec.Y + (num9 - num10) * vec.Z result.Z = (num8 - num11) * vec.X + (num9 + num10) * vec.Y + (1.0 - (num4 + num5)) * vec.Z return result
def JSON2MAvatarPosture(data): data = {} with open(filepath, "r") as f: data = json.load(f) name = data["1"]["str"] jointlist = [] for i in range(2, len(data["2"]["lst"])): bonename = data["2"]["lst"][i]["1"]["str"] bonetype = data["2"]["lst"][i]["2"]["i32"] bonetype = MJointType._VALUES_TO_NAMES[bonetype] vd = data["2"]["lst"][i]["3"]["rec"] vector = MVector3(vd["1"]["dbl"], vd["2"]["dbl"], vd["3"]["dbl"]) qd = data["2"]["lst"][i]["4"]["rec"] quat = MQuaternion(qd["1"]["dbl"], qd["2"]["dbl"], qd["3"]["dbl"], qd["4"]["dbl"]) jointlist.append(MJoint(bonename, bonetype, vector, quat)) return MAvatarPosture(name, jointlist)
def ToEuler(q : MQuaternion): euler = MVector3() unit = (q.X* q.X) + (q.Y * q.Y) + (q.Z * q.Z) + (q.W * q.W) test = q.X * q.W - q.Y * q.Z if test > 0.4995 * unit: euler.X = math.pi / 2 euler.Y = 2.0 * math.atan2(q.Y, q.X) euler.Z = 0 elif test < -0.4995 * unit: euler.X = math.pi / 2 euler.Y = -2.0 * math.atan2(q.Y, q.X) euler.Z = 0 else: euler.X = math.asin(2.0 * (q.W * q.X - q.Y * q.Z)) euler.Y = math.atan2(2.0 * q.W * q.Y + 2.0 * q.Z * q.X, 1 - 2.0 * (q.X * q.X + q.Y * q.Y)) euler.Z = math.atan2(2.0 * q.W * q.Z + 2.0 * q.X * q.Y, 1 - 2.0 * (q.Z * q.Z + q.X * q.X)) euler = Multiply(euler, Rad2Deg) euler.X = euler.X % 360 euler.Y = euler.Y % 360 euler.Z = euler.Z % 360 return euler
identityQ = MQuaternion(0, 0, 0, 1) defaultJointChannels = [ MChannel.WRotation, MChannel.XRotation, MChannel.YRotation, MChannel.ZRotation ] defaultRootChannels = [ MChannel.XOffset, MChannel.YOffset, MChannel.ZOffset, MChannel.WRotation, MChannel.XRotation, MChannel.YRotation, MChannel.ZRotation ] zeroChannels = [] DEFAULT_JOINTS = [ # 7 joints along the spine (6 animated, 39 channels) NewMJoint("PelvisCenter", MJointType.PelvisCentre, MVector3(0, 0, 0), identityQ, None, defaultRootChannels), NewMJoint("S1L5Joint", MJointType.S1L5Joint, MVector3(0, 0.18, 0), identityQ, "PelvisCenter", defaultRootChannels), NewMJoint("T12L1Joint", MJointType.T12L1Joint, MVector3(0, 0.15, 0), identityQ, "S1L5Joint", defaultRootChannels), NewMJoint("T1T2Joint", MJointType.T1T2Joint, MVector3(0, 0.43, 0), identityQ, "T12L1Joint", defaultRootChannels), NewMJoint("C4C5Joint", MJointType.C4C5Joint, MVector3(0, 0.11, 0), identityQ, "T1T2Joint", defaultRootChannels), NewMJoint("HeadJoint", MJointType.HeadJoint, MVector3(0, 0.13, 0), identityQ, "C4C5Joint", defaultJointChannels), NewMJoint("HeadTip", MJointType.HeadTip, MVector3(0, 0.16, 0), identityQ, "HeadJoint", zeroChannels), # Left Arm: 3 joints (3 animated, 15 channels)
def Clone(vector: MVector3): if not vector is None: return MVector3(vector.X, vector.Y, vector.Z) else: return None
def Divide(vector: MVector3, scalar): return MVector3(vector.X / scalar, vector.Y / scalar, vector.Z / scalar)
def Add(v1: MVector3, v2: MVector3): return MVector3(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z)
def Subtract(v1: MVector3, v2: MVector3): return MVector3(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z)
def Multiply(vector: MVector3, scalar): return MVector3(vector.X * scalar, vector.Y * scalar, vector.Z * scalar)
def ToMVector3(values): return MVector3(values[0], values[1], values[2])
def ArrayToMVector3(a): vec = MVector3(-a[0], a[1], a[2]) return vec