Mobile collidable acting as a collision proxy for an entity.
Inheritance: BEPUphysics.BroadPhaseEntries.MobileCollidables.MobileCollidable
 void Events_InitialCollisionDetected(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
 {
     if ("Environment".Equals(other.Tag))
     {
         // do something on collision
     }
 }
        public static void GetShapeMeshData(EntityCollidable collidable, List<VertexPositionNormalTexture> vertices, List<ushort> indices)
        {
            var convexHullShape = collidable.Shape as ConvexHullShape;
            if (convexHullShape == null)
                throw new ArgumentException("Wrong shape type.");

            var hullTriangleVertices = new List<BEPUutilities.Vector3>();
            var hullTriangleIndices = new List<int>();
            ConvexHullHelper.GetConvexHull(convexHullShape.Vertices, hullTriangleIndices, hullTriangleVertices);
            //The hull triangle vertices are used as a dummy to get the unnecessary hull vertices, which are cleared afterwards.
            hullTriangleVertices.Clear();
            foreach (int i in hullTriangleIndices)
            {
                hullTriangleVertices.Add(convexHullShape.Vertices[i]);
            }

            var toReturn = new VertexPositionNormalTexture[hullTriangleVertices.Count];
            Vector3 normal;
            for (ushort i = 0; i < hullTriangleVertices.Count; i += 3)
            {
                normal = MathConverter.Convert(BEPUutilities.Vector3.Normalize(BEPUutilities.Vector3.Cross(hullTriangleVertices[i + 2] - hullTriangleVertices[i], hullTriangleVertices[i + 1] - hullTriangleVertices[i])));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i]), normal, new Vector2(0, 0)));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i + 1]), normal, new Vector2(1, 0)));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i + 2]), normal, new Vector2(0, 1)));
                indices.Add(i);
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)(i + 2));
            }
        }
