public static MDagPath CreateJoint(string jtName) { MFnIkJoint joint = new MFnIkJoint(); MObject jtObject = joint.create(); return(MDagPath.getAPathTo(jtObject)); }
private static string GetParentName(MFnIkJoint Joint) { // Attempt to result var FullPath = Joint.fullPathName; var SplitPath = FullPath.Substring(1).Split('|'); if (SplitPath.Length > 2) { // We have parents, fetch second to last return(CleanNodeName(SplitPath[SplitPath.Length - 2])); } else if (SplitPath.Length == 2) { // We have parents, ensure this is a joint parent var SelectList = new MSelectionList(); SelectList.add(FullPath.Substring(0, FullPath.IndexOf("|", 1))); // Grab it var Result = new MDagPath(); SelectList.getDagPath(0, Result); // Check if (Result.hasFn(MFn.Type.kJoint)) { return(CleanNodeName(SplitPath[SplitPath.Length - 2])); } } // Root bone return(string.Empty); }
public static MDagPath CreateJoint(MVector worldPos, string jtName) { MDagPath jointDagPath = CreateJoint(jtName); MFnIkJoint joint = new MFnIkJoint(jointDagPath); joint.setTranslation(worldPos, MSpace.Space.kWorld); return(jointDagPath); }
public static void BindBodySplineIK(MSelectionList jointList = null) { if (jointList == null) { jointList = BasicFunc.GetSelectedList(); } //check if all of selected objects are joint int count = (int)jointList.length; if (count < 2) { return; } MDagPath dag_breastJoint = new MDagPath(), dag_hipJoint = new MDagPath(); for (int i = 0; i < count; i++) { MDagPath jtDagPath = new MDagPath(); jointList.getDagPath((uint)i, jtDagPath); if (jtDagPath != null) { if (!jtDagPath.hasFn(MFn.Type.kJoint)) { return; } } else { return; } } jointList.getDagPath((uint)(count - 1), dag_breastJoint); jointList.getDagPath(0, dag_hipJoint); MFnIkJoint breastJoint = new MFnIkJoint(dag_breastJoint); MFnIkJoint hipJoint = new MFnIkJoint(dag_hipJoint); MDagPath dag_curve = JointProcess.CreateJointsCurve(jointList); MDagPath dag_jtctl_breast = JointProcess.CreateJoint(breastJoint, "jtctl_breast"); MDagPath dag_jtctl_hip = JointProcess.CreateJoint(hipJoint, "jtctl_hip"); MSelectionList bindSelectionList = new MSelectionList(); bindSelectionList.add(dag_curve); bindSelectionList.add(dag_jtctl_breast); bindSelectionList.add(dag_jtctl_hip); BasicFunc.Select(bindSelectionList); MGlobal.executeCommand("SmoothBindSkin"); string ikName = JointProcess.AddIKHandle(dag_hipJoint, dag_breastJoint, JointProcess.IKSolverType.Spline, dag_curve.fullPathName)[0]; MDagPath dag_ik = BasicFunc.GetDagPathByName(ikName); BasicFunc.ConnectAttr(dag_jtctl_breast.fullPathName + ".rotate.rotateY", dag_ik.fullPathName + ".twist", true, true); }
public void Create() { MItDag jointIterator = new MItDag(MItDag.TraversalType.kDepthFirst, MFn.Type.kJoint); //Create Joints and collect their DAG Paths short jointID = 0; for (; !jointIterator.isDone; jointIterator.next()) { MFnIkJoint ikJoint = new MFnIkJoint(); MDagPath jointDagPath = new MDagPath(); jointIterator.getPath(jointDagPath); this.JointDagPaths.Add(jointDagPath); ikJoint.setObject(jointDagPath); MTransformationMatrix local = new MTransformationMatrix(ikJoint.transformationMatrix); MTransformationMatrix inverseGlobal = new MTransformationMatrix(jointDagPath.inclusiveMatrixInverse); this.Joints.Add(new SKLJoint(jointID, ikJoint.name, local, inverseGlobal)); this.JointIndices.Add(ELF.Hash(ikJoint.name), jointID); jointID++; } //Set Joint parents for (int i = 0; i < this.Joints.Count; i++) { MFnIkJoint ikJoint = new MFnIkJoint(this.JointDagPaths[i]); if (ikJoint.parentCount == 1 && ikJoint.parent(0).apiType == MFn.Type.kJoint) { MFnIkJoint parentJoint = new MFnIkJoint(ikJoint.parent(0)); MDagPath parentDagPath = new MDagPath(); parentJoint.getPath(parentDagPath); //Find index of parent for (int j = 0; j < this.JointDagPaths.Count; j++) { if (parentDagPath.equalEqual(this.JointDagPaths[j])) { this.Joints[i].ParentID = (short)j; } } } else { this.Joints[i].ParentID = -1; } } MGlobal.displayInfo("SKLFile:Create - Created SKL File"); }
public static MDagPath AddRPIKPole(MDagPath middleDagPath = null) { if (middleDagPath == null) { middleDagPath = BasicFunc.GetSelectedDagPath(0); if (middleDagPath == null) { Debug.Log("please select middle joint"); return(null); } } MDagPath rootDagPath = new MDagPath(), endDagPath = new MDagPath(); MFnIkJoint middleJoint = new MFnIkJoint(middleDagPath); if (middleJoint.parentCount > 0) { MDagPath.getAPathTo(middleJoint.parent(0), rootDagPath); MFnIkJoint rootJoint = new MFnIkJoint(rootDagPath); if (middleJoint.childCount > 0) { MDagPath.getAPathTo(middleJoint.child(0), endDagPath); MFnIkJoint endJoint = new MFnIkJoint(endDagPath); MVector rootPos = rootJoint.getTranslation(MSpace.Space.kWorld); MVector middlePos = middleJoint.getTranslation(MSpace.Space.kWorld); MVector endPos = endJoint.getTranslation(MSpace.Space.kWorld); //double len0 = (middlePos - rootPos).length; //double len1 = (endPos - middlePos).length; MVector fitLinePos = (rootPos + endPos) * 0.5; MVector direct_pole = middlePos - fitLinePos; MVector direct_fitLine = rootPos - endPos; MVector direct_projectPolePos = BasicFunc.VerticalProject(direct_pole, direct_fitLine).normal; //MVector nmPos = (rootPos * len0 + endPos * len1) * (1 / (len0 + len1)); float factor = (float)((rootPos - endPos).length / 3); MVector polePos = factor * direct_projectPolePos + middlePos; string locName = "loc_" + rootJoint.name + "_" + endJoint.name; return(BasicFunc.CreateLocator(polePos, locName)); } } return(null); }
public void Load() { for (int i = 0; i < this.Joints.Count; i++) { MFnIkJoint ikJoint = new MFnIkJoint(); SKLJoint joint = this.Joints[i]; ikJoint.create(); MDagPath jointDagPath = new MDagPath(); ikJoint.getPath(jointDagPath); this.JointDagPaths.append(jointDagPath); ikJoint.set(joint.IsLegacy ? joint.Global : joint.Local); ikJoint.setName(joint.Name); } for (int i = 0; i < this.Joints.Count; i++) { SKLJoint joint = this.Joints[i]; if (joint.ParentID == i) { MGlobal.displayWarning(string.Format("SKLFile:Load - {0} has invalid Parent ID: {1}", joint.Name, joint.ParentID)); } else if (joint.ParentID != -1) //Don't need to set up ROOT { MFnIkJoint ikParentJoint = new MFnIkJoint(this.JointDagPaths[joint.ParentID]); MFnIkJoint ikChildJoint = new MFnIkJoint(this.JointDagPaths[i]); ikParentJoint.addChild(ikChildJoint.objectProperty); if (this.IsLegacy) { MVector position = ikChildJoint.getTranslation(MSpace.Space.kTransform); MQuaternion rotation = new MQuaternion(); ikChildJoint.getRotation(rotation, MSpace.Space.kWorld); ikChildJoint.setTranslation(position, MSpace.Space.kWorld); ikChildJoint.setRotation(rotation, MSpace.Space.kWorld); } } } }
public static bool BindFinger(MDagPath rootJointDagPath, string fingerTag, bool useIK = false) { MFnIkJoint rootJoint = new MFnIkJoint(rootJointDagPath); if (rootJoint.childCount > 0) { MObject middleJointObject = rootJoint.child(0); MDagPath middleJointDagPath = MDagPath.getAPathTo(middleJointObject); MFnIkJoint middleJoint = new MFnIkJoint(middleJointObject); if (middleJoint.childCount > 0) { MObject finalJointObject = middleJoint.child(0); MDagPath finalJointDagPath = MDagPath.getAPathTo(finalJointObject); //MFnIkJoint finalJoint(finalJointObject); //enough, start control return(BindFinger(rootJointDagPath, middleJointDagPath, finalJointDagPath, fingerTag, useIK)); } } return(true); }
private void UpdateJoints(object sender, RoutedEventArgs e) { if (joints == null && joints.Count < 2) { return; } MFnIkJoint lastJoint = joints[joints.Count - 1]; MVector lastJointWorldPos = lastJoint.getTranslation(MSpace.Space.kWorld); MVector firstJointWorldPos = joints[0].getTranslation(MSpace.Space.kWorld); MVector direct = lastJointWorldPos - firstJointWorldPos; for (int i = 1; i < joints.Count - 1; i++) { if (i >= sliders.Count || sliders[i] == null) { continue; } double percent = sliders[i].Value; JointProcess.MoveSkinJointsTool(joints[i].dagPath); joints[i].setTranslation(direct * percent + firstJointWorldPos, MSpace.Space.kWorld); } JointProcess.MoveSkinJointsTool(lastJoint.dagPath); lastJoint.setTranslation(lastJointWorldPos, MSpace.Space.kWorld); }
public static MDagPath CreateJoint(MFnIkJoint targetPosJoint, string jtName) { MVector worldPos = targetPosJoint.getTranslation(MSpace.Space.kWorld); return(CreateJoint(worldPos, jtName)); }
public static void ExportXAnim(string FilePath, XAnimType FileType, bool Grab = true, bool ExportTagAlign = false) { // Configure scene using (var MayaCfg = new MayaSceneConfigure()) { // First, get the current selection var ExportObjectList = new MSelectionList(); MGlobal.getActiveSelectionList(ExportObjectList); // If empty, select all joints if (ExportObjectList.DependNodes(MFn.Type.kJoint).Count() == 0) { // Select all joints MGlobal.executeCommand("string $selected[] = `ls -type joint`; select -r $selected;"); // Get it again MGlobal.getActiveSelectionList(ExportObjectList); } // If still empty, error blank scene if (ExportObjectList.DependNodes(MFn.Type.kJoint).Count() == 0) { MGlobal.displayError("[CODTools] The current scene has no joints..."); return; } // Progress MayaCfg.StartProgress("Exporting XAnim...", ((int)ExportObjectList.length + Math.Max((MayaCfg.SceneEnd - MayaCfg.SceneStart) + 1, 1))); // Create new anim var Result = new XAnim(System.IO.Path.GetFileNameWithoutExtension(FilePath)); // Metadata var SceneName = string.Empty; MGlobal.executeCommand("file -q -sceneName", out SceneName); Result.Comments.Add(string.Format("Export filename: '{0}'", FilePath)); Result.Comments.Add(string.Format("Source filename: '{0}'", SceneName)); Result.Comments.Add(string.Format("Export time: {0}", DateTime.Now.ToString())); // Iterate and add joints var UniqueBones = new HashSet <string>(); var JointControllers = new List <MFnIkJoint>(); foreach (var Joint in ExportObjectList.DependNodes(MFn.Type.kJoint)) { // Step MayaCfg.StepProgress(); // Grab the controller var Path = CODXModel.GetObjectDagPath(Joint); var Controller = new MFnIkJoint(Path); // Create a new bone var TagName = CODXModel.CleanNodeName(Controller.name); if (UniqueBones.Contains(TagName)) { continue; } UniqueBones.Add(TagName); // Add to the controller list JointControllers.Add(Controller); // Add to the part list Result.Parts.Add(new Part(TagName)); } // Add TAG_ALIGN if (ExportTagAlign) { Result.Parts.Add(new Part("TAG_ALIGN")); } // Iterate over the frame range, then generate part frames for (int i = MayaCfg.SceneStart; i < (MayaCfg.SceneEnd + 1); i++) { // Step and set time MayaCfg.StepProgress(); MayaCfg.SetTime(i); // Iterate over the parts for this time for (int p = 0; p < JointControllers.Count; p++) { // Make new frame var NewFrame = new PartFrame(); // Fetch the world-space position and rotation var WorldPosition = JointControllers[p].getTranslation(MSpace.Space.kWorld); var WorldRotation = new MQuaternion(MQuaternion.identity); JointControllers[p].getRotation(WorldRotation, MSpace.Space.kWorld); // Create the matrix NewFrame.Offset = WorldPosition * (1 / 2.54); NewFrame.RotationMatrix = WorldRotation.asMatrix; // Add it Result.Parts[p].Frames.Add(NewFrame); } // Add TAG_ALIGN if (ExportTagAlign) { var NewFrame = new PartFrame(); NewFrame.Offset = new MVector(0, 0, 0); NewFrame.RotationMatrix = new MMatrix(); Result.Parts[JointControllers.Count].Frames.Add(NewFrame); } } // Reset time MayaCfg.SetTime(MayaCfg.SceneStart); // Grab XAnim notetracks if (Grab) { LoadNotetracks(ref Result); } // Write switch (FileType) { case XAnimType.Export: Result.WriteExport(FilePath); break; case XAnimType.Bin: Result.WriteBin(FilePath); break; case XAnimType.SiegeAnimSource: Result.WriteSiegeSource(FilePath); break; } } // Log complete MGlobal.displayInfo(string.Format("[CODTools] Exported {0}", System.IO.Path.GetFileName(FilePath))); }
public static void ExportXModel(string FilePath, XModelType FileType, bool Siege = false, string Cosmetic = "") { // Configure scene using (var MayaCfg = new MayaSceneConfigure()) { // First, get the current selection var ExportObjectList = new MSelectionList(); MGlobal.getActiveSelectionList(ExportObjectList); // If empty, select all joints and meshes if (ExportObjectList.length == 0) { // Select all joints and meshes MGlobal.executeCommand("string $selected[] = `ls -type joint`; select -r $selected;"); MGlobal.executeCommand("string $transforms[] = `ls -tr`;string $polyMeshes[] = `filterExpand -sm 12 $transforms`;select -add $polyMeshes;"); // Get it again MGlobal.getActiveSelectionList(ExportObjectList); } // If still empty, error blank scene if (ExportObjectList.length == 0) { MGlobal.displayError("[CODTools] The current scene is empty..."); return; } // Progress MayaCfg.StartProgress("Exporting XModel...", (int)ExportObjectList.length); // Create new model var Result = new XModel(System.IO.Path.GetFileNameWithoutExtension(FilePath)); // Assign siege model flag (Default: false) Result.SiegeModel = Siege; // Metadata var SceneName = string.Empty; MGlobal.executeCommand("file -q -sceneName", out SceneName); Result.Comments.Add(string.Format("Export filename: '{0}'", FilePath)); Result.Comments.Add(string.Format("Source filename: '{0}'", SceneName)); Result.Comments.Add(string.Format("Export time: {0}", DateTime.Now.ToString())); // Iterate and add joints var ParentStack = new List <string>(); var UniqueBones = new HashSet <string>(); foreach (var Joint in ExportObjectList.DependNodes(MFn.Type.kJoint)) { // Step MayaCfg.StepProgress(); // Grab the controller var Path = GetObjectDagPath(Joint); var Controller = new MFnIkJoint(Path); // Create a new bone var TagName = CleanNodeName(Controller.name); if (UniqueBones.Contains(TagName)) { continue; } UniqueBones.Add(TagName); var NewBone = new Bone(TagName); // Add parent ParentStack.Add(GetParentName(Controller)); // Fetch the world-space position and rotation var WorldPosition = Controller.getTranslation(MSpace.Space.kWorld); var WorldRotation = new MQuaternion(MQuaternion.identity); Controller.getRotation(WorldRotation, MSpace.Space.kWorld); var WorldScale = new double[3] { 1, 1, 1 }; Controller.getScale(WorldScale); // Create the matrix NewBone.Translation = WorldPosition * (1 / 2.54); NewBone.Scale = new MVector(WorldScale[0], WorldScale[1], WorldScale[2]); NewBone.RotationMatrix = WorldRotation.asMatrix; // Add it Result.Bones.Add(NewBone); } // Sort joints SortJoints(ref Result, ParentStack, Cosmetic); // Pre-fetch skins var SkinClusters = GetSkinClusters(); var BoneMapping = Result.GetBoneMapping(); // A list of used materials int MaterialIndex = 0; var UsedMaterials = new Dictionary <string, int>(); var UsedMeshes = new HashSet <string>(); // Iterate and add meshes foreach (var Mesh in ExportObjectList.DependNodes(MFn.Type.kMesh)) { // Step MayaCfg.StepProgress(); // Grab the controller var Path = GetObjectDagPath(Mesh); Path.extendToShape(); var Controller = new MFnMesh(Path); // Ignore duplicates if (UsedMeshes.Contains(Path.partialPathName)) { continue; } UsedMeshes.Add(Path.partialPathName); // Pre-fetch materials var MeshMaterials = GetMaterialsMesh(ref Controller, ref Path); foreach (var Mat in MeshMaterials) { if (!UsedMaterials.ContainsKey(Mat.Name)) { UsedMaterials.Add(Mat.Name, MaterialIndex++); Result.Materials.Add(Mat); } } // New mesh var NewMesh = new Mesh(); // Grab iterators var VertexIterator = new MItMeshVertex(Path); var FaceIterator = new MItMeshPolygon(Path); // Get the cluster for this var SkinCluster = FindSkinCluster(ref SkinClusters, Controller); var SkinJoints = new MDagPathArray(); if (SkinCluster != null) { SkinCluster.influenceObjects(SkinJoints); } // Build vertex array for (; !VertexIterator.isDone; VertexIterator.next()) { // Prepare var NewVert = new Vertex(); // Grab data NewVert.Position = VertexIterator.position(MSpace.Space.kWorld) * (1 / 2.54); // Weights if valid if (SkinCluster != null) { var WeightValues = new MDoubleArray(); uint Influence = 0; SkinCluster.getWeights(Path, VertexIterator.currentItem(), WeightValues, ref Influence); for (int i = 0; i < (int)WeightValues.length; i++) { if (WeightValues[i] < 0.000001) { continue; } var WeightTagName = CleanNodeName(SkinJoints[i].partialPathName); var WeightID = (BoneMapping.ContainsKey(WeightTagName)) ? BoneMapping[WeightTagName] : 0; NewVert.Weights.Add(new Tuple <int, float>(WeightID, (float)WeightValues[i])); } } if (NewVert.Weights.Count == 0) { NewVert.Weights.Add(new Tuple <int, float>(0, 1.0f)); } // Add it NewMesh.Vertices.Add(NewVert); } // Build face array for (; !FaceIterator.isDone; FaceIterator.next()) { var Indices = new MIntArray(); var Normals = new MVectorArray(); var UVUs = new MFloatArray(); var UVVs = new MFloatArray(); FaceIterator.getVertices(Indices); FaceIterator.getNormals(Normals, MSpace.Space.kWorld); FaceIterator.getUVs(UVUs, UVVs); // Only support TRIS/QUAD if (Indices.Count < 3) { continue; } if (Indices.Count == 3) { // Create new face var NewFace = new FaceVertex(); // Setup NewFace.Indices[0] = Indices[0]; NewFace.Indices[2] = Indices[1]; NewFace.Indices[1] = Indices[2]; // Normals NewFace.Normals[0] = new MVector(Normals[0][0], Normals[0][1], Normals[0][2]); NewFace.Normals[2] = new MVector(Normals[1][0], Normals[1][1], Normals[1][2]); NewFace.Normals[1] = new MVector(Normals[2][0], Normals[2][1], Normals[2][2]); // Colors FaceIterator.getColor(NewFace.Colors[0], 0); FaceIterator.getColor(NewFace.Colors[2], 1); FaceIterator.getColor(NewFace.Colors[1], 2); // Append UV Layers NewFace.UVs[0] = new Tuple <float, float>(UVUs[0], 1 - UVVs[0]); NewFace.UVs[2] = new Tuple <float, float>(UVUs[1], 1 - UVVs[1]); NewFace.UVs[1] = new Tuple <float, float>(UVUs[2], 1 - UVVs[2]); // Set material index if (MeshMaterials.Count > 0) { NewFace.MaterialIndex = UsedMaterials[MeshMaterials[0].Name]; } // Add it NewMesh.Faces.Add(NewFace); } else { // Create new faces FaceVertex NewFace = new FaceVertex(), NewFace2 = new FaceVertex(); // Setup NewFace.Indices[0] = Indices[0]; NewFace.Indices[2] = Indices[1]; NewFace.Indices[1] = Indices[2]; NewFace2.Indices[0] = Indices[0]; NewFace2.Indices[2] = Indices[2]; NewFace2.Indices[1] = Indices[3]; // Normals NewFace.Normals[0] = new MVector(Normals[0][0], Normals[0][1], Normals[0][2]); NewFace.Normals[2] = new MVector(Normals[1][0], Normals[1][1], Normals[1][2]); NewFace.Normals[1] = new MVector(Normals[2][0], Normals[2][1], Normals[2][2]); NewFace2.Normals[0] = new MVector(Normals[0][0], Normals[0][1], Normals[0][2]); NewFace2.Normals[2] = new MVector(Normals[2][0], Normals[2][1], Normals[2][2]); NewFace2.Normals[1] = new MVector(Normals[3][0], Normals[3][1], Normals[3][2]); // Colors FaceIterator.getColor(NewFace.Colors[0], 0); FaceIterator.getColor(NewFace.Colors[2], 1); FaceIterator.getColor(NewFace.Colors[1], 2); FaceIterator.getColor(NewFace2.Colors[0], 0); FaceIterator.getColor(NewFace2.Colors[2], 2); FaceIterator.getColor(NewFace2.Colors[1], 3); // Append UV Layers NewFace.UVs[0] = new Tuple <float, float>(UVUs[0], 1 - UVVs[0]); NewFace.UVs[2] = new Tuple <float, float>(UVUs[1], 1 - UVVs[1]); NewFace.UVs[1] = new Tuple <float, float>(UVUs[2], 1 - UVVs[2]); NewFace2.UVs[0] = new Tuple <float, float>(UVUs[0], 1 - UVVs[0]); NewFace2.UVs[2] = new Tuple <float, float>(UVUs[2], 1 - UVVs[2]); NewFace2.UVs[1] = new Tuple <float, float>(UVUs[3], 1 - UVVs[3]); // Set material index if (MeshMaterials.Count > 0) { NewFace.MaterialIndex = UsedMaterials[MeshMaterials[0].Name]; NewFace2.MaterialIndex = UsedMaterials[MeshMaterials[0].Name]; } // Add it NewMesh.Faces.Add(NewFace); NewMesh.Faces.Add(NewFace2); } } // Add it Result.Meshes.Add(NewMesh); } // Write switch (FileType) { case XModelType.Export: Result.WriteExport(FilePath); break; case XModelType.Bin: Result.WriteBin(FilePath); break; } } // Log complete MGlobal.displayInfo(string.Format("[CODTools] Exported {0}", System.IO.Path.GetFileName(FilePath))); }
private static Dictionary <string, MayaM2Bone> ExtractJoints(List <MayaM2Sequence> seqList) { var jointMap = new Dictionary <string, MayaM2Bone>(); //Goal of iteration : Extract raw joint data and store it in intermediate object, MayaM2Bone var processedJoints = new HashSet <string>(); for (var jointIter = new MItDag(MItDag.TraversalType.kDepthFirst, MFn.Type.kJoint); !jointIter.isDone; jointIter.next()) { var jointPath = new MDagPath(); jointIter.getPath(jointPath); if (processedJoints.Contains(jointPath.fullPathName)) { continue; } MGlobal.displayInfo("Extracting raw data of " + jointPath.fullPathName); var joint = new MFnIkJoint(jointPath); var mayaBone = new MayaM2Bone(); jointMap[jointPath.fullPathName] = mayaBone; // Hierarchy var isRoot = joint.parentCount == 0 || !joint.parent(0).hasFn(MFn.Type.kJoint); if (!isRoot) { var parentPath = new MDagPath(); MDagPath.getAPathTo(joint.parent(0), parentPath); if (!jointMap.ContainsKey(parentPath.fullPathName)) { MGlobal.displayError("\tParent is not referenced. Crash incoming. Path : " + parentPath.fullPathName); } jointMap[jointPath.fullPathName].Parent = jointMap[parentPath.fullPathName]; } //Note : M2Bone.submesh_id is wrong in the wiki. Do not try to compute it. // Label jointMap[jointPath.fullPathName].Type = MGlobal.executeCommandStringResult("getAttr -asString " + joint.fullPathName + ".type"); jointMap[jointPath.fullPathName].OtherType = MGlobal.executeCommandStringResult("getAttr -asString " + joint.fullPathName + ".otherType"); jointMap[jointPath.fullPathName].Side = MGlobal.executeCommandStringResult("getAttr -asString " + joint.fullPathName + ".side"); // Base translation is used to compute position MAnimControl.currentTime = 0; jointMap[jointPath.fullPathName].BaseTranslation = joint.getTranslation(MSpace.Space.kTransform); foreach (var seq in seqList) { var transData = new List <Tuple <uint, MVector> >(); var rotData = new List <Tuple <uint, MQuaternion> >(); var scaleData = new List <Tuple <uint, MVector> >(); for (var i = seq.Start; i < seq.End; i += 33) //TODO FIXME What if not multiple of 33 ? { //Get data for this joint for this frame MAnimControl.currentTime = new MTime(i, MTime.Unit.kMilliseconds); var translation = joint.getTranslation(MSpace.Space.kTransform); var rotation = new MQuaternion(); joint.getRotation(rotation, MSpace.Space.kTransform); var scaleArray = new double[3]; joint.getScale(scaleArray); var scale = new MVector(scaleArray); if (!translation.isEquivalent(MVector.zero, Epsilon)) { var previousIsTheSame = transData.Count > 0 && transData.Last().Item2.isEquivalent(translation, Epsilon); if (!previousIsTheSame) { transData.Add(new Tuple <uint, MVector>((uint)(i - seq.Start), translation)); } } if (!rotation.isEquivalent(MQuaternion.identity, Epsilon)) { var previousIsTheSame = rotData.Count > 0 && rotData.Last().Item2.isEquivalent(rotation, Epsilon); if (!previousIsTheSame) { rotData.Add(new Tuple <uint, MQuaternion>((uint)(i - seq.Start), rotation)); } } if (!scale.isEquivalent(MVector.one, Epsilon)) { var previousIsTheSame = scaleData.Count > 0 && scaleData.Last().Item2.isEquivalent(scale, Epsilon); if (!previousIsTheSame) { scaleData.Add(new Tuple <uint, MVector>((uint)(i - seq.Start), scale)); } } } if (transData.Count > 0) { jointMap[joint.fullPathName].Translation.Add(transData); } if (rotData.Count > 0) { jointMap[joint.fullPathName].Rotation.Add(rotData); } if (scaleData.Count > 0) { jointMap[joint.fullPathName].Scale.Add(scaleData); } } processedJoints.Add(jointPath.fullPathName); } //Goal of iteration : apply transformations to joint data & their children processedJoints.Clear(); for (var jointIter = new MItDag(MItDag.TraversalType.kBreadthFirst, MFn.Type.kJoint); !jointIter.isDone; jointIter.next()) { var jointPath = new MDagPath(); jointIter.getPath(jointPath); if (processedJoints.Contains(jointPath.fullPathName)) { continue; } MGlobal.displayInfo("Applying joint orient of " + jointPath.fullPathName); var joint = new MFnIkJoint(jointPath); var jointOrient = new MQuaternion(); joint.getOrientation(jointOrient); for (uint i = 0; i < joint.childCount; i++) { if (!joint.child(i).hasFn(MFn.Type.kJoint)) { continue; } var childFn = new MFnIkJoint(joint.child(i)); MGlobal.displayInfo("\tto " + childFn.fullPathName + ";"); jointMap[childFn.fullPathName].RotateTranslation(jointOrient); } processedJoints.Add(jointPath.fullPathName); } return(jointMap); }
public override void doSolve() { MIkHandleGroup handle_group = handleGroup; if (handle_group == null) { throw new InvalidOperationException("Invalid handle group"); } MObject handle = handle_group.handle(0); MDagPath handlePath = MDagPath.getAPathTo(handle); MFnIkHandle handleFn = new MFnIkHandle(handlePath); //Effector // MDagPath effectorPath = new MDagPath(); handleFn.getEffector(effectorPath); MFnIkEffector effectorFn = new MFnIkEffector(effectorPath); effectorPath.pop(); MFnIkJoint midJoinFn = new MFnIkJoint(effectorPath); // Start Joint // MDagPath startJointPath = new MDagPath(); handleFn.getStartJoint(startJointPath); MFnIkJoint startJointFn = new MFnIkJoint(startJointPath); // Preferred angles // double [] startJointPrefAngle = new double[3]; double[] midJointPrefAngle = new double[3]; startJointFn.getPreferedAngle(startJointPrefAngle); midJoinFn.getPreferedAngle(midJointPrefAngle); // Set to preferred angles // startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder); midJoinFn.setRotation(midJointPrefAngle, midJoinFn.rotationOrder); MPoint handlePos = handleFn.rotatePivot(MSpace.Space.kWorld); AwPoint awHandlePos = new AwPoint(handlePos.x, handlePos.y, handlePos.z, handlePos.w); MPoint effectorPos = effectorFn.rotatePivot(MSpace.Space.kWorld); AwPoint awEffectorPos = new AwPoint(effectorPos.x, effectorPos.y, effectorPos.z, effectorPos.w); MPoint midJoinPos = midJoinFn.rotatePivot(MSpace.Space.kWorld); AwPoint awMidJoinPos = new AwPoint(midJoinPos.x, midJoinPos.y, midJoinPos.z, midJoinPos.w); MPoint startJointPos = startJointFn.rotatePivot(MSpace.Space.kWorld); AwPoint awStartJointPos = new AwPoint(startJointPos.x, startJointPos.y, startJointPos.z, startJointPos.w); AwVector poleVector = poleVectorFromHandle(handlePath); MMatrix m = handlePath.exclusiveMatrix; AwMatrix awM = new AwMatrix(); awM.setMatrix(m); poleVector = poleVector.mulMatrix(awM); double twistValue = twistFromHandle(handlePath); AwQuaternion qStart = new AwQuaternion(); AwQuaternion qMid = new AwQuaternion(); solveIK(awStartJointPos, awMidJoinPos, awEffectorPos, awHandlePos, poleVector, twistValue, qStart, qMid); MQuaternion mid = new MQuaternion(qMid.x, qMid.y, qMid.z, qMid.w); MQuaternion start = new MQuaternion(qStart.x, qStart.y, qStart.z, qStart.w); midJoinFn.rotateBy(mid, MSpace.Space.kWorld); startJointFn.rotateBy(start, MSpace.Space.kWorld); return; }
public override void doSolve() { MIkHandleGroup handle_group = handleGroup; if (handle_group == null) throw new InvalidOperationException("Invalid handle group"); MObject handle = handle_group.handle(0); MDagPath handlePath = MDagPath.getAPathTo(handle); MFnIkHandle handleFn = new MFnIkHandle(handlePath); //Effector // MDagPath effectorPath = new MDagPath(); handleFn.getEffector(effectorPath); MFnIkEffector effectorFn = new MFnIkEffector(effectorPath); effectorPath.pop(); MFnIkJoint midJoinFn = new MFnIkJoint(effectorPath); // Start Joint // MDagPath startJointPath = new MDagPath(); handleFn.getStartJoint(startJointPath); MFnIkJoint startJointFn = new MFnIkJoint(startJointPath); // Preferred angles // double [] startJointPrefAngle = new double[3]; double[] midJointPrefAngle = new double[3]; startJointFn.getPreferedAngle(startJointPrefAngle); midJoinFn.getPreferedAngle(midJointPrefAngle); // Set to preferred angles // startJointFn.setRotation(startJointPrefAngle, startJointFn.rotationOrder); midJoinFn.setRotation(midJointPrefAngle, midJoinFn.rotationOrder); MPoint handlePos = handleFn.rotatePivot(MSpace.Space.kWorld); AwPoint awHandlePos = new AwPoint(handlePos.x, handlePos.y, handlePos.z, handlePos.w); MPoint effectorPos = effectorFn.rotatePivot(MSpace.Space.kWorld); AwPoint awEffectorPos = new AwPoint(effectorPos.x, effectorPos.y, effectorPos.z, effectorPos.w); MPoint midJoinPos = midJoinFn.rotatePivot(MSpace.Space.kWorld); AwPoint awMidJoinPos = new AwPoint(midJoinPos.x, midJoinPos.y, midJoinPos.z, midJoinPos.w); MPoint startJointPos = startJointFn.rotatePivot(MSpace.Space.kWorld); AwPoint awStartJointPos = new AwPoint(startJointPos.x, startJointPos.y, startJointPos.z, startJointPos.w); AwVector poleVector = poleVectorFromHandle(handlePath); MMatrix m = handlePath.exclusiveMatrix; AwMatrix awM = new AwMatrix(); awM.setMatrix(m); poleVector = poleVector.mulMatrix(awM); double twistValue = twistFromHandle(handlePath); AwQuaternion qStart = new AwQuaternion(); AwQuaternion qMid = new AwQuaternion(); solveIK(awStartJointPos, awMidJoinPos, awEffectorPos, awHandlePos, poleVector, twistValue, qStart, qMid); MQuaternion mid = new MQuaternion(qMid.x, qMid.y, qMid.z, qMid.w); MQuaternion start = new MQuaternion(qStart.x, qStart.y, qStart.z, qStart.w); midJoinFn.rotateBy(mid, MSpace.Space.kWorld); startJointFn.rotateBy(start, MSpace.Space.kWorld); return; }
public static MFnIkJoint[] AddReverseFootBone(MDagPath rootDagPath, MDagPath middleDagPath, MDagPath endDagPath) { //啊啊 //*reverseBones = new MDagPath[8]; MFnIkJoint[] result = new MFnIkJoint[8]; MFnIkJoint rootJoint = new MFnIkJoint(); MVector rootPos = new MFnTransform(rootDagPath).getTranslation(MSpace.Space.kWorld); MVector middlePos = new MFnTransform(middleDagPath).getTranslation(MSpace.Space.kWorld); MVector endPos = new MFnTransform(endDagPath).getTranslation(MSpace.Space.kWorld); //Debug.Log("root:" + BasicFunc.ToCMDSParamStr(rootPos) + " middle:" + BasicFunc.ToCMDSParamStr(middlePos) + " end:" + BasicFunc.ToCMDSParamStr(endPos)); MObject jt_ankle_Object = rootJoint.create(); result[0] = new MFnIkJoint(MDagPath.getAPathTo(jt_ankle_Object)); result[0].setTranslation(rootPos, MSpace.Space.kWorld); MObject jt_heel_Object = rootJoint.create(jt_ankle_Object); result[1] = new MFnIkJoint(MDagPath.getAPathTo(jt_heel_Object)); result[1].setTranslation(new MVector(rootPos.x, endPos.y, rootPos.z), MSpace.Space.kWorld); MObject jt_side_Object = rootJoint.create(jt_heel_Object); result[2] = new MFnIkJoint(MDagPath.getAPathTo(jt_side_Object)); MVector footDirect = endPos - middlePos; MVector middleGround = new MVector(middlePos.x, endPos.y, middlePos.z); MVector offset = BasicFunc.Cross(footDirect, new MVector(0, 0.6, 0)); offset *= Math.Sign(BasicFunc.Dot(middleGround, offset)); //float sideFactor = (float)(0.6 * (middlePos - endPos).length / Math.Abs(middlePos.z)); result[2].setTranslation(middleGround + offset, MSpace.Space.kWorld); MObject jt_front_Object = rootJoint.create(jt_side_Object); result[3] = new MFnIkJoint(MDagPath.getAPathTo(jt_front_Object)); result[3].setTranslation(endPos, MSpace.Space.kWorld); MObject jt_middleF_Object = rootJoint.create(jt_front_Object); result[4] = new MFnIkJoint(MDagPath.getAPathTo(jt_middleF_Object)); result[4].setTranslation(middlePos, MSpace.Space.kWorld); MObject jt_middleB_Object = rootJoint.create(jt_front_Object); result[5] = new MFnIkJoint(MDagPath.getAPathTo(jt_middleB_Object)); result[5].setTranslation(middlePos, MSpace.Space.kWorld); MObject jt_toe_Object = rootJoint.create(jt_middleF_Object); result[6] = new MFnIkJoint(MDagPath.getAPathTo(jt_toe_Object)); result[6].setTranslation(endPos, MSpace.Space.kWorld); MObject jt_ankleIn_Object = rootJoint.create(jt_middleB_Object); result[7] = new MFnIkJoint(MDagPath.getAPathTo(jt_ankleIn_Object)); result[7].setTranslation(rootPos, MSpace.Space.kWorld); Debug.Log("create joints ok"); return(result); }