System.Math.Abs(float)

Here are the examples of the csharp api System.Math.Abs(float) taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

1741 Examples 7

19 View Source File : ConvexHullHelper.cs
License : The Unlicense
Project Creator : aeroson

private static void ComputeInitialTetrahedron(RawList<Vector3> points, RawList<int> outsidePointCandidates, RawList<int> triangleIndices, out Vector3 centroid)
        {
            //Find four points on the hull.
            //We'll start with using the x axis to identify two points on the hull.
            int a, b, c, d;
            Vector3 direction;
            //Find the extreme points along the x axis.
            float minimumX = float.MaxValue, maximumX = -float.MaxValue;
            int minimumXIndex = 0, maximumXIndex = 0;
            for (int i = 0; i < points.Count; ++i)
            {
                var v = points.Elements[i];
                if (v.X > maximumX)
                {
                    maximumX = v.X;
                    maximumXIndex = i;
                }
                else if (v.X < minimumX)
                {
                    minimumX = v.X;
                    minimumXIndex = i;
                }
            }
            a = minimumXIndex;
            b = maximumXIndex;
            //Check for redundancies..
            if (a == b)
                throw new ArgumentException("Point set is degenerate; convex hulls must have volume.");

            //Now, use a second axis perpendicular to the two points we found.
            Vector3 ab;
            Vector3.Subtract(ref points.Elements[b], ref points.Elements[a], out ab);
            Vector3.Cross(ref ab, ref Toolbox.UpVector, out direction);
            if (direction.LengthSquared() < Toolbox.Epsilon)
                Vector3.Cross(ref ab, ref Toolbox.RightVector, out direction);
            float minimumDot, maximumDot;
            int minimumIndex, maximumIndex;
            GetExtremePoints(ref direction, points, out maximumDot, out minimumDot, out maximumIndex, out minimumIndex);
            //Compare the location of the extreme points to the location of the axis.
            float dot;
            Vector3.Dot(ref direction, ref points.Elements[a], out dot);
            //Use the point further from the axis.
            if (Math.Abs(dot - minimumDot) > Math.Abs(dot - maximumDot))
            {
                //In this case, we should use the minimum index.
                c = minimumIndex;
            }
            else
            {
                //In this case, we should use the maximum index.
                c = maximumIndex;
            }

            //Check for redundancies..
            if (a == c || b == c)
                throw new ArgumentException("Point set is degenerate; convex hulls must have volume.");

            //Use a third axis perpendicular to the plane defined by the three unique points a, b, and c.
            Vector3 ac;
            Vector3.Subtract(ref points.Elements[c], ref points.Elements[a], out ac);
            Vector3.Cross(ref ab, ref ac, out direction);

            GetExtremePoints(ref direction, points, out maximumDot, out minimumDot, out maximumIndex, out minimumIndex);
            //Compare the location of the extreme points to the location of the plane.
            Vector3.Dot(ref direction, ref points.Elements[a], out dot);
            //Use the point further from the plane. 
            if (Math.Abs(dot - minimumDot) > Math.Abs(dot - maximumDot))
            {
                //In this case, we should use the minimum index.
                d = minimumIndex;
            }
            else
            {
                //In this case, we should use the maximum index.
                d = maximumIndex;
            }

            //Check for redundancies..
            if (a == d || b == d || c == d)
                throw new ArgumentException("Point set is degenerate; convex hulls must have volume.");

            //Add the triangles.
            triangleIndices.Add(a);
            triangleIndices.Add(b);
            triangleIndices.Add(c);

            triangleIndices.Add(a);
            triangleIndices.Add(b);
            triangleIndices.Add(d);

            triangleIndices.Add(a);
            triangleIndices.Add(c);
            triangleIndices.Add(d);

            triangleIndices.Add(b);
            triangleIndices.Add(c);
            triangleIndices.Add(d);

            //The centroid is guaranteed to be within the convex hull.  It will be used to verify the windings of triangles throughout the hull process.
            Vector3.Add(ref points.Elements[a], ref points.Elements[b], out centroid);
            Vector3.Add(ref centroid, ref points.Elements[c], out centroid);
            Vector3.Add(ref centroid, ref points.Elements[d], out centroid);
            Vector3.Multiply(ref centroid, 0.25f, out centroid);

            for (int i = 0; i < triangleIndices.Count; i += 3)
            {
                var vA = points.Elements[triangleIndices.Elements[i]];
                var vB = points.Elements[triangleIndices.Elements[i + 1]];
                var vC = points.Elements[triangleIndices.Elements[i + 2]];

                //Check the signed volume of a parallelepiped with the edges of this triangle and the centroid.
                Vector3 cross;
                Vector3.Subtract(ref vB, ref vA, out ab);
                Vector3.Subtract(ref vC, ref vA, out ac);
                Vector3.Cross(ref ac, ref ab, out cross);
                Vector3 offset;
                Vector3.Subtract(ref vA, ref centroid, out offset);
                float volume;
                Vector3.Dot(ref offset, ref cross, out volume);
                //This volume/cross product could also be used to check for degeneracy, but we already tested for that.
                if (Math.Abs(volume) < Toolbox.BigEpsilon)
                {
                    throw new ArgumentException("Point set is degenerate; convex hulls must have volume.");
                }
                if (volume < 0)
                {
                    //If the signed volume is negative, that means the triangle's winding is opposite of what we want.
                    //Flip it around!
                    var temp = triangleIndices.Elements[i];
                    triangleIndices.Elements[i] = triangleIndices.Elements[i + 1];
                    triangleIndices.Elements[i + 1] = temp;
                }
            }

            //Points which belong to the tetrahedra are guaranteed to be 'in' the convex hull. Do not allow them to be considered.
            var tetrahedronIndices = CommonResources.GetIntList();
            tetrahedronIndices.Add(a);
            tetrahedronIndices.Add(b);
            tetrahedronIndices.Add(c);
            tetrahedronIndices.Add(d);
            //Sort the indices to allow a linear time loop.
            Array.Sort(tetrahedronIndices.Elements, 0, 4);
            int tetrahedronIndex = 0;
            for (int i = 0; i < points.Count; ++i)
            {
                if (tetrahedronIndex < 4 && i == tetrahedronIndices[tetrahedronIndex])
                {
                    //Don't add a tetrahedron index. Now that we've found this index, though, move on to the next one.
                    ++tetrahedronIndex;
                }
                else
                {
                    outsidePointCandidates.Add(i);
                }
            }
            CommonResources.GiveBack(tetrahedronIndices);
        }

19 View Source File : TwistLimit.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            float velocityA, velocityB;
            //Find the velocity contribution from each connection
            Vector3.Dot(ref connectionA.angularVelocity, ref jacobianA, out velocityA);
            Vector3.Dot(ref connectionB.angularVelocity, ref jacobianB, out velocityB);
            //Add in the constraint space bias velocity
            float lambda = -(velocityA + velocityB) + biasVelocity - softness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Clamp acreplacedulated impulse (can't go negative)
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Max(acreplacedulatedImpulse + lambda, 0);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jacobianA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jacobianB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return Math.Abs(lambda);
        }

19 View Source File : IComparerPVPchkPtID.cs
License : GNU General Public License v3.0
Project Creator : aelariane

int IComparer.Compare(object x, object y)
    {
        float num = (float)((PVPcheckPoint)x).id;
        float num2 = (float)((PVPcheckPoint)y).id;
        if (num == num2 || Math.Abs(num - num2) < 1.401298E-45f)
        {
            return 0;
        }
        if (num < num2)
        {
            return -1;
        }
        return 1;
    }

19 View Source File : SwivelHingeAngularJoint.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            float velocityA, velocityB;
            //Find the velocity contribution from each connection
            Vector3.Dot(ref connectionA.angularVelocity, ref jacobianA, out velocityA);
            Vector3.Dot(ref connectionB.angularVelocity, ref jacobianB, out velocityB);
            //Add in the constraint space bias velocity
            float lambda = -(velocityA + velocityB) - biasVelocity - softness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Acreplacedulate the impulse
            acreplacedulatedImpulse += lambda;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jacobianA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jacobianB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return (Math.Abs(lambda));
        }

19 View Source File : TriangleMeshConvexContactManifold.cs
License : The Unlicense
Project Creator : aeroson

private bool IsContactUnique(ref ContactData contactCandidate)
        {
            contactCandidate.Validate();
            float distanceSquared;
            RigidTransform meshTransform = MeshTransform;
            for (int i = 0; i < contacts.Count; i++)
            {
                Vector3.DistanceSquared(ref contacts.Elements[i].Position, ref contactCandidate.Position, out distanceSquared);
                if (distanceSquared < CollisionDetectionSettings.ContactMinimumSeparationDistanceSquared)
                {
                    //This is a nonconvex manifold.  There will be times where a an object will be shoved into a corner such that
                    //a single position will have two reasonable normals.  If the normals aren't mostly aligned, they should NOT be considered equivalent.
                    Vector3.Dot(ref contacts.Elements[i].Normal, ref contactCandidate.Normal, out distanceSquared);
                    if (Math.Abs(distanceSquared) >= CollisionDetectionSettings.nonconvexNormalDotMinimum)
                    {
                        //Update the existing 'redundant' contact with the new information.
                        //This works out because the new contact is the deepest contact according to the previous collision detection iteration.
                        contacts.Elements[i].Normal = contactCandidate.Normal;
                        contacts.Elements[i].Position = contactCandidate.Position;
                        contacts.Elements[i].PenetrationDepth = contactCandidate.PenetrationDepth;
                        supplementData.Elements[i].BasePenetrationDepth = contactCandidate.PenetrationDepth;
                        RigidTransform.TransformByInverse(ref contactCandidate.Position, ref convex.worldTransform, out supplementData.Elements[i].LocalOffsetA);
                        RigidTransform.TransformByInverse(ref contactCandidate.Position, ref meshTransform, out supplementData.Elements[i].LocalOffsetB);
                        return false;
                    }
                }
            }
            for (int i = 0; i < candidatesToAdd.Count; i++)
            {
                Vector3.DistanceSquared(ref candidatesToAdd.Elements[i].Position, ref contactCandidate.Position, out distanceSquared);
                if (distanceSquared < CollisionDetectionSettings.ContactMinimumSeparationDistanceSquared)
                {
                    //This is a nonconvex manifold.  There will be times where a an object will be shoved into a corner such that
                    //a single position will have two reasonable normals.  If the normals aren't mostly aligned, they should NOT be considered equivalent.
                    Vector3.Dot(ref candidatesToAdd.Elements[i].Normal, ref contactCandidate.Normal, out distanceSquared);
                    if (Math.Abs(distanceSquared) >= CollisionDetectionSettings.nonconvexNormalDotMinimum)
                        return false;
                }
            }
            //for (int i = 0; i < edgeContacts.count; i++)
            //{
            //    Vector3.DistanceSquared(ref edgeContacts.Elements[i].ContactData.Position, ref contactCandidate.Position, out distanceSquared);
            //    if (distanceSquared < CollisionDetectionSettings.ContactMinimumSeparationDistanceSquared)
            //    {
            //        return false;
            //    }
            //}
            //for (int i = 0; i < vertexContacts.count; i++)
            //{
            //    Vector3.DistanceSquared(ref vertexContacts.Elements[i].ContactData.Position, ref contactCandidate.Position, out distanceSquared);
            //    if (distanceSquared < CollisionDetectionSettings.ContactMinimumSeparationDistanceSquared)
            //    {
            //        return false;
            //    }
            //}
            return true;

        }

19 View Source File : Fishie.cs
License : GNU General Public License v3.0
Project Creator : aedenthorn

protected override void updateAnimation(GameTime time)
        {
            base.updateAnimation(time);
            if (wareplacedCounter >= 0)
            {
                wareplacedCounter -= time.ElapsedGameTime.Milliseconds;
            }
            Sprite.Animate(time, 0, 9, 40f);
            float xSlope = (float)(-(float)(base.Player.GetBoundingBox().Center.X - GetBoundingBox().Center.X));
            float ySlope = (float)(base.Player.GetBoundingBox().Center.Y - GetBoundingBox().Center.Y);
            float t = Math.Max(1f, Math.Abs(xSlope) + Math.Abs(ySlope));
            if (t < 64f)
            {
                xVelocity = Math.Max(-7f, Math.Min(7f, xVelocity * 1.1f));
                yVelocity = Math.Max(-7f, Math.Min(7f, yVelocity * 1.1f));
            }
            xSlope /= t;
            ySlope /= t;
            if (wareplacedCounter <= 0)
            {
                targetRotation = (float)Math.Atan2((double)(-(double)ySlope), (double)xSlope) - 1.57079637f;
                if ((double)(Math.Abs(targetRotation) - Math.Abs(rotation)) > 2.748893571891069 && Game1.random.NextDouble() < 0.5)
                {
                    turningRight = true;
                }
                else if ((double)(Math.Abs(targetRotation) - Math.Abs(rotation)) < 0.39269908169872414)
                {
                    turningRight = false;
                }
                if (turningRight)
                {
                    rotation -= (float)Math.Sign(targetRotation - rotation) * 0.0490873866f;
                }
                else
                {
                    rotation += (float)Math.Sign(targetRotation - rotation) * 0.0490873866f;
                }
                rotation %= 6.28318548f;
                wareplacedCounter = 5 + Game1.random.Next(-1, 2);
            }
            float maxAccel = Math.Min(7f, Math.Max(2f, 7f - t / 64f / 2f));
            xSlope = (float)Math.Cos((double)rotation + 1.5707963267948966);
            ySlope = -(float)Math.Sin((double)rotation + 1.5707963267948966);
            xVelocity += -xSlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
            yVelocity += -ySlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
            if (Math.Abs(xVelocity) > Math.Abs(-xSlope * 7f))
            {
                xVelocity -= -xSlope * maxAccel / 6f;
            }
            if (Math.Abs(yVelocity) > Math.Abs(-ySlope * 7f))
            {
                yVelocity -= -ySlope * maxAccel / 6f;
            }
            base.resetAnimationSpeed();
        }

