def getTransposedVector(v, position0, position1, inverse=False): v0 = XSIMath.CreateVector3() v0.Sub(position0[1], position0[0]) v0.NormalizeInPlace() v1 = XSIMath.CreateVector3() v1.Sub(position1[1], position1[0]) v1.NormalizeInPlace() ra = v0.Angle(v1) if inverse: ra = -ra axis = XSIMath.CreateVector3() #axis.Cross(v, v0) axis.Cross(v0, v1) r = XSIMath.CreateRotation() r.SetFromAxisAngle(axis, ra) vector = XSIMath.CreateVector3() vector.MulByRotation(v, r) # Check if the rotation has been set in the right order ra2 = (math.pi * .5) - v1.Angle(vector) r.SetFromAxisAngle(axis, -ra2) vector.MulByRotationInPlace(r) return vector
def addObjects(self): self.root = self.addRoot() self.locs = self.addLocMulti("#_loc", self.root) centers = [self.root] centers.extend(self.locs) self.dispcrv = self.addDispCurve("crv", centers) # Heel and pivots vHeel = XSIMath.CreateVector3(self.root.Kinematics.Global.PosX.Value, 0, self.root.Kinematics.Global.PosZ.Value) vLeftPivot = XSIMath.CreateVector3( self.root.Kinematics.Global.PosX.Value + .3, 0, self.root.Kinematics.Global.PosZ.Value) vRightPivot = XSIMath.CreateVector3( self.root.Kinematics.Global.PosX.Value - .3, 0, self.root.Kinematics.Global.PosZ.Value) self.heel = self.addLoc("heel", self.root, vHeel) self.outpivot = self.addLoc("outpivot", self.root, vLeftPivot) self.inpivot = self.addLoc("inpivot", self.root, vRightPivot) self.dispcrv = self.addDispCurve( "1", [self.root, self.heel, self.outpivot, self.heel, self.inpivot])
def getClosestGlobalTransform(position, crv, subcurve=0, tan_axis="x", upv_axis="y", normal=XSIMath.CreateVector3(0, 1, 0)): crv_geo = crv.ActivePrimitive.Geometry crv_sub = crv_geo.Curves(subcurve) crv_tra = crv.Kinematics.Global.Transform pos = XSIMath.MapWorldPositionToObjectSpace(crv_tra, position) rtn = crv_geo.GetClosestCurvePosition2(pos) u = rtn[2] pos = rtn[3] pos = XSIMath.MapObjectPositionToWorldSpace(crv_tra, pos) tan = crv_sub.EvaluatePosition(u)[1] r = crv_tra.Rotation r.InvertInPlace() tan.MulByRotationInPlace(r) tan.AddInPlace(pos) t = tra.getTransformLookingAt(pos, tan, normal, tan_axis + upv_axis, False) return t
def switchToFk(self): # Match Rotation tra.matchGlobalTransform(self.fk0, self.jnt0, False, True, True) tra.matchGlobalTransform(self.fk1, self.jnt1, False, True, True) # Scale self.scale.Value = (self.length0 + self.length1) / self.rest # Switch to FK self.blend.Value = 0 if self.isleg: x = XSIMath.CreateVector3(0, 0, 1) y = XSIMath.CreateVector3(0, 1, 0) if self.negate: x.NegateInPlace() y.NegateInPlace() x.MulByRotationInPlace( self.ik.Kinematics.Global.Transform.Rotation) y.MulByRotationInPlace( self.ik.Kinematics.Global.Transform.Rotation) t = self.ik.Kinematics.Global.Transform t.SetRotation(tra.getRotationFromAxis(x, y, "xy")) self.fk2.Kinematics.Global.Transform = t else: tra.matchGlobalTransform(self.fk2, self.ik, False, True, True)
def addNullFromPos(parent, name, position=XSIMath.CreateVector3(), size=1, color=[0,0,0]): t = XSIMath.CreateTransform() t.SetTranslation(position) null = addNull(parent, name, t, size, color) return null
def addBoneFromPos(parent, name, position=XSIMath.CreateVector3(), length=1): t = XSIMath.CreateTransform() t.SetTranslation(position) bone = addBone(parent, name, t, length) return bone
def alignRootToFirstBone(xChain): t = XSIMath.CreateTransform() t.SetTranslation(xChain.root.Kinematics.Global.Transform.Translation) t.SetRotation(xChain.bones[0].Kinematics.Global.Transform.Rotation) xChain.root.Kinematics.Global.Transform = t t = XSIMath.CreateTransform() xChain.bones[0].Kinematics.Local.Transform = t
def getClosestGlobalPosition(position, crv, subcurve=0): crv_geo = crv.ActivePrimitive.Geometry crv_sub = crv_geo.Curves(subcurve) crv_tra = crv.Kinematics.Global.Transform pos = XSIMath.MapWorldPositionToObjectSpace(crv_tra, position) pos = crv_geo.GetClosestCurvePosition2(pos)[3] pos = XSIMath.MapObjectPositionToWorldSpace(crv_tra, pos) return pos
def __init__(self, t=XSIMath.CreateTransform()): self.transform = t self.x = XSIMath.CreateVector3(1, 0, 0) self.y = XSIMath.CreateVector3(0, 1, 0) self.z = XSIMath.CreateVector3(0, 0, 1) self.x.MulByRotationInPlace(t.Rotation) self.y.MulByRotationInPlace(t.Rotation) self.z.MulByRotationInPlace(t.Rotation)
def getTransformLookingAt(position, lookat, normal, axis="xy", negate=False): a = XSIMath.CreateVector3() a.Sub(lookat, position) r = getRotationFromAxis(a, normal, axis, negate) t = XSIMath.CreateTransform() t.SetTranslation(position) t.SetRotation(r) return t
def getPlaneBiNormal(v0, v1, v2): normal = getPlaneNormal(v0, v1, v2) vector0 = XSIMath.CreateVector3() vector0.Sub(v1, v0) biNormal = XSIMath.CreateVector3() biNormal.Cross(normal, vector0) biNormal.NormalizeInPlace() return biNormal
def getDistanceToAxe(pos, axe_pos0, axe_pos1): axe = XSIMath.CreateVector3() axe.Sub(axe_pos1, axe_pos0) hyp = XSIMath.CreateVector3() hyp.Sub(pos, axe_pos0) a = axe.Angle(hyp) distance = trigo_adj(hyp.Length(), a) return distance
def getOrthocentreDistances(v0, v1, v2): axe = XSIMath.CreateVector3() axe.Sub(v2, v0) hyp = XSIMath.CreateVector3() hyp.Sub(v1, v0) a = axe.Angle(hyp) distanceA = trigo_opp(hyp.Length(), a) distanceB = axe.Length() - distanceA return distanceA, distanceB
def logMatrix4AsSRT(m, msg="matrix4"): t = XSIMath.CreateTransform() t.SetMatrix4(m) vScl = t.Scaling vRot = t.Rotation.XYZAngles vRot.Set(XSIMath.RadiansToDegrees(vRot.X), XSIMath.RadiansToDegrees(vRot.Y), XSIMath.RadiansToDegrees(vRot.Z)) vPos = t.Translation logVector(vScl, msg + " S") logVector(vRot, msg + " R") logVector(vPos, msg + " T")
def getBladeBiNormalFromXml(xml_def): xNurbsCurveList = xsixmldom.NurbsCurveList(xml_def) t = xNurbsCurveList.globalTransform p = xNurbsCurveList.getPointArray() points = [] for i in range(3): v = XSIMath.CreateVector3(p[i * 3 + 0], p[i * 3 + 1], p[i * 3 + 2]) points.append(XSIMath.MapObjectPositionToWorldSpace(t, v)) normal = getPlaneBiNormal(points[0], points[1], points[2]) return normal
def addCubeChain(parent, name, positions, normal, negate=False, size=1, color=[0,0,0]): # Name if "#" in name: name = name.replace("#", "%s") else: name += "%s" # Draw bones = [] for i in range(len(positions)-1): v0 = positions[i-1] v1 = positions[i] v2 = positions[i+1] # Normal Offset if i > 0: normal = vec.getTransposedVector(normal, [v0, v1], [v1, v2]) t = tra.getTransformLookingAt(v1, v2, normal, "xy", negate) # Cube Offset d = vec.getDistance(v1, v2) offset = XSIMath.CreateVector3(d*.5, 0, 0) if negate: offset.NegateInPlace() # Draw bone = icon.cube(parent, name%i, d, size, size, color, t, offset) bones.append(bone) parent = bone return bones
def logMatrix3AsAngles(m, msg="matrix3"): r = XSIMath.CreateRotation() r.SetFromMatrix3(m) v = r.XYZAngles logVector(v, msg)
def pickPositionMulti(message="Pick position", logWarning=True, minimum=1, maximum=-1): pickedPositions = [] while True: rtn = xsi.PickPosition(message, message) if not rtn.Value("ButtonPressed"): break v = XSIMath.CreateVector3(rtn("PosX"), rtn("PosY"), rtn("PosZ")) pickedPositions.append(v) if addHelpers: null = pri.addNullFromPos(xsi.ActiveSceneRoot, "temp_0", v) pri.setNullDisplay(null, 1, .5, 2, 0, 0, 0, .5, .5, .5, [0, 1, 0]) helpers.Add(null) if maximum > 0 and len(pickedPositions) >= maximum: break if len(pickedPositions) < minimum: if logWarning: xsi.LogMessage("Pick Session Aborded", c.siWarning) return False return pickedPositions
def draw(self, parent=None): # Initial hierarchy if parent is None: self.initialHierarchy() parent = self.model # Controlers for name, controler in self.controlers.items(): obj = controler.create(self.controlers_org, name, XSIMath.CreateTransform(), [.25, .35, .25]) self.controlers_grp.AddMember(obj) # Components for name in self.componentsIndex: comp_guide = self.components[name] if comp_guide.parentComponent is None: parent = self.model else: parent = self.model.FindChild( comp_guide.parentComponent.getName( comp_guide.parentLocalName)) if not parent: gear.log( "Unable to find parent (%s.%s) for guide %s" % (comp_guide.parentComponent.getFullName, comp_guide.parentLocalName, comp_guide.getFullName)) parent = self.model comp_guide.drawFromXml(parent)
def getNegatedTransform(t, axis="xy"): m = t.Matrix4 if axis == "yz": m.Set(m.Value(0, 0), m.Value(0, 1), m.Value(0, 2), m.Value(0, 3), -m.Value(1, 0), -m.Value(1, 1), -m.Value(1, 2), m.Value(1, 3), -m.Value(2, 0), -m.Value(2, 1), -m.Value(2, 2), m.Value(2, 3), m.Value(3, 0), m.Value(3, 1), m.Value(3, 2), m.Value(3, 3)) elif axis == "xy": m.Set(-m.Value(0, 0), -m.Value(0, 1), -m.Value(0, 2), m.Value(0, 3), -m.Value(1, 0), -m.Value(1, 1), -m.Value(1, 2), m.Value(1, 3), m.Value(2, 0), m.Value(2, 1), m.Value(2, 2), m.Value(2, 3), m.Value(3, 0), m.Value(3, 1), m.Value(3, 2), m.Value(3, 3)) elif axis == "zx": m.Set(-m.Value(0, 0), -m.Value(0, 1), -m.Value(0, 2), m.Value(0, 3), m.Value(1, 0), m.Value(1, 1), m.Value(1, 2), m.Value(1, 3), -m.Value(2, 0), -m.Value(2, 1), -m.Value(2, 2), m.Value(2, 3), m.Value(3, 0), m.Value(3, 1), m.Value(3, 2), m.Value(3, 3)) t = XSIMath.CreateTransform() t.Matrix4 = m return t
def addOptionsValues(self): # Convert color sliders to list for s in ["R_", "L_", "C_"]: self.values[s + "color_fk"] = [ self.values[s + "color_fk_r"], self.values[s + "color_fk_g"], self.values[s + "color_fk_b"] ] self.values[s + "color_ik"] = [ self.values[s + "color_ik_r"], self.values[s + "color_ik_g"], self.values[s + "color_ik_b"] ] # When not wip, some options are forced if self.values["mode"] == 0: self.values["setHidden"] = True self.values["setUnselectable"] = True self.values["setDeformers"] = True self.values["setGeometries"] = True self.values["popUpControls"] = False self.values["isolateResult"] = False # Get rig size to adapt size of object to the scale of the character maximum = 1 v = XSIMath.CreateVector3() for comp in self.components.values(): for pos in comp.apos: d = vec.getDistance(v, pos) maximum = max(d, maximum) self.values["size"] = max(maximum * .05, .1)
def getPlaneNormal(v0, v1, v2): vector0 = XSIMath.CreateVector3() vector1 = XSIMath.CreateVector3() vector0.Sub(v1, v0) vector1.Sub(v2, v0) vector0.NormalizeInPlace() vector1.NormalizeInPlace() normal = XSIMath.CreateVector3() normal.Cross(vector1, vector0) normal.NormalizeInPlace() return normal
def linearlyInterpolate(v0, v1, blend=.5): vector = XSIMath.CreateVector3() vector.Sub(v1, v0) vector.ScaleInPlace(blend) vector.AddInPlace(v0) return vector
def getOrthocentre(v0, v1, v2): axe = XSIMath.CreateVector3() axe.Sub(v2, v0) hyp = XSIMath.CreateVector3() hyp.Sub(v1, v0) a = axe.Angle(hyp) distance = trigo_opp(hyp.Length(), a) axe.NormalizeInPlace() axe.ScaleInPlace(distance) axe.AddInPlace(v0) return axe
def addImplicite(parent, preset, name, t=XSIMath.CreateTransform(), size=1): implicite = parent.AddPrimitive(preset, name) implicite.Parameters("length").Value = max(size, .01) implicite.Kinematics.Global.Transform = t return implicite
def gear_SmoothShapeOp_Update(ctxt): # Inputs ----------------------------------------------- shape = ctxt.GetInputValue(0, 0, 0) geo = ctxt.GetInputValue(1, 0, 0).Geometry cls = ctxt.GetInputValue(2, 0, 0) neighbor_depth = ctxt.GetParameterValue("NeighbourDepth") blend = ctxt.GetParameterValue("Blend") # Process ---------------------------------------------- shape_tuple = shape.Elements.Array shape_array = [ shape_tuple[j][i] for i in range(len(shape_tuple[0])) for j in range(len(shape_tuple)) ] points = cls.Elements.Array vSmoothShape = XSIMath.CreateVector3() vOriShape = XSIMath.CreateVector3() for i in points: vertex = geo.Vertices(i) cNghbVertices = vertex.NeighborVertices(neighbor_depth) vSmoothShape.Set(0, 0, 0) vOriShape.Set(shape_array[i * 3 + 0], shape_array[i * 3 + 1], shape_array[i * 3 + 2]) for oVtx in cNghbVertices: index = oVtx.Index vSmoothShape.X += shape_array[index * 3 + 0] vSmoothShape.Y += shape_array[index * 3 + 1] vSmoothShape.Z += shape_array[index * 3 + 2] vSmoothShape.ScaleInPlace(blend / cNghbVertices.Count) vOriShape.ScaleInPlace(1 - blend) shape_array[i * 3 + 0] = vSmoothShape.X + vOriShape.X shape_array[i * 3 + 1] = vSmoothShape.Y + vOriShape.Y shape_array[i * 3 + 2] = vSmoothShape.Z + vOriShape.Z # Output ----------------------------------------------- Out = ctxt.OutputTarget Out.Elements.Array = shape_array
def lipVector(X, Y, Z, vectorMultiply): x = X * vectorMultiply y = Y * vectorMultiply z = Z * vectorMultiply vLip = XSIMath.CreateVector3( self.tongueT.Kinematics.Global.PosX.Value + x, self.tongueT.Kinematics.Global.PosY.Value + y, self.tongueT.Kinematics.Global.PosZ.Value + z) return vLip
def getGlobalPointPosition(index, crv): crv_geo = crv.ActivePrimitive.Geometry crv_tra = crv.Kinematics.Global.Transform pos = XSIMath.MapObjectPositionToWorldSpace(crv_tra, crv_geo.Points(index).Position) return pos
def rotateVectorAlongAxis(v, axis, a=0): # Angle as to be in radians sa = math.sin(a / 2.0) ca = math.cos(a / 2.0) q1 = XSIMath.CreateQuaternion(0, v.X, v.Y, v.Z) q2 = XSIMath.CreateQuaternion(ca, axis.X * sa, axis.Y * sa, axis.Z * sa) q2n = XSIMath.CreateQuaternion(ca, -axis.X * sa, -axis.Y * sa, -axis.Z * sa) q = XSIMath.CreateQuaternion() q.Mul(q2, q1) q.MulInPlace(q2n) vector = XSIMath.CreateVector3(q.X, q.Y, q.Z) return vector
def addNull(parent, name, t=XSIMath.CreateTransform(), size=1, color=[0,0,0]): null = parent.AddNull(name) null.Parameters("Size").Value = max(size, .01) null.Kinematics.Global.Transform = t uti.setColor(null, color) return null