Beispiel #3
0
        public static void GetShapeMeshData(EntityCollidable collidable, List<VertexPositionNormalTexture> vertices, List<ushort> indices)
        {
            var shape = collidable.Shape as ConvexShape;
            if (shape == null)
                throw new ArgumentException("Wrong shape type for this helper.");
            var vertexPositions = new BEPUutilities.Vector3[SampleDirections.Length];

            for (int i = 0; i < SampleDirections.Length; ++i)
            {
                shape.GetLocalExtremePoint(SampleDirections[i], out vertexPositions[i]);
            }

            var hullIndices = new RawList<int>();
            ConvexHullHelper.GetConvexHull(vertexPositions, hullIndices);

            var hullTriangleVertices = new RawList<BEPUutilities.Vector3>();
            foreach (int i in hullIndices)
            {
                hullTriangleVertices.Add(vertexPositions[i]);
            }

            for (ushort i = 0; i < hullTriangleVertices.Count; i += 3)
            {
                Vector3 normal = MathConverter.Convert(BEPUutilities.Vector3.Normalize(BEPUutilities.Vector3.Cross(hullTriangleVertices[i + 2] - hullTriangleVertices[i], hullTriangleVertices[i + 1] - hullTriangleVertices[i])));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i]), normal, new Vector2(0, 0)));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i + 1]), normal, new Vector2(1, 0)));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i + 2]), normal, new Vector2(0, 1)));
                indices.Add(i);
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)(i + 2));
            }
        }
 internal CompoundChild(CompoundShape shape, EntityCollidable collisionInformation, Material material, int index)
 {
     this.shape = shape;
     this.collisionInformation = collisionInformation;
     Material = material;
     this.shapeIndex = index;
 }
        private void CollisionDetectedHandler(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
        {
            EntityCollidable otherEntityCollidable = other as EntityCollidable;
            Terrain otherTerrain = other as Terrain;
            if (otherEntityCollidable != null &&
                otherEntityCollidable.Entity != null &&
                otherEntityCollidable.Entity.Tag != null)
            {
                int actorId = (int)(otherEntityCollidable.Entity.Tag);
                if (actorId == mOwnerActorId)
                    return;
                Actor actorHit = GameResources.ActorManager.GetActorById(actorId);
                IDamagable damage = actorHit.GetBehaviorThatImplementsType<IDamagable>();
                if (damage != null)
                {
                    damage.TakeDamage(mDamage);
                }

                Impact();
            }
            else if (otherTerrain != null)
            {
                Impact();
            }
        }
Beispiel #6
0
        public static void GetShapeMeshData(EntityCollidable collidable, List<VertexPositionNormalTexture> vertices, List<ushort> indices)
        {
            var compoundCollidable = collidable as CompoundCollidable;
            if (compoundCollidable == null)
                throw new ArgumentException("Wrong shape type.");
            var tempIndices = new List<ushort>();
            var tempVertices = new List<VertexPositionNormalTexture>();
            for (int i = 0; i < compoundCollidable.Children.Count; i++)
            {
                var child = compoundCollidable.Children[i];
                ModelDrawer.ShapeMeshGetter shapeMeshGetter;
                if (ModelDrawer.ShapeMeshGetters.TryGetValue(child.CollisionInformation.GetType(), out shapeMeshGetter))
                {
                    shapeMeshGetter(child.CollisionInformation, tempVertices, tempIndices);

                    for (int j = 0; j < tempIndices.Count; j++)
                    {
                        indices.Add((ushort)(tempIndices[j] + vertices.Count));
                    }
                    RigidTransform localTransform = child.Entry.LocalTransform;
                    Vector3 localPosition = child.CollisionInformation.LocalPosition;
                    for (int j = 0; j < tempVertices.Count; j++)
                    {
                        VertexPositionNormalTexture vertex = tempVertices[j];
                        Vector3.Add(ref vertex.Position, ref localPosition, out vertex.Position);
                        RigidTransform.Transform(ref vertex.Position, ref localTransform, out vertex.Position);
                        Vector3.Transform(ref vertex.Normal, ref localTransform.Orientation, out vertex.Normal);
                        vertices.Add(vertex);
                    }

                    tempVertices.Clear();
                    tempIndices.Clear();
                }
            }
        }
Beispiel #7
0
        public static void GetShapeMeshData(EntityCollidable collidable, List<VertexPositionNormalTexture> vertices, List<ushort> indices)
        {
            var minkowskiShape = collidable.Shape as MinkowskiSumShape;
            if (minkowskiShape == null)
                throw new ArgumentException("Wrong shape type.");

            var points = new List<Vector3>();
            Vector3 max;
            var direction = new Vector3();
            float angleChange = MathHelper.TwoPi / NumSamples;

            for (int i = 1; i < NumSamples / 2 - 1; i++)
            {
                float phi = MathHelper.PiOver2 - i * angleChange;
                var sinPhi = (float)Math.Sin(phi);
                var cosPhi = (float)Math.Cos(phi);
                for (int j = 0; j < NumSamples; j++)
                {
                    float theta = j * angleChange;
                    direction.X = (float)Math.Cos(theta) * cosPhi;
                    direction.Y = sinPhi;
                    direction.Z = (float)Math.Sin(theta) * cosPhi;

                    minkowskiShape.GetLocalExtremePoint(direction, out max);
                    points.Add(max);
                }
            }

            minkowskiShape.GetLocalExtremePoint(Toolbox.UpVector, out max);
            points.Add(max);
            minkowskiShape.GetLocalExtremePoint(Toolbox.DownVector, out max);
            points.Add(max);


            var hullTriangleVertices = new List<Vector3>();
            var hullTriangleIndices = new List<int>();
            ConvexHullHelper.GetConvexHull(points, hullTriangleIndices, hullTriangleVertices);
            //The hull triangle vertices are used as a dummy to get the unnecessary hull vertices, which are cleared afterwards.
            hullTriangleVertices.Clear();
            foreach (int i in hullTriangleIndices)
            {
                hullTriangleVertices.Add(points[i]);
            }

            Vector3 normal;
            for (ushort i = 0; i < hullTriangleVertices.Count; i += 3)
            {
                normal = Vector3.Normalize(Vector3.Cross(hullTriangleVertices[i + 2] - hullTriangleVertices[i], hullTriangleVertices[i + 1] - hullTriangleVertices[i]));
                vertices.Add(new VertexPositionNormalTexture(hullTriangleVertices[i], normal, new Vector2(0, 0)));
                vertices.Add(new VertexPositionNormalTexture(hullTriangleVertices[i + 1], normal, new Vector2(1, 0)));
                vertices.Add(new VertexPositionNormalTexture(hullTriangleVertices[i + 2], normal, new Vector2(0, 1)));
                indices.Add(i);
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)(i + 2));
            }
        }
        public void InitialCollisionDetected(EntityCollidable sender, Collidable other, CollidablePairHandler collisionPair)
        {
            if (other == acceptedTrigger)
            {
                //If the detector collided with the accepted trigger, move the box.
                movedBox.Position = new Vector3(4, 5, 0);
                movedBox.Orientation = Quaternion.Identity;
                movedBox.LinearVelocity = Vector3.Zero;
                movedBox.AngularVelocity = Vector3.Zero;

            }
        }
        private void Events_InitialCollisionDetected(BEPUphysics.BroadPhaseEntries.MobileCollidables.EntityCollidable sender, BEPUphysics.BroadPhaseEntries.Collidable other, BEPUphysics.NarrowPhaseSystems.Pairs.CollidablePairHandler pair)
        {
            Console.WriteLine(duckID + " Duck Collision");
            var    otherEntityInformation = other as EntityCollidable;
            string tag = (string)otherEntityInformation.Entity.Tag;

            // don't remove if it hits any of the packs
            if (!tag.Contains("fuelPack") && !tag.Contains("torpedoPack"))
            {
                RemoveFromGame();
            }
        }
 private void InitialCollisionDetectedHandler(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
 {
     EntityCollidable otherEntityCollidable = other as EntityCollidable;
     if (otherEntityCollidable != null &&
         otherEntityCollidable.Entity != null &&
         otherEntityCollidable.Entity.Tag != null &&
         mTriggerSet &&
         GameResources.ActorManager.IsPlayer((int)(otherEntityCollidable.Entity.Tag)))
     {
         mTriggerSet = false;
         GameResources.LoadNewLevelDelegate(mLevelName);
     }
 }
Beispiel #11
0
        private void Events_InitialCollisionDetected(BEPUphysics.BroadPhaseEntries.MobileCollidables.EntityCollidable sender, BEPUphysics.BroadPhaseEntries.Collidable other, BEPUphysics.NarrowPhaseSystems.Pairs.CollidablePairHandler pair)
        {
            // issues with motion upon impact with other objects
            Console.WriteLine("Ship Collision");
            var    otherEntityInformation = other as EntityCollidable;
            string tag = (string)otherEntityInformation.Entity.Tag;

            if (tag.Contains("duck"))
            {
                Console.WriteLine("Hit DUCK");
                if (!shieldActive)
                {
                    health            -= duckDamage;
                    generalInfoMessage = "DAMAGE TAKEN";
                }
            }
            if (tag.Equals("turtle"))
            {
                Console.WriteLine("Hit Turtle");
                if (Vector3.Distance(linearVelocity, maxVelocityToWin) <= 2f)

                {
                    conclusionMessage = "You successfully claimed the sacred Turtle!";
                }
                else
                {
                    conclusionMessage = "Your ship was going too fast! Failed to safely aquire the Turtle.";
                }
            }
            if (tag.Contains("fuelPack"))
            {
                float newValue = fuelLevel + fuelPackValue;

                // can't go over 100 fuel
                if (newValue > 100)
                {
                    fuelLevel = 100;
                }
                else
                {
                    fuelLevel = newValue;
                }
                generalInfoMessage = "FUEL PACK AQUIRED ";
            }
            if (tag.Contains("torpedoPack"))
            {
                // TODO - broken
                // AddTorpedo();
                generalInfoMessage = "TORPEDO PACK AQUIRED";
            }
        }
        public static void GetShapeMeshData(EntityCollidable collidable, List<VertexPositionNormalTexture> vertices, List<ushort> indices)
        {
            ConeShape coneShape = collidable.Shape as ConeShape;
            if (coneShape == null)
                throw new ArgumentException("Wrong shape type.");

            float verticalOffset = -coneShape.Height / 4;
            float angleBetweenFacets = MathHelper.TwoPi / NumSides;
            float radius = coneShape.Radius;

            //Create the vertex list

            var topVertexPosition = new Vector3(0, coneShape.Height + verticalOffset, 0);

            for (int i = 0; i < NumSides; i++)
            {
                float theta = i * angleBetweenFacets;
                var position = new Vector3((float)Math.Cos(theta) * radius, verticalOffset, (float)Math.Sin(theta) * radius);
                Vector3 offset = topVertexPosition - position;
                Vector3 normal = Vector3.Normalize(Vector3.Cross(Vector3.Cross(offset, Vector3.Up), offset));
                //Top vertex
                vertices.Add(new VertexPositionNormalTexture(topVertexPosition, normal, Vector2.Zero));
                //Sloped vertices
                vertices.Add(new VertexPositionNormalTexture(position, normal, Vector2.Zero));
                //Bottom vertices
                vertices.Add(new VertexPositionNormalTexture(position, Vector3.Down, Vector2.Zero));
            }


            //Create the index list
            for (ushort i = 0; i < vertices.Count; i += 3)
            {
                //Each iteration, the loop advances to the next vertex 'column.'
                //Four triangles per column (except for the four degenerate cap triangles).

                //Sloped Triangles
                indices.Add(i);
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)((i + 4) % vertices.Count));

                //Bottom cap triangles.
                var nextIndex = (ushort)((i + 5) % vertices.Count);
                if (nextIndex != 2) //Don't add cap indices if it's going to be a degenerate triangle.
                {
                    indices.Add((ushort)(i + 2));
                    indices.Add(2);
                    indices.Add(nextIndex);
                }
            }
        }
