Beispiel #1
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            float xA = 0.0f, yA = 0.0f, rA = 0.0f;
            gxtKeyboard kb = gxtKeyboardManager.Singleton.GetKeyboard();
            gxtMouse mouse = gxtMouseManager.Singleton.GetMouse();

            //if (kb.IsDown(Keys.Down))
                //world.Camera.Zoom -= 0.0005f;
            //else if (kb.IsDown(Keys.Up))
            //    world.Camera.Zoom += 0.0005f;

            int dScroll = mouse.GetDeltaScroll();
            if (dScroll != 0)
            {
                world.GameSpeed = gxtMath.Clamp(world.GameSpeed + (dScroll * 0.05f), 0.05f, 1.0f);
            }

            // assume gravity on
            float force = 10.5f;
            float torque = 3.5f;
            bodyA.IgnoreGravity = false;
            bodyF.IgnoreGravity = false;

            // otherwise switch
            if (!gravityOn)
            {
                bodyA.IgnoreGravity = true;
                bodyF.IgnoreGravity = true;
                force = 6.5f;
                torque = 1.25f;
            }

            if (kb.GetState(Keys.G) == gxtControlState.FIRST_PRESSED)
                gravityOn = !gravityOn;

            if (kb.GetState(Keys.C) == gxtControlState.FIRST_PRESSED)
            {
                geomA.CollisionResponseEnabled = !geomA.CollisionResponseEnabled;
                geomF.CollisionResponseEnabled = !geomF.CollisionResponseEnabled;
            }

            if (kb.GetState(Keys.F) == gxtControlState.FIRST_PRESSED)
            {
                bodyF.FixedRotation = !bodyF.FixedRotation;
                if (!bodyF.FixedRotation)
                {
                    bodyF.Inertia = gxtRigidBody.GetInertiaForPolygon(geomF.Polygon, bodyF.Mass);
                }
            }

            Vector2 virtualMousePos = world.Camera.GetVirtualMousePosition(mouse.GetPosition());
            if (kb.GetState(Keys.T) == gxtControlState.FIRST_PRESSED)
            {
                Vector2 physicsWorldPos = virtualMousePos * gxtPhysicsWorld.ONE_OVER_PHYSICS_SCALE;
                //physicsWorldPos = (world.Camera.Position + physicsWorldPos) * gxtPhysicsWorld.ONE_OVER_PHYSICS_SCALE; // + (physicsWorldPos * gxtPhysicsWorld.ONE_OVER_PHYSICS_SCALE);
                float explosionForce = 750.0f;
                float sphereRadius = 4.5f;
                List<gxtGeom> hitGeoms;
                gxtSphere sphere = new gxtSphere(physicsWorldPos, sphereRadius);
                //gxtAABB box = new gxtAABB(physicsWorldPos, new Vector2(sphereRadius));
                float adjustedRadius = sphereRadius * gxtPhysicsWorld.PHYSICS_SCALE;
                gxtSphere adjustedSphere = new gxtSphere(virtualMousePos, adjustedRadius);
                Color sphereColor = Color.Blue;
                if (world.PhysicsWorld.PointCastAll(physicsWorldPos, out hitGeoms))
                {
                    //gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, "Something was hit...");
                    sphereColor = Color.Red;
                    for (int i = 0; i < hitGeoms.Count; ++i)
                    {
                        if (hitGeoms[i].HasAttachedBody())
                        {
                            Vector2 forceToApply = Vector2.Normalize(hitGeoms[i].GetWorldCentroid() - physicsWorldPos) * explosionForce;
                            hitGeoms[i].RigidBody.ApplyForceAtPoint(forceToApply, physicsWorldPos);
                        }
                    }
                }
                gxtDebugDrawer.Singleton.AddPt(physicsWorldPos * gxtPhysicsWorld.PHYSICS_SCALE, Color.Blue, 0.0f, System.TimeSpan.FromSeconds(3.0));
                gxtDebugDrawer.Singleton.AddSphere(adjustedSphere, sphereColor, 0.5f, TimeSpan.FromSeconds(3.0));
            }
            gxtDebugDrawer.Singleton.AddPt(virtualMousePos, Color.White, 0.0f);

            bodyA.Damping = damping;

            if (kb.IsDown(Keys.Left))
                xA -= force;
            if (kb.IsDown(Keys.Right))
                xA += force;
            if (kb.IsDown(Keys.Up))
                yA -= force;
            if (kb.IsDown(Keys.Down))
                yA += force;
            if (kb.IsDown(Keys.OemOpenBrackets))
                rA -= torque;
            if (kb.IsDown(Keys.OemCloseBrackets))
                rA += torque;

            if (xA != 0.0f || yA != 0.0f)
                bodyA.ApplyForce(new Vector2(xA, yA));
            if (rA != 0.0f)
                bodyA.ApplyTorque(rA);

            float xF = 0.0f, yF = 0.0f, rF = 0.0f;

            if (kb.IsDown(Keys.A))
                xF -= force;
            if (kb.IsDown(Keys.D))
                xF += force;
            if (kb.IsDown(Keys.W))
                yF -= force;
            if (kb.IsDown(Keys.S))
                yF += force;
            if (kb.IsDown(Keys.Q))
                rF -= torque;
            if (kb.IsDown(Keys.E))
                rF += torque;

            if (kb.GetState(Keys.Space) == gxtControlState.FIRST_PRESSED)
            {
                bodyF.Velocity -= new Vector2(0.0f, 8.0f);
                bodyF.ApplyForce(new Vector2(0.0f, -100.0f));
            }

            if (xF != 0.0f || yF != 0.0f)
                bodyF.ApplyForce(new Vector2(xF, yF));
            if (rF != 0.0f)
                bodyF.ApplyTorque(rF);

            //gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, "Velocity F: {0}", bodyF.Velocity.ToString());
            //bodyA.Translate(new Vector2(xA, yA));
            //bodyA.SetRotation(bodyA.Rotation + rA);

            Vector2 forceBeforeClearA = bodyA.Force;
            //Vector2 forceBeforeClearF = bodyF.Force;

            world.PhysicsWorld.DebugDrawGeoms(Color.Yellow, Color.Salmon, Color.Gray, Color.Blue, Color.Red, 0.5f, 0.55f, 0.5f, true, true, false);
            //world.PhysicsWorld.DebugDrawRigidBodies(Color.White);

            //gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, bodyA.Acceleration.ToString());

            //float scalar = 0.85f;

            /*
            gxtDebugDrawer.Singleton.AddPolygon(geomA.Polygon, Color.Yellow, 0.5f);
            gxtDebugDrawer.Singleton.AddPolygon(geomB.Polygon, Color.Yellow, 0.5f);
            gxtDebugDrawer.Singleton.AddLine(bodyA.Position, bodyA.Position + forceBeforeClearA * scalar, Color.Blue, 0.0f);
            gxtDebugDrawer.Singleton.AddLine(bodyF.Position, bodyF.Position + forceBeforeClearF * scalar, Color.Blue, 0.0f);
            gxtDebugDrawer.Singleton.AddPolygon(geomC.Polygon, Color.Yellow, 0.0f);
            gxtDebugDrawer.Singleton.AddPolygon(geomD.Polygon, Color.Yellow, 0.0f);
            gxtDebugDrawer.Singleton.AddPolygon(geomE.Polygon, Color.Yellow, 0.0f);
            gxtDebugDrawer.Singleton.AddPolygon(geomF.Polygon, Color.Yellow, 0.0f);
            */
            //gxtDebugDrawer.Singleton.AddPolygon(geomB.Polygon, color, 0.5f);
            //gxtDebugDrawer.Singleton.AddString(geomB.Position.ToString(), geomB.Position, Color.White, 0.0f);

            //gxtLog.WriteLineV(gxtVerbosityLevel.INFORMATIONAL, "{0}", float.Epsilon);

            string fpsString = "FPS: " + gxtDebug.GetFPS().ToString();
            Vector2 strSize = gxtDebugDrawer.Singleton.DebugFont.MeasureString(fpsString);
            strSize *= 0.5f;
            Vector2 topLeftCorner = new Vector2(-gxtDisplayManager.Singleton.ResolutionWidth * 0.5f, -gxtDisplayManager.Singleton.ResolutionHeight * 0.5f);
            gxtDebugDrawer.Singleton.AddString("FPS: " + gxtDebug.GetFPS(), topLeftCorner + strSize, Color.White, 0.0f);

            //gxtDebugDrawer.Singleton.AddString("Velocity: " + bodyF.Velocity.ToString(), Vector2.Zero, Color.White, 0.0f);
            //gxtDebugDrawer.Singleton.AddString("");
            //xna reach profile has no alpha transparency!
            //world.Physics.DebugDrawGeoms(Color.Yellow, 0.5f, new Color(0.0f, 0.0f, 1.0f, 0.25f), 0.51f, true);
            world.Update(gameTime);
            world.LateUpdate(gameTime);
        }