19 View Source File : DistanceLimit.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            //Compute the current relative velocity.
            float lambda, dot;
            Vector3.Dot(ref jLinearA, ref connectionA.linearVelocity, out lambda);
            Vector3.Dot(ref jAngularA, ref connectionA.angularVelocity, out dot);
            lambda += dot;
            Vector3.Dot(ref jLinearB, ref connectionB.linearVelocity, out dot);
            lambda += dot;
            Vector3.Dot(ref jAngularB, ref connectionB.angularVelocity, out dot);
            lambda += dot;

            //Add in the constraint space bias velocity
            lambda = -lambda + biasVelocity - softness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Clamp acreplacedulated impulse (can't go negative)
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Max(acreplacedulatedImpulse + lambda, 0);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jLinearA, lambda, out impulse);
                connectionA.ApplyLinearImpulse(ref impulse);
                Vector3.Multiply(ref jAngularA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jLinearB, lambda, out impulse);
                connectionB.ApplyLinearImpulse(ref impulse);
                Vector3.Multiply(ref jAngularB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return (Math.Abs(lambda));
        }

19 View Source File : MotionTable.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

public void change_cycle_speed(Sequence sequence, MotionData motionData, float substateMod, float speedMod)
        {
            if (Math.Abs(substateMod) > PhysicsGlobals.EPSILON)
                sequence.multiply_cyclic_animation_framerate(speedMod / substateMod);

            else if (Math.Abs(speedMod) < PhysicsGlobals.EPSILON)
                sequence.multiply_cyclic_animation_framerate(0);
        }

19 View Source File : WheelBrake.cs
License : The Unlicense
Project Creator : aeroson

internal void PreStep(float dt)
        {
            vehicleEnreplacedy = wheel.Vehicle.Body;
            supportEnreplacedy = wheel.SupportingEnreplacedy;
            supportIsDynamic = supportEnreplacedy != null && supportEnreplacedy.isDynamic;

            //Grab jacobian and mreplaced matrix from the driving motor!
            linearAX = wheel.drivingMotor.linearAX;
            linearAY = wheel.drivingMotor.linearAY;
            linearAZ = wheel.drivingMotor.linearAZ;

            angularAX = wheel.drivingMotor.angularAX;
            angularAY = wheel.drivingMotor.angularAY;
            angularAZ = wheel.drivingMotor.angularAZ;
            angularBX = wheel.drivingMotor.angularBX;
            angularBY = wheel.drivingMotor.angularBY;
            angularBZ = wheel.drivingMotor.angularBZ;

            velocityToImpulse = wheel.drivingMotor.velocityToImpulse;

            //Friction
            //Which coefficient? Check velocity.
            if (isBraking)
                if (Math.Abs(RelativeVelocity) < staticFrictionVelocityThreshold)
                    blendedCoefficient = frictionBlender(staticBrakingFrictionCoefficient, wheel.supportMaterial.staticFriction, false, wheel);
                else
                    blendedCoefficient = frictionBlender(kineticBrakingFrictionCoefficient, wheel.supportMaterial.kineticFriction, true, wheel);
            else
                blendedCoefficient = rollingFrictionCoefficient;


        }

19 View Source File : Landblock.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

public bool OnRoad(Vector3 obj)
        {
            int x = (int)(obj.X / TileLength);
            int y = (int)(obj.Y / TileLength);

            float rMin = RoadWidth;
            float rMax = TileLength - RoadWidth;

            int x0 = x;
            int x1 = x0 + 1;
            int y0 = y;
            int y1 = y0 + 1;

            uint r0 = GetRoad(x0, y0);
            uint r1 = GetRoad(x0, y1);
            uint r2 = GetRoad(x1, y0);
            uint r3 = GetRoad(x1, y1);

            if (r0 == 0 && r1 == 0 && r2 == 0 && r3 == 0)
                return false;

            float dx = obj.X - x * TileLength;
            float dy = obj.Y - y * TileLength;

            if (r0 > 0)
            {
                if (r1 > 0)
                {
                    if (r2 > 0)
                    {
                        if (r3 > 0)
                            return true;
                        else
                            return (dx < rMin || dy < rMin);
                    }
                    else
                    {
                        if (r3 > 0)
                            return (dx < rMin || dy > rMax);
                        else
                            return (dx < rMin);
                    }
                }
                else
                {
                    if (r2 > 0)
                    {
                        if (r3 > 0)
                            return (dx > rMax || dy < rMin);
                        else
                            return (dy < rMin);
                    }
                    else
                    {
                        if (r3 > 0)
                            return (Math.Abs(dx - dy) < rMin);
                        else
                            return (dx + dy < rMin);
                    }
                }
            }
            else
            {
                if (r1 > 0)
                {
                    if (r2 > 0)
                    {
                        if (r3 > 0)
                            return (dx > rMax || dy > rMax);
                        else
                            return (Math.Abs(dx + dy - TileLength) < rMin);
                    }
                    else
                    {
                        if (r3 > 0)
                            return (dy > rMax);
                        else
                            return (TileLength + dx - dy < rMin);
                    }
                }
                else
                {
                    if (r2 > 0)
                    {
                        if (r3 > 0)
                            return (dx > rMax);
                        else
                            return (TileLength - dx + dy < rMin);
                    }
                    else
                    {
                        if (r3 > 0)
                            return (TileLength * 2f - dx - dy < rMin);
                        else
                            return false;
                    }
                }
            }
        }

19 View Source File : EllipseSwingLimit.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            float velocityA, velocityB;
            //Find the velocity contribution from each connection
            Vector3.Dot(ref connectionA.angularVelocity, ref jacobianA, out velocityA);
            Vector3.Dot(ref connectionB.angularVelocity, ref jacobianB, out velocityB);
            //Add in the constraint space bias velocity
            float lambda = (-velocityA - velocityB) - biasVelocity - softness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Clamp acreplacedulated impulse (can't go negative)
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Min(acreplacedulatedImpulse + lambda, 0);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jacobianA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jacobianB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return (Math.Abs(lambda));
        }

19 View Source File : TwistMotor.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            float velocityA, velocityB;
            //Find the velocity contribution from each connection
            Vector3.Dot(ref connectionA.angularVelocity, ref jacobianA, out velocityA);
            Vector3.Dot(ref connectionB.angularVelocity, ref jacobianB, out velocityB);
            //Add in the constraint space bias velocity
            float lambda = -(velocityA + velocityB) + biasVelocity - usedSoftness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Acreplacedulate the impulse
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Clamp(acreplacedulatedImpulse + lambda, -maxForceDt, maxForceDt);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jacobianA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jacobianB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return Math.Abs(lambda);
        }

19 View Source File : BatFamiliar.cs
License : GNU General Public License v3.0
Project Creator : aedenthorn

public override void behaviorAtGameTick(GameTime time)
        {
            invincibleCountdown = 1000;
            if (timeBeforeAIMovementAgain > 0f)
            {
                timeBeforeAIMovementAgain -= (float)time.ElapsedGameTime.Milliseconds;
            }
            if (lastHitCounter >= 0)
            {
                lastHitCounter.Value -= time.ElapsedGameTime.Milliseconds;
            }
            if (lastScreechCounter >= 0)
            {
                lastScreechCounter.Value -= time.ElapsedGameTime.Milliseconds;
            }
            if (lastScreechCounter < 0 && GetBoundingBox().Intersects(GetOwner().GetBoundingBox()))
            {
                if(ModEntry.Config.BatSoundEffects)
                    currentLocation.playSound("batScreech", NetAudio.SoundContext.Default);
                lastScreechCounter.Value = 10000;
            }

            chargingMonster = false;
            if(lastHitCounter < 0 && !(currentLocation is SlimeHutch))
            {
                foreach (NPC npc in currentLocation.characters)
                {
                    if (npc is Familiar)
                        continue;

                    if (npc is Monster && FamiliarsUtils.monstersColliding(this, (Monster)npc))
                    {
                        if (BaseDamage() >= 0)
                        {
                            int damageAmount = Game1.random.Next(BaseDamage(), BaseDamage() * 2 + 1);
                            damageAmount = (npc as Monster).takeDamage(damageAmount, 0, 0, false, 0, GetOwner());
                            if((npc as Monster).Health <= 0)
                            {
                                AddExp(10);
                            }
                            else
                            {
                                AddExp(1);
                            }
                        }
                        lastHitCounter.Value = AttackInterval();
                        chargingMonster = false;
                        break;
                    }
                    else if (npc is Monster && FamiliarsUtils.withinMonsterThreshold(this, (Monster)npc, 2))
                    {
                        chargingMonster = true;
                        if (currentTarget == null || Vector2.Distance(npc.position, position) < Vector2.Distance(currentTarget.position, position))
                        {
                            currentTarget = (Monster)npc;
                        }
                    }
                }
            }

            if (wareplacedCounter >= 0)
            {
                wareplacedCounter.Value -= time.ElapsedGameTime.Milliseconds;
            }

            if (chargingMonster || followingOwner)
            {
                seenPlayer.Value = true;

                Vector2 center = Position + new Vector2(8, 8);
                Vector2 playerCenter = GetOwner().position + new Vector2(64, 92);
                if (Vector2.Distance(playerCenter, center) > 256)
                {
                    Position = Vector2.Distance(playerCenter, center) * 0.03f * Vector2.Normalize(playerCenter - center) + center - new Vector2(8, 8);

                }

                float xSlope = (float)(-(float)(playerCenter.X - center.X));
                float ySlope = (float)(playerCenter.Y - center.Y);
                float t = Math.Max(1f, Math.Abs(xSlope) + Math.Abs(ySlope));
                if (t < (float)((extraVelocity > 0f) ? 192 : 64))
                {
                    xVelocity = Math.Max(-maxSpeed, Math.Min(maxSpeed, xVelocity * 1.05f));
                    yVelocity = Math.Max(-maxSpeed, Math.Min(maxSpeed, yVelocity * 1.05f));
                }
                xSlope /= t;
                ySlope /= t;
                if (wareplacedCounter <= 0)
                {
                    targetRotation = (float)Math.Atan2((double)(-(double)ySlope), (double)xSlope) - 1.57079637f;
                    if ((double)(Math.Abs(targetRotation) - Math.Abs(rotation)) > 2.748893571891069 && Game1.random.NextDouble() < 0.5)
                    {
                        turningRight.Value = true;
                    }
                    else if ((double)(Math.Abs(targetRotation) - Math.Abs(rotation)) < 0.39269908169872414)
                    {
                        turningRight.Value = false;
                    }
                    if (turningRight)
                    {
                        rotation -= (float)Math.Sign(targetRotation - rotation) * 0.0490873866f;
                    }
                    else
                    {
                        rotation += (float)Math.Sign(targetRotation - rotation) * 0.0490873866f;
                    }
                    rotation %= 6.28318548f;
                    wareplacedCounter.Value = 0;
                }
                float maxAccel = Math.Min(5f, Math.Max(1f, 5f - t / 64f / 2f)) + extraVelocity;
                xSlope = (float)Math.Cos((double)rotation + 1.5707963267948966);
                ySlope = -(float)Math.Sin((double)rotation + 1.5707963267948966);
                xVelocity += -xSlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
                yVelocity += -ySlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
                if (Math.Abs(xVelocity) > Math.Abs(-xSlope * maxSpeed))
                {
                    xVelocity -= -xSlope * maxAccel / 6f;
                }
                if (Math.Abs(yVelocity) > Math.Abs(-ySlope * maxSpeed))
                {
                    yVelocity -= -ySlope * maxAccel / 6f;
                }
            }
        }

19 View Source File : LinearAxisMotor.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            //Compute the current relative velocity.
            float lambda, dot;
            Vector3.Dot(ref jLinearA, ref connectionA.linearVelocity, out lambda);
            Vector3.Dot(ref jAngularA, ref connectionA.angularVelocity, out dot);
            lambda += dot;
            Vector3.Dot(ref jLinearB, ref connectionB.linearVelocity, out dot);
            lambda += dot;
            Vector3.Dot(ref jAngularB, ref connectionB.angularVelocity, out dot);
            lambda += dot;

            //Add in the constraint space bias velocity
            lambda = -lambda + biasVelocity - usedSoftness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= mreplacedMatrix;

            //Clamp acreplacedulated impulse
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Clamp(acreplacedulatedImpulse + lambda, -maxForceDt, maxForceDt);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jLinearA, lambda, out impulse);
                connectionA.ApplyLinearImpulse(ref impulse);
                Vector3.Multiply(ref jAngularA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jLinearB, lambda, out impulse);
                connectionB.ApplyLinearImpulse(ref impulse);
                Vector3.Multiply(ref jAngularB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return (Math.Abs(lambda));
        }

19 View Source File : Sequence.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

public void apply_physics(AFrame frame, float quantum, float sign)
        {
            if (sign >= 0.0)
                quantum = Math.Abs(quantum);
            else
                quantum = -Math.Abs(quantum);

            frame.Origin += Velocity * quantum;
            frame.Rotate(Omega * quantum);
        }

19 View Source File : ContactFrictionConstraint.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            //Compute relative velocity and convert to impulse
            float lambda = RelativeVelocity * velocityToImpulse;


            //Clamp acreplacedulated impulse
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            float maxForce = friction * penetrationConstraint.acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Clamp(acreplacedulatedImpulse + lambda, -maxForce, maxForce);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
#if !WINDOWS
            Vector3 linear = new Vector3();
            Vector3 angular = new Vector3();
#else
            Vector3 linear, angular;
#endif
            linear.X = lambda * linearAX;
            linear.Y = lambda * linearAY;
            linear.Z = lambda * linearAZ;
            if (enreplacedyAIsDynamic)
            {
                angular.X = lambda * angularAX;
                angular.Y = lambda * angularAY;
                angular.Z = lambda * angularAZ;
                enreplacedyA.ApplyLinearImpulse(ref linear);
                enreplacedyA.ApplyAngularImpulse(ref angular);
            }
            if (enreplacedyBIsDynamic)
            {
                linear.X = -linear.X;
                linear.Y = -linear.Y;
                linear.Z = -linear.Z;
                angular.X = lambda * angularBX;
                angular.Y = lambda * angularBY;
                angular.Z = lambda * angularBZ;
                enreplacedyB.ApplyLinearImpulse(ref linear);
                enreplacedyB.ApplyAngularImpulse(ref angular);
            }

            return Math.Abs(lambda);
        }

