예제 #1
0
        /// <summary>
        /// Handles contact
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="other"></param>
        /// <param name="pair"></param>
        /// <param name="contact"></param>
        private void handleContactCreated(EntityCollidable sender, Collidable other, CollidablePairHandler pair, ContactData contact)
        {
            var compoundBody = sender as CompoundCollidable;
            var ballEntity   = other as EntityCollidable;


            // Find exact block being hit by ball
            float         minDistance  = 0;
            CompoundChild closestChild = null;

            foreach (CompoundChild child in compoundBody.Children)
            {
                if (child.CollisionInformation.CollisionRules.Group != gameLevel.RemovedBlocksGroup)
                {
                    Vector3 p = Vector3.Transform(child.Entry.LocalTransform.Position, compoundBody.WorldTransform.Matrix);

                    float distance = 0.0f;
                    Vector3.DistanceSquared(ref contact.Position, ref p, out distance);

                    if (closestChild != null)
                    {
                        if (minDistance > distance)
                        {
                            closestChild = child;
                            minDistance  = distance;
                        }
                    }
                    else
                    {
                        closestChild = child;
                        minDistance  = distance;
                    }
                }
            }

            // Obtain block instance
            Block hittedBlock = null;

            foreach (Block block in gameLevel.Blocks)
            {
                if (block.Entity == closestChild)
                {
                    hittedBlock = block;
                    break;
                }
            }

            // Obtain ball instance
            Ball hittingBall = null;

            foreach (Platform platform in platforms)
            {
                foreach (Ball ball in platform.Balls)
                {
                    if (ball.Active == true && ball.Entity.CollisionInformation == ballEntity)
                    {
                        hittingBall = ball;
                        break;
                    }
                }
            }

            // We have obtained block and ball which are collided, now we can run game logic
            if (hittedBlock != null && hittingBall != null)
            {
                // Get hit points from the ball
                int ballHitPoints = hittingBall.HitPoints;

                int gainedHitPoints = Math.Min(hittedBlock.HitPoints, hittingBall.HitPoints);
                gainedHitPoints *= hittedBlock.BlockType.ScoresPerHitPoint;

                hittedBlock.HitPoints -= hittingBall.HitPoints;

                // Run block logic
                BlockType blockType = hittedBlock.BlockType;

                gameLevel.AnimateHit(hittedBlock, contact.Position, hittingBall.Platform);

                foreach (BlockEvent blockAction in blockType.Events)
                {
                    blockAction.HandleEvent(hittedBlock);
                }

                if (hittedBlock.HitPoints <= 0)
                {
                    blockType.Owner.RemoveBlock(hittedBlock);
                }
            }
        }
 ///<summary>
 /// Constructs a new enumerator.
 ///</summary>
 ///<param name="collection">Owning collection.</param>
 public Enumerator(EntityCollidableCollection collection)
 {
     this.collection = collection;
     index           = -1;
     current         = null;
 }
예제 #3
0
 /// <summary>
 /// Raises the appropriate ParentObject collision events depending on its CollisionType value
 /// </summary>
 /// <param name="sender">The current ISpaceObject instance</param>
 /// <param name="other">The ISpaceObject instance which collided</param>
 /// <param name="pair"/>
 private void OnEntityCollisionDetected(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
 {
     OnCollisionDetected(sender, other, pair);
 }
예제 #4
0
 void Events_ContactCreated(EntityCollidable sender, Collidable other, BEPUphysics.NarrowPhaseSystems.Pairs.CollidablePairHandler pair, ContactData contact)
 {
     this.Collided.Execute(other, pair.Contacts);
 }
예제 #5
0
 private void Events_DetectingInitialCollision(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
 {
     _sound.Impact(sender.Entity);
 }
예제 #6
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));
            }
        }
예제 #7
0
 ///<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);
 }
