Exemple #1
0
        static unsafe void CheckRaycastHit(ref Physics.PhysicsWorld world, RaycastInput input, RaycastHit hit, string failureMessage)
        {
            // Fetch the leaf collider
            ChildCollider leaf;
            {
                Physics.RigidBody body = world.Bodies[hit.RigidBodyIndex];
                Collider.GetLeafCollider(body.Collider, body.WorldFromBody, hit.ColliderKey, out leaf);
            }

            // Check that the hit position matches the fraction
            float3 hitPosition = input.Ray.Origin + input.Ray.Direction * hit.Fraction;

            Assert.Less(math.length(hitPosition - hit.Position), tolerance, failureMessage + ": inconsistent fraction and position");

            // Query the hit position and check that it's on the surface of the shape
            PointDistanceInput pointInput = new PointDistanceInput
            {
                Position    = math.transform(math.inverse(leaf.TransformFromChild), hit.Position),
                MaxDistance = float.MaxValue
            };
            DistanceHit distanceHit;

            leaf.Collider->CalculateDistance(pointInput, out distanceHit);
            if (((ConvexCollider *)leaf.Collider)->ConvexHull.ConvexRadius > 0.0f)
            {
                // Convex raycast approximates radius, so it's possible that the hit position is not exactly on the shape, but must at least be outside
                Assert.Greater(distanceHit.Distance, -tolerance, failureMessage);
            }
            else
            {
                Assert.AreEqual(distanceHit.Distance, 0.0f, tolerance, failureMessage);
            }
        }
Exemple #2
0
        //the same as DrawJumpRange except it shows what areas the player can currently fall to
        private void DrawFallRange(Graphics displayDevice)
        {
            Physics.RigidBody temp = new Physics.RigidBody();
            temp.Shape = new Physics.Circle(7);
            temp.SetPosition(new Physics.Vector2D());

            //draw a grid of dots 40 units apart
            for (int i = -700; i < 700; i += 40)
            {
                for (int j = -360; j < 400; j += 40)
                {
                    //calculate the position of the dot
                    temp.Position.X  = playerCharacter.playerBody.Position.X + i;
                    temp.Position.X -= temp.Position.X % 40;
                    temp.Position.Y  = playerCharacter.playerBody.Position.Y + j;
                    temp.Position.Y -= temp.Position.Y % 40;

                    //set colour based on ability to fall to calculated position
                    if (physEng.CanPlayerFallFromTo(playerCharacter, playerCharacter.playerBody.Position, temp.Position))
                    {
                        temp.Shape.mColor = Color.Black;
                    }
                    else
                    {
                        temp.Shape.mColor = Color.White;
                    }

                    //draw a dot at that position
                    mRenderer.Draw(temp, displayDevice);
                }
            }
        }
Exemple #3
0
        public unsafe void RigidBodyCalculateDistancePointTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;

            var queryPos = new float3(-10, -10, -10);

            rigidbody.Collider = (Collider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            var pointDistanceInput = new PointDistanceInput();

            pointDistanceInput.Position = queryPos;
            pointDistanceInput.Filter   = CollisionFilter.Default;

            var closestHit = new DistanceHit();
            var allHits    = new NativeList <DistanceHit>(Allocator.Temp);

            // OK case : with enough max distance
            pointDistanceInput.MaxDistance = 10000.0f;
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput));
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput, out closestHit));
            Assert.IsTrue(rigidbody.CalculateDistance(pointDistanceInput, ref allHits));

            // Fail case : not enough max distance
            pointDistanceInput.MaxDistance = 1;
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput));
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput, out closestHit));
            Assert.IsFalse(rigidbody.CalculateDistance(pointDistanceInput, ref allHits));
        }
Exemple #4
0
        static unsafe void GetHitLeaf(ref Physics.PhysicsWorld world, int rigidBodyIndex, ColliderKey colliderKey, MTransform queryFromWorld, out ChildCollider leaf, out MTransform queryFromTarget)
        {
            Physics.RigidBody body = world.Bodies[rigidBodyIndex];
            Collider.GetLeafCollider(body.Collider, body.WorldFromBody, colliderKey, out leaf);
            MTransform worldFromLeaf = new MTransform(leaf.TransformFromChild);

            queryFromTarget = Math.Mul(queryFromWorld, worldFromLeaf);
        }
 //Draw a given point as a circle with radius 3, with colour Azure
 public void Draw(Physics.Vector2D point, Graphics g)
 {
     Physics.RigidBody temp = new Physics.RigidBody();
     temp.SetPosition(point);
     temp.Shape        = new Physics.Circle(3);
     temp.Shape.mColor = Color.Azure;
     Draw(temp, g);
 }
Exemple #6
0
        protected internal override void OnLoad()
        {
            base.OnLoad();

            var shape = CreateCollisionShape();

            rigidBody     = Bullet.CreateRigidBody(Mass, GameObject.Transform.WorldTransform, shape, CollideGroup, CollideMask);
            rigidBody.tag = this;
            SetIgnore(true);
        }
Exemple #7
0
        //Adds a dynamic box to the world
        static public unsafe void addDynamicBoxToWorld(Physics.PhysicsWorld world, int index, Vector3 pos, Quaternion orientation, Vector3 size)
        {
            Assert.IsTrue(index < world.NumDynamicBodies, "Dynamic body index is out of range in addDynamicBoxToWorld");
            Unity.Collections.NativeSlice <Physics.RigidBody> dynamicBodies = world.DynamicBodies;
            Physics.RigidBody rb = dynamicBodies[index];
            BlobAssetReference <Physics.Collider> collider = Unity.Physics.BoxCollider.Create(pos, orientation, size, .01f);

            rb.Collider          = (Collider *)collider.GetUnsafePtr();
            dynamicBodies[index] = rb;
        }
Exemple #8
0
        public unsafe void RigidBodyCalculateAabb_SphereColliderTest()
        {
            Physics.RigidBody rigidbodySphere = Unity.Physics.RigidBody.Zero;
            const float       convexRadius    = 1.0f;

            rigidbodySphere.Collider = (Collider *)SphereCollider.Create(float3.zero, convexRadius).GetUnsafePtr();

            var sphereAabb = rigidbodySphere.CalculateAabb();
            var sphere     = (Collider *)SphereCollider.Create(float3.zero, convexRadius).GetUnsafePtr();

            Assert.IsTrue(sphereAabb.Equals(sphere->CalculateAabb()));
        }