19 View Source File : SwimHelperEvents.cs
License : GNU General Public License v3.0
Project Creator : aedenthorn

public static void AbigailCaveTick()
        {

            Game1.player.CurrentToolIndex = Game1.player.items.Count;

            List<NPC> list = Game1.player.currentLocation.characters.ToList().FindAll((n) => (n is Monster) && (n as Monster).Health <= 0);
            foreach(NPC n in list)
            {
                Game1.player.currentLocation.characters.Remove(n);
            }

            if (abigailTicks.Value < 0)
            {
                return;
            }
            Game1.exitActiveMenu();

            if (abigailTicks.Value == 0)
            {
                FieldInfo f1 = Game1.player.currentLocation.characters.GetType().GetField("OnValueRemoved", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
                f1.SetValue(Game1.player.currentLocation.characters, null);
            }

            Vector2 v = Vector2.Zero;
            float yrt = (float)(1/Math.Sqrt(2));
            if (Helper.Input.IsDown(SButton.Up) || Helper.Input.IsDown(SButton.RightThumbstickUp))
            {
                if(Helper.Input.IsDown(SButton.Right) || Helper.Input.IsDown(SButton.RightThumbstickRight))
                    v = new Vector2(yrt, -yrt);
                else if(Helper.Input.IsDown(SButton.Left) || Helper.Input.IsDown(SButton.RightThumbstickLeft))
                    v = new Vector2(-yrt, -yrt);
                else 
                    v = new Vector2(0, -1);
            }
            else if (Helper.Input.IsDown(SButton.Down) || Helper.Input.IsDown(SButton.RightThumbstickDown))
            {
                if(Helper.Input.IsDown(SButton.Right) || Helper.Input.IsDown(SButton.RightThumbstickRight))
                    v = new Vector2(yrt, yrt);
                else if(Helper.Input.IsDown(SButton.Left) || Helper.Input.IsDown(SButton.RightThumbstickLeft))
                    v = new Vector2(-yrt, yrt);
                else 
                    v = new Vector2(0, 1);
            }
            else if (Helper.Input.IsDown(SButton.Right) || Helper.Input.IsDown(SButton.RightThumbstickDown))
                v = new Vector2(1, 0);
            else if (Helper.Input.IsDown(SButton.Left) || Helper.Input.IsDown(SButton.RightThumbstickLeft))
                v = new Vector2(-1, 0);
            else if (Helper.Input.IsDown(SButton.MouseLeft))
            {
                float x = Game1.viewport.X + Game1.getOldMouseX() - Game1.player.position.X;
                float y = Game1.viewport.Y + Game1.getOldMouseY() - Game1.player.position.Y;
                float dx = Math.Abs(x);
                float dy = Math.Abs(y);
                if(y < 0)
                {
                    if(x > 0)
                    {
                        if(dy > dx)
                        {
                            if (dy-dx > dy / 2)
                                v = new Vector2(0, -1);
                            else
                                v = new Vector2(yrt, -yrt);

                        }
                        else
                        {
                            if (dx - dy > x / 2)
                                v = new Vector2(1, 0);
                            else
                                v = new Vector2(yrt, -yrt);
                        }
                    }
                    else
                    {
                        if (dy > dx)
                        {
                            if (dy - dx > dy / 2)
                                v = new Vector2(0, -1);
                            else
                                v = new Vector2(-yrt, -yrt);

                        }
                        else
                        {
                            if (dx - dy > x / 2)
                                v = new Vector2(-1, 0);
                            else
                                v = new Vector2(-yrt, -yrt);
                        }
                    }
                }
                else
                {
                    if (x > 0)
                    {
                        if (dy > dx)
                        {
                            if (dy - dx > dy / 2)
                                v = new Vector2(0, 1);
                            else
                                v = new Vector2(yrt, yrt);

                        }
                        else
                        {
                            if (dx - dy > x / 2)
                                v = new Vector2(1, 0);
                            else
                                v = new Vector2(yrt, yrt);
                        }
                    }
                    else
                    {
                        if (dy > dx)
                        {
                            if (dy - dx > dy / 2)
                                v = new Vector2(0, -1);
                            else
                                v = new Vector2(-yrt, yrt);

                        }
                        else
                        {
                            if (dx - dy > x / 2)
                                v = new Vector2(-1, 0);
                            else
                                v = new Vector2(-yrt, yrt);
                        }
                    }
                }
            }

            if (v != Vector2.Zero && Game1.player.millisecondsPlayed - lastProjectile.Value > 350)
            {
                Game1.player.currentLocation.projectiles.Add(new AbigailProjectile(1, 383, 0, 0, 0, v.X * 6, v.Y * 6, new Vector2(Game1.player.getStandingX() - 24, Game1.player.getStandingY() - 48), "Cowboy_monsterDie", "Cowboy_gunshot", false, true, Game1.player.currentLocation, Game1.player, true)); 
                lastProjectile.Value = Game1.player.millisecondsPlayed;
            }

            foreach (SButton button in abigailShootButtons)
            {
                if (Helper.Input.IsDown(button))
                {
                    switch (button)
                    {
                        case SButton.Up:
                            break;
                        case SButton.Right:
                            v = new Vector2(1, 0);
                            break;
                        case SButton.Down:
                            v = new Vector2(0, 1);
                            break;
                        default:
                            v = new Vector2(-1, 0);
                            break;
                    }
                }
            }


            abigailTicks.Value++;
            if(abigailTicks.Value > 80000 / 16f)
            {
                if (Game1.player.currentLocation.characters.ToList().FindAll((n) => (n is Monster)).Count > 0)
                    return;

                abigailTicks.Value = -1;
                Game1.player.hat.Value = null;
                Game1.stopMusicTrack(Game1.MusicContext.Default);

                if(!Game1.player.mailReceived.Contains("ScubaFins"))
                {
                    Game1.playSound("Cowboy_Secret");
                    SwimMaps.AddScubaChest(Game1.player.currentLocation, new Vector2(8, 8), "ScubaFins");
                }

                Game1.player.currentLocation.setMapTile(8, 16, 91, "Buildings", null);
                Game1.player.currentLocation.setMapTile(9, 16, 92, "Buildings", null);
                Game1.player.currentLocation.setTileProperty(9, 16, "Back", "Water", "T");
                Game1.player.currentLocation.setMapTile(10, 16, 93, "Buildings", null);
                Game1.player.currentLocation.setMapTile(8, 17, 107, "Buildings", null);
                Game1.player.currentLocation.setMapTile(9, 17, 108, "Back", null);
                Game1.player.currentLocation.setTileProperty(9, 17, "Back", "Water", "T");
                Game1.player.currentLocation.removeTile(9, 17, "Buildings");
                Game1.player.currentLocation.setMapTile(10, 17, 109, "Buildings", null); 
                Game1.player.currentLocation.setMapTile(8, 18, 139, "Buildings", null);
                Game1.player.currentLocation.setMapTile(9, 18, 140, "Buildings", null);
                Game1.player.currentLocation.setMapTile(10, 18, 141, "Buildings", null);
                SwimMaps.AddWaterTiles(Game1.player.currentLocation);
            }
            else
            {
                if (Game1.random.NextDouble() < 0.03)
                {
                    int which = Game1.random.Next(3);
                    Point p = new Point();
                    switch (Game1.random.Next(4))
                    {
                        case 0:
                            p = new Point(8 + which, 1);
                            break;
                        case 1:
                            p = new Point(1, 8 + which);
                            break;
                        case 2:
                            p = new Point(8 + which, 16);
                            break;
                        case 3:
                            p = new Point(16, 8 + which);
                            break;
                    }
                    Game1.player.currentLocation.characters.Add(new AbigailMetalHead(new Vector2(p.X * Game1.tileSize, p.Y * Game1.tileSize), 0));
                }

            }
        }

19 View Source File : RevoluteLimit.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            float lambda;
            float lambdaTotal = 0;
            float velocityA, velocityB;
            float previousAcreplacedulatedImpulse;
            if (minIsActive)
            {
                //Find the velocity contribution from each connection
                Vector3.Dot(ref connectionA.angularVelocity, ref jacobianMinA, out velocityA);
                Vector3.Dot(ref connectionB.angularVelocity, ref jacobianMinB, out velocityB);
                //Add in the constraint space bias velocity
                lambda = -(velocityA + velocityB) + biasVelocity.X - softness * acreplacedulatedImpulse.X;

                //Transform to an impulse
                lambda *= velocityToImpulse.X;

                //Clamp acreplacedulated impulse (can't go negative)
                previousAcreplacedulatedImpulse = acreplacedulatedImpulse.X;
                acreplacedulatedImpulse.X = MathHelper.Max(acreplacedulatedImpulse.X + lambda, 0);
                lambda = acreplacedulatedImpulse.X - previousAcreplacedulatedImpulse;

                //Apply the impulse
                Vector3 impulse;
                if (connectionA.isDynamic)
                {
                    Vector3.Multiply(ref jacobianMinA, lambda, out impulse);
                    connectionA.ApplyAngularImpulse(ref impulse);
                }
                if (connectionB.isDynamic)
                {
                    Vector3.Multiply(ref jacobianMinB, lambda, out impulse);
                    connectionB.ApplyAngularImpulse(ref impulse);
                }

                lambdaTotal += Math.Abs(lambda);
            }
            if (maxIsActive)
            {
                //Find the velocity contribution from each connection
                Vector3.Dot(ref connectionA.angularVelocity, ref jacobianMaxA, out velocityA);
                Vector3.Dot(ref connectionB.angularVelocity, ref jacobianMaxB, out velocityB);
                //Add in the constraint space bias velocity
                lambda = -(velocityA + velocityB) + biasVelocity.Y - softness * acreplacedulatedImpulse.Y;

                //Transform to an impulse
                lambda *= velocityToImpulse.Y;

                //Clamp acreplacedulated impulse (can't go negative)
                previousAcreplacedulatedImpulse = acreplacedulatedImpulse.Y;
                acreplacedulatedImpulse.Y = MathHelper.Max(acreplacedulatedImpulse.Y + lambda, 0);
                lambda = acreplacedulatedImpulse.Y - previousAcreplacedulatedImpulse;

                //Apply the impulse
                Vector3 impulse;
                if (connectionA.isDynamic)
                {
                    Vector3.Multiply(ref jacobianMaxA, lambda, out impulse);
                    connectionA.ApplyAngularImpulse(ref impulse);
                }
                if (connectionB.isDynamic)
                {
                    Vector3.Multiply(ref jacobianMaxB, lambda, out impulse);
                    connectionB.ApplyAngularImpulse(ref impulse);
                }

                lambdaTotal += Math.Abs(lambda);
            }
            return lambdaTotal;
        }

19 View Source File : FloatExtensions.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

public static bool EpsilonEquals(this float num, float val/*, int decimalPlaces = 4*/)
        {
            //var epsilon = 1.0f / Math.Pow(10, decimalPlaces);
            var epsilon = 0.0001f;

            return Math.Abs(num - val) < epsilon;
        }

19 View Source File : RevoluteMotor.cs
License : The Unlicense
Project Creator : aeroson

public override void Update(float dt)
        {
            //Transform the axes into world space.
            basis.rotationMatrix = connectionA.orientationMatrix;
            basis.ComputeWorldSpaceAxes();
            Matrix3x3.Transform(ref localTestAxis, ref connectionB.orientationMatrix, out worldTestAxis);

            float updateRate = 1 / dt;
            if (settings.mode == MotorMode.Servomechanism)
            {
                float y, x;
                Vector3 yAxis;
                Vector3.Cross(ref basis.primaryAxis, ref basis.xAxis, out yAxis);
                Vector3.Dot(ref worldTestAxis, ref yAxis, out y);
                Vector3.Dot(ref worldTestAxis, ref basis.xAxis, out x);
                var angle = (float)Math.Atan2(y, x);

                //****** VELOCITY BIAS ******//
                //Compute the correction velocity.
                error = GetDistanceFromGoal(angle);


                float absErrorOverDt = Math.Abs(error * updateRate);
                float errorReduction;
                settings.servo.springSettings.ComputeErrorReductionAndSoftness(dt, updateRate, out errorReduction, out usedSoftness);
                biasVelocity = Math.Sign(error) * MathHelper.Min(settings.servo.baseCorrectiveSpeed, absErrorOverDt) + error * errorReduction;

                biasVelocity = MathHelper.Clamp(biasVelocity, -settings.servo.maxCorrectiveVelocity, settings.servo.maxCorrectiveVelocity);
            }
            else
            {
                biasVelocity = settings.velocityMotor.goalVelocity;
                usedSoftness = settings.velocityMotor.softness * updateRate;
                error = 0;
            }


            //Compute the jacobians
            jacobianA = basis.primaryAxis;
            jacobianB.X = -jacobianA.X;
            jacobianB.Y = -jacobianA.Y;
            jacobianB.Z = -jacobianA.Z;


            //****** EFFECTIVE Mreplaced MATRIX ******//
            //Connection A's contribution to the mreplaced matrix
            float entryA;
            Vector3 transformedAxis;
            if (connectionA.isDynamic)
            {
                Matrix3x3.Transform(ref jacobianA, ref connectionA.inertiaTensorInverse, out transformedAxis);
                Vector3.Dot(ref transformedAxis, ref jacobianA, out entryA);
            }
            else
                entryA = 0;

            //Connection B's contribution to the mreplaced matrix
            float entryB;
            if (connectionB.isDynamic)
            {
                Matrix3x3.Transform(ref jacobianB, ref connectionB.inertiaTensorInverse, out transformedAxis);
                Vector3.Dot(ref transformedAxis, ref jacobianB, out entryB);
            }
            else
                entryB = 0;

            //Compute the inverse mreplaced matrix
            velocityToImpulse = 1 / (usedSoftness + entryA + entryB);


            //Update the maximum force
            ComputeMaxForces(settings.maximumForce, dt);



        }

19 View Source File : TriangleConvexPairTester.cs
License : The Unlicense
Project Creator : aeroson