Beispiel #13
0
 private void InitialCollisionDetectedHandler(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
 {
     EntityCollidable otherEntityCollidable = other as EntityCollidable;
     if (otherEntityCollidable != null &&
         otherEntityCollidable.Entity != null &&
         otherEntityCollidable.Entity.Tag != null &&
         mTriggerSet &&
         GameResources.ActorManager.IsPlayer((int)(otherEntityCollidable.Entity.Tag)))
     {
         PlayerView finder = GameResources.ActorManager.GetPlayerViewOfAvatar((int)(otherEntityCollidable.Entity.Tag));
         finder.AvatarDesc.ObtainItem(Item);
         mTriggerSet = false;
         Owner.Despawn();
     }
 }
Beispiel #14
0
        private void Events_InitialCollisionDetected(BEPUphysics.BroadPhaseEntries.MobileCollidables.EntityCollidable sender, BEPUphysics.BroadPhaseEntries.Collidable other, BEPUphysics.NarrowPhaseSystems.Pairs.CollidablePairHandler pair)
        {
            Console.WriteLine(fuelPackID + " FuellPack Collision");
            var    otherEntityInformation = other as EntityCollidable;
            string tag = (string)otherEntityInformation.Entity.Tag;

            // only remove object if comes in contact with the ship
            if (tag.Equals("ship"))
            {
                if (Game.Components.Contains(this))
                {
                    RemoveFromGame();
                }
            }
        }
Beispiel #15
0
        private void Events_InitialCollisionDetected(BEPUphysics.BroadPhaseEntries.MobileCollidables.EntityCollidable sender, BEPUphysics.BroadPhaseEntries.Collidable other, BEPUphysics.NarrowPhaseSystems.Pairs.CollidablePairHandler pair)
        {
            Console.WriteLine(torpedoID + " Collision");
            var    otherEntityInformation = other as EntityCollidable;
            string tag = (string)otherEntityInformation.Entity.Tag;

            // hitting the ship doesn't remove the torpedo (would interfer with firing logic
            if (!tag.Equals("ship"))
            {
                if (Game.Components.Contains(this))
                {
                    RemoveFromGame();
                }
            }
        }
 protected void TryToAdd(EntityCollidable collidable)
 {
     CollisionRule rule;
     if ((rule = CollisionRules.collisionRuleCalculator(DetectorVolume, collidable)) < CollisionRule.NoNarrowPhasePair)
     {
         //Clamp the rule to the parent's rule.  Always use the more restrictive option.
         //Don't have to test for NoNarrowPhasePair rule on the parent's rule because then the parent wouldn't exist!
         if (rule < CollisionRule)
             rule = CollisionRule;
         if (!subPairs.ContainsKey(collidable))
         {
             var newPair = NarrowPhaseHelper.GetPairHandler(DetectorVolume, collidable, rule) as DetectorVolumePairHandler;
             if (newPair != null)
             {
                 newPair.Parent = this;
                 subPairs.Add(collidable, newPair);
             }
         }
         containedPairs.Add(collidable);
     }
 }
Beispiel #17
0
        public static void GetShapeMeshData(EntityCollidable collidable, List<VertexPositionNormalTexture> vertices, List<ushort> indices)
        {
            var triangleShape = collidable.Shape as TriangleShape;
            if(triangleShape == null)
                throw new ArgumentException("Wrong shape type.");
            Vector3 normal = triangleShape.GetLocalNormal();
            vertices.Add(new VertexPositionNormalTexture(triangleShape.VertexA, -normal, new Vector2(0, 0)));
            vertices.Add(new VertexPositionNormalTexture(triangleShape.VertexB, -normal, new Vector2(0, 1)));
            vertices.Add(new VertexPositionNormalTexture(triangleShape.VertexC, -normal, new Vector2(1, 0)));

            vertices.Add(new VertexPositionNormalTexture(triangleShape.VertexA, normal, new Vector2(0, 0)));
            vertices.Add(new VertexPositionNormalTexture(triangleShape.VertexB, normal, new Vector2(0, 1)));
            vertices.Add(new VertexPositionNormalTexture(triangleShape.VertexC, normal, new Vector2(1, 0)));

            indices.Add(0);
            indices.Add(1);
            indices.Add(2);

            indices.Add(3);
            indices.Add(5);
            indices.Add(4);
        }
        public static void GetShapeMeshData(EntityCollidable collidable, List<VertexPositionNormalTexture> vertices, List<ushort> indices)
        {
            MobileMeshShape shape = collidable.Shape as MobileMeshShape;
            var tempVertices = new VertexPositionNormalTexture[shape.TriangleMesh.Data.Vertices.Length];
            for (int i = 0; i < shape.TriangleMesh.Data.Vertices.Length; i++)
            {
                BEPUutilities.Vector3 position;
                shape.TriangleMesh.Data.GetVertexPosition(i, out position);
                tempVertices[i] = new VertexPositionNormalTexture(
                    MathConverter.Convert(position),
                    Vector3.Zero, 
                    Vector2.Zero);
            }

            for (int i = 0; i < shape.TriangleMesh.Data.Indices.Length; i++)
            {
                indices.Add((ushort)shape.TriangleMesh.Data.Indices[i]);
            }
            for (int i = 0; i < indices.Count; i += 3)
            {
                int a = indices[i];
                int b = indices[i + 1];
                int c = indices[i + 2];
                Vector3 normal = Vector3.Normalize(Vector3.Cross(
                    tempVertices[c].Position - tempVertices[a].Position,
                    tempVertices[b].Position - tempVertices[a].Position));
                tempVertices[a].Normal += normal;
                tempVertices[b].Normal += normal;
                tempVertices[c].Normal += normal;
            }

            for (int i = 0; i < tempVertices.Length; i++)
            {
                tempVertices[i].Normal.Normalize();
                vertices.Add(tempVertices[i]);
            }
        }
Beispiel #19
0
        /// <summary>
        /// Finds contacts between the query object and any intersected objects within the character's bounding box.
        /// </summary>
        /// <param name="queryObject">Collidable to query for contacts with.</param>
        /// <param name="tractionContacts">Output contacts that would provide traction.</param>
        /// <param name="supportContacts">Output contacts that would provide support.</param>
        /// <param name="sideContacts">Output contacts on the sides of the query object.</param>
        /// <param name="headContacts">Output contacts on the head of the query object.</param>
        public void QueryContacts(EntityCollidable queryObject,
            ref QuickList<CharacterContact> tractionContacts, ref QuickList<CharacterContact> supportContacts, ref QuickList<CharacterContact> sideContacts, ref QuickList<CharacterContact> headContacts)
        {
            var downDirection = characterBody.orientationMatrix.Down;

            tractionContacts.Clear();
            supportContacts.Clear();
            sideContacts.Clear();
            headContacts.Clear();

            foreach (var collidable in characterBody.CollisionInformation.OverlappedCollidables)
            {
                //The query object is assumed to have a valid bounding box.
                if (collidable.BoundingBox.Intersects(queryObject.BoundingBox))
                {
                    var pair = new CollidablePair(collidable, queryObject);
                    var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                    if (pairHandler.CollisionRule == CollisionRule.Normal)
                    {
                        pairHandler.SuppressEvents = true;
                        pairHandler.UpdateCollision(0);
                        pairHandler.SuppressEvents = false;

                        contactCategorizer.CategorizeContacts(pairHandler, characterBody.CollisionInformation, ref downDirection,
                                                              ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts);
                    }
                    //TODO: It would be nice if this was a bit easier.
                    //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving.
                    //No one would ever just guess this correctly.
                    //At least hide it behind a NarrowPhaseHelper function.
                    pairHandler.CleanUp();
                    pairHandler.Factory.GiveBack(pairHandler);
                }
            }

        }
        void QueryContacts(Vector3 position, EntityCollidable queryObject)
        {
            ClearContacts();

            //Update the position and orientation of the query object.
            RigidTransform transform;
            transform.Position = position;
            transform.Orientation = character.Body.Orientation;
            queryObject.UpdateBoundingBoxForTransform(ref transform, 0);

            foreach (var collidable in character.Body.CollisionInformation.OverlappedCollidables)
            {
                if (collidable.BoundingBox.Intersects(queryObject.BoundingBox))
                {
                    var pair = new CollidablePair(collidable, queryObject);
                    var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair);
                    if (pairHandler.CollisionRule == CollisionRule.Normal)
                    {
                        pairHandler.SuppressEvents = true;
                        pairHandler.UpdateCollision(0);
                        pairHandler.SuppressEvents = false;
                        foreach (var contact in pairHandler.Contacts)
                        {
                            //Must check per-contact collision rules, just in case
                            //the pair was actually a 'parent pair.'
                            if (contact.Pair.CollisionRule == CollisionRule.Normal)
                            {
                                ContactData contactData;
                                contactData.Position = contact.Contact.Position;
                                contactData.Normal = contact.Contact.Normal;
                                contactData.Id = contact.Contact.Id;
                                contactData.PenetrationDepth = contact.Contact.PenetrationDepth;
                                contacts.Add(contactData);
                            }
                        }
                    }
                    //TODO: It would be nice if this was a bit easier.
                    //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving.
                    //No one would ever just guess this correctly.
                    //At least hide it behind a NarrowPhaseHelper function.
                    pairHandler.CleanUp();
                    pairHandler.Factory.GiveBack(pairHandler);
                }
            }

            CategorizeContacts(ref position);
        }