Exemple #9
0
        public unsafe void RigidBodyCalculateAabb_BoxColliderTest()
        {
            Physics.RigidBody rigidbodyBox = Unity.Physics.RigidBody.Zero;
            const float       size         = 1.0f;
            const float       convexRadius = 0.2f;

            rigidbodyBox.Collider = (Collider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            var boxAabb = rigidbodyBox.CalculateAabb();
            var box     = (BoxCollider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            Assert.IsTrue(boxAabb.Equals(box->CalculateAabb()));
        }
Exemple #10
0
        //Draw the nodes and connections associated with all the rigidbodies, and any current AI paths through the rigidbody graph
        private void DrawRigidbodyGraph(Graphics displayDevice)
        {
            Physics.RigidBody temp = new Physics.RigidBody();
            temp.Shape = new Physics.Circle(5);

            AI.NodeIndex previousNode;

            //for each rigidbody, draw it's core node, all its child nodes, and all its connections
            foreach (AI.Node rb in AIgraph.topLevelNode.internalNodes)
            {
                //draw the node
                temp.SetPosition(AIgraph.topLevelNode.GetNodePosition(rb.index));
                temp.Shape.mColor = Color.DarkOrange;
                mRenderer.Draw(temp, displayDevice);

                //draw its children
                foreach (AI.Node nd in rb.internalNodes)
                {
                    temp.SetPosition(AIgraph.topLevelNode.GetNodePosition(nd.index));
                    temp.Shape.mColor = Color.Chocolate;
                    mRenderer.Draw(temp, displayDevice);
                }

                //draw its connections
                foreach (AI.Connection rbconn in rb.connections)
                {
                    mRenderer.DrawLine(rb.position, AIgraph.topLevelNode.GetNodePosition(rbconn.destination), displayDevice, Color.FromArgb(9, Color.Black));
                }

                //draw each Ai's current high level path
                if (AIgraph.topLevelNode.lastPaths != null)
                {
                    foreach (List <AI.NodeIndex> lastPath in AIgraph.topLevelNode.lastPaths)
                    {
                        previousNode = null;
                        if (lastPath != null)
                        {
                            foreach (AI.NodeIndex node in lastPath)
                            {
                                previousNode = AIgraph.topLevelNode.GetNode(node).previousNode;

                                if (previousNode != null)
                                {
                                    mRenderer.DrawLine(AIgraph.topLevelNode.GetNodePosition(previousNode), AIgraph.topLevelNode.GetNodePosition(node), displayDevice, Color.FromArgb(129, Color.Black));
                                }
                            }
                        }
                    }
                }
            }
        }
        public unsafe void RigidBodyCalculateDistanceTest()
        {
            const float size         = 1.0f;
            const float convexRadius = 0.0f;
            const float sphereRadius = 1.0f;

            var queryPos = new float3(-10, -10, -10);

            BlobAssetReference <Collider> boxCollider = BoxCollider.Create(new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = size,
                BevelRadius = convexRadius
            });
            BlobAssetReference <Collider> sphereCollider = SphereCollider.Create(new SphereGeometry
            {
                Center = float3.zero,
                Radius = sphereRadius
            });

            var rigidBody = new Physics.RigidBody
            {
                WorldFromBody = RigidTransform.identity,
                Collider      = boxCollider
            };

            var colliderDistanceInput = new ColliderDistanceInput
            {
                Collider  = (Collider *)sphereCollider.GetUnsafePtr(),
                Transform = new RigidTransform(quaternion.identity, queryPos)
            };

            var closestHit = new DistanceHit();
            var allHits    = new NativeList <DistanceHit>(Allocator.Temp);

            // OK case : with enough max distance
            colliderDistanceInput.MaxDistance = 10000.0f;
            Assert.IsTrue(rigidBody.CalculateDistance(colliderDistanceInput));
            Assert.IsTrue(rigidBody.CalculateDistance(colliderDistanceInput, out closestHit));
            Assert.IsTrue(rigidBody.CalculateDistance(colliderDistanceInput, ref allHits));

            // Fail case : not enough max distance
            colliderDistanceInput.MaxDistance = 1;
            Assert.IsFalse(rigidBody.CalculateDistance(colliderDistanceInput));
            Assert.IsFalse(rigidBody.CalculateDistance(colliderDistanceInput, out closestHit));
            Assert.IsFalse(rigidBody.CalculateDistance(colliderDistanceInput, ref allHits));

            boxCollider.Dispose();
            sphereCollider.Dispose();
        }
Exemple #12
0
        //check all dynamic objects for collisions against dynamic and static objects, then resolve them
        public void updateCollisions()
        {
            //Check collisions of all dynamic objects
            for (int i = dynamicPhysicsObjects.Count - 1; i >= 0; i--)
            {
                Physics.RigidBody a = dynamicPhysicsObjects[i];

                //against other dynamic objects
                for (int j = dynamicPhysicsObjects.Count - 1; j >= 0; j--)
                {
                    if (i != j)
                    {
                        Physics.RigidBody b = dynamicPhysicsObjects[j];


                        if (a.Shape.IsCollided(b.Shape, a.Position, b.Position))
                        {
                            Physics.Vector2D          normal = a.Shape.GetCollisionNormal(b.Shape, a.Position, b.Position);
                            Physics.CollisionPairData pair   = new Physics.CollisionPairData();
                            pair.BodyA         = a;
                            pair.BodyB         = b;
                            pair.ContactNormal = normal;

                            mCollisionResponder.AddCollisionPair(pair);
                        }
                    }
                }

                //and against all static objects
                for (int j = staticPhysicsObjects.Count - 1; j >= 0; j--)
                {
                    Physics.RigidBody b = staticPhysicsObjects[j];

                    if (a.Shape.IsCollided(b.Shape, a.Position, b.Position))
                    {
                        Physics.Vector2D          normal = a.Shape.GetCollisionNormal(b.Shape, a.Position, b.Position);
                        Physics.CollisionPairData pair   = new Physics.CollisionPairData();
                        pair.BodyA         = a;
                        pair.BodyB         = b;
                        pair.ContactNormal = normal;

                        mCollisionResponder.AddCollisionPair(pair);
                    }
                }

                mCollisionResponder.ResolveAllPairs(playerCharacter);
            }
        }
        public unsafe void RigidBodyCalculateAabb_SphereColliderTest()
        {
            var geometry = new SphereGeometry
            {
                Center = float3.zero,
                Radius = 1.0f
            };

            Physics.RigidBody rigidbodySphere = Unity.Physics.RigidBody.Zero;
            rigidbodySphere.Collider = (Collider *)SphereCollider.Create(geometry).GetUnsafePtr();

            var sphereAabb = rigidbodySphere.CalculateAabb();
            var sphere     = (Collider *)SphereCollider.Create(geometry).GetUnsafePtr();

            Assert.IsTrue(sphereAabb.Equals(sphere->CalculateAabb()));
        }
        //Adds a static box to the world
        static public unsafe void addStaticBoxToWorld(Physics.PhysicsWorld world, int index, Vector3 pos, Quaternion orientation, Vector3 size)
        {
            Assert.IsTrue(index < world.NumStaticBodies, "Static body index is out of range in addStaticBoxToWorld");
            Unity.Collections.NativeSlice <Physics.RigidBody> staticBodies = world.StaticBodies;
            Physics.RigidBody rb = staticBodies[index];
            BlobAssetReference <Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry
            {
                Center      = pos,
                Orientation = orientation,
                Size        = size,
                BevelRadius = 0.01f
            });

            rb.Collider         = (Collider *)collider.GetUnsafePtr();
            staticBodies[index] = rb;
        }