public override VoronoiRegion GetRegion(ref ContactData contact)
        {
            //Deep contact can produce non-triangle normals while still being within the triangle.
            //To solve this problem, find the voronoi region to which the contact belongs using its normal.
            //The voronoi region will be either the most extreme vertex, or the edge that includes
            //the first and second most extreme vertices.
            //If the normal dotted with an extreme edge direction is near 0, then it belongs to the edge.
            //Otherwise, it belongs to the vertex.
            //MPR tends to produce 'approximate' normals, though.
            //Use a fairly forgiving epsilon.
            float dotA, dotB, dotC;
            Vector3.Dot(ref triangle.vA, ref contact.Normal, out dotA);
            Vector3.Dot(ref triangle.vB, ref contact.Normal, out dotB);
            Vector3.Dot(ref triangle.vC, ref contact.Normal, out dotC);

            //Since normal points from convex to triangle always, reverse dot signs.
            dotA = -dotA;
            dotB = -dotB;
            dotC = -dotC;


            float faceEpsilon = .01f;
            const float edgeEpsilon = .01f;

            float edgeDot;
            Vector3 edgeDirection;
            if (dotA > dotB && dotA > dotC)
            {
                //A is extreme.
                if (dotB > dotC)
                {
                    //B is second most extreme.
                    if (Math.Abs(dotA - dotC) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return VoronoiRegion.ABC;
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vB, ref triangle.vA, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                            return VoronoiRegion.AB;
                        else
                            return VoronoiRegion.A;
                    }
                }
                else
                {
                    //C is second most extreme.
                    if (Math.Abs(dotA - dotB) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return VoronoiRegion.ABC;
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vC, ref triangle.vA, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                            return VoronoiRegion.AC;
                        else
                            return VoronoiRegion.A;
                    }
                }
            }
            else if (dotB > dotC)
            {
                //B is extreme.
                if (dotC > dotA)
                {
                    //C is second most extreme.
                    if (Math.Abs(dotB - dotA) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return VoronoiRegion.ABC;
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vC, ref triangle.vB, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                            return VoronoiRegion.BC;
                        else
                            return VoronoiRegion.B;
                    }
                }
                else
                {
                    //A is second most extreme.
                    if (Math.Abs(dotB - dotC) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return VoronoiRegion.ABC;
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vA, ref triangle.vB, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                            return VoronoiRegion.AB;
                        else
                            return VoronoiRegion.B;
                    }
                }
            }
            else
            {
                //C is extreme.
                if (dotA > dotB)
                {
                    //A is second most extreme.
                    if (Math.Abs(dotC - dotB) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return VoronoiRegion.ABC;
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vA, ref triangle.vC, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                            return VoronoiRegion.AC;
                        else
                            return VoronoiRegion.C;
                    }
                }
                else
                {
                    //B is second most extreme.
                    if (Math.Abs(dotC - dotA) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return VoronoiRegion.ABC;
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vB, ref triangle.vC, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                            return VoronoiRegion.BC;
                        else
                            return VoronoiRegion.C;
                    }
                }
            }

        }

19 View Source File : TriangleMeshConvexContactManifold.cs
License : The Unlicense
Project Creator : aeroson

public override void Update(float dt)
        {
            //First, refresh all existing contacts.  This is an incremental manifold.
            var transform = MeshTransform;
            ContactRefresher.ContactRefresh(contacts, supplementData, ref convex.worldTransform, ref transform, contactIndicesToRemove);

            RemoveQueuedContacts();


            CleanUpOverlappingTriangles();
            //Get all the overlapped triangle indices.
            int triangleCount = FindOverlappingTriangles(dt);

            Matrix3x3 orientation;
            Matrix3x3.CreateFromQuaternion(ref convex.worldTransform.Orientation, out orientation);
            var guaranteedContacts = 0;
            for (int i = 0; i < triangleCount; i++)
            {
                //Initialize the local triangle.
                TriangleIndices indices;
                if (ConfigureTriangle(i, out indices))
                {

                    //Find a pairtester for the triangle.
                    TrianglePairTester pairTester;
                    if (!activePairTesters.TryGetValue(indices, out pairTester))
                    {
                        pairTester = GetTester();
                        pairTester.Initialize(convex.Shape, localTriangleShape);
                        activePairTesters.Add(indices, pairTester);
                    }
                    pairTester.Updated = true;


                    //Put the triangle into the local space of the convex.
                    Vector3.Subtract(ref localTriangleShape.vA, ref convex.worldTransform.Position, out localTriangleShape.vA);
                    Vector3.Subtract(ref localTriangleShape.vB, ref convex.worldTransform.Position, out localTriangleShape.vB);
                    Vector3.Subtract(ref localTriangleShape.vC, ref convex.worldTransform.Position, out localTriangleShape.vC);
                    Matrix3x3.TransformTranspose(ref localTriangleShape.vA, ref orientation, out localTriangleShape.vA);
                    Matrix3x3.TransformTranspose(ref localTriangleShape.vB, ref orientation, out localTriangleShape.vB);
                    Matrix3x3.TransformTranspose(ref localTriangleShape.vC, ref orientation, out localTriangleShape.vC);

                    //Now, generate a contact between the two shapes.
                    ContactData contact;
                    TinyStructList<ContactData> contactList;
                    if (pairTester.GenerateContactCandidate(out contactList))
                    {
                        for (int j = 0; j < contactList.Count; j++)
                        {
                            contactList.Get(j, out contact);


                            if (UseImprovedBoundaryHandling)
                            {
                                if (replacedyzeCandidate(ref indices, pairTester, ref contact))
                                {
                                    //This is let through if there's a face contact. Face contacts cannot be blocked.
                                    guaranteedContacts++;
                                    AddLocalContact(ref contact, ref orientation);
                                }
                            }
                            else
                            {
                                AddLocalContact(ref contact, ref orientation);
                            }

                        }
                    }

                    //Get the voronoi region from the contact candidate generation.  Possibly just recalculate, since most of the systems don't calculate it.
                    //Depending on which voronoi region it is in (Switch on enumeration), identify the indices composing that region.  For face contacts, don't bother- just add it if unique.
                    //For AB, AC, or BC, add an Edge to the blockedEdgeRegions set with the corresponding indices.
                    //For A, B, or C, add the index of the vertex to the blockedVertexRegions set.
                    //If the edge/vertex is already present in the set, then DO NOT add the contact.
                    //When adding a contact, add ALL other voronoi regions to the blocked sets. 
                }

            }



            if (UseImprovedBoundaryHandling)
            {

                //If there were no face contacts that absolutely must be included, we may get into a very rare situation
                //where absolutely no contacts get created.  For example, a sphere falling directly on top of a vertex in a flat terrain.
                //It will generally get locked out of usage by belonging only to restricted regions (numerical issues make it visible by both edges and vertices).
                //In some cases, the contacts will be ignored instead of corrected (e.g. spheres).
                //To prevent objects from just falling through the ground in such a situation, force-correct the contacts regardless of the pair tester's desires.
                //Sure, it might not be necessary under normal cirreplacedstances, but it's a better option than having no contacts.
                //TODO: There is another option: Changing restricted regions so that a vertex only restricts the other two vertices and the far edge,
                //and an edge only restricts the far vertex and other two edges.  This introduces an occasional bump though...

                //It's possible, in very specific instances, for an object to wedge itself between two adjacent triangles.
                //For this state to continue beyond a brief instant generally requires the object be orientation locked and slender.
                //However, some characters fit this description, so it can't be ignored!

                //Conceptually, this issue can occur at either a vertex junction or a shared edge (usually on extremely flat surfaces only).
                //However, an object stuck between multiple triangles is not in a stable state.  In the edge case, the object gets shoved to one side
                //as one contact 'wins' the solver war.  That's not enough to escape, unfortunately.
                //The vertex case, on the other hand, is degenerate and decays into an edge case rapidly thanks to this lack of stability.
                //So, we don't have to explicitly handle the somewhat more annoying and computationally expensive vertex unstucking case, because the edge case handles both! :)

                //This isn't a completely free operation, but it's guarded behind pretty rare conditions.
                //Essentially, we will check to see if there's just edge contacts fighting against each other.
                //If they are, then we will correct any stuck-contributing normals to the triangle normal.
                if (vertexContacts.Count == 0 && guaranteedContacts == 0 && edgeContacts.Count > 1)
                {
                    //There are only edge contacts, check to see if:
                    //all normals are coplanar, and
                    //at least one normal faces against the other normals (meaning it's probably stuck, as opposed to just colliding on a corner).

                    bool allNormalsInSamePlane = true;
                    bool atLeastOneNormalAgainst = false;

                    var firstNormal = edgeContacts.Elements[0].ContactData.Normal;
                    edgeContacts.Elements[0].CorrectedNormal.Normalize();
                    float dot;
                    Vector3.Dot(ref firstNormal, ref edgeContacts.Elements[0].CorrectedNormal, out dot);
                    if (Math.Abs(dot) > .01f)
                    {
                        //Go ahead and test the first contact separately, since we're using its contact normal to determine coplanarity.
                        allNormalsInSamePlane = false;
                    }
                    else
                    {
                        //TODO: Note that we're only checking the new edge contacts, not the existing contacts.
                        //It's possible that some existing contacts could interfere and cause issues, but for the sake of simplicity and due to rarity
                        //we'll ignore that possibility for now.
                        for (int i = 1; i < edgeContacts.Count; i++)
                        {
                            Vector3.Dot(ref edgeContacts.Elements[i].ContactData.Normal, ref firstNormal, out dot);
                            if (dot < 0)
                            {
                                atLeastOneNormalAgainst = true;
                            }
                            //Check to see if the normal is outside the plane.
                            Vector3.Dot(ref edgeContacts.Elements[i].ContactData.Normal, ref edgeContacts.Elements[0].CorrectedNormal, out dot);

                            if (Math.Abs(dot) > .01f)
                            {

                                //We are not stuck!
                                allNormalsInSamePlane = false;
                                break;
                            }
                        }
                    }

                    if (allNormalsInSamePlane && atLeastOneNormalAgainst)
                    {
                        //Uh oh! all the normals are parallel... The object is probably in a weird situation.
                        //Let's correct the normals!

                        //Already normalized the first contact above.
                        //We don't need to perform the perpendicularity test here- we did that before! We know it's perpendicular already.
                        edgeContacts.Elements[0].ContactData.Normal = edgeContacts.Elements[0].CorrectedNormal;
                        edgeContacts.Elements[0].ShouldCorrect = true;

                        for (int i = 1; i < edgeContacts.Count; i++)
                        {
                            //Must normalize the corrected normal before using it.
                            edgeContacts.Elements[i].CorrectedNormal.Normalize();
                            Vector3.Dot(ref edgeContacts.Elements[i].CorrectedNormal, ref edgeContacts.Elements[i].ContactData.Normal, out dot);
                            if (dot < .01)
                            {
                                //Only bother doing the correction if the normal appears to be pointing nearly horizontally- implying that it's a contributor to the stuckness!
                                //If it's blocked, the next section will use the corrected normal- if it's not blocked, the next section will use the direct normal.
                                //Make them the same thing :)
                                edgeContacts.Elements[i].ContactData.Normal = edgeContacts.Elements[i].CorrectedNormal;
                                edgeContacts.Elements[i].ShouldCorrect = true;
                                //Note that the penetration depth is NOT corrected.  The contact's depth no longer represents the true depth.
                                //However, we only need to have some penetration depth to get the object to escape the rut.
                                //Furthermore, the depth computed from the horizontal opposing contacts is known to be less than the depth in the perpendicular direction.
                                //If the current depth was NOT less than the true depth along the corrected normal, then the collision detection system 
                                //would have picked a different depth, as it finds a reasonable approximation of the minimum penetration!
                                //As a consequence, this contact will not be active beyond the object's destuckification, because its contact depth will be negative (or very close to it).

                            }
                        }
                    }
                }


              


                for (int i = 0; i < edgeContacts.Count; i++)
                {
                    //Only correct if it's allowed AND it's blocked.
                    //If it's not blocked, the contact being created is necessary!
                    //The normal generated by the triangle-convex tester is already known not to
                    //violate the triangle sidedness.
                    if (!blockedEdgeRegions.Contains(edgeContacts.Elements[i].Edge))
                    {
                        //If it's not blocked, use the contact as-is without correcting it.
                        AddLocalContact(ref edgeContacts.Elements[i].ContactData, ref orientation);

                    }
                    else if (edgeContacts.Elements[i].ShouldCorrect || guaranteedContacts == 0)
                    {
                        //If it is blocked, we can still make use of the contact.  But first, we need to change the contact normal to ensure that
                        //it will not interfere (and cause a bump or something).
                        float dot;
                        edgeContacts.Elements[i].CorrectedNormal.Normalize();
                        Vector3.Dot(ref edgeContacts.Elements[i].CorrectedNormal, ref edgeContacts.Elements[i].ContactData.Normal, out dot);
                        edgeContacts.Elements[i].ContactData.Normal = edgeContacts.Elements[i].CorrectedNormal;
                        edgeContacts.Elements[i].ContactData.PenetrationDepth *= MathHelper.Max(0, dot); //Never cause a negative penetration depth.
                        AddLocalContact(ref edgeContacts.Elements[i].ContactData, ref orientation);
                    }
                    //If it's blocked AND it doesn't allow correction, ignore its existence.



                }




                for (int i = 0; i < vertexContacts.Count; i++)
                {

                    if (!blockedVertexRegions.Contains(vertexContacts.Elements[i].Vertex))
                    {
                        //If it's not blocked, use the contact as-is without correcting it.
                        AddLocalContact(ref vertexContacts.Elements[i].ContactData, ref orientation);
                    }
                    else if (vertexContacts.Elements[i].ShouldCorrect || guaranteedContacts == 0)
                    {
                        //If it is blocked, we can still make use of the contact.  But first, we need to change the contact normal to ensure that
                        //it will not interfere (and cause a bump or something).
                        float dot;
                        vertexContacts.Elements[i].CorrectedNormal.Normalize();
                        Vector3.Dot(ref vertexContacts.Elements[i].CorrectedNormal, ref vertexContacts.Elements[i].ContactData.Normal, out dot);
                        vertexContacts.Elements[i].ContactData.Normal = vertexContacts.Elements[i].CorrectedNormal;
                        vertexContacts.Elements[i].ContactData.PenetrationDepth *= MathHelper.Max(0, dot); //Never cause a negative penetration depth.
                        AddLocalContact(ref vertexContacts.Elements[i].ContactData, ref orientation);
                    }
                    //If it's blocked AND it doesn't allow correction, ignore its existence.


                }



                blockedEdgeRegions.Clear();
                blockedVertexRegions.Clear();
                vertexContacts.Clear();
                edgeContacts.Clear();


            }



            //Remove stale pair testers.
            //This will only remove 8 stale ones per frame, but it doesn't really matter.
            //VERY rarely will there be more than 8 in a single frame, and they will be immediately taken care of in the subsequent frame.
            var toRemove = new TinyList<TriangleIndices>();
            foreach (KeyValuePair<TriangleIndices, TrianglePairTester> pair in activePairTesters)
            {
                if (!pair.Value.Updated)
                {
                    if (!toRemove.Add(pair.Key))
                        break;
                }
                else
                    pair.Value.Updated = false;
            }



            for (int i = toRemove.Count - 1; i >= 0; i--)
            {
                var pairTester = activePairTesters[toRemove[i]];
                pairTester.CleanUp();
                GiveBackTester(pairTester);
                activePairTesters.Remove(toRemove[i]);
            }


            //Some child types will want to do some extra post processing on the manifold.        
            ProcessCandidates(candidatesToAdd);


            //Check if adding the new contacts would overflow the manifold.
            if (contacts.Count + candidatesToAdd.Count > 4)
            {
                //Adding all the contacts would overflow the manifold.  Reduce to the best subset.
                ContactReducer.ReduceContacts(contacts, candidatesToAdd, contactIndicesToRemove, reducedCandidates);
                RemoveQueuedContacts();
                for (int i = reducedCandidates.Count - 1; i >= 0; i--)
                {
                    Add(ref reducedCandidates.Elements[i]);
                    reducedCandidates.RemoveAt(i);
                }
            }
            else if (candidatesToAdd.Count > 0)
            {
                //Won't overflow the manifold, so just toss it in PROVIDED that it isn't too close to something else.
                for (int i = 0; i < candidatesToAdd.Count; i++)
                {
                    Add(ref candidatesToAdd.Elements[i]);
                }
            }



            candidatesToAdd.Clear();

        }