Beispiel #21
0
 private void PrepareQueryObject(EntityCollidable queryObject, ref Vector3 position)
 {
     RigidTransform transform;
     transform.Position = position;
     transform.Orientation = characterBody.Orientation;
     queryObject.UpdateBoundingBoxForTransform(ref transform, 0);
 }
 public void CollisionEnded(EntityCollidable sender, Collidable other, CollidablePairHandler collisionPair)
 {
     if (other == acceptedTrigger)
     {
         //If the detector ceases to collide, get rid of the spawned box.
         movedBox.Position = new Vector3(-4, 5, 0);
         movedBox.Orientation = Quaternion.Identity;
         movedBox.LinearVelocity = Vector3.Zero;
         movedBox.AngularVelocity = Vector3.Zero;
     }
 }
Beispiel #23
0
        float GetSubmergedHeight(EntityCollidable collidable, float maxLength, float boundingBoxHeight, ref System.Numerics.Vector3 rayOrigin, ref System.Numerics.Vector3 xSpacing, ref System.Numerics.Vector3 zSpacing, int i, int j, out System.Numerics.Vector3 volumeCenter)
        {
            Ray ray;
            Vector3Ex.Multiply(ref xSpacing, i, out ray.Position);
            Vector3Ex.Multiply(ref zSpacing, j, out ray.Direction);
            Vector3Ex.Add(ref ray.Position, ref ray.Direction, out ray.Position);
            Vector3Ex.Add(ref ray.Position, ref rayOrigin, out ray.Position);

            ray.Direction = upVector;
            //do a bottom-up raycast.
            RayHit rayHit;
            //Only go up to maxLength.  If it's further away than maxLength, then it's above the water and it doesn't contribute anything.
            if (collidable.RayCast(ray, maxLength, out rayHit))
            {
                //Position the ray to point from the other side.
                Vector3Ex.Multiply(ref ray.Direction, boundingBoxHeight, out ray.Direction);
                Vector3Ex.Add(ref ray.Position, ref ray.Direction, out ray.Position);
                Vector3Ex.Negate(ref upVector, out ray.Direction);

                //Transform the hit into local space.
                RigidTransform.TransformByInverse(ref rayHit.Location, ref surfaceTransform, out rayHit.Location);
                float bottomY = rayHit.Location.Y;
                float bottom = rayHit.T;
                System.Numerics.Vector3 bottomPosition = rayHit.Location;
                if (collidable.RayCast(ray, boundingBoxHeight - rayHit.T, out rayHit))
                {
                    //Transform the hit into local space.
                    RigidTransform.TransformByInverse(ref rayHit.Location, ref surfaceTransform, out rayHit.Location);
                    Vector3Ex.Add(ref rayHit.Location, ref bottomPosition, out volumeCenter);
                    Vector3Ex.Multiply(ref volumeCenter, .5f, out volumeCenter);
                    return Math.Min(-bottomY, boundingBoxHeight - rayHit.T - bottom);
                }
                //This inner raycast should always hit, but just in case it doesn't due to some numerical problem, give it a graceful way out.
                volumeCenter = System.Numerics.Vector3.Zero;
                return 0;
            }
            volumeCenter = System.Numerics.Vector3.Zero;
            return 0;
        }