Exemple #15
0
        //Draw the local nodes and their connections of the rigidbody with index stored in "showLocalNodes"
        private void DrawLocalNodes(Graphics displayDevice)
        {
            Physics.RigidBody temp = new Physics.RigidBody();
            temp.Shape = new Physics.Circle(5);

            //reset showLocalNodes to it's null value if it has been incremented above the number of rigidbodies
            if (showLocalNodes >= AIgraph.topLevelNode.internalNodes.Count)
            {
                showLocalNodes = -1;
            }
            else
            {
                foreach (AI.Node nd in AIgraph.topLevelNode.internalNodes[showLocalNodes].internalNodes)
                {
                    //draw the node
                    temp.SetPosition(AIgraph.topLevelNode.GetNodePosition(nd.index));
                    temp.Shape.mColor = Color.Chocolate;
                    mRenderer.Draw(temp, displayDevice);

                    //draw its connections
                    foreach (AI.Connection ndconn in nd.connections)
                    {
                        if (ndconn.connType == AI.CONNECTION_TYPE.JUMP)
                        {
                            mRenderer.DrawLine(temp.Position, AIgraph.topLevelNode.GetNodePosition(ndconn.destination), displayDevice, Color.DarkOrange);
                        }
                        else if (ndconn.connType == AI.CONNECTION_TYPE.FALL)
                        {
                            mRenderer.DrawLine(temp.Position, AIgraph.topLevelNode.GetNodePosition(ndconn.destination), displayDevice, Color.DarkMagenta);
                        }
                        else
                        {
                            mRenderer.DrawLine(temp.Position, AIgraph.topLevelNode.GetNodePosition(ndconn.destination), displayDevice, Color.Black);
                        }
                    }
                }
            }

            //also draw the player's current node, if the player has one
            AI.Node nearestNode = AIgraph.GetNodeAtPoint(playerCharacter.playerBody.Position);
            if (nearestNode != null)
            {
                temp.SetPosition(AIgraph.topLevelNode.GetNodePosition(nearestNode.index));
                temp.Shape.mColor = Color.Black;
                mRenderer.Draw(temp, displayDevice);
            }
        }
        public unsafe void RigidBodyCastColliderTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;
            const float sphereRadius = 1.0f;

            var rayStartOK = new float3(-10, -10, -10);
            var rayEndOK   = new float3(10, 10, 10);

            var rayStartFail = new float3(-10, 10, -10);
            var rayEndFail   = new float3(10, 10, 10);

            rigidbody.Collider = (Collider *)BoxCollider.Create(new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = size,
                BevelRadius = convexRadius
            }).GetUnsafePtr();

            var colliderCastInput = new ColliderCastInput();
            var closestHit        = new ColliderCastHit();
            var allHits           = new NativeList <ColliderCastHit>(Allocator.Temp);

            // OK case : Sphere hits the box collider
            colliderCastInput.Start    = rayStartOK;
            colliderCastInput.End      = rayEndOK;
            colliderCastInput.Collider = (Collider *)SphereCollider.Create(
                new SphereGeometry {
                Center = float3.zero, Radius = sphereRadius
            }
                ).GetUnsafePtr();

            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput));
            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput, out closestHit));
            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput, ref allHits));

            // Fail case : wrong direction
            colliderCastInput.Start = rayStartFail;
            colliderCastInput.End   = rayEndFail;

            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput));
            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput, out closestHit));
            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput, ref allHits));
        }
Exemple #17
0
        //Adds a dynamic box to the world
        static public unsafe void addDynamicBoxToWorld(Physics.PhysicsWorld world, int index, Vector3 pos, Quaternion orientation, Vector3 size)
        {
            Assert.IsTrue(index < world.NumDynamicBodies, "Dynamic body index is out of range in addDynamicBoxToWorld");
            NativeArray <Physics.RigidBody> dynamicBodies = world.DynamicBodies;

            Physics.RigidBody             rb       = dynamicBodies[index];
            BlobAssetReference <Collider> collider = BoxCollider.Create(new BoxGeometry
            {
                Center      = pos,
                Orientation = orientation,
                Size        = size,
                BevelRadius = 0.01f
            });

            rb.Collider          = collider;
            dynamicBodies[index] = rb;
        }
        public unsafe void RigidBodyCalculateAabb_BoxColliderTest()
        {
            var geometry = new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = 1.0f,
                BevelRadius = 0.2f
            };

            Physics.RigidBody rigidbodyBox = Unity.Physics.RigidBody.Zero;
            rigidbodyBox.Collider = (Collider *)BoxCollider.Create(geometry).GetUnsafePtr();

            var boxAabb     = rigidbodyBox.CalculateAabb();
            var boxCollider = (BoxCollider *)BoxCollider.Create(geometry).GetUnsafePtr();

            Assert.IsTrue(boxAabb.Equals(boxCollider->CalculateAabb()));
        }
        public unsafe void RigidBodyCastRayTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;

            var rayStartOK = new float3(-10, -10, -10);
            var rayEndOK   = new float3(10, 10, 10);

            var rayStartFail = new float3(-10, 10, -10);
            var rayEndFail   = new float3(10, 10, 10);

            rigidbody.Collider = BoxCollider.Create(new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = size,
                BevelRadius = convexRadius
            });

            var raycastInput = new RaycastInput();
            var closestHit   = new RaycastHit();
            var allHits      = new NativeList <RaycastHit>(Allocator.Temp);

            // OK case : Ray hits the box collider
            raycastInput.Start  = rayStartOK;
            raycastInput.End    = rayEndOK;
            raycastInput.Filter = CollisionFilter.Default;

            Assert.IsTrue(rigidbody.CastRay(raycastInput));
            Assert.IsTrue(rigidbody.CastRay(raycastInput, out closestHit));
            Assert.IsTrue(rigidbody.CastRay(raycastInput, ref allHits));

            // Fail Case : wrong direction
            raycastInput.Start = rayStartFail;
            raycastInput.End   = rayEndFail;

            Assert.IsFalse(rigidbody.CastRay(raycastInput));
            Assert.IsFalse(rigidbody.CastRay(raycastInput, out closestHit));
            Assert.IsFalse(rigidbody.CastRay(raycastInput, ref allHits));
        }