19 View Source File : WorldDatabaseWithEntityCache.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

private void TreasureMaterialBase_Normalize(Dictionary<int, Dictionary<int, List<TreasureMaterialBase>>> materialBase)
        {
            foreach (var kvp in materialBase)
            {
                var materialCode = kvp.Key;
                var tiers = kvp.Value;

                foreach (var kvp2 in tiers)
                {
                    var tier = kvp2.Key;
                    var list = kvp2.Value;

                    var totalProbability = list.Sum(i => i.Probability);

                    if (Math.Abs(1.0f - totalProbability) < NormalizeEpsilon)
                        continue;

                    //Console.WriteLine($"TotalProbability {totalProbability} found for TreasureMaterialBase {materialCode} tier {tier}");

                    var factor = 1.0f / totalProbability;

                    foreach (var item in list)
                        item.Probability *= factor;

                    /*totalProbability = list.Sum(i => i.Probability);

                    Console.WriteLine($"After: {totalProbability}");*/
                }
            }
        }

19 View Source File : RevoluteMotor.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            float velocityA, velocityB;
            //Find the velocity contribution from each connection
            Vector3.Dot(ref connectionA.angularVelocity, ref jacobianA, out velocityA);
            Vector3.Dot(ref connectionB.angularVelocity, ref jacobianB, out velocityB);
            //Add in the constraint space bias velocity
            float lambda = -(velocityA + velocityB) - biasVelocity - usedSoftness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Acreplacedulate the impulse
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Clamp(acreplacedulatedImpulse + lambda, -maxForceDt, maxForceDt);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jacobianA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jacobianB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return Math.Abs(lambda);
        }

19 View Source File : MoveToManager.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

public static float heading_diff(float h1, float h2, uint motion)
        {
            var result = h1 - h2;

            if (Math.Abs(result) < PhysicsGlobals.EPSILON)
                result = 0.0f;
            if (result < -PhysicsGlobals.EPSILON)
                result += 360.0f;
            if (result > PhysicsGlobals.EPSILON && motion != (uint)MotionCommand.TurnRight)
                result = 360.0f - result;
            return result;
        }

19 View Source File : TwistFrictionConstraint.cs
License : The Unlicense
Project Creator : aeroson

public override void Update(float dt)
        {

            enreplacedyADynamic = enreplacedyA != null && enreplacedyA.isDynamic;
            enreplacedyBDynamic = enreplacedyB != null && enreplacedyB.isDynamic;

            //Compute the jacobian......  Real hard!
            Vector3 normal = contactManifoldConstraint.penetrationConstraints.Elements[0].contact.Normal;
            angularX = normal.X;
            angularY = normal.Y;
            angularZ = normal.Z;

            //Compute inverse effective mreplaced matrix
            float entryA, entryB;

            //these are the transformed coordinates
            float tX, tY, tZ;
            if (enreplacedyADynamic)
            {
                tX = angularX * enreplacedyA.inertiaTensorInverse.M11 + angularY * enreplacedyA.inertiaTensorInverse.M21 + angularZ * enreplacedyA.inertiaTensorInverse.M31;
                tY = angularX * enreplacedyA.inertiaTensorInverse.M12 + angularY * enreplacedyA.inertiaTensorInverse.M22 + angularZ * enreplacedyA.inertiaTensorInverse.M32;
                tZ = angularX * enreplacedyA.inertiaTensorInverse.M13 + angularY * enreplacedyA.inertiaTensorInverse.M23 + angularZ * enreplacedyA.inertiaTensorInverse.M33;
                entryA = tX * angularX + tY * angularY + tZ * angularZ + enreplacedyA.inverseMreplaced;
            }
            else
                entryA = 0;

            if (enreplacedyBDynamic)
            {
                tX = angularX * enreplacedyB.inertiaTensorInverse.M11 + angularY * enreplacedyB.inertiaTensorInverse.M21 + angularZ * enreplacedyB.inertiaTensorInverse.M31;
                tY = angularX * enreplacedyB.inertiaTensorInverse.M12 + angularY * enreplacedyB.inertiaTensorInverse.M22 + angularZ * enreplacedyB.inertiaTensorInverse.M32;
                tZ = angularX * enreplacedyB.inertiaTensorInverse.M13 + angularY * enreplacedyB.inertiaTensorInverse.M23 + angularZ * enreplacedyB.inertiaTensorInverse.M33;
                entryB = tX * angularX + tY * angularY + tZ * angularZ + enreplacedyB.inverseMreplaced;
            }
            else
                entryB = 0;

            velocityToImpulse = -1 / (entryA + entryB);


            //Compute the relative velocity to determine what kind of friction to use
            float relativeAngularVelocity = RelativeVelocity;
            //Set up friction and find maximum friction force
            Vector3 relativeSlidingVelocity = contactManifoldConstraint.SlidingFriction.relativeVelocity;
            friction = Math.Abs(relativeAngularVelocity) > CollisionResponseSettings.StaticFrictionVelocityThreshold ||
                       Math.Abs(relativeSlidingVelocity.X) + Math.Abs(relativeSlidingVelocity.Y) + Math.Abs(relativeSlidingVelocity.Z) > CollisionResponseSettings.StaticFrictionVelocityThreshold
                           ? contactManifoldConstraint.materialInteraction.KineticFriction
                           : contactManifoldConstraint.materialInteraction.StaticFriction;
            friction *= CollisionResponseSettings.TwistFrictionFactor;

            contactCount = contactManifoldConstraint.penetrationConstraints.Count;

            Vector3 contactOffset;
            for (int i = 0; i < contactCount; i++)
            {
                Vector3.Subtract(ref contactManifoldConstraint.penetrationConstraints.Elements[i].contact.Position, ref contactManifoldConstraint.SlidingFriction.manifoldCenter, out contactOffset);
                leverArms[i] = contactOffset.Length();
            }



        }

19 View Source File : TwistMotor.cs
License : The Unlicense
Project Creator : aeroson

public override void Update(float dt)
        {
            basisA.rotationMatrix = connectionA.orientationMatrix;
            basisB.rotationMatrix = connectionB.orientationMatrix;
            basisA.ComputeWorldSpaceAxes();
            basisB.ComputeWorldSpaceAxes();

            if (settings.mode == MotorMode.Servomechanism)
            {
                Quaternion rotation;
                Quaternion.GetQuaternionBetweenNormalizedVectors(ref basisB.primaryAxis, ref basisA.primaryAxis, out rotation);

                //Transform b's 'Y' axis so that it is perpendicular with a's 'X' axis for measurement.
                Vector3 twistMeasureAxis;
                Quaternion.Transform(ref basisB.xAxis, ref rotation, out twistMeasureAxis);


                //By dotting the measurement vector with a 2d plane's axes, we can get a local X and Y value.
                float y, x;
                Vector3.Dot(ref twistMeasureAxis, ref basisA.yAxis, out y);
                Vector3.Dot(ref twistMeasureAxis, ref basisA.xAxis, out x);
                var angle = (float) Math.Atan2(y, x);

                //Compute goal velocity.
                error = GetDistanceFromGoal(angle);
                float absErrorOverDt = Math.Abs(error / dt);
                float errorReduction;
                settings.servo.springSettings.ComputeErrorReductionAndSoftness(dt, 1 / dt, out errorReduction, out usedSoftness);
                biasVelocity = Math.Sign(error) * MathHelper.Min(settings.servo.baseCorrectiveSpeed, absErrorOverDt) + error * errorReduction;

                biasVelocity = MathHelper.Clamp(biasVelocity, -settings.servo.maxCorrectiveVelocity, settings.servo.maxCorrectiveVelocity);
            }
            else
            {
                biasVelocity = settings.velocityMotor.goalVelocity;
                usedSoftness = settings.velocityMotor.softness / dt;
                error = 0;
            }


            //The nice thing about this approach is that the jacobian entry doesn't flip.
            //Instead, the error can be negative due to the use of Atan2.
            //This is important for limits which have a unique high and low value.

            //Compute the jacobian.
            Vector3.Add(ref basisA.primaryAxis, ref basisB.primaryAxis, out jacobianB);
            if (jacobianB.LengthSquared() < Toolbox.Epsilon)
            {
                //A nasty singularity can show up if the axes are aligned perfectly.
                //In a 'real' situation, this is impossible, so just ignore it.
                isActiveInSolver = false;
                return;
            }

            jacobianB.Normalize();
            jacobianA.X = -jacobianB.X;
            jacobianA.Y = -jacobianB.Y;
            jacobianA.Z = -jacobianB.Z;

            //Update the maximum force
            ComputeMaxForces(settings.maximumForce, dt);


            //****** EFFECTIVE Mreplaced MATRIX ******//
            //Connection A's contribution to the mreplaced matrix
            float entryA;
            Vector3 transformedAxis;
            if (connectionA.isDynamic)
            {
                Matrix3x3.Transform(ref jacobianA, ref connectionA.inertiaTensorInverse, out transformedAxis);
                Vector3.Dot(ref transformedAxis, ref jacobianA, out entryA);
            }
            else
                entryA = 0;

            //Connection B's contribution to the mreplaced matrix
            float entryB;
            if (connectionB.isDynamic)
            {
                Matrix3x3.Transform(ref jacobianB, ref connectionB.inertiaTensorInverse, out transformedAxis);
                Vector3.Dot(ref transformedAxis, ref jacobianB, out entryB);
            }
            else
                entryB = 0;

            //Compute the inverse mreplaced matrix
            velocityToImpulse = 1 / (usedSoftness + entryA + entryB);

            
        }

19 View Source File : ToughGhost.cs
License : GNU General Public License v3.0
Project Creator : aedenthorn

public override void behaviorAtGameTick(GameTime time)
        {
            base.behaviorAtGameTick(time);
            this.faceDirection(0);
            float xSlope = (float)(-(float)(base.Player.GetBoundingBox().Center.X - this.GetBoundingBox().Center.X));
            float ySlope = (float)(base.Player.GetBoundingBox().Center.Y - this.GetBoundingBox().Center.Y);
            float t = Math.Max(1f, Math.Abs(xSlope) + Math.Abs(ySlope));
            if (t < 64f)
            {
                this.xVelocity = Math.Max(-7f, Math.Min(7f, this.xVelocity * 1.1f));
                this.yVelocity = Math.Max(-7f, Math.Min(7f, this.yVelocity * 1.1f));
            }
            xSlope /= t;
            ySlope /= t;
            if (this.wareplacedCounter <= 0)
            {
                this.targetRotation = (float)Math.Atan2((double)(-(double)ySlope), (double)xSlope) - 1.57079637f;
                if ((double)(Math.Abs(this.targetRotation) - Math.Abs(this.rotation)) > 2.748893571891069 && Game1.random.NextDouble() < 0.5)
                {
                    this.turningRight = true;
                }
                else if ((double)(Math.Abs(this.targetRotation) - Math.Abs(this.rotation)) < 0.39269908169872414)
                {
                    this.turningRight = false;
                }
                if (this.turningRight)
                {
                    this.rotation -= (float)Math.Sign(this.targetRotation - this.rotation) * 0.0490873866f;
                }
                else
                {
                    this.rotation += (float)Math.Sign(this.targetRotation - this.rotation) * 0.0490873866f;
                }
                this.rotation %= 6.28318548f;
                this.wareplacedCounter = 5 + Game1.random.Next(-1, 2);
            }
            float maxAccel = Math.Min(7f, Math.Max(2f, 7f - t / 64f / 2f))*2;
            xSlope = (float)Math.Cos((double)this.rotation + 1.5707963267948966);
            ySlope = -(float)Math.Sin((double)this.rotation + 1.5707963267948966);
            this.xVelocity += -xSlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
            this.yVelocity += -ySlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
            if (Math.Abs(this.xVelocity) > Math.Abs(-xSlope * 7f))
            {
                this.xVelocity -= -xSlope * maxAccel / 6f;
            }
            if (Math.Abs(this.yVelocity) > Math.Abs(-ySlope * 7f))
            {
                this.yVelocity -= -ySlope * maxAccel / 6f;
            }
        }