예제 #8
0
        public static void GetShapeMeshData(EntityCollidable collidable, List <VertexPositionNormalTexture> vertices, List <ushort> indices)
        {
            var sphereShape = collidable.Shape as SphereShape;

            if (sphereShape == null)
            {
                throw new ArgumentException("Wrong shape type");
            }

            var   n = new Vector3();
            float angleBetweenFacets = MathHelper.TwoPi / NumSides;
            float radius             = (float)sphereShape.Radius;

            //Create the vertex list
            vertices.Add(new VertexPositionNormalTexture(new Vector3(0, radius, 0), Vector3.Up, Vector2.Zero));
            for (int i = 1; i < NumSides / 2; i++)
            {
                float phi    = MathHelper.PiOver2 - i * angleBetweenFacets;
                var   sinPhi = (float)Math.Sin(phi);
                var   cosPhi = (float)Math.Cos(phi);

                for (int j = 0; j < NumSides; j++)
                {
                    float theta = j * angleBetweenFacets;

                    n.X = (float)Math.Cos(theta) * cosPhi;
                    n.Y = sinPhi;
                    n.Z = (float)Math.Sin(theta) * cosPhi;

                    vertices.Add(new VertexPositionNormalTexture(n * radius, n, Vector2.Zero));
                }
            }
            vertices.Add(new VertexPositionNormalTexture(new Vector3(0, -radius, 0), Vector3.Down, Vector2.Zero));


            //Create the index list
            for (int i = 0; i < NumSides; i++)
            {
                indices.Add((ushort)(vertices.Count - 1));
                indices.Add((ushort)(vertices.Count - 2 - i));
                indices.Add((ushort)(vertices.Count - 2 - (i + 1) % NumSides));
            }

            for (int i = 0; i < NumSides / 2 - 2; i++)
            {
                for (int j = 0; j < NumSides; j++)
                {
                    int nextColumn = (j + 1) % NumSides;

                    indices.Add((ushort)(i * NumSides + nextColumn + 1));
                    indices.Add((ushort)(i * NumSides + j + 1));
                    indices.Add((ushort)((i + 1) * NumSides + j + 1));

                    indices.Add((ushort)((i + 1) * NumSides + nextColumn + 1));
                    indices.Add((ushort)(i * NumSides + nextColumn + 1));
                    indices.Add((ushort)((i + 1) * NumSides + j + 1));
                }
            }

            for (int i = 0; i < NumSides; i++)
            {
                indices.Add(0);
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)((i + 1) % NumSides + 1));
            }
        }
예제 #9
0
 ///<summary>
 /// Constructs a new morphable entity.
 ///</summary>
 ///<param name="collisionInformation">Collidable to use with the entity.</param>
 ///<param name="mass">Mass of the entity.</param>
 /// <param name="inertiaTensor">Inertia tensor of the entity.</param>
 public MorphableEntity(EntityCollidable collisionInformation, Fix64 mass, Matrix3x3 inertiaTensor)
     : base(collisionInformation, mass, inertiaTensor)
 {
 }
예제 #10
0
 ///<summary>
 /// Constructs a new kinematic entity.
 ///</summary>
 ///<param name="collisionInformation">Collidable to use with the entity.</param>
 public Entity(EntityCollidable collisionInformation)
     : this()
 {
     Initialize(collisionInformation);
 }
예제 #11
0
 ///<summary>
 /// Constructs a new morphable entity.
 ///</summary>
 ///<param name="collisionInformation">Collidable to use with the entity.</param>
 ///<param name="mass">Mass of the entity.</param>
 public MorphableEntity(EntityCollidable collisionInformation, Fix64 mass)
     : base(collisionInformation, mass)
 {
 }
예제 #12
0
 ///<summary>
 /// Constructs a new morphable entity.
 ///</summary>
 ///<param name="collisionInformation">Collidable to use with the entity.</param>
 public MorphableEntity(EntityCollidable collisionInformation)
     : base(collisionInformation)
 {
 }
예제 #13
0
        public static void GetShapeMeshData(EntityCollidable collidable, List <VertexPositionNormalTexture> vertices, List <ushort> indices)
        {
            var cylinderShape = collidable.Shape as CylinderShape;

            if (cylinderShape == null)
            {
                throw new ArgumentException("Wrong shape type.");
            }

            float verticalOffset     = cylinderShape.Height / 2;
            float angleBetweenFacets = MathHelper.TwoPi / NumSides;
            float radius             = cylinderShape.Radius;

            //Create the vertex list
            for (int i = 0; i < NumSides; i++)
            {
                float theta = i * angleBetweenFacets;
                float x     = (float)Math.Cos(theta) * radius;
                float z     = (float)Math.Sin(theta) * radius;
                //Top cap
                vertices.Add(new VertexPositionNormalTexture(new Vector3(x, verticalOffset, z), Vector3.Up, Vector2.Zero));
                //Top part of body
                vertices.Add(new VertexPositionNormalTexture(new Vector3(x, verticalOffset, z), new Vector3(x, 0, z), Vector2.Zero));
                //Bottom part of body
                vertices.Add(new VertexPositionNormalTexture(new Vector3(x, -verticalOffset, z), new Vector3(x, 0, z), Vector2.Zero));
                //Bottom cap
                vertices.Add(new VertexPositionNormalTexture(new Vector3(x, -verticalOffset, z), Vector3.Down, Vector2.Zero));
            }


            //Create the index list
            //The vertices are arranged a little nonintuitively.
            //0 is part of the top cap, 1 is the upper body, 2 is lower body, and 3 is bottom cap.
            for (ushort i = 0; i < vertices.Count; i += 4)
            {
                //Each iteration, the loop advances to the next vertex 'column.'
                //Four triangles per column (except for the four degenerate cap triangles).

                //Top cap triangles
                var nextIndex = (ushort)((i + 4) % vertices.Count);
                if (nextIndex != 0) //Don't add cap indices if it's going to be a degenerate triangle.
                {
                    indices.Add(i);
                    indices.Add(nextIndex);
                    indices.Add(0);
                }

                //Body triangles
                nextIndex = (ushort)((i + 5) % vertices.Count);
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)(i + 2));
                indices.Add(nextIndex);

                indices.Add(nextIndex);
                indices.Add((ushort)(i + 2));
                indices.Add((ushort)((i + 6) % vertices.Count));

                //Bottom cap triangles.
                nextIndex = (ushort)((i + 7) % vertices.Count);
                if (nextIndex != 3) //Don't add cap indices if it's going to be a degenerate triangle.
                {
                    indices.Add((ushort)(i + 3));
                    indices.Add(3);
                    indices.Add(nextIndex);
                }
            }
        }
 ///<summary>
 /// Constructs a new EntityCollidableCollection.
 ///</summary>
 ///<param name="owner">Owner of the collection.</param>
 public EntityCollidableCollection(EntityCollidable owner)
 {
     this.owner = owner;
 }