Exemple #20
0
        public unsafe void RigidBodyCastColliderTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;
            const float sphereRadius = 1.0f;

            var rayStartOK = new float3(-10, -10, -10);
            var rayEndOK   = new float3(10, 10, 10);

            var rayStartFail = new float3(-10, 10, -10);
            var rayEndFail   = new float3(10, 10, 10);

            rigidbody.Collider = (Collider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            var colliderCastInput = new ColliderCastInput();
            var closestHit        = new ColliderCastHit();
            var allHits           = new NativeList <ColliderCastHit>(Allocator.Temp);

            // OK case : Sphere hits the box collider
            float3 rayDir = rayEndOK - rayStartOK;

            colliderCastInput.Position  = rayStartOK;
            colliderCastInput.Direction = rayDir;
            colliderCastInput.Collider  = (Collider *)SphereCollider.Create(float3.zero, sphereRadius).GetUnsafePtr();

            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput));
            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput, out closestHit));
            Assert.IsTrue(rigidbody.CastCollider(colliderCastInput, ref allHits));

            // Fail case : wrong direction
            rayDir = rayEndFail - rayStartFail;
            colliderCastInput.Position  = rayStartFail;
            colliderCastInput.Direction = rayDir;

            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput));
            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput, out closestHit));
            Assert.IsFalse(rigidbody.CastCollider(colliderCastInput, ref allHits));
        }
Exemple #21
0
        //Draw the short term paths of all AI and display the current number of active AI
        private void DrawAIPath(Graphics displayDevice)
        {
            //write the number of AI currently active in the top right of the screen
            mRenderer.Draw(AIgraph.paths.Count().ToString(), new Physics.Vector2D(1200, 10), displayDevice);

            //draw all short term paths
            Physics.RigidBody temp = new Physics.RigidBody();
            AI.NodeIndex      previousNode;
            for (int i = 0; i < AIgraph.paths.Count(); ++i)
            {
                //Draw the AI's current destination node
                temp.Shape        = new Physics.Circle(8);
                temp.Shape.mColor = Color.BlueViolet;
                temp.SetPosition(AIgraph.topLevelNode.GetNodePosition(AIgraph.GetNextDestination(i, AIgraph.GetNodeAtPoint(mAImanager.aiControllers[i].AIPlayer.playerBody.Position))));
                if (temp.Position != null)
                {
                    mRenderer.Draw(temp, displayDevice);
                }

                //draw all nodes in the short term path
                temp.Shape.mColor = Color.Green;
                temp.Shape        = new Physics.Circle(5);
                foreach (AI.NodeIndex node in AIgraph.paths[i])
                {
                    //draw the node
                    temp.SetPosition(AIgraph.topLevelNode.GetNodePosition(node));
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }

                    //draw the connection between that node and the previous node
                    previousNode = AIgraph.topLevelNode.GetNode(node).previousNode;
                    if (previousNode != null)
                    {
                        mRenderer.DrawArrow(AIgraph.topLevelNode.GetNodePosition(previousNode), temp.Position, displayDevice);
                    }
                }
            }
        }
Exemple #22
0
        public unsafe void RigidBodyCastRayTest()
        {
            Physics.RigidBody rigidbody = Unity.Physics.RigidBody.Zero;

            const float size         = 1.0f;
            const float convexRadius = 0.0f;

            var rayStartOK = new float3(-10, -10, -10);
            var rayEndOK   = new float3(10, 10, 10);

            var rayStartFail = new float3(-10, 10, -10);
            var rayEndFail   = new float3(10, 10, 10);

            rigidbody.Collider = (Collider *)BoxCollider.Create(float3.zero, quaternion.identity, new float3(size), convexRadius).GetUnsafePtr();

            var raycastInput = new RaycastInput();
            var closestHit   = new RaycastHit();
            var allHits      = new NativeList <RaycastHit>(Allocator.Temp);

            // OK case : Ray hits the box collider
            float3 rayDir = rayEndOK - rayStartOK;

            raycastInput.Ray.Origin    = rayStartOK;
            raycastInput.Ray.Direction = rayDir;
            raycastInput.Filter        = CollisionFilter.Default;

            Assert.IsTrue(rigidbody.CastRay(raycastInput));
            Assert.IsTrue(rigidbody.CastRay(raycastInput, out closestHit));
            Assert.IsTrue(rigidbody.CastRay(raycastInput, ref allHits));

            // Fail Case : wrong direction
            rayDir = rayEndFail - rayStartFail;
            raycastInput.Ray.Origin    = rayStartFail;
            raycastInput.Ray.Direction = rayDir;

            Assert.IsFalse(rigidbody.CastRay(raycastInput));
            Assert.IsFalse(rigidbody.CastRay(raycastInput, out closestHit));
            Assert.IsFalse(rigidbody.CastRay(raycastInput, ref allHits));
        }
        public void Draw(Physics.RigidBody rb, Graphics g)
        {
            //colour is dependant on the colour specified in the rigidbody
            mBrush.Color = rb.Shape.mColor;

            //a different draw method is needed for boxes than for circles
            if (rb.Shape is Physics.Circle)
            {
                float radius   = ((Physics.Circle)rb.Shape).Radius;
                float diameter = ((Physics.Circle)rb.Shape).Radius * 2.0f;

                //draw an ellipse with width and height that match the diameter of the circle
                //the position of the camera is used to determine where the object is drawn
                g.FillEllipse(mBrush,
                              rb.Position.X - radius + cameraLocation.X,
                              rb.Position.Y - radius + cameraLocation.Y,
                              diameter,
                              diameter
                              );
            }
            else if (rb.Shape is Physics.Box)
            {
                //Create the four points that are to be drawn
                PointF[]    pts   = new PointF[4];
                Physics.Box box   = ((Physics.Box)rb.Shape);
                int         index = 0;

                //the position of the camera is used to determine where the object is drawn
                foreach (Physics.Vector2D vert in box.Vertices)
                {
                    pts[index].X   = rb.Position.X + vert.X + cameraLocation.X;
                    pts[index++].Y = rb.Position.Y + vert.Y + cameraLocation.Y;
                }

                //fill the polygon defined by the above points
                g.FillPolygon(mBrush, pts);
            }
        }