19 View Source File : DistanceJoint.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            //Compute the current relative velocity.
            float lambda, dot;
            Vector3.Dot(ref jLinearA, ref connectionA.linearVelocity, out lambda);
            Vector3.Dot(ref jAngularA, ref connectionA.angularVelocity, out dot);
            lambda += dot;
            Vector3.Dot(ref jLinearB, ref connectionB.linearVelocity, out dot);
            lambda += dot;
            Vector3.Dot(ref jAngularB, ref connectionB.angularVelocity, out dot);
            lambda += dot;

            //Add in the constraint space bias velocity
            lambda = -lambda + biasVelocity - softness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Acreplacedulate impulse
            acreplacedulatedImpulse += lambda;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jLinearA, lambda, out impulse);
                connectionA.ApplyLinearImpulse(ref impulse);
                Vector3.Multiply(ref jAngularA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jLinearB, lambda, out impulse);
                connectionB.ApplyLinearImpulse(ref impulse);
                Vector3.Multiply(ref jAngularB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return (Math.Abs(lambda));
        }

19 View Source File : WorldDatabaseWithEntityCache.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

private void TreasureMaterialGroups_Normalize(Dictionary<int, Dictionary<int, List<TreasureMaterialGroups>>> materialGroups)
        {
            foreach (var kvp in materialGroups)
            {
                var materialGroup = kvp.Key;
                var tiers = kvp.Value;

                foreach (var kvp2 in tiers)
                {
                    var tier = kvp2.Key;
                    var list = kvp2.Value;

                    var totalProbability = list.Sum(i => i.Probability);

                    if (Math.Abs(1.0f - totalProbability) < NormalizeEpsilon)
                        continue;

                    //Console.WriteLine($"TotalProbability {totalProbability} found for TreasureMaterialGroup {(MaterialType)materialGroup} tier {tier}");

                    var factor = 1.0f / totalProbability;

                    foreach (var item in list)
                        item.Probability *= factor;

                    /*totalProbability = list.Sum(i => i.Probability);

                    Console.WriteLine($"After: {totalProbability}");*/
                }
            }
        }

19 View Source File : TwistJoint.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            float velocityA, velocityB;
            //Find the velocity contribution from each connection
            Vector3.Dot(ref connectionA.angularVelocity, ref jacobianA, out velocityA);
            Vector3.Dot(ref connectionB.angularVelocity, ref jacobianB, out velocityB);
            //Add in the constraint space bias velocity
            float lambda = -(velocityA + velocityB) + biasVelocity - softness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Acreplacedulate the impulse
            acreplacedulatedImpulse += lambda;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jacobianA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jacobianB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return (Math.Abs(lambda));
        }

19 View Source File : ButterflyFamiliar.cs
License : GNU General Public License v3.0
Project Creator : aedenthorn

public override void behaviorAtGameTick(GameTime time)
        {
            invincibleCountdown = 1000;
            if (timeBeforeAIMovementAgain > 0f)
            {
                timeBeforeAIMovementAgain -= time.ElapsedGameTime.Milliseconds;
            }
            if (lastBuff >= 0)
            {
                lastBuff.Value -= time.ElapsedGameTime.Milliseconds;
            }

            if (wareplacedCounter >= 0)
            {
                wareplacedCounter.Value -= time.ElapsedGameTime.Milliseconds;
            }

            if (followingOwner)
            {

                Vector2 center = Position + new Vector2(8, 8);
                Vector2 playerCenter = GetOwner().position + new Vector2(64, 92);
                if (Vector2.Distance(playerCenter, center) > 256)
                {
                    Position = Vector2.Distance(playerCenter, center) * 0.03f * Vector2.Normalize(playerCenter - center) + center - new Vector2(8,8);

                }

                float xSlope = (float)(-(float)(playerCenter.X - center.X));
                float ySlope = (float)(playerCenter.Y - center.Y);
                float t = Math.Max(1f, Math.Abs(xSlope) + Math.Abs(ySlope));
                if (t < (float)((extraVelocity > 0f) ? 192 : 64))
                {
                    xVelocity = Math.Max(-maxSpeed, Math.Min(maxSpeed, xVelocity * 1.05f));
                    yVelocity = Math.Max(-maxSpeed, Math.Min(maxSpeed, yVelocity * 1.05f));
                }
                xSlope /= t;
                ySlope /= t;
                if (wareplacedCounter <= 0)
                {
                    targetRotation = (float)Math.Atan2((double)(-(double)ySlope), (double)xSlope) - 1.57079637f;
                    if ((double)(Math.Abs(targetRotation) - Math.Abs(rotation)) > 2.748893571891069 && Game1.random.NextDouble() < 0.5)
                    {
                        turningRight.Value = true;
                    }
                    else if ((double)(Math.Abs(targetRotation) - Math.Abs(rotation)) < 0.39269908169872414)
                    {
                        turningRight.Value = false;
                    }
                    if (turningRight)
                    {
                        rotation -= (float)Math.Sign(targetRotation - rotation) * 0.0490873866f;
                    }
                    else
                    {
                        rotation += (float)Math.Sign(targetRotation - rotation) * 0.0490873866f;
                    }
                    rotation %= 6.28318548f;
                    wareplacedCounter.Value = 0;
                }
                float maxAccel = Math.Min(5f, Math.Max(1f, 5f - t / 64f / 2f)) + extraVelocity;
                xSlope = (float)Math.Cos((double)rotation + 1.5707963267948966);
                ySlope = -(float)Math.Sin((double)rotation + 1.5707963267948966);
                xVelocity += -xSlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
                yVelocity += -ySlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
                if (Math.Abs(xVelocity) > Math.Abs(-xSlope * maxSpeed))
                {
                    xVelocity -= -xSlope * maxAccel / 6f;
                }
                if (Math.Abs(yVelocity) > Math.Abs(-ySlope * maxSpeed))
                {
                    yVelocity -= -ySlope * maxAccel / 6f;
                }
                if (lastBuff <= 0 && Vector2.Distance(GetOwner().getTileLocation(), getTileLocation()) < 3)
                {
                    if (Game1.random.NextDouble() < BuffChance())
                    {
                        if (ModEntry.Config.ButterflySoundEffects)
                            Game1.playSound("yoba");
                        BuffsDisplay buffsDisplay = Game1.buffsDisplay;
                        Buff buff2 = GetBuff();
                        buffsDisplay.addOtherBuff(buff2);
                        AddExp(1);
                        lastBuff.Value = GetBuffInterval();
                    }
                    else
                        lastBuff.Value = 1000;
                }
            }
        }

19 View Source File : LinearAxisMotor.cs
License : The Unlicense
Project Creator : aeroson

public override void Update(float dt)
        {
            //Compute the 'pre'-jacobians
            Matrix3x3.Transform(ref localAnchorA, ref connectionA.orientationMatrix, out worldOffsetA);
            Matrix3x3.Transform(ref localAnchorB, ref connectionB.orientationMatrix, out worldOffsetB);
            Vector3.Add(ref worldOffsetA, ref connectionA.position, out worldAnchorA);
            Vector3.Add(ref worldOffsetB, ref connectionB.position, out worldAnchorB);
            Vector3.Subtract(ref worldAnchorB, ref connectionA.position, out rA);
            Matrix3x3.Transform(ref localAxis, ref connectionA.orientationMatrix, out worldAxis);

            float updateRate = 1 / dt;
            if (settings.mode == MotorMode.Servomechanism)
            {
                //Compute error
#if !WINDOWS
            Vector3 separation = new Vector3();
#else
                Vector3 separation;
#endif
                separation.X = worldAnchorB.X - worldAnchorA.X;
                separation.Y = worldAnchorB.Y - worldAnchorA.Y;
                separation.Z = worldAnchorB.Z - worldAnchorA.Z;

                Vector3.Dot(ref separation, ref worldAxis, out error);

                //Compute error
                error = error - settings.servo.goal;


                //Compute bias
                float absErrorOverDt = Math.Abs(error * updateRate);
                float errorReduction;
                settings.servo.springSettings.ComputeErrorReductionAndSoftness(dt, updateRate, out errorReduction, out usedSoftness);
                biasVelocity = Math.Sign(error) * MathHelper.Min(settings.servo.baseCorrectiveSpeed, absErrorOverDt) + error * errorReduction;
                biasVelocity = MathHelper.Clamp(biasVelocity, -settings.servo.maxCorrectiveVelocity, settings.servo.maxCorrectiveVelocity);
            }
            else
            {
                biasVelocity = -settings.velocityMotor.goalVelocity;
                usedSoftness = settings.velocityMotor.softness * updateRate;
                error = 0;
            }

            //Compute jacobians
            jLinearA = worldAxis;
            jLinearB.X = -jLinearA.X;
            jLinearB.Y = -jLinearA.Y;
            jLinearB.Z = -jLinearA.Z;
            Vector3.Cross(ref rA, ref jLinearA, out jAngularA);
            Vector3.Cross(ref worldOffsetB, ref jLinearB, out jAngularB);

            //compute mreplaced matrix
            float entryA, entryB;
            Vector3 intermediate;
            if (connectionA.isDynamic)
            {
                Matrix3x3.Transform(ref jAngularA, ref connectionA.inertiaTensorInverse, out intermediate);
                Vector3.Dot(ref intermediate, ref jAngularA, out entryA);
                entryA += connectionA.inverseMreplaced;
            }
            else
                entryA = 0;
            if (connectionB.isDynamic)
            {
                Matrix3x3.Transform(ref jAngularB, ref connectionB.inertiaTensorInverse, out intermediate);
                Vector3.Dot(ref intermediate, ref jAngularB, out entryB);
                entryB += connectionB.inverseMreplaced;
            }
            else
                entryB = 0;
            mreplacedMatrix = 1 / (entryA + entryB + usedSoftness);

            //Update the maximum force
            ComputeMaxForces(settings.maximumForce, dt);



        }

19 View Source File : P2PManager.cs
License : MIT License
Project Creator : absurd-joy

void ReadTimeSyncMessage(ulong remoteID, byte[] msg)
		{
			if (!m_remoteSentTimeCache.ContainsKey(remoteID))
			{
				SendTimeSyncMessage(remoteID);
				return;
			}

			int offset = 1;
			float remoteTime = UnpackFloat(msg, ref offset);
			float now = Time.realtimeSinceStartup;
			float latency = (now - m_remoteSentTimeCache[remoteID]) / 2;
			float remoteTimeOffset = now - (remoteTime + latency);

			m_remoteSyncTimeCache[remoteID].Add(remoteTimeOffset);

			if (m_remoteSyncTimeCache[remoteID].Count < TIME_SYNC_MESSAGE_COUNT)
			{
				SendTimeSyncMessage(remoteID);
			}
			else
			{
				if (PlatformManager.MyID < remoteID)
				{
					// this client started the sync, need to send one last message to
					// the remote so they can finish their sync calculation
					SendTimeSyncMessage(remoteID);
				}

				// sort the times and remember the median
				m_remoteSyncTimeCache[remoteID].Sort();
				float median = m_remoteSyncTimeCache[remoteID][TIME_SYNC_MESSAGE_COUNT/2];

				// calucate the mean and standard deviation
				double mean = 0;
				foreach (var time in m_remoteSyncTimeCache[remoteID])
				{
					mean += time;
				}
				mean /= TIME_SYNC_MESSAGE_COUNT;

				double std_dev = 0;
				foreach (var time in m_remoteSyncTimeCache[remoteID])
				{
					std_dev += (mean-time)*(mean-time);
				}
				std_dev = Math.Sqrt(std_dev)/TIME_SYNC_MESSAGE_COUNT;

				// time delta is the mean of the values less than 1 standard deviation from the median
				mean = 0;
				int meanCount = 0;
				foreach (var time in m_remoteSyncTimeCache[remoteID])
				{
					if (Math.Abs(time-median) < std_dev)
					{
						mean += time;
						meanCount++;
					}
				}
				mean /= meanCount;
				Debug.LogFormat("Time offset to {0} is {1}", remoteID, mean);

				m_remoteSyncTimeCache.Remove(remoteID);
				m_remoteSentTimeCache.Remove(remoteID);
				m_remotePlayers[remoteID].remoteTimeOffset = (float)mean;

				// now that times are synchronized, lets try to coordinate the
				// start time for the match
				OfferMatchStartTime();
			}
		}

19 View Source File : Quaternion.cs
License : The Unlicense
Project Creator : aeroson

public Vector4 ToAxisAngle()
        {
            Quaternion q = this;
            if (Math.Abs(q.W) > 1.0f)
                q.Normalize();

            Vector4 result = new Vector4();

            result.W = 2.0f * (float)System.Math.Acos(q.W); // angle
            float den = (float)System.Math.Sqrt(1.0 - q.W * q.W);
            if (den > 0.0001f)
            {
                result.Xyz = q.Xyz / den;
            }
            else
            {
                // This occurs when the angle is zero. 
                // Not a problem: just set an arbitrary normalized axis.
                result.Xyz = Vector3.UnitX;
            }

            return result;
        }

19 View Source File : ModEntry.cs
License : GNU General Public License v3.0
Project Creator : aedenthorn