Beispiel #2
0
        /// <summary>
        /// Computes a sphere given a set of vertices/points
        /// </summary>
        /// <param name="ptSet">enumerator of points</param>
        /// <returns>sphere for the point set</returns>
        public static gxtSphere ComputeSphere(IEnumerator<Vector2> ptSet)
        {
            //  Find most distant points on AABB
            Vector2 min, max;
            GetMostDistantPoints(out min, out max, ptSet);

            // Constructs initial sphere from distant points
            Vector2 c = (min + max) * 0.5f;
            float r = Vector2.Distance(max, c);
            gxtSphere sphere = new gxtSphere(c, r);

            ptSet.Reset();
            // Check to include all points in circle
            while (ptSet.MoveNext())
            {
                MakeSphereIncludePt(ref sphere, ptSet.Current);
            }
            return sphere;
        }
Beispiel #3
0
 /// <summary>
 /// Enlarges the sphere to include itself and the outside point
 /// if it is outside the existing sphere.
 /// </summary>
 /// <param name="sphere">sphere</param>
 /// <param name="pt">Pt in set</param>
 public static void MakeSphereIncludePt(ref gxtSphere sphere, Vector2 pt)
 {
     Vector2 diff = pt - sphere.Position;
     float distSq = diff.LengthSquared();
     // Contains check
     if (distSq > sphere.Radius * sphere.Radius)
     {
         float dist = gxtMath.Sqrt(distSq);
         // New radius half the sum of this distance and old
         // Works because position will also be adjusted
         float adjRadius = (sphere.Radius + dist) * 0.5f;
         // Adjust position by component vector
         sphere.Position += diff * ((adjRadius - sphere.Radius) / dist);
         sphere.Radius = adjRadius;
     }
 }
