예제 #1
0
        public QJoint FindJointByIndex(int idx)
        {
            QJoint result = hierarchy;

            if (result.index == idx)
            {
                return(result);
            }
            List <QJoint> remaining = new List <QJoint>();
            List <QJoint> nextBatch = new List <QJoint>();

            remaining.AddRange(result.children);
            do
            {
                var jEnum = remaining.GetEnumerator();
                while (jEnum.MoveNext())
                {
                    QJoint joint = jEnum.Current;
                    if (joint.index == idx)
                    {
                        return(joint);
                    }
                    nextBatch.AddRange(joint.children);
                }
                jEnum.Dispose();
                remaining = new List <QJoint>(nextBatch);
                nextBatch.Clear();
            }while (remaining.Count > 0);
            Debug.LogError("joint index not found!");
            return(null);
        }
예제 #2
0
 public QAnimation(float _length, HashSet <string> _jointNames, QJoint _hierarchy, Dictionary <string, KeyBlob> _keyFrames)
 {
     length     = _length;
     hierarchy  = _hierarchy;
     jointNames = _jointNames;
     keyFrames  = _keyFrames;
 }
예제 #3
0
 private void AddJointsToArray(QJoint headJoint, Matrix4x4[] jointArray)
 {
     //jointArray[headJoint.index] = headJoint.animatedTransform;
     foreach (QJoint joint in headJoint.children)
     {
         AddJointsToArray(joint, jointArray);
     }
 }
예제 #4
0
 public QModel(Mesh _mesh, Material _material, QJoint _rootJoint, int _jointCount)
 {
     mesh       = _mesh;
     material   = _material;
     rootJoint  = _rootJoint;
     jointCount = _jointCount;
     //rootJoint.CalculateInverseTransform(new Matrix4x4());
 }
예제 #5
0
 QJoint SiftChildren(QJoint parent, string targetName)
 {
     foreach (QJoint child in parent.children)
     {
         if (child.name == targetName)
         {
             return(child);
         }
     }
     return(null);
 }
예제 #6
0
        void ApplyPoseToJoints(Dictionary <string, Matrix4x4> currentPose, QJoint joint, Matrix4x4 parentTransform)
        {
            Matrix4x4 currentLocalTransform = currentPose[joint.name];
            Matrix4x4 currentTransform      = parentTransform * currentLocalTransform;

            foreach (QJoint child in joint.children)
            {
                ApplyPoseToJoints(currentPose, child, currentTransform);
            }
            //currentTransform *= joint.GetInverseBindTransform();
            //joint.animatedTransform = currentTransform;
        }