private static async void HereFishyFishy(Farmer who, int x, int y)
        {
            hereFishying = true;
            if (fishySound != null)
            {
                fishySound.Play();
            }
            who.completelyStopAnimatingOrDoingAction();
            who.jitterStrength = 2f;
            List<FarmerSprite.AnimationFrame> animationFrames = new List<FarmerSprite.AnimationFrame>(){
                new FarmerSprite.AnimationFrame(94, 100, false, false, null, false).AddFrameAction(delegate (Farmer f)
                {
                    f.jitterStrength = 2f;
                })
            };
            who.FarmerSprite.setCurrentAnimation(animationFrames.ToArray());
            who.FarmerSprite.PauseForSingleAnimation = true;
            who.FarmerSprite.loop = true;
            who.FarmerSprite.loopThisAnimation = true;
            who.Sprite.currentFrame = 94;

            await System.Threading.Tasks.Task.Delay(1793);

            canPerfect = true;
            perfect = false;

            who.synchronizedJump(8f);

            await System.Threading.Tasks.Task.Delay(100);

            canPerfect = false;

            await System.Threading.Tasks.Task.Delay(900);

            who.stopJittering();
            who.completelyStopAnimatingOrDoingAction();
            who.forceCanMove();

            hereFishying = false;

            await System.Threading.Tasks.Task.Delay(Game1.random.Next(500, 1000));

            Object o = who.currentLocation.getFish(0, -1, 1, who, 0, new Vector2(x, y), who.currentLocation.Name);
            if (o == null || o.ParentSheetIndex <= 0)
            {
                o = new Object(Game1.random.Next(167, 173), 1, false, -1, 0);
            }


            int parentSheetIndex = o.parentSheetIndex;
            animations.Clear();
            float t;
            lastUser = who;
            whichFish = parentSheetIndex;
            Dictionary<int, string> data = Game1.content.Load<Dictionary<int, string>>("Data\\Fish");
            string[] datas = null;
            if (data.ContainsKey(whichFish))
            {
                datas = data[whichFish].Split('/');
            }


            bool non_fishable_fish = false;
            if (o is Furniture)
            {
                non_fishable_fish = true;
            }
            else if (Utility.IsNormalObjectAtParentSheetIndex(o, o.ParentSheetIndex) && data.ContainsKey(o.ParentSheetIndex))
            {
                string[] array = data[o.ParentSheetIndex].Split(new char[]
                {
                            '/'
                });
                int difficulty = -1;
                if (!int.TryParse(array[1], out difficulty))
                {
                    non_fishable_fish = true;
                }
            }
            else
            {
                non_fishable_fish = true;
            }


            float fs = 1f;
            int minimumSizeContribution = 1 + who.FishingLevel / 2;
            fs *= (float)Game1.random.Next(minimumSizeContribution, Math.Max(6, minimumSizeContribution)) / 5f;
            fs *= 1.2f;
            fs *= 1f + (float)Game1.random.Next(-10, 11) / 100f;
            fs = Math.Max(0f, Math.Min(1f, fs));
            if(datas != null && !non_fishable_fish)
            {
                try
                {
                    int minFishSize = int.Parse(datas[3]);
                    int maxFishSize = int.Parse(datas[4]);
                    fishSize = (int)((float)minFishSize + (float)(maxFishSize - minFishSize) * fishSize);
                    fishSize++;
                    fishQuality = (((double)fishSize < 0.33) ? 0 : (((double)fishSize < 0.66) ? 1 : 2));
                    if (perfect)
                        fishQuality *= 2;
                }
                catch 
                {
                    context.Monitor.Log($"Error getting fish size from {data[whichFish]}", LogLevel.Error);
                }
            }
            bossFish = FishingRod.isFishBossFish(whichFish);
            caughtDoubleFish = !bossFish && Game1.random.NextDouble() < 0.1 + Game1.player.DailyLuck / 2.0;

            context.Monitor.Log($"pulling fish {whichFish} {fishSize} {who.Name} {x},{y}");

            if (who.IsLocalPlayer)
            {
                if (datas != null && !non_fishable_fish)
                {
                    fishDifficulty = int.Parse(datas[1]);

                }
                else
                    fishDifficulty = 0;
                
                int experience = Math.Max(1, (fishQuality + 1) * 3 + fishDifficulty / 3);
                if (bossFish)
                {
                    experience *= 5;
                }
                
                if(perfect)
                    experience += (int)((float)experience * 1.4f);
                
                who.gainExperience(1, experience);
            }

            if (who.FacingDirection == 1 || who.FacingDirection == 3)
            {
                float distance = Vector2.Distance(new Vector2(x, y), who.Position);
                float gravity = 0.001f;
                float height = 128f - (who.Position.Y - y + 10f);
                double angle = 1.1423973285781066;
                float yVelocity = (float)((double)(distance * gravity) * Math.Tan(angle) / Math.Sqrt((double)(2f * distance * gravity) * Math.Tan(angle) - (double)(2f * gravity * height)));
                if (float.IsNaN(yVelocity))
                {
                    yVelocity = 0.6f;
                }
                float xVelocity = (float)((double)yVelocity * (1.0 / Math.Tan(angle)));
                t = distance / xVelocity;
                animations.Add(new TemporaryAnimatedSprite("Maps\\springobjects", Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, parentSheetIndex, 16, 16), t, 1, 0, new Vector2(x,y), false, false, y / 10000f, 0f, Color.White, 4f, 0f, 0f, 0f, false)
                {
                    motion = new Vector2((float)((who.FacingDirection == 3) ? -1 : 1) * -xVelocity, -yVelocity),
                    acceleration = new Vector2(0f, gravity),
                    timeBasedMotion = true,
                    endFunction = new TemporaryAnimatedSprite.endBehavior(playerCaughtFishEndFunction),
                    extraInfoForEndBehavior = parentSheetIndex,
                    endSound = "tinyWhip"
                });
                if (caughtDoubleFish)
                {
                    distance = Vector2.Distance(new Vector2(x, y), who.Position);
                    gravity = 0.0008f;
                    height = 128f - (who.Position.Y - y + 10f);
                    angle = 1.1423973285781066;
                    yVelocity = (float)((double)(distance * gravity) * Math.Tan(angle) / Math.Sqrt((double)(2f * distance * gravity) * Math.Tan(angle) - (double)(2f * gravity * height)));
                    if (float.IsNaN(yVelocity))
                    {
                        yVelocity = 0.6f;
                    }
                    xVelocity = (float)((double)yVelocity * (1.0 / Math.Tan(angle)));
                    t = distance / xVelocity;
                    animations.Add(new TemporaryAnimatedSprite("Maps\\springobjects", Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, parentSheetIndex, 16, 16), t, 1, 0, new Vector2(x, y), false, false, y / 10000f, 0f, Color.White, 4f, 0f, 0f, 0f, false)
                    {
                        motion = new Vector2((float)((who.FacingDirection == 3) ? -1 : 1) * -xVelocity, -yVelocity),
                        acceleration = new Vector2(0f, gravity),
                        timeBasedMotion = true,
                        endSound = "fishSlap",
                        Parent = who.currentLocation
                    });
                }
            }
            else
            {
                float distance2 = y - (float)(who.getStandingY() - 64);
                float height2 = Math.Abs(distance2 + 256f + 32f);
                if (who.FacingDirection == 0)
                {
                    height2 += 96f;
                }
                float gravity2 = 0.003f;
                float velocity = (float)Math.Sqrt((double)(2f * gravity2 * height2));
                t = (float)(Math.Sqrt((double)(2f * (height2 - distance2) / gravity2)) + (double)(velocity / gravity2));
                float xVelocity2 = 0f;
                if (t != 0f)
                {
                    xVelocity2 = (who.Position.X - x) / t;
                }
                animations.Add(new TemporaryAnimatedSprite("Maps\\springobjects", Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, parentSheetIndex, 16, 16), t, 1, 0, new Vector2(x, y), false, false, y / 10000f, 0f, Color.White, 4f, 0f, 0f, 0f, false)
                {
                    motion = new Vector2(xVelocity2, -velocity),
                    acceleration = new Vector2(0f, gravity2),
                    timeBasedMotion = true,
                    endFunction = new TemporaryAnimatedSprite.endBehavior(playerCaughtFishEndFunction),
                    extraInfoForEndBehavior = parentSheetIndex,
                    endSound = "tinyWhip"
                });
                if (caughtDoubleFish)
                {
                    distance2 = y - (float)(who.getStandingY() - 64);
                    height2 = Math.Abs(distance2 + 256f + 32f);
                    if (who.FacingDirection == 0)
                    {
                        height2 += 96f;
                    }
                    gravity2 = 0.004f;
                    velocity = (float)Math.Sqrt((double)(2f * gravity2 * height2));
                    t = (float)(Math.Sqrt((double)(2f * (height2 - distance2) / gravity2)) + (double)(velocity / gravity2));
                    xVelocity2 = 0f;
                    if (t != 0f)
                    {
                        xVelocity2 = (who.Position.X - x) / t;
                    }
                    animations.Add(new TemporaryAnimatedSprite("Maps\\springobjects", Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, parentSheetIndex, 16, 16), t, 1, 0, new Vector2(x, y), false, false, y / 10000f, 0f, Color.White, 4f, 0f, 0f, 0f, false)
                    {
                        motion = new Vector2(xVelocity2, -velocity),
                        acceleration = new Vector2(0f, gravity2),
                        timeBasedMotion = true,
                        endSound = "fishSlap",
                        Parent = who.currentLocation
                    });
                }
            }
        }

19 View Source File : ContactPenetrationConstraint.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {

            //Compute relative velocity
            float lambda = (RelativeVelocity - bias + softness * acreplacedulatedImpulse) * velocityToImpulse;

            //Clamp acreplacedulated impulse
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Max(0, acreplacedulatedImpulse + lambda);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;


            //Apply the impulse
#if !WINDOWS
            Vector3 linear = new Vector3();
            Vector3 angular = new Vector3();
#else
            Vector3 linear, angular;
#endif
            linear.X = lambda * linearAX;
            linear.Y = lambda * linearAY;
            linear.Z = lambda * linearAZ;
            if (enreplacedyADynamic)
            {
                angular.X = lambda * angularAX;
                angular.Y = lambda * angularAY;
                angular.Z = lambda * angularAZ;
                enreplacedyA.ApplyLinearImpulse(ref linear);
                enreplacedyA.ApplyAngularImpulse(ref angular);
            }
            if (enreplacedyBDynamic)
            {
                linear.X = -linear.X;
                linear.Y = -linear.Y;
                linear.Z = -linear.Z;
                angular.X = lambda * angularBX;
                angular.Y = lambda * angularBY;
                angular.Z = lambda * angularBZ;
                enreplacedyB.ApplyLinearImpulse(ref linear);
                enreplacedyB.ApplyAngularImpulse(ref angular);
            }

            return Math.Abs(lambda);
        }

19 View Source File : Sequence.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

public void update_internal(float timeElapsed, ref LinkedListNode<AnimSequenceNode> animNode, ref float frameNum, ref AFrame frame)
        {
            var currAnim = animNode.Value;

            var framerate = currAnim.Framerate;
            var frametime = framerate * timeElapsed;

            var lastFrame = (int)Math.Floor(frameNum);

            frameNum += frametime;
            var frameTimeElapsed = 0.0f;
            var animDone = false;

            if (frametime > 0.0f)
            {
                if (currAnim.get_high_frame() < Math.Floor(frameNum))
                {
                    var frameOffset = frameNum - currAnim.get_high_frame() - 1.0f;
                    if (frameOffset < 0.0f)
                        frameOffset = 0.0f;

                    if (Math.Abs(framerate) > PhysicsGlobals.EPSILON)
                        frameTimeElapsed = frameOffset / framerate;

                    frameNum = currAnim.get_high_frame();
                    animDone = true;
                }
                while (Math.Floor(frameNum) > lastFrame)
                {
                    if (frame != null)
                    {
                        if (currAnim.Anim.PosFrames != null)
                            frame = AFrame.Combine(frame, currAnim.get_pos_frame(lastFrame));

                        if (Math.Abs(framerate) > PhysicsGlobals.EPSILON)
                            apply_physics(frame, 1.0f / framerate, timeElapsed);
                    }

                    execute_hooks(currAnim.get_part_frame(lastFrame), AnimationHookDir.Forward);
                    lastFrame++;
                }
            }
            else if (frametime < 0.0f)
            {
                if (currAnim.get_low_frame() > Math.Floor(frameNum))
                {
                    var frameOffset = frameNum - currAnim.get_low_frame();
                    if (frameOffset > 0.0f)
                        frameOffset = 0.0f;

                    if (Math.Abs(framerate) > PhysicsGlobals.EPSILON)
                        frameTimeElapsed = frameOffset / framerate;

                    frameNum = currAnim.get_low_frame();
                    animDone = true;
                }
                while (Math.Floor(frameNum) < lastFrame)
                {
                    if (frame != null)
                    {
                        if (currAnim.Anim.PosFrames != null)
                            frame.Subtract(currAnim.get_pos_frame(lastFrame));

                        if (Math.Abs(framerate) > PhysicsGlobals.EPSILON)
                            apply_physics(frame, 1.0f / framerate, timeElapsed);
                    }

                    execute_hooks(currAnim.get_part_frame(lastFrame), AnimationHookDir.Backward);
                    lastFrame--;
                }
            }
            else
            {
                if (frame != null && Math.Abs(timeElapsed) > PhysicsGlobals.EPSILON)
                    apply_physics(frame, timeElapsed, timeElapsed);
            }

            if (!animDone)
                return;

            if (HookObj != null)
            {
                var node = AnimList.First;
                if (!node.Equals(FirstCyclic))
                    HookObj.add_anim_hook(AnimationHook.AnimDoneHook);
            }

            advance_to_next_animation(timeElapsed, ref animNode, ref frameNum, ref frame);
            timeElapsed = frameTimeElapsed;

            // loop to next anim
            update_internal(timeElapsed, ref animNode, ref frameNum, ref frame);    
        }