Beispiel #4
0
        /// <summary>
        /// Sphere intersection test which calculates t and the intersection point
        /// The normal can later be found with Normalize(pt - sphere.Position)
        /// </summary>
        /// <param name="sphere">Sphere</param>
        /// <param name="t">Max Distance</param>
        /// <param name="pt">Contact Point</param>
        /// <returns>If intersecting</returns>
        public bool IntersectsSphere(gxtSphere sphere, out float t, out Vector2 pt)
        {
            Vector2 m = origin - sphere.Position;
            float b = Vector2.Dot(m, direction);
            float c = m.LengthSquared();

            if (c > 0.0f && b > 0.0f)
            {
                t = 0.0f;
                pt = origin;
                return false;
            }

            float discr = b * b - c;
            if (discr < 0.0f)
            {
                t = 0.0f;
                pt = origin;
                return false;
            }

            t = -b - gxtMath.Sqrt(discr);
            if (t < 0.0f)
                t = 0.0f;
            pt = GetPoint(t);
            return true;
        }
Beispiel #5
0
        /// <summary>
        /// Computes a sphere given a set of vertices/points
        /// </summary>
        /// <param name="ptSet">array of points</param>
        /// <returns>sphere for the point set</returns>
        public static gxtSphere ComputeSphere(Vector2[] ptSet)
        {
            //  Find most distant points on AABR
            int min, max;
            GetMostDistantPoints(out min, out max, ptSet);

            // Constructs initial circle from distant points
            Vector2 c = (ptSet[min] + ptSet[max]) * 0.5f;
            float r = Vector2.Distance(ptSet[max], c);
            gxtSphere sphere = new gxtSphere(c, r);

            // Check to include all points in circle
            for (int i = 0; i < ptSet.Length; i++)
            {
                MakeSphereIncludePt(ref sphere, ptSet[i]);
            }
            return sphere;
        }
Beispiel #6
0
        /// <summary>
        /// A fast boolean intersection test that omits an expensive square root call
        /// However, it does not return values for t and the contact point
        /// </summary>
        /// <param name="sphere">Sphere</param>
        /// <returns>If intersecting</returns>
        public bool IntersectsSphere(gxtSphere sphere)
        {
            Vector2 m = origin - sphere.Position;
            float c = m.LengthSquared() - sphere.Radius * sphere.Radius;

            if (c <= 0.0f)
                return true;

            float b = Vector2.Dot(m, direction);

            if (b > 0.0f)
                return false;

            float disc = b * b - c;
            if (disc < 0.0f)
                return false;

            return true;
        }
