예제 #1
0
        /// <summary>
        /// Updates the positions of bones acted upon by the joints given to this solver.
        /// This variant of the solver can be used when there are no goal-driven controls in the simulation.
        /// This amounts to running just the 'fixer iterations' of a normal control-driven solve.
        /// </summary>
        public void Solve(List <IKJoint> joints)
        {
            ActiveSet.UpdateActiveSet(joints);

            //Reset the permutation index; every solve should proceed in exactly the same order.
            permutationMapper.PermutationIndex = 0;

            float updateRate = 1 / TimeStepDuration;

            foreach (var joint in ActiveSet.joints)
            {
                joint.Preupdate(TimeStepDuration, updateRate);
            }

            for (int i = 0; i < FixerIterationCount; i++)
            {
                //Update the world inertia tensors of objects for the latest position.
                foreach (Bone bone in ActiveSet.bones)
                {
                    bone.UpdateInertiaTensor();
                }

                //Update the per-constraint jacobians and effective mass for the current bone orientations and positions.
                foreach (IKJoint joint in ActiveSet.joints)
                {
                    joint.UpdateJacobiansAndVelocityBias();
                    joint.ComputeEffectiveMass();
                    joint.WarmStart();
                }

                for (int j = 0; j < VelocitySubiterationCount; j++)
                {
                    //A permuted version of the indices is used. The randomization tends to avoid issues with solving order in corner cases.
                    for (int jointIndex = 0; jointIndex < ActiveSet.joints.Count; ++jointIndex)
                    {
                        int remappedIndex = permutationMapper.GetMappedIndex(jointIndex, ActiveSet.joints.Count);
                        ActiveSet.joints[remappedIndex].SolveVelocityIteration();
                    }
                    //Increment to use the next permutation.
                    ++permutationMapper.PermutationIndex;
                }

                //Integrate the positions of the bones forward.
                foreach (Bone bone in ActiveSet.bones)
                {
                    bone.UpdatePosition();
                }
            }

            //Clear out accumulated impulses; they should not persist through to another solving round because the state could be arbitrarily different.
            for (int j = 0; j < ActiveSet.joints.Count; j++)
            {
                ActiveSet.joints[j].ClearAccumulatedImpulses();
            }
        }
        private void SolveIteration(int i)
        {
            var constraint = constraints.Elements[permutationMapper.GetMappedIndex(i, constraints.Count)];

            constraint.EnterLock();
            constraint.SolveIteration();
            constraint.ApplyImpulses();
            constraint.ExitLock();
        }
예제 #3
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public PermutationTestDemo(DemosGame game)
            : base(game)
        {
            var permutations = new HashSet <Permutation>();
            var mapper       = new PermutationMapper();

            var representedIndices = new HashSet <int>();

            mapper.PermutationIndex = 0;
            const int setSize        = 250;
            const int iterationCount = 150000;
            var       conflicts      = 0;

            for (int i = 0; i < iterationCount; ++i)
            {
                var permutedIndices = new int[setSize];
                for (int setIndex = 0; setIndex < setSize; ++setIndex)
                {
                    permutedIndices[setIndex] = mapper.GetMappedIndex(setIndex, setSize);
                }

                for (int index = 0; index < permutedIndices.Length; ++index)
                {
                    if (!representedIndices.Add(permutedIndices[index]))
                    {
                        throw new Exception("Not a permutation!");
                    }
                }
                representedIndices.Clear();

                var permutation = new Permutation(permutedIndices);


                if (!permutations.Add(permutation))
                {
                    ++conflicts;
                }
                ++mapper.PermutationIndex;

                if (i % (iterationCount / 100) == 0)
                {
                    Console.WriteLine("{0}% complete", ((double)i * 100) / iterationCount);
                }
            }

            Console.WriteLine("Set size: {0}", setSize);
            Console.WriteLine("Iteration count: {0}", iterationCount);
            Console.WriteLine("Permutation count: {0}", permutations.Count);
            Console.WriteLine("Conflict count: {0}", conflicts);
        }