Esempio n. 1
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)
            {
                jointNames = new List <string>();
                string jointName;
                for (int i = 0; i < FJointNameInput.SliceCount; i++)
                {
                    FJointNameInput.GetString(i, out jointName);
                    jointNames.Add(jointName);
                }
                recalculate = true;
            }

            if (FSkeletonInput.PinIsChanged || recalculate)
            {
                if (FSkeletonInput.IsConnected)
                {
                    object currInterface;
                    FSkeletonInput.GetUpstreamInterface(out currInterface);
                    s = (Skeleton)currInterface;
                    if (inputSkeleton == null || !s.Uid.Equals(inputSkeleton.Uid))
                    {
                        inputSkeleton = (Skeleton)s.DeepCopy();
                    }
                    else
                    {
                        foreach (KeyValuePair <string, IJoint> pair in s.JointTable)
                        {
                            if (!jointNames.Exists(delegate(string name) { return(name == pair.Key); }))
                            {
                                inputSkeleton.JointTable[pair.Key].BaseTransform      = pair.Value.BaseTransform;
                                inputSkeleton.JointTable[pair.Key].AnimationTransform = pair.Value.AnimationTransform;
                            }
                            inputSkeleton.JointTable[pair.Key].Constraints = pair.Value.Constraints;
                        }
                    }
                }
                else
                {
                    inputSkeleton = null;
                }
            }

            if (FSkeletonInput.PinIsChanged || FAnimationTransformInput.PinIsChanged || FBaseTransformInput.PinIsChanged || FParentNameInput.PinIsChanged || FConstraintsInput.PinIsChanged || recalculate)
            {
                if (inputSkeleton != null)
                {
                    IJoint currJoint;
                    for (int i = 0; i < jointNames.Count; i++)
                    {
                        currJoint = inputSkeleton.JointTable[jointNames[i]];
                        Matrix4x4 currAnimationT;
                        Matrix4x4 currBaseT;
                        string    currParentName;
                        if (currJoint != null)
                        {
                            if (FAnimationTransformInput.IsConnected)
                            {
                                FAnimationTransformInput.GetMatrix(i, out currAnimationT);
                                currJoint.AnimationTransform = currAnimationT;
                            }
                            else
                            {
                                currJoint.AnimationTransform = s.JointTable[currJoint.Name].AnimationTransform;
                            }

                            if (FBaseTransformInput.IsConnected)
                            {
                                FBaseTransformInput.GetMatrix(i, out currBaseT);
                                currJoint.BaseTransform = currBaseT;
                            }
                            else
                            {
                                currJoint.BaseTransform = s.JointTable[currJoint.Name].BaseTransform;
                            }

                            /*if (FRotationInput.IsConnected)
                             * {
                             *      currRotation = new Vector3D(0);
                             *      FRotationInput.GetValue3D(i, out currRotation.x, out currRotation.y, out currRotation.z);
                             *      //currJoint.Rotation = currRotation;
                             *
                             * }
                             */

                            /*if (FConstraintsInput.IsConnected)
                             * {
                             *      currConstraints = new List<Vector2D>();
                             *      Vector2D currConstraint;
                             *      for (int j=0; j<3; j++)
                             *      {
                             *              currConstraint = new Vector2D(0);
                             *              FConstraintsInput.GetValue2D(i*3, out currConstraint.x, out currConstraint.y);
                             *              currConstraints.Add(currConstraint);
                             *      }
                             *      currJoint.Constraints = currConstraints;
                             * }
                             */

                            FParentNameInput.GetString(i, out currParentName);
                            if (currParentName != null && (FParentNameInput.SliceCount > 1 || !string.IsNullOrEmpty(currParentName)))
                            {
                                IJoint parent = inputSkeleton.JointTable[currParentName];
                                if (parent != null)
                                {
                                    currJoint.Parent = parent;
                                }
                            }
                        }
                    }
                }

                FSkeletonOutput.MarkPinAsChanged();
            }

            FSkeletonOutput.SetInterface(inputSkeleton);
        }
Esempio n. 2
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);
        }