Exemple #1
0
 // Used when we only change position.
 public override void MoveAABB(FixVec2 posDiff)
 {
     boundingBox.min.x += posDiff.X;
     boundingBox.min.y += posDiff.Y;
     boundingBox.max.x += posDiff.X;
     boundingBox.max.y += posDiff.Y;
 }
Exemple #2
0
        public void initialize()
        {
            // Calculate average bounciness/restitution
            e = FixMath.Min(A.Bounciness, B.Bounciness);

            // Calculate static & dynamic friction
            sf = FixMath.Sqrt(A.StaticFriction * A.StaticFriction + B.StaticFriction * B.StaticFriction);
            df = FixMath.Sqrt(A.DynamicFriction * A.DynamicFriction + B.DynamicFriction * B.DynamicFriction);

            for (int i = 0; i < contactCount; i++)
            {
                //Calculate radii from COM to contact
                FixVec2 ra = contacts[i] -= A.info.position;
                FixVec2 rb = contacts[i] -= B.info.position;

                //?
                FixVec2 rv = B.info.velocity + FixVec2.Cross(B.info.angularVelocity, rb)
                             - A.info.velocity - FixVec2.Cross(A.info.angularVelocity, ra);

                // Determine if we should perform a resting collision or not
                // The idea is if the only thing moving this object is gravity,
                // then the collision should be performed without any restitution
                if (rv.GetMagnitudeSquared() < TFPhysics.instance.resting)
                {
                    e = 0;
                }
            }
        }
Exemple #3
0
        public static void Update(Contexts contexts)
        {
            var dt      = contexts.Configuration().Get <TimeStep>().Value;
            var g       = contexts.Configuration().Get <GlobalForce>().Value;
            var context = contexts.Get <Game>();

            foreach (var entity in context.AllWith <Force, Mass, Velocity>())
            {
                if (entity.Is <Destroyed>())
                {
                    continue;
                }

                var force    = entity.Get <Force>().Value + g;
                var mass     = entity.Get <Mass>().Value;
                var velocity = entity.Get <Velocity>().Value;
                var damping  = entity.Has <Damping>() ? entity.Get <Damping>().Value : 0;

                velocity += dt * force / mass;
                velocity *= Fix.One / (Fix.One + dt * damping);

                if (entity.Has <MaxVelocity>())
                {
                    var maxVelocity = entity.Get <MaxVelocity>();

                    velocity = FixVec2.ClampMagnitude(velocity, maxVelocity.Value);
                }

                entity.Replace(new Velocity(velocity));
                entity.Replace(new Force());
            }
        }
Exemple #4
0
 // Used when we rotate or vertices are added/removed.
 public override void RecalcAABB(FixVec2 pos)
 {
     boundingBox.min.x = pos.x;
     boundingBox.max.x = pos.x;
     boundingBox.min.y = pos.y;
     boundingBox.max.y = pos.y;
     for (int i = 0; i < vertices.Count; i++)
     {
         FixVec2 v = u.Transposed() * vertices[i];
         if (v.x + pos.x < boundingBox.min.x)
         {
             boundingBox.min.x = v.x + pos.x;
         }
         if (v.y + pos.y < boundingBox.min.y)
         {
             boundingBox.min.y = v.y + pos.y;
         }
         if (v.x + pos.x > boundingBox.max.x)
         {
             boundingBox.max.x = v.x + pos.x;
         }
         if (v.y + pos.y > boundingBox.max.y)
         {
             boundingBox.max.y = v.y + pos.y;
         }
     }
 }
Exemple #5
0
        /// <summary>
        /// Expand the AABB by increasing its size by amount along each side.
        /// </summary>
        /// <param name="amount"></param>
        public void Expand(Fix amount)
        {
            FixVec2 extendAmt = FixVec2.one * amount;

            min -= extendAmt;
            max += extendAmt;
        }
Exemple #6
0
 public FixTrans2 Scale(FixVec2 scale)
 {
     return(new FixTrans2(
                M11 * scale.X, M12 * scale.X, M13 * scale.X,
                M21 * scale.Y, M22 * scale.Y, M23 * scale.Y
                ));
 }
Exemple #7
0
 public FixTrans2 Translate(FixVec2 delta)
 {
     return(new FixTrans2(
                M11, M12, M13 + delta.X,
                M21, M22, M23 + delta.Y
                ));
 }
