Пример #1
0
        /// <summary>
        /// Gets the bounding box of an element in the data.
        /// </summary>
        /// <param name="triangleIndex">Index of the triangle in the data.</param>
        /// <param name="boundingBox">Bounding box of the triangle.</param>
        public void GetBoundingBox(int triangleIndex, out BoundingBox boundingBox)
        {
            Vector3f v1, v2, v3;

            GetTriangle(triangleIndex, out v1, out v2, out v3);
            Vector3f.ComponentMin(ref v1, ref v2, out boundingBox.Min);
            Vector3f.ComponentMin(ref boundingBox.Min, ref v3, out boundingBox.Min);
            Vector3f.ComponentMax(ref v1, ref v2, out boundingBox.Max);
            Vector3f.ComponentMax(ref boundingBox.Max, ref v3, out boundingBox.Max);
        }
Пример #2
0
        /// <summary>
        /// Initializes the detector entity and any other necessary logic.
        /// </summary>
        protected internal override void Initialize()
        {
            //Setup the dimensions of the detector.
            Vector3f startpoint = wheel.suspension.localAttachmentPoint;
            Vector3f endpoint = startpoint + wheel.suspension.localDirection * wheel.suspension.restLength;
            Vector3f min, max;

            Vector3f.ComponentMin(ref startpoint, ref endpoint, out min);
            Vector3f.ComponentMax(ref startpoint, ref endpoint, out max);

            detector.Width  = max.X - min.X;
            detector.Height = max.Y - min.Y;
            detector.Length = max.Z - min.Z;
        }
Пример #3
0
        /// <summary>
        /// Gets the bounding box of the shape given a transform.
        /// </summary>
        /// <param name="shapeTransform">Transform to use.</param>
        /// <param name="boundingBox">Bounding box of the transformed shape.</param>
        public override void GetBoundingBox(ref RigidTransform shapeTransform, out BoundingBox boundingBox)
        {
            Vector3f a, b, c;

            Matrix3f o;

            Matrix3f.FromQuaternion(ref shapeTransform.Orientation, out o);
            Vector3f.Transform(ref vA, ref o, out a);
            Vector3f.Transform(ref vB, ref o, out b);
            Vector3f.Transform(ref vC, ref o, out c);

            Vector3f.ComponentMin(ref a, ref b, out boundingBox.Min);
            Vector3f.ComponentMin(ref c, ref boundingBox.Min, out boundingBox.Min);

            Vector3f.ComponentMax(ref a, ref b, out boundingBox.Max);
            Vector3f.ComponentMax(ref c, ref boundingBox.Max, out boundingBox.Max);

            boundingBox.Min.X += shapeTransform.Position.X - collisionMargin;
            boundingBox.Min.Y += shapeTransform.Position.Y - collisionMargin;
            boundingBox.Min.Z += shapeTransform.Position.Z - collisionMargin;
            boundingBox.Max.X += shapeTransform.Position.X + collisionMargin;
            boundingBox.Max.Y += shapeTransform.Position.Y + collisionMargin;
            boundingBox.Max.Z += shapeTransform.Position.Z + collisionMargin;
        }
Пример #4
0
        protected internal override void SolveVelocityIteration()
        {
            //Compute the 'relative' linear and angular velocities. For single bone constraints, it's based entirely on the one bone's velocities!
            //They have to be pulled into constraint space first to compute the necessary impulse, though.
            Vector3f linearContributionA;

            Vector3f.TransformTranspose(ref ConnectionA.linearVelocity, ref linearJacobianA, out linearContributionA);
            Vector3f angularContributionA;

            Vector3f.TransformTranspose(ref ConnectionA.angularVelocity, ref angularJacobianA, out angularContributionA);
            Vector3f linearContributionB;

            Vector3f.TransformTranspose(ref ConnectionB.linearVelocity, ref linearJacobianB, out linearContributionB);
            Vector3f angularContributionB;

            Vector3f.TransformTranspose(ref ConnectionB.angularVelocity, ref angularJacobianB, out angularContributionB);

            //The constraint velocity error will be the velocity we try to remove.
            Vector3f constraintVelocityError;

            Vector3f.Add(ref linearContributionA, ref angularContributionA, out constraintVelocityError);
            Vector3f.Add(ref constraintVelocityError, ref linearContributionB, out constraintVelocityError);
            Vector3f.Add(ref constraintVelocityError, ref angularContributionB, out constraintVelocityError);
            //However, we need to take into account two extra sources of velocities which modify our target velocity away from zero.
            //First, the velocity bias from position correction:
            Vector3f.Subtract(ref constraintVelocityError, ref velocityBias, out constraintVelocityError);
            //And second, the bias from softness:
            Vector3f softnessBias;

            Vector3f.Multiply(ref accumulatedImpulse, -softness, out softnessBias);
            Vector3f.Subtract(ref constraintVelocityError, ref softnessBias, out constraintVelocityError);

            //By now, the constraint velocity error contains all the velocity we want to get rid of.
            //Convert it into an impulse using the effective mass matrix.
            Vector3f constraintSpaceImpulse;

            Vector3f.Transform(ref constraintVelocityError, ref effectiveMass, out constraintSpaceImpulse);

            Vector3f.Negate(ref constraintSpaceImpulse, out constraintSpaceImpulse);

            //Add the constraint space impulse to the accumulated impulse so that warm starting and softness work properly.
            Vector3f preadd = accumulatedImpulse;

            Vector3f.Add(ref constraintSpaceImpulse, ref accumulatedImpulse, out accumulatedImpulse);
            //Limits can only apply positive impulses.
            Vector3f.ComponentMax(ref Toolbox.ZeroVector, ref accumulatedImpulse, out accumulatedImpulse);
            //But wait! The accumulated impulse may exceed this constraint's capacity! Check to make sure!
            float impulseSquared = accumulatedImpulse.LengthSquared;

            if (impulseSquared > maximumImpulseSquared)
            {
                //Oops! Clamp that down.
                Vector3f.Multiply(ref accumulatedImpulse, maximumImpulse / (float)Math.Sqrt(impulseSquared), out accumulatedImpulse);
            }
            //Update the impulse based upon the clamped accumulated impulse and the original, pre-add accumulated impulse.
            Vector3f.Subtract(ref accumulatedImpulse, ref preadd, out constraintSpaceImpulse);

            //The constraint space impulse now represents the impulse we want to apply to the bone... but in constraint space.
            //Bring it out to world space using the transposed jacobian.
            if (!ConnectionA.Pinned)//Treat pinned elements as if they have infinite inertia.
            {
                Vector3f linearImpulseA;
                Vector3f.Transform(ref constraintSpaceImpulse, ref linearJacobianA, out linearImpulseA);
                Vector3f angularImpulseA;
                Vector3f.Transform(ref constraintSpaceImpulse, ref angularJacobianA, out angularImpulseA);

                //Apply them!
                ConnectionA.ApplyLinearImpulse(ref linearImpulseA);
                ConnectionA.ApplyAngularImpulse(ref angularImpulseA);
            }
            if (!ConnectionB.Pinned)//Treat pinned elements as if they have infinite inertia.
            {
                Vector3f linearImpulseB;
                Vector3f.Transform(ref constraintSpaceImpulse, ref linearJacobianB, out linearImpulseB);
                Vector3f angularImpulseB;
                Vector3f.Transform(ref constraintSpaceImpulse, ref angularJacobianB, out angularImpulseB);

                //Apply them!
                ConnectionB.ApplyLinearImpulse(ref linearImpulseB);
                ConnectionB.ApplyAngularImpulse(ref angularImpulseB);
            }
        }