Beispiel #24
0
        void GetBuoyancyInformation(EntityCollidable collidable, out float submergedVolume, out System.Numerics.Vector3 submergedCenter)
        {
            BoundingBox entityBoundingBox;

            RigidTransform localTransform;
            RigidTransform.MultiplyByInverse(ref collidable.worldTransform, ref surfaceTransform, out localTransform);
            collidable.Shape.GetBoundingBox(ref localTransform, out entityBoundingBox);
            if (entityBoundingBox.Min.Y > 0)
            {
                //Fish out of the water.  Don't need to do raycast tests on objects not at the boundary.
                submergedVolume = 0;
                submergedCenter = collidable.worldTransform.Position;
                return;
            }
            if (entityBoundingBox.Max.Y < 0)
            {
                submergedVolume = collidable.entity.CollisionInformation.Shape.Volume;
                submergedCenter = collidable.worldTransform.Position;
                return;
            }

            System.Numerics.Vector3 origin, xSpacing, zSpacing;
            float perColumnArea;
            GetSamplingOrigin(ref entityBoundingBox, out xSpacing, out zSpacing, out perColumnArea, out origin);

            float boundingBoxHeight = entityBoundingBox.Max.Y - entityBoundingBox.Min.Y;
            float maxLength = -entityBoundingBox.Min.Y;
            submergedCenter = new System.Numerics.Vector3();
            submergedVolume = 0;
            for (int i = 0; i < samplePointsPerDimension; i++)
            {
                for (int j = 0; j < samplePointsPerDimension; j++)
                {
                    System.Numerics.Vector3 columnVolumeCenter;
                    float submergedHeight;
                    if ((submergedHeight = GetSubmergedHeight(collidable, maxLength, boundingBoxHeight, ref origin, ref xSpacing, ref zSpacing, i, j, out columnVolumeCenter)) > 0)
                    {
                        float columnVolume = submergedHeight * perColumnArea;
                        Vector3Ex.Multiply(ref columnVolumeCenter, columnVolume, out columnVolumeCenter);
                        Vector3Ex.Add(ref columnVolumeCenter, ref submergedCenter, out submergedCenter);
                        submergedVolume += columnVolume;
                    }
                }
            }
            Vector3Ex.Divide(ref submergedCenter, submergedVolume, out submergedCenter);
            //Pull the submerged center into world space before applying the force.
            RigidTransform.Transform(ref submergedCenter, ref surfaceTransform, out submergedCenter);
        }
 ///<summary>
 /// Constructs a new kinematic entity.
 ///</summary>
 ///<param name="collisionInformation">Collidable to use with the entity.</param>
 public Entity(EntityCollidable collisionInformation)
     : this()
 {
     Initialize(collisionInformation);
 }