Exemple #24
0
        //given a rigidbody, create its node and its child nodes, then return its node
        public static Node CreateNodesFromRB(Physics.RigidBody theRB, NodeIndex parentIndex, int localIndex)
        {
            //create the node for the rigidbody
            Node rigidBody = new Node(theRB.Position, new NodeIndex(parentIndex, localIndex), NODE_TYPE.RIGIDBODY);

            //this temporary position is used to place the child nodes
            Physics.Vector2D nodePosition = new Physics.Vector2D();
            nodePosition.Y = theRB.Shape.ComputeAABB().MIN.Y - (Physics.Player.playerRadius + 1);


            //Create the leftmost fall node
            nodePosition.X = theRB.Shape.ComputeAABB().MIN.X - (Physics.Player.playerRadius + 1);
            rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FALL));


            //Move the node position so it is not above a sheer drop
            nodePosition.X = theRB.Shape.ComputeAABB().MIN.X + (Physics.Player.playerRadius / 2);

            //Create the regular nodes an even distance apart
            float surfaceWidth  = theRB.Shape.ComputeAABB().MAX.X - theRB.Shape.ComputeAABB().MIN.X;
            int   numberOfNodes = (int)(surfaceWidth / (Physics.Player.playerRadius * 2) + 0.5);
            float step          = (surfaceWidth - Physics.Player.playerRadius) / numberOfNodes;

            for (int i = 0; i <= numberOfNodes; ++i)
            {
                rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FLOOR));
                nodePosition.X += step;
            }


            //Create the rightmost fall node
            nodePosition.X = theRB.Shape.ComputeAABB().MAX.X + (Physics.Player.playerRadius + 1);
            rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FALL));


            return(rigidBody);
        }
Exemple #25
0
        private void InitialiseDefaults(float chosenRadius, int chosenSpeed)
        {
            //create the player's rigidbody
            playerBody              = new Physics.RigidBody();
            playerBody.type         = RBTypes.PLAYER;
            playerBody.Shape        = new Physics.Circle(chosenRadius);
            playerBody.Shape.mColor = System.Drawing.Color.Firebrick;
            playerBody.SetDynamic();
            playerBody.Mass = 120;

            //set speed to the input speed, and update all variables calculated using speed
            SetSpeed(chosenSpeed);

            for (int i = 0; i < (int)CONTROLS.NUM_OF_CONTROLS; ++i)
            {
                controls[i] = false;
            }

            gunForce          = 300;
            gunReload         = 0.0f;
            collisionCooldown = 0.0f;

            won = false;
        }
Exemple #26
0
        private void CreateObjects()
        {
            Physics.RigidBody newBody = new Physics.RigidBody();

            //declare the colours used
            System.Drawing.Color wallColour         = System.Drawing.Color.DarkSlateGray;
            System.Drawing.Color furnitureColour    = System.Drawing.Color.Brown;
            System.Drawing.Color cloudColour        = System.Drawing.Color.LightGray;
            System.Drawing.Color liftColour         = System.Drawing.Color.BlueViolet;
            System.Drawing.Color goalColour         = System.Drawing.Color.Gold;
            System.Drawing.Color wreckingBallColour = System.Drawing.Color.Black;


            //create the ground floor
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(1700, 80);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(400, 700));
            thePhysicsEngine.addRigidBody(newBody);
            //front desk
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(200, 40);
            newBody.Shape.mColor = furnitureColour;
            newBody.SetPosition(new Physics.Vector2D(1100, 640));
            thePhysicsEngine.addRigidBody(newBody);

            //Create the left wall
            //bottom bit
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(40, 650);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(0, 275));
            thePhysicsEngine.addRigidBody(newBody);

            //top bit
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(40, 300);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(0, -300));
            thePhysicsEngine.addRigidBody(newBody);

            //create the right wall
            //Top bit
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(40, 850);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(1200, -25));
            thePhysicsEngine.addRigidBody(newBody);

            //bottom bit
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(40, 200);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(1200, 650));
            thePhysicsEngine.addRigidBody(newBody);

            //breakaway bit
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(40, 149);
            newBody.Shape.mColor = wallColour;
            newBody.Mass         = 4000.0f;
            newBody.SetPosition(new Physics.Vector2D(1200, 475));
            newBody.SetDynamic();
            thePhysicsEngine.addRigidBody(newBody);


            //create the first floor
            //floor
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(1000, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(500, 550));
            thePhysicsEngine.addRigidBody(newBody);

            //stairs
            float width = 400, height = 20;
            float Xpos = 200, Ypos = 530;

            for (int i = 0; i < 9; ++i)
            {
                newBody              = new Physics.RigidBody();
                newBody.Shape        = new Physics.Box(width, height);
                newBody.Shape.mColor = wallColour;
                newBody.SetPosition(new Physics.Vector2D(Xpos, Ypos));
                thePhysicsEngine.addRigidBody(newBody);

                width -= 40;
                Ypos  -= 20;
                Xpos  -= 20;
            }

            //create the second floor
            //left bit
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(250, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(425, 300));
            thePhysicsEngine.addRigidBody(newBody);
            //right bit
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(500, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(950, 300));
            thePhysicsEngine.addRigidBody(newBody);
            //fallen bit
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(145, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(620, 302));
            newBody.SetDynamic();
            thePhysicsEngine.addRigidBody(newBody);
            //girdir to hold the fallen piece up
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(10, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(550, 313));
            thePhysicsEngine.addRigidBody(newBody);

            //create the fragmented floor
            //piece 1
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(130, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(940, 220));
            thePhysicsEngine.addRigidBody(newBody);
            //piece 2
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(190, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(650, 130));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 3
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(100, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(400, 90));
            thePhysicsEngine.addRigidBody(newBody);

            //extra step for balcony
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(50, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(250, 20));
            thePhysicsEngine.addRigidBody(newBody);

            //create jumping "puzzle"
            //piece 4
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(80, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(730, 50));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 5
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(70, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(850, -20));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 6
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(30, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(900, -80));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 7
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(80, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(1000, -50));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 8
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(80, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(1100, -170));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 9
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(70, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(800, -150));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 9
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(30, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(700, -30));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 10
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(60, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(600, -80));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 11
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(40, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(670, -160));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 12
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(70, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(950, -230));
            thePhysicsEngine.addRigidBody(newBody);

            //piece 13
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(130, 10);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(1120, -310));
            thePhysicsEngine.addRigidBody(newBody);


            //create balcony
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(400, 20);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(-50, -50));
            thePhysicsEngine.addRigidBody(newBody);
            //lip
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(10, 40);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(-245, -70));
            thePhysicsEngine.addRigidBody(newBody);

            //create clouds outside balcony
            //cloud 1
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(40, 40);
            newBody.Shape.mColor = cloudColour;
            newBody.SetPosition(new Physics.Vector2D(-350, -100));
            thePhysicsEngine.addRigidBody(newBody);


            //cloud 2
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(50, 50);
            newBody.Shape.mColor = cloudColour;
            newBody.SetPosition(new Physics.Vector2D(-490, -130));
            thePhysicsEngine.addRigidBody(newBody);

            //cloud 3
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(90, 70);
            newBody.Shape.mColor = cloudColour;
            newBody.SetPosition(new Physics.Vector2D(-600, -170));
            thePhysicsEngine.addRigidBody(newBody);

            //cloud 4
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(150, 100);
            newBody.Shape.mColor = cloudColour;
            newBody.SetPosition(new Physics.Vector2D(-800, -230));
            thePhysicsEngine.addRigidBody(newBody);

            //cloud 5
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(350, 160);
            newBody.Shape.mColor = cloudColour;
            newBody.SetPosition(new Physics.Vector2D(-300, -370));
            thePhysicsEngine.addRigidBody(newBody);

            //cloud 6
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(50, 30);
            newBody.Shape.mColor = cloudColour;
            newBody.SetPosition(new Physics.Vector2D(-600, -350));
            thePhysicsEngine.addRigidBody(newBody);

            //cloud 7
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(700, 500);
            newBody.Shape.mColor = cloudColour;
            newBody.SetPosition(new Physics.Vector2D(-1100, -700));
            thePhysicsEngine.addRigidBody(newBody);


            //create the roof
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(900, 40);
            newBody.Shape.mColor = wallColour;
            newBody.SetPosition(new Physics.Vector2D(450, -450));
            thePhysicsEngine.addRigidBody(newBody);


            //create the lifts
            Physics.MovingPlatform newPlatform;
            Physics.Shape          platShape;

            platShape        = new Physics.Box(60, 10);
            platShape.mColor = liftColour;
            newPlatform      = new Physics.MovingPlatform(platShape, new Physics.Vector2D(180, -60), new Physics.Vector2D(180, -300), 30f, 1.0f);
            newPlatform.platform.staticFriction  = 0.7f;
            newPlatform.platform.dynamicFriction = 0.6f;
            thePhysicsEngine.addMovingPlatform(newPlatform);


            platShape        = new Physics.Box(60, 10);
            platShape.mColor = liftColour;
            newPlatform      = new Physics.MovingPlatform(platShape, new Physics.Vector2D(700, -280), new Physics.Vector2D(240, -280), 50f, 1.0f);
            newPlatform.platform.staticFriction  = 0.7f;
            newPlatform.platform.dynamicFriction = 0.6f;
            thePhysicsEngine.addMovingPlatform(newPlatform);

            //the final lift to the goal
            platShape        = new Physics.Box(80, 20);
            platShape.mColor = liftColour;
            newPlatform      = new Physics.MovingPlatform(platShape, new Physics.Vector2D(960, -800), new Physics.Vector2D(960, -400), 10f, 1.0f);
            newPlatform.platform.staticFriction  = 0.7f;
            newPlatform.platform.dynamicFriction = 0.6f;
            thePhysicsEngine.addMovingPlatform(newPlatform);

            //The goal platform
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Box(200, 20);
            newBody.Shape.mColor = goalColour;
            newBody.type         = Physics.RBTypes.GOAL;
            newBody.SetPosition(new Physics.Vector2D(800, -800));
            thePhysicsEngine.addRigidBody(newBody);


            //add the wrecking ball
            //the moving arm
            platShape        = new Physics.Box(10, 10);
            platShape.mColor = liftColour;
            newPlatform      = new Physics.MovingPlatform(platShape, new Physics.Vector2D(1300, 330), new Physics.Vector2D(1550, 330), 50f, 1.0f);
            newPlatform.platform.staticFriction  = 1.0f;
            newPlatform.platform.dynamicFriction = 0.9f;
            thePhysicsEngine.addMovingPlatform(newPlatform);

            //the ball
            newBody              = new Physics.RigidBody();
            newBody.Shape        = new Physics.Circle(40);
            newBody.Shape.mColor = wreckingBallColour;
            newBody.SetPosition(new Physics.Vector2D(1300, 510));
            newBody.Mass = 2000;
            newBody.SetDynamic();
            thePhysicsEngine.addRigidBody(newBody);

            //the chain
            Physics.SpringJoint wreckingBallChain = new Physics.SpringJoint(newPlatform.platform, newBody);
            wreckingBallChain.RestLength = 180;
            wreckingBallChain.Stiffness  = 1000000;
            wreckingBallChain.Dampen     = 1;
            thePhysicsEngine.springs.Add(wreckingBallChain);
        }
