Пример #1
0
        public void getChildJoints(string code)
        {
            NumberFormatInfo nf = new CultureInfo("en-US", false).NumberFormat;
            Stack            s  = new Stack();
            Regex            r  = new Regex(@"\s*Frame (joint[0-9]+)+");

            char[] separators = new char[2];
            separators[0] = ',';
            separators[1] = ';';
            string[] el;

            int currJointIndex = 0;

            MatchCollection m = r.Matches(code);

            Match m2;
            Match m3;

            for (int i = 0; i < m.Count; i++)
            {
                m2 = Regex.Match(m[i].Groups[0].ToString(), @"^\s*");
                int depth = m2.ToString().Length / 4;
                m3 = Regex.Match(code, m[i].Groups[1].ToString() + @" \{\s*FrameTransformMatrix \{([^\}]+)\}");
                el = m3.Groups[1].ToString().Split(separators);
                JointInfo jointInfo = new JointInfo(m[i].Groups[1].ToString());
                jointInfo.index = currJointIndex;
                currJointIndex++;
                Matrix4x4 t = new Matrix4x4(Double.Parse(el[0], nf), Double.Parse(el[1], nf), Double.Parse(el[2], nf), Double.Parse(el[3], nf),
                                            Double.Parse(el[4], nf), Double.Parse(el[5], nf), Double.Parse(el[6], nf), Double.Parse(el[7], nf),
                                            Double.Parse(el[8], nf), Double.Parse(el[9], nf), Double.Parse(el[10], nf), Double.Parse(el[11], nf),
                                            Double.Parse(el[12], nf), Double.Parse(el[13], nf), Double.Parse(el[14], nf), Double.Parse(el[15], nf));
                jointInfo.setTransform(t);
                int maxJointVertexIndex = readSkinWeights(jointInfo, code);
                if (maxJointVertexIndex > maxVertexIndex)
                {
                    maxVertexIndex = maxJointVertexIndex;
                }

                while (depth < s.Count)
                {
                    s.Pop();
                }

                if (depth > 0)
                {
                    jointInfo.Parent = (JointInfo)s.Peek();
                    //((JointInfo)s.Peek()).AddChild(jointInfo);
                }
                s.Push(jointInfo);
            }

            while (s.Count > 1)
            {
                s.Pop();
            }
            outputJoint    = (JointInfo)s.Peek();
            outputSkeleton = new Skeleton(outputJoint);

            outputSkeleton.BuildJointTable();
        }
Пример #2
0
 public void Evaluate(int SpreadMax)
 {
     if (FJoints.SliceCount == 0)
     {
         FOut.SliceCount = 0;
         return;
     }
     if (FJoints.IsChanged)
     {
         FOut.Stream.IsChanged = true;
         for (int i = 0; i < FOut.SliceCount; i++)
         {
             if (FOut[i] == null)
             {
                 var newskeleton = new Skeleton(FJoints[i]);
                 newskeleton.RenewUid();
                 newskeleton.BuildJointTable();
                 var ii = 0;
                 foreach (var j in newskeleton.JointTable.Values)
                 {
                     j.Id = ii;
                     ii++;
                 }
                 FOut[i] = newskeleton;
             }
             if (!(FJoints[i] is JointInfoV2))
             {
                 continue;
             }
             var joint = (JointInfoV2)FJoints[i];
             if (joint.ChildrenChanged)
             {
                 FOut[i].BuildJointTable();
             }
         }
     }
     else
     {
         FOut.Stream.IsChanged = false;
     }
 }