Beispiel #26
0
        protected internal void Initialize(EntityCollidable collisionInformation, float mass)
        {
            CollisionInformation = collisionInformation;

            if (mass > 0)
            {
                ShapeDistributionInformation shapeInfo;
                collisionInformation.Shape.ComputeDistributionInformation(out shapeInfo);
                Matrix3x3.Multiply(ref shapeInfo.VolumeDistribution, mass * InertiaHelper.InertiaTensorScale, out shapeInfo.VolumeDistribution);

                volume = shapeInfo.Volume;

                BecomeDynamic(mass, shapeInfo.VolumeDistribution);
            }
            else
            {
                volume = collisionInformation.Shape.ComputeVolume();
                BecomeKinematic();
            }

            collisionInformation.Entity = this;
        }
        protected internal void Initialize(EntityCollidable collisionInformation, float mass, Matrix3x3 inertiaTensor)
        {
            CollisionInformation = collisionInformation;

            if (mass > 0)
                BecomeDynamic(mass, inertiaTensor);
            else
                BecomeKinematic();

            collisionInformation.Entity = this;
        }
        protected internal void Initialize(EntityCollidable collisionInformation, float mass)
        {
            CollisionInformation = collisionInformation;

            if (mass > 0)
            {
                BecomeDynamic(mass, collisionInformation.Shape.VolumeDistribution * (mass * InertiaHelper.InertiaTensorScale));
            }
            else
            {
                BecomeKinematic();
            }

            collisionInformation.Entity = this;
        }
 //These initialize methods make it easier to construct some Entity prefab types.
 protected internal void Initialize(EntityCollidable collisionInformation)
 {
     CollisionInformation = collisionInformation;
     BecomeKinematic();
     collisionInformation.Entity = this;
 }
 ///<summary>
 /// Constructs a new entity.
 ///</summary>
 ///<param name="collisionInformation">Collidable to use with the entity.</param>
 ///<param name="mass">Mass of the entity. If positive, the entity will be dynamic. Otherwise, it will be kinematic.</param>
 /// <param name="inertiaTensor">Inertia tensor of the entity. Only used for a dynamic entity.</param>
 public Entity(EntityCollidable collisionInformation, float mass, Matrix3x3 inertiaTensor)
     : this()
 {
     Initialize(collisionInformation, mass, inertiaTensor);
 }
 ///<summary>
 /// Constructs a new entity.
 ///</summary>
 ///<param name="collisionInformation">Collidable to use with the entity.</param>
 ///<param name="mass">Mass of the entity. If positive, the entity will be dynamic. Otherwise, it will be kinematic.</param>
 public Entity(EntityCollidable collisionInformation, float mass)
     : this()
 {
     Initialize(collisionInformation, mass);
 }