Exemple #27
0
        public unsafe void ManifoldQueryTest()
        {
            const uint seed      = 0x98765432;
            Random     rnd       = new Random(seed);
            int        numWorlds = 1000;

            uint dbgWorld = 0;

            if (dbgWorld > 0)
            {
                numWorlds = 1;
            }

            for (int iWorld = 0; iWorld < numWorlds; iWorld++)
            {
                // Save state to repro this query without doing everything that came before it
                if (dbgWorld > 0)
                {
                    rnd.state = dbgWorld;
                }
                uint worldState            = rnd.state;
                Physics.PhysicsWorld world = TestUtils.GenerateRandomWorld(ref rnd, rnd.NextInt(1, 20), 3.0f);

                // Manifold test
                // TODO would be nice if we could change the world collision tolerance
                for (int iBodyA = 0; iBodyA < world.NumBodies; iBodyA++)
                {
                    for (int iBodyB = iBodyA + 1; iBodyB < world.NumBodies; iBodyB++)
                    {
                        Physics.RigidBody bodyA = world.Bodies[iBodyA];
                        Physics.RigidBody bodyB = world.Bodies[iBodyB];
                        if (bodyA.Collider->Type == ColliderType.Mesh && bodyB.Collider->Type == ColliderType.Mesh)
                        {
                            continue; // TODO - no mesh-mesh manifold support yet
                        }

                        // Build manifolds
                        BlockStream        contacts      = new BlockStream(1, 0, Allocator.Temp);
                        BlockStream.Writer contactWriter = contacts;
                        contactWriter.BeginForEachIndex(0);
                        ManifoldQueries.BodyBody(ref world, new BodyIndexPair {
                            BodyAIndex = iBodyA, BodyBIndex = iBodyB
                        }, 1.0f, ref contactWriter);
                        contactWriter.EndForEachIndex();

                        // Read each manifold
                        BlockStream.Reader contactReader = contacts;
                        contactReader.BeginForEachIndex(0);
                        int manifoldIndex = 0;
                        while (contactReader.RemainingItemCount > 0)
                        {
                            string failureMessage = iWorld + " (" + worldState + ") " + iBodyA + " vs " + iBodyB + " #" + manifoldIndex;
                            manifoldIndex++;

                            // Read the manifold header
                            ContactHeader header = contactReader.Read <ContactHeader>();
                            ConvexConvexManifoldQueries.Manifold manifold = new ConvexConvexManifoldQueries.Manifold();
                            manifold.NumContacts = header.NumContacts;
                            manifold.Normal      = header.Normal;

                            // Get the leaf shapes
                            ChildCollider leafA, leafB;
                            {
                                Collider.GetLeafCollider(bodyA.Collider, bodyA.WorldFromBody, header.ColliderKeys.ColliderKeyA, out leafA);
                                Collider.GetLeafCollider(bodyB.Collider, bodyB.WorldFromBody, header.ColliderKeys.ColliderKeyB, out leafB);
                            }

                            // Read each contact point
                            int minIndex = 0;
                            for (int iContact = 0; iContact < header.NumContacts; iContact++)
                            {
                                // Read the contact and find the closest
                                ContactPoint contact = contactReader.Read <ContactPoint>();
                                manifold[iContact] = contact;
                                if (contact.Distance < manifold[minIndex].Distance)
                                {
                                    minIndex = iContact;
                                }

                                // Check that the contact point is on or inside the shape
                                CheckPointOnSurface(ref leafA, contact.Position + manifold.Normal * contact.Distance, failureMessage + " contact " + iContact + " leaf A");
                                CheckPointOnSurface(ref leafB, contact.Position, failureMessage + " contact " + iContact + " leaf B");
                            }

                            // Check the closest point
                            {
                                ContactPoint           closestPoint = manifold[minIndex];
                                RigidTransform         aFromWorld   = math.inverse(leafA.TransformFromChild);
                                DistanceQueries.Result result       = new DistanceQueries.Result
                                {
                                    PositionOnAinA = math.transform(aFromWorld, closestPoint.Position + manifold.Normal * closestPoint.Distance),
                                    NormalInA      = math.mul(aFromWorld.rot, manifold.Normal),
                                    Distance       = closestPoint.Distance
                                };

                                MTransform aFromB            = new MTransform(math.mul(aFromWorld, leafB.TransformFromChild));
                                float      referenceDistance = DistanceQueries.ConvexConvex(leafA.Collider, leafB.Collider, aFromB).Distance;
                                ValidateDistanceResult(result, ref ((ConvexCollider *)leafA.Collider)->ConvexHull, ref ((ConvexCollider *)leafB.Collider)->ConvexHull, aFromB, referenceDistance, failureMessage + " closest point");
                            }

                            // Check that the manifold is flat
                            CheckManifoldFlat(ref manifold, manifold.Normal, failureMessage + ": non-flat A");
                            CheckManifoldFlat(ref manifold, float3.zero, failureMessage + ": non-flat B");
                        }

                        contacts.Dispose();
                    }
                }

                world.Dispose(); // TODO leaking memory if the test fails
            }
        }
