public static MDagPath CreateJoint(string jtName)
        {
            MFnIkJoint joint    = new MFnIkJoint();
            MObject    jtObject = joint.create();

            return(MDagPath.getAPathTo(jtObject));
        }
Exemple #2
0
        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);
        }
Exemple #4
0
        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");
        }
Exemple #6
0
        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);
                    }
                }
            }
        }
Exemple #8
0
        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));
        }
Exemple #11
0
        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)));
        }
Exemple #12
0
        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)));
        }
Exemple #13
0
        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);
        }
Exemple #14
0
        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;
        }
Exemple #15
0
        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;
        }
Exemple #16
0
        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);
        }