Beispiel #32
0
        protected internal void Initialize(EntityCollidable collisionInformation, float mass, Matrix3x3 inertiaTensor, float volume)
        {
            CollisionInformation = collisionInformation;
            this.volume = volume;
            BecomeDynamic(mass, inertiaTensor);

            collisionInformation.Entity = this;
        }
 void RemoveFriction(EntityCollidable sender, BroadPhaseEntry other, NarrowPhasePair pair)
 {
     var collidablePair = pair as CollidablePairHandler;
     if (collidablePair != null)
     {
         //The default values for InteractionProperties is all zeroes- zero friction, zero bounciness.
         //That's exactly how we want the character to behave when hitting objects.
         collidablePair.UpdateMaterialProperties(new InteractionProperties());
     }
 }
Beispiel #34
0
		void GetBuoyancyInformation(EntityCollidable info, out float submergedVolume, out Vector3 submergedCenter)
		{
			BoundingBox entityBoundingBox;
			entityBoundingBox = info.BoundingBox;// new BoundingBox();
			//info.ComputeBoundingBox(ref surfaceOrientationTranspose, out entityBoundingBox);
			if (entityBoundingBox.Min.Y > surfacePlaneHeight)
			{
				//Fish out of the water.  Don't need to do raycast tests on objects not at the boundary.
				submergedVolume = 0;
				submergedCenter = info.WorldTransform.Position;
				return;
			}
			if (entityBoundingBox.Max.Y < surfacePlaneHeight)
			{
				submergedVolume = info.Entity.Volume;
				submergedCenter = info.WorldTransform.Position;
				return;
			}

			Vector3 origin, xSpacing, zSpacing;
			float perColumnArea;
			GetSamplingOrigin(ref entityBoundingBox, out xSpacing, out zSpacing, out perColumnArea, out origin);

			float boundingBoxHeight = entityBoundingBox.Max.Y - entityBoundingBox.Min.Y;
			float maxLength = surfacePlaneHeight - entityBoundingBox.Min.Y;
			submergedCenter = new Vector3();
			submergedVolume = 0;
			for (int i = 0; i < samplePointsPerDimension; i++)
			{
				for (int j = 0; j < samplePointsPerDimension; j++)
				{
					Vector3 columnVolumeCenter;
					float submergedHeight;
					if ((submergedHeight = GetSubmergedHeight(info, maxLength, boundingBoxHeight, ref origin, ref xSpacing, ref zSpacing, i, j, out columnVolumeCenter)) > 0)
					{
						float columnVolume = submergedHeight * perColumnArea;
						Vector3.Multiply(ref columnVolumeCenter, columnVolume, out columnVolumeCenter);
						Vector3.Add(ref columnVolumeCenter, ref submergedCenter, out submergedCenter);
						submergedVolume += columnVolume;
					}
				}
			}
			Vector3.Divide(ref submergedCenter, submergedVolume, out submergedCenter);

		}