Exemple #28
0
        //the same as the above method but for falling
        //this method is effectively just copy/pasted from Player.FallCollidesWithRB() with modifications to display the results
        private void DrawFallCullingPoints(Graphics displayDevice)
        {
            Physics.RigidBody temp = new Physics.RigidBody();
            temp.Shape        = new Physics.Circle(3);
            temp.Shape.mColor = Color.OrangeRed;

            //store the start and endpoints of the fall
            Physics.Vector2D source      = playerCharacter.playerBody.Position;
            Physics.Vector2D destination = jumpDestination;
            if (destination == null)
            {
                destination = new Physics.Vector2D(0, 0);
            }
            Physics.Vector2D displacement = destination - source;

            Tuple <float, float> timeToFall = Physics.SuvatEquations.TfromSUA(displacement.Y, 0.0f, 98);

            if (timeToFall == null)
            {
                return;
            }
            if (float.IsNaN(timeToFall.Item1) && float.IsNaN(timeToFall.Item2))
            {
                return;
            }

            //calculate the acceleration needed to fall to the destination
            float acceleration = Physics.SuvatEquations.AfromSUT(displacement.X, 0.0f, Math.Max(timeToFall.Item1, timeToFall.Item2));

            //calculate the four points where the path defined by acceleration could potentially collide with the rigidbody
            Tuple <float, float> timeToReach;

            float leftmostX;
            float leftmostY;

            float righttmostX;
            float righttmostY;

            float topY;
            float topX;

            float bottomY;
            float bottomX;

            //draw the points where the fall arc could collide with each rigidbody
            foreach (Physics.RigidBody RB in physEng.staticPhysicsObjects)
            {
                //obtain the X positions of the sides of the rigidbody
                leftmostX   = (RB.Position.X + RB.Shape.ComputeAABB().MIN.X) - source.X;
                righttmostX = (RB.Position.X + RB.Shape.ComputeAABB().MAX.X) - source.X;
                //obtain the Y positions of the top and bottom of the rigidbody
                topY    = (RB.Position.Y + RB.Shape.ComputeAABB().MIN.Y) - source.Y;
                bottomY = (RB.Position.Y + RB.Shape.ComputeAABB().MAX.Y) - source.Y;



                //calculate the time to reach the left side of the rigidbody
                timeToReach = Physics.SuvatEquations.TfromSUA(leftmostX, 0.0f, acceleration);

                //calculate the first Y position, draw the first point, calculate the second, draw the second point
                leftmostY = Physics.SuvatEquations.SfromUAT(0.0f, 98, timeToReach.Item1);
                if (!float.IsNaN(leftmostY))
                {
                    mRenderer.Draw(temp, displayDevice);
                    temp.SetPosition(new Physics.Vector2D(leftmostX, leftmostY) + source);
                }
                leftmostY = Physics.SuvatEquations.SfromUAT(0.0f, 98, timeToReach.Item2);
                if (!float.IsNaN(leftmostY))
                {
                    mRenderer.Draw(temp, displayDevice);
                    temp.SetPosition(new Physics.Vector2D(leftmostX, leftmostY) + source);
                }



                //calculate the time to reach the right side of the rigidbody
                timeToReach = Physics.SuvatEquations.TfromSUA(righttmostX, 0.0f, acceleration);

                //calculate the first Y position, draw the first point, calculate the second, draw the second point
                righttmostY = Physics.SuvatEquations.SfromUAT(0.0f, 98, timeToReach.Item1);
                if (!float.IsNaN(righttmostY))
                {
                    mRenderer.Draw(temp, displayDevice);
                    temp.SetPosition(new Physics.Vector2D(righttmostX, righttmostY) + source);
                }
                righttmostY = Physics.SuvatEquations.SfromUAT(0.0f, 98, timeToReach.Item2);
                if (!float.IsNaN(righttmostY))
                {
                    mRenderer.Draw(temp, displayDevice);
                    temp.SetPosition(new Physics.Vector2D(righttmostX, righttmostY) + source);
                }



                //calculate the time to reach the top of the rigidbody
                timeToReach = Physics.SuvatEquations.TfromSUA(topY, 0.0f, 98);

                //calculate the first X position, draw the first point, calculate the second, draw the second point
                topX = Physics.SuvatEquations.SfromUAT(0.0f, acceleration, timeToReach.Item1);
                if (!float.IsNaN(topX))
                {
                    mRenderer.Draw(temp, displayDevice);
                    temp.SetPosition(new Physics.Vector2D(topX, topY) + source);
                }
                topX = Physics.SuvatEquations.SfromUAT(0.0f, acceleration, timeToReach.Item2);
                if (!float.IsNaN(topX))
                {
                    mRenderer.Draw(temp, displayDevice);
                    temp.SetPosition(new Physics.Vector2D(topX, topY) + source);
                }



                //calculate the time to reach the bottom of the rigidbody
                timeToReach = Physics.SuvatEquations.TfromSUA(bottomY, 0.0f, 98);

                //calculate the first X position, draw the first point, calculate the second, draw the second point
                bottomX = Physics.SuvatEquations.SfromUAT(0.0f, acceleration, timeToReach.Item1);
                if (!float.IsNaN(bottomX))
                {
                    mRenderer.Draw(temp, displayDevice);
                    temp.SetPosition(new Physics.Vector2D(bottomX, bottomY) + source);
                }
                bottomX = Physics.SuvatEquations.SfromUAT(0.0f, acceleration, timeToReach.Item2);
                if (!float.IsNaN(bottomX))
                {
                    mRenderer.Draw(temp, displayDevice);
                    temp.SetPosition(new Physics.Vector2D(bottomX, bottomY) + source);
                }
            }
        }