Пример #3
0
        //parse JOINT
        private void ParseJoint(ref int index, ref List <string> tokens, BVHJoint parent)
        {
            //NOTE: can't assign same joint name in vvvv Skeleton!
            string name = tokens[index++];
            string tmpName;
            int    num = 2;

            //set name without number as temp
            tmpName = name;

            //rename while enable
            while (FSkeleton.JointTable.ContainsKey(name))
            {
                name = tmpName + num.ToString();
                num++;
            }

            //create BVHJoint
            BVHJoint joint = new BVHJoint(FJointCounter++, name, parent);

            if (parent != null)
            {
                FSkeleton.InsertJoint(parent.Name, joint);
            }
            else
            {
                //"parent == null" means ROOT

                FSkeleton.InsertJoint("", joint);

                FSkeleton.Root = joint;

                FSkeleton.BuildJointTable();    //what's happen here?
            }

            while (index < tokens.Count)
            {
                //get token
                string token = tokens[index++];

                if (token == "OFFSET")
                {
                    Vector3D translate = new Vector3D();

                    //set offset(=initial) position

                    //This is not working with some culture settings
                    //translate.x = double.Parse(tokens[index++]);
                    //translate.y = double.Parse(tokens[index++]);
                    //translate.z = double.Parse(tokens[index++]);// *-1;   //Right Hand to Left Hand

                    //to solve that, use InvariantInfo
                    translate.x = double.Parse(tokens[index++], NumberFormatInfo.InvariantInfo);
                    translate.y = double.Parse(tokens[index++], NumberFormatInfo.InvariantInfo);
                    translate.z = double.Parse(tokens[index++], NumberFormatInfo.InvariantInfo);


                    //set BaseTransform
                    joint.BaseTransform = VMath.Translate(translate);
                    //joint.AnimationTransform = VMath.Translate(translate);
                }
                else if (token == "CHANNELS")
                {
                    //get channel count from token
                    //int channelCount = int.Parse(tokens[index++]);
                    int channelCount = int.Parse(tokens[index++], NumberFormatInfo.InvariantInfo);

                    //set channel count
                    joint.SetChannelCount(channelCount);

                    //update total count of Skeleton's channels
                    FChannelCountOfSkeleton += channelCount;

                    //processing each channel
                    for (int i = 0; i < channelCount; i++)
                    {
                        //to lower case
                        string channel = tokens[index++].ToLower();

                        //detect axis and tranform type by first two char
                        char axis  = channel[0];
                        char trans = channel[1];
                        switch (trans)
                        {
                        case 'p':       //position
                            switch (axis)
                            {
                            case 'x': joint.SetChannel(i, BVHChannel.X_POSITION); break;

                            case 'y': joint.SetChannel(i, BVHChannel.Y_POSITION); break;

                            case 'z': joint.SetChannel(i, BVHChannel.Z_POSITION); break;
                            }
                            break;

                        case 'r':       //rotation
                            switch (axis)
                            {
                            case 'x': joint.SetChannel(i, BVHChannel.X_ROTATION); break;

                            case 'y': joint.SetChannel(i, BVHChannel.Y_ROTATION); break;

                            case 'z': joint.SetChannel(i, BVHChannel.Z_ROTATION); break;
                            }
                            break;
                        }
                    }
                }
                else if (token == "JOINT")
                {
                    //recusive call
                    ParseJoint(ref index, ref tokens, joint);
                }
                else if (token == "End")
                {
                    //recusive call
                    ParseJoint(ref index, ref tokens, joint);
                }
                else if (token == "}")
                {
                    //go next
                    break;
                }
            }
        }
Пример #4
0
        //here we go, thats the method called by vvvv each frame
        //all data handling should be in here
        public void Evaluate(int SpreadMax)
        {
            //if any of the inputs has changed
            //recompute the outputs
            bool recalculate = false;

            if (FInput.PinIsChanged)
            {
                FInput.GetValue(0, out input);
                recalculate = true;
            }

            object currInterface;

            for (int i = 0; i < FPoseNodes.Count; i++)
            {
                if (FPoseNodes[i].PinIsChanged)
                {
                    if (FPoseNodes[i].IsConnected)
                    {
                        FPoseNodes[i].GetUpstreamInterface(out currInterface);
                        IJoint currPose = ((Skeleton)currInterface).Root;
                        FPoses[i] = currPose;
                    }
                    else
                    {
                        FPoses[i] = null;
                        if (i == 0)
                        {
                            FOutputJoint = null;
                        }
                    }
                    recalculate = true;
                }
            }

            if (recalculate)
            {
                int    index1  = (int)Math.Floor(input);
                int    index2  = (int)Math.Min(Math.Ceiling(input), poseCount - 1);
                double amount2 = input - index1;
                double amount1 = (input - index2) * -1;

                if (amount2 == 0)
                {
                    FOutputJoint = FPoses[index1];
                    if (passthrough != index1)
                    {
                        FSkeleton.Root = FOutputJoint;
                        FSkeleton.BuildJointTable();
                    }
                    passthrough = index1;
                }
                else if (amount1 == 0)
                {
                    FOutputJoint = FPoses[index2];
                    if (passthrough != -1)
                    {
                        FSkeleton.Root = FOutputJoint;
                        FSkeleton.BuildJointTable();
                    }
                    passthrough = index2;
                }
                else
                {
                    if (FOutputJoint == null || passthrough >= 0)
                    {
                        FOutputJoint   = FPoses[index1].DeepCopy();
                        FSkeleton.Root = FOutputJoint;
                        FSkeleton.BuildJointTable();
                    }
                    else
                    {
                        copyAttributes(FPoses[index1], FOutputJoint);
                    }
                    mixJoints(FOutputJoint, FPoses[index1], amount1, FPoses[index2], amount2);
                    passthrough = -1;
                }

                FSkeleton.Root = FOutputJoint;
                FPoseOutput.MarkPinAsChanged();
            }

            FPoseOutput.SetInterface(FSkeleton);
        }