예제 #7
0
        public QAnimation LoadBagel(string path)
        {
            int jointIndex = 0;

            string bagelData = System.IO.File.ReadAllText(path);

            string[] jointBlocks = bagelData.Split(new[] { "&$*" }, StringSplitOptions.RemoveEmptyEntries);

            float animationLength = -1f;

            Matrix4x4[] bindXForms = model.bindposes;

            for (int i = 0; i < jointBlocks.Length; i++)
            {
                string   jointBlock = jointBlocks[i];
                string[] lines      = jointBlock.Split('\n');
                //we offset the base index since the first jointblock has the
                //animation length encoded in the 0th line
                int baseIndex = i == 0 ? 1 : 0;
                if (i == 0)
                {
                    animationLength = float.Parse(lines[0]);
                }

                string   jointPath      = lines[baseIndex];
                string[] hierarchyOrder = jointPath.Split(new[] { '/', '\r' }, StringSplitOptions.RemoveEmptyEntries);
                string   jointName      = hierarchyOrder[hierarchyOrder.Length - 1];

                jointNames.Add(jointName);

                scalarBlobs.Add(jointName, new Dictionary <string, ScalarBlob>());

                //case on whether we are reading the root
                if (hierarchy == null)
                {
                    hierarchy = new QJoint(jointIndex, jointName, bindXForms[jointIndex]);
                    jointIndex++;
                }
                else
                {
                    QJoint hierarchyWalker = hierarchy;

                    int hierarchyIndex = 1;
                    while (hierarchyIndex < hierarchyOrder.Length - 1)
                    {
                        hierarchyWalker = SiftChildren(hierarchyWalker, hierarchyOrder[hierarchyIndex++]);
                    }

                    //Matrix4x4 localBind = bindXForms[hierarchyWalker.index] * bindXForms[jointIndex].inverse;

                    //int startIdx = jointName.IndexOfAny(new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' });
                    //string numSub = jointName.Substring(startIdx);
                    //jointIndex = int.Parse(numSub) - 1;
                    QJoint newJoint = hierarchyWalker;
                    if (jointIndex != 0)
                    {
                        newJoint = new QJoint(jointIndex, jointName, bindXForms[jointIndex]);
                        hierarchyWalker.AddChild(newJoint);
                    }
                    jointIndex++;
                }


                //parsing keyframes for each attribute
                string[] animatedAttributes = jointBlock.Split(new[] { "#_#" }, StringSplitOptions.None);
                //we ignore the 0th entry in animatedAttributes since that will contain the information that
                //we just parsed before
                for (int j = 1; j < animatedAttributes.Length; j++)
                {
                    string[] attributeLines = animatedAttributes[j].Split('\n');
                    string   attributeNameAndElementLength = attributeLines[0];
                    string[] nameAndLength = attributeNameAndElementLength.Split(new[] { "##" }, StringSplitOptions.None);
                    string   attributeName = nameAndLength[0];
                    int      nKeyframes    = int.Parse(nameAndLength[1]);
                    for (int k = 1; k < nKeyframes + 1; k++)
                    {
                        string[] curveProperties = attributeLines[k].Split(new[] { "*#*" }, StringSplitOptions.None);
                        float    inTangent       = float.Parse(curveProperties[0]),
                                 frameValue      = float.Parse(curveProperties[1]),
                                 outTangent      = float.Parse(curveProperties[2]),
                                 time            = float.Parse(curveProperties[3]);
                        ScalarKeyFrame propKey   = new ScalarKeyFrame(inTangent, outTangent, frameValue, time);
                        ScalarFrame    propFrame = new ScalarFrame(inTangent, outTangent, frameValue);
                        //check if we have previous entries for a property
                        if (!scalarBlobs[jointName].ContainsKey(attributeName))
                        {
                            scalarBlobs[jointName].Add(attributeName, new ScalarBlob(attributeName, new SortedList <float, ScalarFrame>()));
                        }
                        scalarBlobs[jointName][attributeName].values.Add(time, propFrame);
                    }
                }
                keyframes.Add(jointName, new KeyBlob(scalarBlobs[jointName]));
            }
            return(new QAnimation(animationLength, jointNames, hierarchy, keyframes));
        }
예제 #8
0
 public void AddChild(QJoint child)
 {
     children.Add(child);
 }
예제 #9
0
        public TransformData GetTransformAt(int jointIdx, float time)
        {
            TransformData result         = new TransformData();
            Vector3       rPosition      = new Vector3();
            Vector4       rRotation      = new Vector4();
            Vector3       rScale         = new Vector3();
            QJoint        joint          = FindJointByIndex(jointIdx);
            var           JointKeyFrames = keyFrames[joint.name];

            foreach (string attribName in JointKeyFrames.keyedAttributes.Keys)
            {
                SortedList <float, ScalarFrame> frames = JointKeyFrames.keyedAttributes[attribName].values;
                int   minIdx  = BinarySearchLowerBound(frames.Keys, time);
                float minTime = frames.Keys[minIdx];
                float lerpVal = frames[minTime].value;
                if (minIdx + 1 < frames.Keys.Count)
                {
                    float minTangent = frames[minTime].outTangent;
                    float maxTime    = frames.Keys[minIdx + 1];
                    float maxVal     = frames[maxTime].value;
                    float maxTangent = frames[maxTime].inTangent;
                    lerpVal = CalculateInterpolation(time, minTangent, lerpVal, minTime,
                                                     maxTangent, maxVal, maxTime);
                }
                switch (attribName)
                {
                case ("m_LocalPosition.x"):
                    rPosition.x = lerpVal;
                    break;

                case ("m_LocalPosition.y"):
                    rPosition.y = lerpVal;
                    break;

                case ("m_LocalPosition.z"):
                    rPosition.z = lerpVal;
                    break;

                case ("m_LocalRotation.x"):
                    rRotation.x = lerpVal;
                    break;

                case ("m_LocalRotation.y"):
                    rRotation.y = lerpVal;
                    break;

                case ("m_LocalRotation.z"):
                    rRotation.z = lerpVal;
                    break;

                case ("m_LocalRotation.w"):
                    rRotation.w = lerpVal;
                    break;

                case ("m_LocalScale.x"):
                    rScale.x = lerpVal;
                    break;

                case ("m_LocalScale.y"):
                    rScale.y = lerpVal;
                    break;

                case ("m_LocalScale.z"):
                    rScale.z = lerpVal;
                    break;
                }
            }
            result.position = rPosition;
            rRotation.Normalize();
            result.rotation = new Quaternion(rRotation.x, rRotation.y, rRotation.z, rRotation.w);
            result.scale    = rScale;
            return(result);
        }