Exemple #29
0
        //draw the points of the player's jump arc at each edge of every rigidbody
        //Used to debug the method that determines if a jump collides with a rigidbody
        //this method is effectively just copy/pasted from Player.JumpCollidesWithRB() with modifications to display the results
        private void DrawJumpCullingPoints(Graphics displayDevice)
        {
            Physics.RigidBody temp = new Physics.RigidBody();
            temp.Shape        = new Physics.Circle(3);
            temp.Shape.mColor = Color.OrangeRed;

            //store the list of positions at each edge of a box rigidbody
            Tuple <Tuple <Physics.Vector2D, Physics.Vector2D, Physics.Vector2D, Physics.Vector2D>, Tuple <Physics.Vector2D, Physics.Vector2D, Physics.Vector2D, Physics.Vector2D> > possibleCollisionPoints;

            //for every static rigidbody
            foreach (Physics.RigidBody RB in physEng.staticPhysicsObjects)
            {
                //obtain the list of coordinates
                possibleCollisionPoints = playerCharacter.GetBoxCollisionPoints(RB, playerCharacter.playerBody.Position, 0.0f, 15.0f, physEng.gravity);

                //draw each valid coordinate as a small red circle
                if (possibleCollisionPoints != null)
                {
                    temp.SetPosition(possibleCollisionPoints.Item1.Item1);
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }
                    temp.SetPosition(possibleCollisionPoints.Item1.Item2);
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }
                    temp.SetPosition(possibleCollisionPoints.Item1.Item3);
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }
                    temp.SetPosition(possibleCollisionPoints.Item1.Item4);
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }

                    temp.SetPosition(possibleCollisionPoints.Item2.Item1);
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }
                    temp.SetPosition(possibleCollisionPoints.Item2.Item2);
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }
                    temp.SetPosition(possibleCollisionPoints.Item2.Item3);
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }
                    temp.SetPosition(possibleCollisionPoints.Item2.Item4);
                    if (temp.Position != null)
                    {
                        mRenderer.Draw(temp, displayDevice);
                    }
                }
            }
        }
Exemple #30
0
        //draw the jump arc of a specified player to a specified destination
        //if specified destination is null then draw the jump assuming the player jumped with no acceleration or deceleration

        //This function is useful for debugging the "Player.GetJumpFromSourceToDest()", "Player.GetJumpYFromX()", and "Player.GetJumpXFromY()" methods
        private void DrawJumpArc(Graphics displayDevice, Physics.Player thePlayer, Physics.Vector2D goal)
        {
            //a temporary variable used in draw calls
            Physics.RigidBody temp = new Physics.RigidBody();

            //stores how long the player accelerates after hitting jump
            float accelerationTime = 0.0f;

            //if a goal was specified
            //	calculate the amount of time the player would need to accelerate after jumping in order to reach the goal
            //	draw the goal point
            if (goal != null)
            {
                accelerationTime = thePlayer.GetJumpFromSourceToDest(thePlayer.playerBody.Position, goal, physEng.gravity);

                //draw the goal
                temp.Shape        = new Physics.Circle(6);
                temp.Shape.mColor = Color.Purple;
                temp.SetPosition(goal);
                mRenderer.Draw(temp, displayDevice);
            }

            //set the object to be drawn to a circle of radius 3
            temp.Shape = new Physics.Circle(3);


            //Temporary variable used to store the coordinates returned from the GetJumpYFromX() and GetJumpXFromY() methods
            Tuple <Physics.Vector2D, Physics.Vector2D> resultingPoints;

            //loop through the 1200 X coordinates around the player, calculating the Y position of the jump at that point
            //Draw a circle at each combined X,Y coordinate in Green
            temp.Shape.mColor = Color.Green;
            for (int i = -600; i < 600; i += 1)
            {
                //Get the two possible X,Y coords of the jump given a specific X coord
                resultingPoints = thePlayer.GetJumpYFromX(thePlayer.playerBody.Position, accelerationTime, 15.0f, physEng.gravity, thePlayer.playerBody.Position.X - i);

                //draw any valid returned coordinates
                if (resultingPoints.Item1 != null)
                {
                    temp.SetPosition(resultingPoints.Item1);
                    mRenderer.Draw(temp, displayDevice);
                }
                if (resultingPoints.Item2 != null)
                {
                    temp.SetPosition(resultingPoints.Item2);
                    mRenderer.Draw(temp, displayDevice);
                }
            }

            //loop through the 1200 Y coordinates around the player, calculating the X position of the jump at that point
            //Draw a circle at each combined X,Y coordinate in red
            temp.Shape.mColor = Color.OrangeRed;
            for (int i = -600; i < 600; i += 10)
            {
                //Get the two possible X,Y coords of the jump given a specific Y coord
                resultingPoints = thePlayer.GetJumpXFromY(thePlayer.playerBody.Position, accelerationTime, 15.0f, physEng.gravity, thePlayer.playerBody.Position.Y - i);

                //draw any valid returned coordinates
                if (resultingPoints.Item1 != null)
                {
                    temp.SetPosition(resultingPoints.Item1);
                    mRenderer.Draw(temp, displayDevice);
                }
                if (resultingPoints.Item2 != null)
                {
                    temp.SetPosition(resultingPoints.Item2);
                    mRenderer.Draw(temp, displayDevice);
                }
            }
        }