예제 #15
0
 ///<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);
 }
예제 #16
0
        public bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweepnorm, double slen, MaterialSolidity solidness, out RayHit hit)
        {
            RigidTransform rot = new RigidTransform(Vector3.Zero, startingTransform.Orientation);

            castShape.GetBoundingBox(ref rot, out BoundingBox bb);
            double  adv    = 0.1f;
            double  max    = slen + adv;
            bool    gotOne = false;
            RayHit  BestRH = default(RayHit);
            Vector3 sweep  = sweepnorm * slen;

            for (double f = 0; f < max; f += adv)
            {
                Vector3 c  = startingTransform.Position + sweepnorm * f;
                int     mx = (int)Math.Ceiling(c.X + bb.Max.X);
                for (int x = (int)Math.Floor(c.X + bb.Min.X); x <= mx; x++)
                {
                    if (x < 0 || x >= ChunkSize.X)
                    {
                        continue;
                    }
                    int my = (int)Math.Ceiling(c.Y + bb.Max.Y);
                    for (int y = (int)Math.Floor(c.Y + bb.Min.Y); y <= my; y++)
                    {
                        if (y < 0 || y >= ChunkSize.Y)
                        {
                            continue;
                        }
                        int mz = (int)Math.Ceiling(c.Z + bb.Max.Z);
                        for (int z = (int)Math.Floor(c.Z + bb.Min.Z); z <= mz; z++)
                        {
                            if (z < 0 || z >= ChunkSize.Z)
                            {
                                continue;
                            }
                            BlockInternal bi = Blocks[BlockIndex(x, y, z)];
                            if (solidness.HasFlag(((Material)bi.BlockMaterial).GetSolidity()))
                            {
                                EntityShape es = BlockShapeRegistry.BSD[bi.BlockData].GetShape(bi.Damage, out Location offs, false);
                                if (es == null)
                                {
                                    continue;
                                }
                                Vector3          adj  = new Vector3(x + (double)offs.X, y + (double)offs.Y, z + (double)offs.Z);
                                EntityCollidable coll = es.GetCollidableInstance();
                                //coll.LocalPosition = adj;
                                RigidTransform rt = new RigidTransform(Vector3.Zero, BEPUutilities.Quaternion.Identity);
                                coll.LocalPosition  = Vector3.Zero;
                                coll.WorldTransform = rt;
                                coll.UpdateBoundingBoxForTransform(ref rt);
                                RigidTransform adjusted = new RigidTransform(startingTransform.Position - adj, startingTransform.Orientation);
                                bool           b        = coll.ConvexCast(castShape, ref adjusted, ref sweep, out RayHit rhit);
                                if (b && (!gotOne || rhit.T * slen < BestRH.T) && rhit.T >= 0)
                                {
                                    gotOne           = true;
                                    BestRH           = rhit;
                                    BestRH.Location += adj;
                                    BestRH.T        *= slen;           // TODO: ???
                                    BestRH.Normal    = -BestRH.Normal; // TODO: WHY?!
                                }
                            }
                        }
                    }
                }
                if (gotOne)
                {
                    hit = BestRH;
                    return(true);
                }
            }
            hit = new RayHit()
            {
                Location = startingTransform.Position + sweep, Normal = new Vector3(0, 0, 0), T = slen
            };
            return(false);
        }
예제 #17
0
 //These initialize methods make it easier to construct some Entity prefab types.
 protected internal void Initialize(EntityCollidable collisionInformation)
 {
     CollisionInformation = collisionInformation;
     BecomeKinematic();
     collisionInformation.Entity = this;
 }