Exemple #8
0
        private static SteeringVelocity Arrive(Entity <Game> owner, FixVec2 target)
        {
            var tolerance = owner.Get <ArrivalTolerance>();
            var position  = owner.Get <Position>().Value;

            target.Sub(ref position);

            var distance = target.Magnitude;

            if (distance <= tolerance.Distance)
            {
                return(SteeringVelocity.Zero);
            }

            var maxVelocity          = owner.Get <MaxVelocity>().Value;
            var decelerationDistance = tolerance.DecelerationDistance;

            if (distance <= decelerationDistance)
            {
                maxVelocity *= distance / decelerationDistance;
            }

            var velocity = target / distance * maxVelocity;

            return(new SteeringVelocity(FixVec2.ClampMagnitude(velocity, maxVelocity)));
        }
 // Used when we rotate or vertices are added/removed.
 public override void RecalcAABB(FixVec2 pos)
 {
     boundingBox.min.x = pos.X;
     boundingBox.max.x = pos.X;
     boundingBox.min.y = pos.Y;
     boundingBox.max.y = pos.Y;
     for (int i = 0; i < vertices.Count; i++)
     {
         FixVec2 v = u.Transposed() * (vertices[i] * tdTransform.LocalScale);
         if (v.X + pos.x < boundingBox.min.X)
         {
             boundingBox.min.x = v.X + pos.x;
         }
         if (v.Y + pos.y < boundingBox.min.Y)
         {
             boundingBox.min.y = v.Y + pos.y;
         }
         if (v.X + pos.x > boundingBox.max.X)
         {
             boundingBox.max.x = v.X + pos.x;
         }
         if (v.Y + pos.y > boundingBox.max.Y)
         {
             boundingBox.max.y = v.Y + pos.y;
         }
     }
 }
    // Draw the property inside the given rect
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        FixVec2 te = new FixVec2();

        te._x._raw = property.FindPropertyRelative("_x").FindPropertyRelative("_raw").intValue;
        te._y._raw = property.FindPropertyRelative("_y").FindPropertyRelative("_raw").intValue;
        val        = (Vector2)te;

        EditorGUI.BeginProperty(position, label, property);

        // Calculate rects
        var nameRect = new Rect(position.x, position.y, position.width - 90, position.height);
        var xRect    = new Rect(position.x + 130, position.y, 60, position.height);
        var yRect    = new Rect(position.x + 185, position.y, 60, position.height);

        // Draw fields - passs GUIContent.none to each so they are drawn without labels
        //EditorGUI.PropertyField(amountRect, val.x. GUIContent.none);
        //EditorGUI.PropertyField(unitRect, val.y, GUIContent.none);
        //EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none);
        EditorGUI.LabelField(nameRect, property.name);
        val.x = EditorGUI.FloatField(xRect, val.x);
        val.y = EditorGUI.FloatField(yRect, val.y);

        EditorGUI.EndProperty();

        if (GUI.changed)
        {
            FixVec2 tem = (FixVec2)val;
            property.FindPropertyRelative("_x").FindPropertyRelative("_raw").intValue = tem._x._raw;
            property.FindPropertyRelative("_y").FindPropertyRelative("_raw").intValue = tem._y._raw;
        }
    }
        public void HandleCollision(Manifold m, TFRigidbody a, TFRigidbody b)
        {
            TFCircleCollider A = (TFCircleCollider)a.coll;
            TFCircleCollider B = (TFCircleCollider)b.coll;

            //Calculate translational vector, which is normal
            FixVec2 normal = ((FixVec2)b.Position) - ((FixVec2)a.Position);

            Fix distSpr = normal.GetMagnitudeSquared();
            Fix radius  = A.radius + B.radius;

            //Not in contact
            if (distSpr >= radius * radius)
            {
                m.contactCount = 0;
                return;
            }

            Fix distance = FixMath.Sqrt(distSpr);

            m.contactCount = 1;

            if (distance == Fix.zero)
            {
                m.penetration = A.radius;
                m.normal      = new FixVec2(1, 0);
                m.contacts[0] = (FixVec2)a.Position;
            }
            else
            {
                m.penetration = radius - distance;
                m.normal      = normal / distance;
                m.contacts[0] = m.normal * A.radius + ((FixVec2)a.Position);
            }
        }
        public void HandleCollision(Manifold m, TFRigidbody a, TFRigidbody b)
        {
            TFEdgeCollider   A = (TFEdgeCollider)a.coll;
            TFCircleCollider B = (TFCircleCollider)b.coll;

            // No line segments, return out.
            if (A.vertices.Count < 2)
            {
                return;
            }

            // Transform circle center to Edge model space
            FixVec2 circleCenter = A.u.Transposed() * (b.Position - a.Position);

            // Iterate through all the line segments to find contact point.
            for (int i = 0; i < A.vertices.Count - 1; i++)
            {
                FixVec2 rayDir    = (A.vertices[i + 1] - A.vertices[i]);
                FixVec2 centerRay = (A.vertices[i] - circleCenter);
                Fix     k         = rayDir.Dot(rayDir);
                Fix     l         = 2 * centerRay.Dot(rayDir);
                Fix     n         = centerRay.Dot(centerRay) - (B.radius * B.radius);

                Fix discriminant = l * l - 4 * k * n;

                // No intersection.
                if (discriminant <= Fix.zero)
                {
                    continue;
                }

                discriminant = FixMath.Sqrt(discriminant);

                Fix t1 = (-l - discriminant) / (2 * k);
                Fix t2 = (-l + discriminant) / (2 * k);

                Fix s = FixVec2.Dot(A.normals[i], circleCenter - A.vertices[i]);

                if (t1 >= Fix.zero && t1 <= Fix.one)
                {
                    //t1 is the intersection, and it's closer than t2.
                    m.contactCount = 1;
                    m.contacts[0]  = (A.u * A.vertices[i] + a.Position) + (t1 * rayDir);
                    m.normal       = A.normals[i];
                    m.penetration  = B.radius - s;
                    return;
                }

                if (t2 >= Fix.zero && t2 <= Fix.one)
                {
                    // t1 didn't insection, so we either started inside the circle
                    // or completely past it.
                    m.contactCount = 1;
                    m.contacts[0]  = (A.u * A.vertices[i] + a.Position) + (t2 * rayDir);
                    m.normal       = A.normals[i];
                    m.penetration  = B.radius - s;
                    return;
                }
            }
        }