Пример #5
0
        //here we go, thats the method called by vvvv each frame
        //all data handling should be in here
        public void Evaluate(int SpreadMax)
        {
            //if any of the inputs has changed
            //recompute the outputs


            bool   recalculate = false;
            object currInterface;

            for (int i = 0; i < poseNodes.Count; i++)
            {
                if (poseNodes[i].PinIsChanged)
                {
                    if (poseNodes[i].IsConnected)
                    {
                        poseNodes[i].GetUpstreamInterface(out currInterface);
                        IJoint currPose = ((Skeleton)currInterface).Root;
                        poses[i] = currPose;
                    }
                    else
                    {
                        poses[i] = null;
                        if (i == 0)
                        {
                            outputJoint = null;
                        }
                    }
                    recalculate = true;
                }
                if (amountNodes[i].PinIsChanged)
                {
                    double amount;
                    amountNodes[i].GetValue(0, out amount);
                    amounts[i]  = amount;
                    recalculate = true;
                }
            }


            if (recalculate)
            {
                // the following would be much nicer, if mixJoints() would take a dynamic number of poses and amounts
                if (outputJoint == null)
                {
                    outputJoint         = poses[0].DeepCopy();
                    outputSkeleton.Root = outputJoint;
                    outputSkeleton.BuildJointTable();
                }
                else
                {
                    copyAttributes(poses[0], outputJoint);
                }
                double amount = amounts[0];
                IJoint interimPose;
                for (int i = 0; i < poses.Count - 1; i++)
                {
                    if (poses[i + 1] == null)
                    {
                        continue;
                    }
                    interimPose = outputJoint;
                    mixJoints(outputJoint, interimPose, amount, poses[i + 1], amounts[i + 1]);
                    amount = 1.0;
                }
                outputSkeleton.Root = outputJoint;
                FPoseOutput.MarkPinAsChanged();
            }


            FPoseOutput.SetInterface(outputSkeleton);
        }