Beispiel #7
0
        public static bool Intersects(ref gxtPolygon polygon, Vector2 centroid, gxtSphere sphere)
        {
            if (Contains(polygon, sphere.Position))
                return true;
            float r2 = sphere.Radius * sphere.Radius;
            for (int j = polygon.NumVertices - 1, i = 0; i < polygon.NumVertices; j = i, i++)
            {
                Vector2 edgeVector = polygon.v[i] - polygon.v[j];
                Vector2 edgeNormal = Vector2.Normalize(gxtMath.RightPerp(edgeVector));
                float edgeDistance = gxtMath.Abs(Vector2.Dot(polygon.v[j], edgeNormal));
                // void PointEdgeDistance(const Vector& P, const Vector& E0, const Vector& E1, Vector& Q, float& dist2){    Vector D = P - E0;    Vector E = E1 - E0;    float e2 = E * E;    float ed = E * D;    float t  = (ed / e2);       t = (t < 0.0)? 0.0f : (t > 1.0f)? : 1.0f : t;    Q = E0 + t * E;    Vector PQ = Q - P;    dist2 = PQ * PQ;}
                if (edgeDistance <= r2)
                    return true;
            }

            return false;
        }
Beispiel #8
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sphere"></param>
        /// <param name="hitGeoms"></param>
        /// <param name="collisionGroup"></param>
        /// <returns></returns>
        public bool SphereCastAll(gxtSphere sphere, out List<gxtGeom> hitGeoms, gxtCollisionGroup collisionGroup = gxtCollisionGroup.ALL)
        {
            if (collisionGroup == gxtCollisionGroup.NONE)
            {
                hitGeoms = new List<gxtGeom>();
                return false;
            }

            // we pass an aabb of the sphere thru the broadphase collider...for now
            // narrowphase tests use the actual sphere
            gxtAABB aabb = new gxtAABB(sphere.Position, new Vector2(sphere.Radius));
            hitGeoms = broadphaseCollider.AABBCastAll(aabb);

            if (hitGeoms.Count == 0)
                return false;

            gxtPolygon geomPolygon;
            for (int i = hitGeoms.Count - 1; i >= 0; i--)
            {
                if (!CanCollide(collisionGroup, hitGeoms[i]))
                    hitGeoms.RemoveAt(i);
                else
                {
                    geomPolygon = hitGeoms[i].Polygon;
                    // must ue the guranteed world centroid to ensure an accurate test
                    // http://www.gamedev.net/topic/308060-circle-polygon-intersection-more-2d-collisions/
                    if (!gxtGJKCollider.Intersects(ref geomPolygon, hitGeoms[i].GetWorldCentroid(), sphere))
                        hitGeoms.RemoveAt(i);
                }
            }

            return hitGeoms.Count != 0;
        }
Beispiel #9
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="sphere"></param>
 /// <param name="hitGeom"></param>
 /// <param name="collisionGroupName"></param>
 /// <returns></returns>
 public bool SphereCast(gxtSphere sphere, out gxtGeom hitGeom, string collisionGroupName)
 {
     gxtDebug.Assert(collisionGroupsMap.ContainsKey(collisionGroupName), "Named Collision Group: {0} Does Not Exist In Physics World");
     gxtCollisionGroup cgroup = collisionGroupsMap[collisionGroupName];
     return SphereCast(sphere, out hitGeom, cgroup);
 }
Beispiel #10
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="sphere"></param>
 /// <param name="hitGeom"></param>
 /// <param name="collisionGroup"></param>
 /// <returns></returns>
 public bool SphereCast(gxtSphere sphere, out gxtGeom hitGeom, gxtCollisionGroup collisionGroup = gxtCollisionGroup.ALL)
 {
     hitGeom = null;
     List<gxtGeom> geoms;
     if (SphereCastAll(sphere, out geoms, collisionGroup))
     {
         float minDist = float.MaxValue;
         float tmpDist;
         for (int i = 0; i < geoms.Count; i++)
         {
             tmpDist = (sphere.Position - geoms[i].GetWorldCentroid()).LengthSquared();
             if (tmpDist < minDist)
             {
                 hitGeom = geoms[i];
                 minDist = tmpDist;
             }
         }
         return true;
     }
     return false;
 }