예제 #18
0
        public static void GetShapeMeshData(EntityCollidable collidable, List <VertexPositionNormalTexture> vertices, List <ushort> indices)
        {
            var boxShape = collidable.Shape as BoxShape;

            if (boxShape == null)
            {
                throw new ArgumentException("Wrong shape type.");
            }

            var boundingBox = new BoundingBox(
                new Vector3(-boxShape.HalfWidth,
                            -boxShape.HalfHeight,
                            -boxShape.HalfLength),
                new Vector3(boxShape.HalfWidth,
                            boxShape.HalfHeight,
                            boxShape.HalfLength));


            Vector3[] corners = boundingBox.GetCorners();

            var textureCoords = new Vector2[4];

            textureCoords[0] = new Vector2(0, 0);
            textureCoords[1] = new Vector2(1, 0);
            textureCoords[2] = new Vector2(1, 1);
            textureCoords[3] = new Vector2(0, 1);

            vertices.Add(new VertexPositionNormalTexture(corners[0], Vector3.Backward, textureCoords[0]));
            vertices.Add(new VertexPositionNormalTexture(corners[1], Vector3.Backward, textureCoords[1]));
            vertices.Add(new VertexPositionNormalTexture(corners[2], Vector3.Backward, textureCoords[2]));
            vertices.Add(new VertexPositionNormalTexture(corners[3], Vector3.Backward, textureCoords[3]));
            indices.Add(0);
            indices.Add(1);
            indices.Add(2);
            indices.Add(0);
            indices.Add(2);
            indices.Add(3);

            vertices.Add(new VertexPositionNormalTexture(corners[1], Vector3.Right, textureCoords[0]));
            vertices.Add(new VertexPositionNormalTexture(corners[2], Vector3.Right, textureCoords[3]));
            vertices.Add(new VertexPositionNormalTexture(corners[5], Vector3.Right, textureCoords[1]));
            vertices.Add(new VertexPositionNormalTexture(corners[6], Vector3.Right, textureCoords[2]));
            indices.Add(4);
            indices.Add(6);
            indices.Add(7);
            indices.Add(4);
            indices.Add(7);
            indices.Add(5);

            vertices.Add(new VertexPositionNormalTexture(corners[4], Vector3.Forward, textureCoords[1]));
            vertices.Add(new VertexPositionNormalTexture(corners[5], Vector3.Forward, textureCoords[0]));
            vertices.Add(new VertexPositionNormalTexture(corners[6], Vector3.Forward, textureCoords[3]));
            vertices.Add(new VertexPositionNormalTexture(corners[7], Vector3.Forward, textureCoords[2]));
            indices.Add(9);
            indices.Add(8);
            indices.Add(11);
            indices.Add(9);
            indices.Add(11);
            indices.Add(10);

            vertices.Add(new VertexPositionNormalTexture(corners[0], Vector3.Left, textureCoords[1]));
            vertices.Add(new VertexPositionNormalTexture(corners[3], Vector3.Left, textureCoords[2]));
            vertices.Add(new VertexPositionNormalTexture(corners[4], Vector3.Left, textureCoords[0]));
            vertices.Add(new VertexPositionNormalTexture(corners[7], Vector3.Left, textureCoords[3]));
            indices.Add(14);
            indices.Add(12);
            indices.Add(13);
            indices.Add(14);
            indices.Add(13);
            indices.Add(15);

            vertices.Add(new VertexPositionNormalTexture(corners[0], Vector3.Up, textureCoords[2]));
            vertices.Add(new VertexPositionNormalTexture(corners[1], Vector3.Up, textureCoords[3]));
            vertices.Add(new VertexPositionNormalTexture(corners[4], Vector3.Up, textureCoords[1]));
            vertices.Add(new VertexPositionNormalTexture(corners[5], Vector3.Up, textureCoords[0]));
            indices.Add(16);
            indices.Add(19);
            indices.Add(17);
            indices.Add(16);
            indices.Add(18);
            indices.Add(19);

            vertices.Add(new VertexPositionNormalTexture(corners[2], Vector3.Down, textureCoords[1]));
            vertices.Add(new VertexPositionNormalTexture(corners[3], Vector3.Down, textureCoords[0]));
            vertices.Add(new VertexPositionNormalTexture(corners[6], Vector3.Down, textureCoords[2]));
            vertices.Add(new VertexPositionNormalTexture(corners[7], Vector3.Down, textureCoords[3]));
            indices.Add(21);
            indices.Add(20);
            indices.Add(22);
            indices.Add(21);
            indices.Add(22);
            indices.Add(23);
        }
예제 #19
0
 private void Events_CollisionEnded(EntityCollidable sender, Collidable other, CollidablePairHandler pair)
 {
     _sound.RollStop();
 }