Пример #6
0
        //here we go, thats the method called by vvvv each frame
        //all data handling should be in here
        public void Evaluate(int SpreadMax)
        {
            //if any of the inputs has changed
            //recompute the outputs
            bool recalculate            = false;
            bool chainRangeChanged      = false;
            bool recalculateOrientation = false;

            if (FChainStart.PinIsChanged)
            {
                FChainStart.GetString(0, out chainStart);
                recalculate       = true;
                chainRangeChanged = true;
            }

            if (FChainEnd.PinIsChanged)
            {
                FChainEnd.GetString(0, out chainEnd);
                recalculate       = true;
                chainRangeChanged = true;
            }

            object currInterface;

            if (FPoseInput.PinIsChanged || chainRangeChanged)
            {
                if (FPoseInput.IsConnected)
                {
                    FPoseInput.GetUpstreamInterface(out currInterface);
                    Skeleton s = (Skeleton)currInterface;
                    if (outputSkeleton == null || !s.Uid.Equals(outputSkeleton.Uid))
                    {
                        outputSkeleton = (Skeleton)((Skeleton)currInterface).DeepCopy();
                        outputSkeleton.BuildJointTable();
                        workingSkeleton = (Skeleton)outputSkeleton.DeepCopy();
                        workingSkeleton.BuildJointTable();
                        chainRangeChanged = true;
                    }
                    else
                    {
                        foreach (KeyValuePair <string, IJoint> pair in s.JointTable)
                        {
                            if (!jointChain.Exists(delegate(IJoint j) { return(j.Name == pair.Key); }))
                            {
                                outputSkeleton.JointTable[pair.Key].BaseTransform       = pair.Value.BaseTransform;
                                outputSkeleton.JointTable[pair.Key].AnimationTransform  = pair.Value.AnimationTransform;
                                workingSkeleton.JointTable[pair.Key].BaseTransform      = pair.Value.BaseTransform;
                                workingSkeleton.JointTable[pair.Key].AnimationTransform = pair.Value.AnimationTransform;
                            }
                            outputSkeleton.JointTable[pair.Key].Constraints  = pair.Value.Constraints;
                            workingSkeleton.JointTable[pair.Key].Constraints = pair.Value.Constraints;
                        }
                    }
                    workingSkeleton.CalculateCombinedTransforms();
                    recalculate = true;
                }
                else
                {
                    outputSkeleton = null;
                }
            }

            if (FVelocityInput.PinIsChanged)
            {
                double x;
                FVelocityInput.GetValue(0, out x);
                iterationsPerFrame = (int)(x * 10);
            }

            if (iterationsPerFrame > 0)
            {
                if (FTargetInput.PinIsChanged)
                {
                    targetPosW = new Vector3D();
                    FTargetInput.GetValue3D(0, out targetPosW.x, out targetPosW.y, out targetPosW.z);
                    recalculate = true;
                }

                if (FEpsilonInput.PinIsChanged)
                {
                    FEpsilonInput.GetValue(0, out epsilon);
                    recalculate = true;
                }

                if (FPoleTargetInput.PinIsChanged || FEnablePoleTargetInput.PinIsChanged)
                {
                    double x;
                    FEnablePoleTargetInput.GetValue(0, out x);
                    enablePoleTarget = x > 0.0;
                    poleTargetW      = new Vector3D();
                    FPoleTargetInput.GetValue3D(0, out poleTargetW.x, out poleTargetW.y, out poleTargetW.z);
                    recalculateOrientation = true;
                }

                if (chainRangeChanged && outputSkeleton != null)
                {
                    initRotations();
                }

                double delta = VMath.Dist(endPosW, targetPosW);
                if ((delta > epsilon || recalculate) && outputSkeleton != null && !string.IsNullOrEmpty(chainStart) && !string.IsNullOrEmpty(chainEnd))
                {
                    List <Vector2D> constraints = new List <Vector2D>();
                    for (int i = 0; i < iterationsPerFrame; i++)
                    {
                        for (int j = 0; j < 3; j++)
                        {
                            IJoint currJoint = workingSkeleton.JointTable[chainEnd];
                            endPosW = currJoint.CombinedTransform * new Vector3D(0);
                            while (currJoint.Name != chainStart)
                            {
                                currJoint = currJoint.Parent;
                                Vector3D rotationAxis = new Vector3D(0, 0, 0);
                                rotationAxis[j] = 1;
                                double   torque = calculateTorque(currJoint, rotationAxis);
                                Vector3D rot    = rotations[currJoint.Name];
                                if ((rot[j] + torque) < currJoint.Constraints[j].x * 2 * Math.PI || (rot[j] + torque) > currJoint.Constraints[j].y * 2 * Math.PI)
                                {
                                    torque = 0;
                                }
                                Matrix4x4 newTransform = VMath.Rotate(torque * rotationAxis.x, torque * rotationAxis.y, torque * rotationAxis.z) * currJoint.AnimationTransform;
                                Vector3D  testVec      = newTransform * new Vector3D(0);
                                if (!Double.IsInfinity(testVec.x) && !Double.IsNaN(testVec.x))                         // an evil bug fix, to avoid n.def. values in animation transform matrix. the actual reason, why this would happen has not been found yet.
                                {
                                    rot[j] += torque;
                                    rotations[currJoint.Name]    = rot;
                                    currJoint.AnimationTransform = newTransform;
                                    outputSkeleton.JointTable[currJoint.Name].AnimationTransform = currJoint.AnimationTransform;
                                }
                            }
                        }
                        try
                        {
                            Matrix4x4 pre;
                            if (workingSkeleton.JointTable[chainStart].Parent != null)
                            {
                                pre = workingSkeleton.JointTable[chainStart].Parent.CombinedTransform;
                            }
                            else
                            {
                                pre = VMath.IdentityMatrix;
                            }
                            ((JointInfo)workingSkeleton.JointTable[chainStart]).CalculateCombinedTransforms(pre);
                        }
                        catch (Exception)
                        {
                            workingSkeleton.CalculateCombinedTransforms();
                        }
                    }


                    FPoseOutput.MarkPinAsChanged();
                }

                if ((recalculate || recalculateOrientation) && enablePoleTarget && outputSkeleton != null && !string.IsNullOrEmpty(chainStart) && !string.IsNullOrEmpty(chainEnd))
                {
                    endPosW = workingSkeleton.JointTable[chainEnd].CombinedTransform * new Vector3D(0);
                    Vector3D poleTargetLocal = VMath.Inverse(workingSkeleton.JointTable[chainStart].CombinedTransform) * poleTargetW;
                    Vector3D t = VMath.Inverse(workingSkeleton.JointTable[chainStart].CombinedTransform) * endPosW;                                                                                  // endpoint in local coords
                    Vector3D a = VMath.Inverse(workingSkeleton.JointTable[chainStart].CombinedTransform) * (workingSkeleton.JointTable[chainStart].Children[0].CombinedTransform * new Vector3D(0)); // next child in local coords
                    Vector3D x = t * ((a.x * t.x + a.y * t.y + a.z * t.z) / Math.Pow(VMath.Dist(new Vector3D(0), t), 2));
                    Vector3D y = t * ((poleTargetLocal.x * t.x + poleTargetLocal.y * t.y + poleTargetLocal.z * t.z) / Math.Pow(VMath.Dist(new Vector3D(0), t), 2));

                    Vector3D c     = poleTargetLocal - y;
                    Vector3D b     = a - x;
                    double   angle = vectorAngle(b, c);
                    Vector3D n     = new Vector3D();
                    n.x = c.y * b.z - c.z * b.y;
                    n.y = c.z * b.x - c.x * b.z;
                    n.z = c.x * b.y - c.y * b.x;
                    n   = n / VMath.Dist(new Vector3D(0), n);
                    FDebugOutput.SetValue(0, angle);
                    chainRotation = RotateAroundAxis(angle, n);

                    FPoseOutput.MarkPinAsChanged();
                }
                if (!enablePoleTarget)
                {
                    chainRotation = VMath.IdentityMatrix;
                }

                outputSkeleton.JointTable[chainStart].AnimationTransform = chainRotation * outputSkeleton.JointTable[chainStart].AnimationTransform;
            }

            FPoseOutput.SetInterface(outputSkeleton);
        }