19 View Source File : LinearAxisLimit.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            //Compute the current relative velocity.
            float lambda, dot;
            Vector3.Dot(ref jLinearA, ref connectionA.linearVelocity, out lambda);
            Vector3.Dot(ref jAngularA, ref connectionA.angularVelocity, out dot);
            lambda += dot;
            Vector3.Dot(ref jLinearB, ref connectionB.linearVelocity, out dot);
            lambda += dot;
            Vector3.Dot(ref jAngularB, ref connectionB.angularVelocity, out dot);
            lambda += dot;

            //Add in the constraint space bias velocity
            lambda = -lambda + biasVelocity - softness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= mreplacedMatrix;

            //Clamp acreplacedulated impulse (can't go negative)
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            if (unadjustedError < 0)
                acreplacedulatedImpulse = MathHelper.Min(acreplacedulatedImpulse + lambda, 0);
            else
                acreplacedulatedImpulse = MathHelper.Max(acreplacedulatedImpulse + lambda, 0);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
            Vector3 impulse;
            if (connectionA.isDynamic)
            {
                Vector3.Multiply(ref jLinearA, lambda, out impulse);
                connectionA.ApplyLinearImpulse(ref impulse);
                Vector3.Multiply(ref jAngularA, lambda, out impulse);
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Multiply(ref jLinearB, lambda, out impulse);
                connectionB.ApplyLinearImpulse(ref impulse);
                Vector3.Multiply(ref jAngularB, lambda, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return (Math.Abs(lambda));
        }

19 View Source File : FamiliarsUtils.cs
License : GNU General Public License v3.0
Project Creator : aedenthorn

public static Vector2 getAwayFromNPCTrajectory(Microsoft.Xna.Framework.Rectangle monsterBox, NPC who)
        {
            float num = (float)(-(float)(who.GetBoundingBox().Center.X - monsterBox.Center.X));
            float ySlope = (float)(who.GetBoundingBox().Center.Y - monsterBox.Center.Y);
            float total = Math.Abs(num) + Math.Abs(ySlope);
            if (total < 1f)
            {
                total = 5f;
            }
            float x = num / total * (float)(50 + Game1.random.Next(-20, 20));
            ySlope = ySlope / total * (float)(50 + Game1.random.Next(-20, 20));
            return new Vector2(x, ySlope);
        }

19 View Source File : SwingLimit.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            float lambda;
            Vector3 relativeVelocity;
            Vector3.Subtract(ref connectionA.angularVelocity, ref connectionB.angularVelocity, out relativeVelocity);
            //Transform the velocity to with the jacobian
            Vector3.Dot(ref relativeVelocity, ref hingeAxis, out lambda);
            //Add in the constraint space bias velocity
            lambda = -lambda + biasVelocity - softness * acreplacedulatedImpulse;

            //Transform to an impulse
            lambda *= velocityToImpulse;

            //Clamp acreplacedulated impulse (can't go negative)
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            acreplacedulatedImpulse = MathHelper.Max(acreplacedulatedImpulse + lambda, 0);
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;

            //Apply the impulse
            Vector3 impulse;
            Vector3.Multiply(ref hingeAxis, lambda, out impulse);
            if (connectionA.isDynamic)
            {
                connectionA.ApplyAngularImpulse(ref impulse);
            }
            if (connectionB.isDynamic)
            {
                Vector3.Negate(ref impulse, out impulse);
                connectionB.ApplyAngularImpulse(ref impulse);
            }

            return (Math.Abs(lambda));
        }

19 View Source File : Vector3Smoothed.cs
License : Apache License 2.0
Project Creator : abist-co-ltd

public void Update(float deltaTime)
        {
            Current = Vector3.Lerp(Current, Goal, (Math.Abs(SmoothTime) < Mathf.Epsilon) ? 1.0f : deltaTime / SmoothTime);
        }

19 View Source File : TwistLimit.cs
License : The Unlicense
Project Creator : aeroson

public override void Update(float dt)
        {
            basisA.rotationMatrix = connectionA.orientationMatrix;
            basisB.rotationMatrix = connectionB.orientationMatrix;
            basisA.ComputeWorldSpaceAxes();
            basisB.ComputeWorldSpaceAxes();

            Quaternion rotation;
            Quaternion.GetQuaternionBetweenNormalizedVectors(ref basisB.primaryAxis, ref basisA.primaryAxis, out rotation);

            //Transform b's 'Y' axis so that it is perpendicular with a's 'X' axis for measurement.
            Vector3 twistMeasureAxis;
            Quaternion.Transform(ref basisB.xAxis, ref rotation, out twistMeasureAxis);

            //By dotting the measurement vector with a 2d plane's axes, we can get a local X and Y value.
            float y, x;
            Vector3.Dot(ref twistMeasureAxis, ref basisA.yAxis, out y);
            Vector3.Dot(ref twistMeasureAxis, ref basisA.xAxis, out x);
            var angle = (float) Math.Atan2(y, x);

            float distanceFromCurrent, distanceFromMaximum;
            if (IsAngleValid(angle, out distanceFromCurrent, out distanceFromMaximum))
            {
                isActiveInSolver = false;
                acreplacedulatedImpulse = 0;
                error = 0;
                isLimitActive = false;
                return;
            }
            isLimitActive = true;

            //Compute the jacobian.
            if (error > 0)
            {
                Vector3.Add(ref basisA.primaryAxis, ref basisB.primaryAxis, out jacobianB);
                if (jacobianB.LengthSquared() < Toolbox.Epsilon)
                {
                    //A nasty singularity can show up if the axes are aligned perfectly.
                    //In a 'real' situation, this is impossible, so just ignore it.
                    isActiveInSolver = false;
                    return;
                }

                jacobianB.Normalize();
                jacobianA.X = -jacobianB.X;
                jacobianA.Y = -jacobianB.Y;
                jacobianA.Z = -jacobianB.Z;
            }
            else
            {
                //Reverse the jacobian so that the solver loop is easier.
                Vector3.Add(ref basisA.primaryAxis, ref basisB.primaryAxis, out jacobianA);
                if (jacobianA.LengthSquared() < Toolbox.Epsilon)
                {
                    //A nasty singularity can show up if the axes are aligned perfectly.
                    //In a 'real' situation, this is impossible, so just ignore it.
                    isActiveInSolver = false;
                    return;
                }

                jacobianA.Normalize();
                jacobianB.X = -jacobianA.X;
                jacobianB.Y = -jacobianA.Y;
                jacobianB.Z = -jacobianA.Z;
            }

            //****** VELOCITY BIAS ******//
            //Compute the correction velocity.
            error = ComputeAngleError(distanceFromCurrent, distanceFromMaximum);
            float errorReduction;
            springSettings.ComputeErrorReductionAndSoftness(dt, 1 / dt, out errorReduction, out softness);


            //biasVelocity = MathHelper.Clamp(-error * myCorrectionStrength / dt, -myMaxCorrectiveVelocity, myMaxCorrectiveVelocity);
            biasVelocity = MathHelper.Min(MathHelper.Max(0, Math.Abs(error) - margin) * errorReduction, maxCorrectiveVelocity);
            if (bounciness > 0)
            {
                float relativeVelocity;
                float dot;
                //Find the velocity contribution from each connection
                Vector3.Dot(ref connectionA.angularVelocity, ref jacobianA, out relativeVelocity);
                Vector3.Dot(ref connectionB.angularVelocity, ref jacobianB, out dot);
                relativeVelocity += dot;
                biasVelocity = MathHelper.Max(biasVelocity, ComputeBounceVelocity(-relativeVelocity));
            }

            //The nice thing about this approach is that the jacobian entry doesn't flip.
            //Instead, the error can be negative due to the use of Atan2.
            //This is important for limits which have a unique high and low value.


            //****** EFFECTIVE Mreplaced MATRIX ******//
            //Connection A's contribution to the mreplaced matrix
            float entryA;
            Vector3 transformedAxis;
            if (connectionA.isDynamic)
            {
                Matrix3x3.Transform(ref jacobianA, ref connectionA.inertiaTensorInverse, out transformedAxis);
                Vector3.Dot(ref transformedAxis, ref jacobianA, out entryA);
            }
            else
                entryA = 0;

            //Connection B's contribution to the mreplaced matrix
            float entryB;
            if (connectionB.isDynamic)
            {
                Matrix3x3.Transform(ref jacobianB, ref connectionB.inertiaTensorInverse, out transformedAxis);
                Vector3.Dot(ref transformedAxis, ref jacobianB, out entryB);
            }
            else
                entryB = 0;

            //Compute the inverse mreplaced matrix
            velocityToImpulse = 1 / (softness + entryA + entryB);

            
        }

19 View Source File : IComparerRacingResult.cs
License : GNU General Public License v3.0
Project Creator : aelariane

int IComparer.Compare(object x, object y)
    {
        float time = ((RacingResult)x).Time;
        float time2 = ((RacingResult)y).Time;
        if (time == time2 || Math.Abs(time - time2) < 1.401298E-45f)
        {
            return 0;
        }
        if (time < time2)
        {
            return -1;
        }
        return 1;
    }

19 View Source File : MotionInterp.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

public void apply_run_to_command(ref uint motion, ref float speed)
        {
            var speedMod = 1.0f;

            if (WeenieObj != null)
            {
                var runFactor = 0.0f;
                if (WeenieObj.InqRunRate(ref runFactor))
                    speedMod = runFactor;
                else
                    speedMod = MyRunRate;
            }
            switch (motion)
            {
                case (uint)MotionCommand.WalkForward:
                    if (speed > 0.0f)
                        motion = (uint)MotionCommand.RunForward;

                    speed *= speedMod;
                    break;

                case (uint)MotionCommand.TurnRight:
                    speed *= RunTurnFactor;
                    break;

                case (uint)MotionCommand.SideStepRight:
                    speed *= speedMod;

                    if (MaxSidestepAnimRate < Math.Abs(speed))
                    {
                        if (speed > 0.0f)
                            speed = MaxSidestepAnimRate * 1.0f;
                        else
                            speed = MaxSidestepAnimRate * -1.0f;
                    }
                    break;
            }
        }

19 View Source File : UIBar.cs
License : GNU Affero General Public License v3.0
Project Creator : 0ceal0t

public void SetPercent(float value) {
            if (value > 1) value = 1;
            else if (value < 0) value = 0;

            var difference = Math.Abs(value - LastPercent);
            if (difference == 0) return;


            Anim?.Delete();
            if (difference >= 0.01f) {
                Anim = Animation.AddAnim(f => SetPercentInternal(f), 0.2f, LastPercent, value);
            }
            else {
                SetPercentInternal(value);
            }
            LastPercent = value;
        }

19 View Source File : BaseCursor.cs
License : Apache License 2.0
Project Creator : abist-co-ltd

private bool GetCursorTargetAxes(Vector3 normal, ref Vector3 right, ref Vector3 up, ref Vector3 forward)
        {
            if (TargetedObject)
            {
                Vector3 objRight = TargetedObject.transform.TransformDirection(Vector3.right);
                Vector3 objUp = TargetedObject.transform.TransformDirection(Vector3.up);
                Vector3 objForward = TargetedObject.transform.TransformDirection(Vector3.forward);

                float dotRight = Vector3.Dot(normal, objRight);
                float dotUp = Vector3.Dot(normal, objUp);
                float dotForward = Vector3.Dot(normal, objForward);

                if (Math.Abs(dotRight) > Math.Abs(dotUp) &&
                    Math.Abs(dotRight) > Math.Abs(dotForward))
                {
                    forward = (dotRight > 0 ? objRight : -objRight).normalized;
                }
                else if (Math.Abs(dotUp) > Math.Abs(dotForward))
                {
                    forward = (dotUp > 0 ? objUp : -objUp).normalized;
                }
                else
                {
                    forward = (dotForward > 0 ? objForward : -objForward).normalized;
                }

                right = Vector3.Cross(Vector3.up, forward).normalized;
                if (right == Vector3.zero)
                {
                    right = Vector3.Cross(objForward, forward).normalized;
                }
                up = Vector3.Cross(forward, right).normalized;

                return true;
            }

            return false;
        }

19 View Source File : WorldDatabaseWithEntityCache.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

private void TreasureMaterialColor_Normalize(Dictionary<int, Dictionary<int, List<TreasureMaterialColor>>> materialColor)
        {
            foreach (var kvp in materialColor)
            {
                var material = kvp.Key;
                var colorCodes = kvp.Value;

                foreach (var kvp2 in colorCodes)
                {
                    var colorCode = kvp2.Key;
                    var list = kvp2.Value;

                    var totalProbability = list.Sum(i => i.Probability);

                    if (Math.Abs(1.0f - totalProbability) < NormalizeEpsilon)
                        continue;

                    //Console.WriteLine($"TotalProbability {totalProbability} found for TreasureMaterialColor {(MaterialType)material} ColorCode {colorCode}");

                    var factor = 1.0f / totalProbability;

                    foreach (var item in list)
                        item.Probability *= factor;

                    /*totalProbability = list.Sum(i => i.Probability);

                    Console.WriteLine($"After: {totalProbability}");*/
                }
            }
        }

19 View Source File : MoveToManager.cs
License : GNU Affero General Public License v3.0
Project Creator : ACEmulator

public static bool heading_greater(float h1, float h2, uint motion)
        {
            /*var less = Math.Abs(x - y) <= 180.0f ? x < y : y < x;
            var result = (less || x == y) == false;
            if (motion != 0x6500000D)
                result = !result;
            return result;*/
            var diff = Math.Abs(h1 - h2);

            float v1, v2;

            if (diff <= 180.0f)
            {
                v1 = h2;
                v2 = h1;
            }
            else
            {
                v1 = h1;
                v2 = h2;
            }

            var result = (v2 > v1) ? true : false;

            if (motion != (uint)MotionCommand.TurnRight)
                result = !result;

            return result;
        }

19 View Source File : TwistFrictionConstraint.cs
License : The Unlicense
Project Creator : aeroson

public override float SolveIteration()
        {
            //Compute relative velocity.  Collisions can occur between an enreplacedy and a non-enreplacedy.  If it's not an enreplacedy, replacedume it's not moving.
            float lambda = RelativeVelocity;
            
            lambda *= velocityToImpulse; //convert to impulse

            //Clamp acreplacedulated impulse
            float previousAcreplacedulatedImpulse = acreplacedulatedImpulse;
            float maximumFrictionForce = 0;
            for (int i = 0; i < contactCount; i++)
            {
                maximumFrictionForce += leverArms[i] * contactManifoldConstraint.penetrationConstraints.Elements[i].acreplacedulatedImpulse;
            }
            maximumFrictionForce *= friction;
            acreplacedulatedImpulse = MathHelper.Clamp(acreplacedulatedImpulse + lambda, -maximumFrictionForce, maximumFrictionForce); //instead of maximumFrictionForce, could recompute each iteration...
            lambda = acreplacedulatedImpulse - previousAcreplacedulatedImpulse;


            //Apply the impulse
#if !WINDOWS
            Vector3 angular = new Vector3();
#else
            Vector3 angular;
#endif
            angular.X = lambda * angularX;
            angular.Y = lambda * angularY;
            angular.Z = lambda * angularZ;
            if (enreplacedyADynamic)
            {
                enreplacedyA.ApplyAngularImpulse(ref angular);
            }
            if (enreplacedyBDynamic)
            {
                angular.X = -angular.X;
                angular.Y = -angular.Y;
                angular.Z = -angular.Z;
                enreplacedyB.ApplyAngularImpulse(ref angular);
            }


            return Math.Abs(lambda);
        }

See More Examples