Пример #7
0
        //here we go, thats the method called by vvvv each frame
        //all data handling should be in here
        public void Evaluate(int SpreadMax)
        {
            //if any of the inputs has changed
            //recompute the outputs

            bool recalculate = false;

            if (FJointNameInput.PinIsChanged || FBaseTransformInput.PinIsChanged || FOffsetModeInput.PinIsChanged || FParentNameInput.PinIsChanged || FConstraintsInput.PinIsChanged || recalculate)
            {
                skeleton = new Skeleton();

                int currId = 0;
                for (int i = 0; i < FJointNameInput.SliceCount; i++)
                {
                    string jointName;
                    string parentName;
                    FJointNameInput.GetString(i % FJointNameInput.SliceCount, out jointName);
                    FParentNameInput.GetString(i % FParentNameInput.SliceCount, out parentName);
                    IJoint    currJoint = new JointInfo(jointName);
                    Matrix4x4 baseTransform;
                    FBaseTransformInput.GetMatrix(i % FBaseTransformInput.SliceCount, out baseTransform);
                    currJoint.BaseTransform = baseTransform;             //VMath.Translate(basePositionX, basePositionY, basePositionZ);
                    currJoint.Constraints.Clear();
                    for (int j = i * 3; j < i * 3 + 3; j++)
                    {
                        double constraintMin, constraintMax;
                        FConstraintsInput.GetValue2D(j % FConstraintsInput.SliceCount, out constraintMin, out constraintMax);
                        currJoint.Constraints.Add(new Vector2D(constraintMin, constraintMax));
                    }
                    if (string.IsNullOrEmpty(parentName))
                    {
                        if (skeleton.Root == null)
                        {
                            skeleton.Root = currJoint;
                            currJoint.Id  = currId;
                            currId++;
                            skeleton.BuildJointTable();
                        }
                    }
                    else
                    {
                        if (skeleton.JointTable.ContainsKey(parentName))
                        {
                            currJoint.Parent = skeleton.JointTable[parentName];
                            currJoint.Id     = currId;
                            currId++;
                        }
                        skeleton.BuildJointTable();
                    }
                }

                int positionInWorldSpace = 0;
                FOffsetModeInput.GetOrd(0, out positionInWorldSpace);
                if (positionInWorldSpace > 0)
                {
                    List <Vector3D> offsetList = new List <Vector3D>();
                    foreach (KeyValuePair <string, IJoint> pair in skeleton.JointTable)
                    {
                        Vector3D worldPos = pair.Value.BaseTransform * (new Vector3D(0));
                        Vector3D parentWorldPos;
                        if (pair.Value.Parent != null)
                        {
                            parentWorldPos = pair.Value.Parent.BaseTransform * (new Vector3D(0));
                        }
                        else
                        {
                            parentWorldPos = new Vector3D(0);
                        }
                        Vector3D offset = worldPos - parentWorldPos;
                        offsetList.Add(offset);
                    }
                    int i = 0;
                    foreach (KeyValuePair <string, IJoint> pair in skeleton.JointTable)
                    {
                        pair.Value.BaseTransform = VMath.Translate(offsetList[i]);
                        i++;
                    }
                }


                FSkeletonOutput.MarkPinAsChanged();
            }

            FSkeletonOutput.SetInterface(skeleton);
        }