Ejemplo n.º 1
0
 public bool HassSolidEntity(Location min, Location max)
 {
     // TODO: Better alg!
     BoundingBox bb = new BoundingBox(min.ToBVector(), max.ToBVector());
     List<BroadPhaseEntry> entries = new List<BroadPhaseEntry>();
     PhysicsWorld.BroadPhase.QueryAccelerator.GetEntries(bb, entries);
     if (entries.Count == 0)
     {
         return false;
     }
     Location center = (max + min) * 0.5;
     Location rel = max - min;
     BoxShape box = new BoxShape((double)rel.X, (double)rel.Y, (double)rel.Z);
     RigidTransform start = new RigidTransform(center.ToBVector(), Quaternion.Identity);
     Vector3 sweep = new Vector3(0, 0, 0.01f);
     RayHit rh;
     foreach (BroadPhaseEntry entry in entries)
     {
         if (entry is EntityCollidable && Collision.ShouldCollide(entry) &&
             entry.CollisionRules.Group != CollisionUtil.Player &&
             entry.ConvexCast(box, ref start, ref sweep, out rh))
         {
             return true;
         }
     }
     return false;
 }
Ejemplo n.º 2
0
		public void GetOverlaps( Vector3 gridPosition, BoundingBox boundingBox, ref QuickList<Int3> overlaps )
		{
			Vector3.Subtract( ref boundingBox.Min, ref gridPosition, out boundingBox.Min );
			Vector3.Subtract( ref boundingBox.Max, ref gridPosition, out boundingBox.Max );
			var inverseWidth = 1f / CellWidth;
			var min = new Int3
			{
				X = Math.Max( 0, (uint)( boundingBox.Min.X * inverseWidth ) ),
				Y = Math.Max( 0, (uint)( boundingBox.Min.Y * inverseWidth ) ),
				Z = Math.Max( 0, (uint)( boundingBox.Min.Z * inverseWidth ) )
			};
			var max = new Int3
			{
				X = Math.Min( VoxelSector.ZVOXELBLOCSIZE_X - 1, (uint)( boundingBox.Max.X * inverseWidth ) ),
				Y = Math.Min( VoxelSector.ZVOXELBLOCSIZE_Y - 1, (uint)( boundingBox.Max.Y * inverseWidth ) ),
				Z = Math.Min( VoxelSector.ZVOXELBLOCSIZE_Z - 1, (uint)( boundingBox.Max.Z * inverseWidth ) )
			};

			for( uint i = min.X; i <= max.X; ++i )
			{
				for( uint j = min.Y; j <= max.Y; ++j )
				{
					for( uint k = min.Z; k <= max.Z; ++k )
					{
						uint offset = i * VoxelSector.ZVOXELBLOCSIZE_Y + j + k * VoxelSector.ZVOXELBLOCSIZE_X * VoxelSector.ZVOXELBLOCSIZE_Y;
						if( Cells[offset] != VoxelShape.Empty )
						{
							overlaps.Add( new Int3 { X = i, Y = j, Z = k } );
						}
					}
				}
			}
		}
Ejemplo n.º 3
0
		public void GetBoundingBox( ref Vector3 position, out BoundingBox boundingBox )
		{
			var size = new Vector3( CellWidth * VoxelSector.ZVOXELBLOCSIZE_X
								, CellWidth * VoxelSector.ZVOXELBLOCSIZE_Y
								, CellWidth * VoxelSector.ZVOXELBLOCSIZE_Z );
			boundingBox.Min = position;
			Vector3.Add( ref size, ref position, out boundingBox.Max );
		}
 /// <summary>
 /// Gets the bounding box of an element in the data.
 /// </summary>
 /// <param name="triangleIndex">Index of the triangle in the data.</param>
 /// <param name="boundingBox">Bounding box of the triangle.</param>
 public void GetBoundingBox(int triangleIndex, out BoundingBox boundingBox)
 {
     Vector3 v1, v2, v3;
     GetTriangle(triangleIndex, out v1, out v2, out v3);
     Vector3.Min(ref v1, ref v2, out boundingBox.Min);
     Vector3.Min(ref boundingBox.Min, ref v3, out boundingBox.Min);
     Vector3.Max(ref v1, ref v2, out boundingBox.Max);
     Vector3.Max(ref boundingBox.Max, ref v3, out boundingBox.Max);
 }
Ejemplo n.º 5
0
 public MobileChunkCollidable(MobileChunkShape shape)
 {
     ChunkShape = shape;
     base.Shape = ChunkShape;
     Vector3 max = new Vector3(shape.ChunkSize.X, shape.ChunkSize.Y, shape.ChunkSize.Z);
     boundingBox = new BoundingBox(-max, max);
     Events = new ContactEventManager<EntityCollidable>();
     LocalPosition = -shape.Center;
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Determines if a bounding box intersects another bounding box.
        /// </summary>
        /// <param name="boundingBox">Bounding box to test against.</param>
        /// <returns>Whether the bounding boxes intersected.</returns>
        public bool Intersects(BoundingBox boundingBox)
        {
            if (boundingBox.Min.X > Max.X || boundingBox.Min.Y > Max.Y || boundingBox.Min.Z > Max.Z)
                return false;
            if (Min.X > boundingBox.Max.X || Min.Y > boundingBox.Max.Y || Min.Z > boundingBox.Max.Z)
                return false;
            return true;

        }
Ejemplo n.º 7
0
 public FullChunkObject(Vector3 pos, BlockInternal[] blocks)
 {
     ChunkShape = new FullChunkShape(blocks);
     base.Shape = ChunkShape;
     Position = pos;
     boundingBox = new BoundingBox(Position, Position + new Vector3(30, 30, 30));
     Events = new ContactEventManager<FullChunkObject>(this);
     Material.Bounciness = 0.75f;
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Creates a bounding box from a bounding sphere.
        /// </summary>
        /// <param name="boundingSphere">Bounding sphere to be used to create the bounding box.</param>
        /// <param name="boundingBox">Bounding box created from the bounding sphere.</param>
        public static void CreateFromSphere(ref BoundingSphere boundingSphere, out BoundingBox boundingBox)
        {
            boundingBox.Min.X = boundingSphere.Center.X - boundingSphere.Radius;
            boundingBox.Min.Y = boundingSphere.Center.Y - boundingSphere.Radius;
            boundingBox.Min.Z = boundingSphere.Center.Z - boundingSphere.Radius;

            boundingBox.Max.X = boundingSphere.Center.X + boundingSphere.Radius;
            boundingBox.Max.Y = boundingSphere.Center.Y + boundingSphere.Radius;
            boundingBox.Max.Z = boundingSphere.Center.Z + boundingSphere.Radius;
        }
 /// <summary>
 /// Gets the triangles whose bounding boxes are overlapped by the query.
 /// </summary>
 /// <param name="boundingBox">Shape to query against the tree.</param>
 /// <param name="outputOverlappedElements">Indices of triangles in the index buffer with bounding boxes which are overlapped by the query.</param>
 /// <returns>Whether or not any elements were overlapped.</returns>
 public bool GetOverlaps(BoundingBox boundingBox, IList<int> outputOverlappedElements)
 {
     if (root != null)
     {
         bool intersects;
         root.BoundingBox.Intersects(ref boundingBox, out intersects);
         if (intersects)
             root.GetOverlaps(ref boundingBox, outputOverlappedElements);
     }
     return outputOverlappedElements.Count > 0;
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Gets the bounding box of the shape given a transform.
 /// </summary>
 /// <param name="shapeTransform">Transform to use.</param>
 /// <param name="boundingBox">Bounding box of the transformed shape.</param>
 public override void GetBoundingBox(ref RigidTransform shapeTransform, out BoundingBox boundingBox)
 {
     #if !WINDOWS
     boundingBox = new BoundingBox();
     #endif
     boundingBox.Min.X = shapeTransform.Position.X - collisionMargin;
     boundingBox.Min.Y = shapeTransform.Position.Y - collisionMargin;
     boundingBox.Min.Z = shapeTransform.Position.Z - collisionMargin;
     boundingBox.Max.X = shapeTransform.Position.X + collisionMargin;
     boundingBox.Max.Y = shapeTransform.Position.Y + collisionMargin;
     boundingBox.Max.Z = shapeTransform.Position.Z + collisionMargin;
 }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public LotsOfBoxesTestDemo(DemosGame game)
            : base(game)
        {
            var ground = new Box(new Vector3(0, -.5f, 0), 200, 1, 200);
            Space.Add(ground);



            var spawnVolume = new BoundingBox
                {
                    Min = new Vector3(-25, 2, -25),
                    Max = new Vector3(25, 102, 25)
                };

            var span = spawnVolume.Max - spawnVolume.Min;

            NarrowPhaseHelper.Factories.BoxBox.EnsureCount(30000);

            var random = new Random(5);
            for (int i = 0; i < 5000; ++i)
            {
                Vector3 position;
                position.X = spawnVolume.Min.X + (float)random.NextDouble() * span.X;
                position.Y = spawnVolume.Min.Y + (float)random.NextDouble() * span.Y;
                position.Z = spawnVolume.Min.Z + (float)random.NextDouble() * span.Z;

                var entity = new Box(position, 2, 2, 2, 10);
                Space.Add(entity);
            }

            for (int i = 0; i < 100; ++i)
            {
                Space.Update();
            }

            Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
            
            var start = Stopwatch.GetTimestamp();
            for (int i = 0; i < 200; ++i)
            {
                Space.Update();
            }
            var end = Stopwatch.GetTimestamp();
            var time = (end - start) / (double)Stopwatch.Frequency;

            Console.WriteLine("Time: {0}", time);
 
            game.Camera.Position = new Vector3(-10, 10, 10);
            game.Camera.Yaw((float)Math.PI / -4f);
            game.Camera.Pitch((float)Math.PI / 9f);
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Determines if a bounding box intersects another bounding box.
 /// </summary>
 /// <param name="boundingBox">Bounding box to test against.</param>
 /// <param name="intersects">Whether the bounding boxes intersect.</param>
 public void Intersects(ref BoundingBox boundingBox, out bool intersects)
 {
     if (boundingBox.Min.X > Max.X || boundingBox.Min.Y > Max.Y || boundingBox.Min.Z > Max.Z)
     {
         intersects = false;
         return;
     }
     if (Min.X > boundingBox.Max.X || Min.Y > boundingBox.Max.Y || Min.Z > boundingBox.Max.Z)
     {
         intersects = false;
         return;
     }
     intersects = true;
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Method defining the loading of the model in our space
        /// </summary>
        /// <param name="space">the current space</param>
        /// <param name="game">the current game</param>
        public void Load(Space space, Game game)
        {
            //Using the ModelDataExtractor in order to extract the bounding of the model and activate the collisions
            ModelDataExtractor.GetVerticesAndIndicesFromModel(ModelLevel, out Vector3[] vertices, out int[] indices);
            var meshLevel = new StaticMesh(vertices, indices, new AffineTransform(new Vector3(0, -40, 0)));

            BoundingLevel = meshLevel.BoundingBox;
            space.Add(meshLevel);
            game.Components.Add(new StaticModel(ModelLevel, meshLevel.WorldTransform.Matrix, game));

            ModelDataExtractor.GetVerticesAndIndicesFromModel(ModelArrival, out vertices, out indices);
            var meshArrival = new StaticMesh(vertices, indices, new AffineTransform(new Vector3(0, -40, 0)));

            BoundingArrive = meshArrival.BoundingBox;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Gets the bounding box of the shape given a transform.
        /// </summary>
        /// <param name="shapeTransform">Transform to use.</param>
        /// <param name="boundingBox">Bounding box of the transformed shape.</param>
        public override void GetBoundingBox(ref RigidTransform shapeTransform, out BoundingBox boundingBox)
        {
            #if !WINDOWS
            boundingBox = new BoundingBox();
            #endif
            Matrix3x3 o;
            Matrix3x3.CreateFromQuaternion(ref shapeTransform.Orientation, out o);
            //Sample the local directions from the orientation matrix, implicitly transposed.

            Vector3 right;
            var direction = new Vector3(o.M11, o.M21, o.M31);
            GetLocalExtremePointWithoutMargin(ref direction, out right);

            Vector3 left;
            direction = new Vector3(-o.M11, -o.M21, -o.M31);
            GetLocalExtremePointWithoutMargin(ref direction, out left);

            Vector3 up;
            direction = new Vector3(o.M12, o.M22, o.M32);
            GetLocalExtremePointWithoutMargin(ref direction, out up);

            Vector3 down;
            direction = new Vector3(-o.M12, -o.M22, -o.M32);
            GetLocalExtremePointWithoutMargin(ref direction, out down);

            Vector3 backward;
            direction = new Vector3(o.M13, o.M23, o.M33);
            GetLocalExtremePointWithoutMargin(ref direction, out backward);

            Vector3 forward;
            direction = new Vector3(-o.M13, -o.M23, -o.M33);
            GetLocalExtremePointWithoutMargin(ref direction, out forward);

            //Rather than transforming each axis independently (and doing three times as many operations as required), just get the 6 required values directly.
            Vector3 positive, negative;
            TransformLocalExtremePoints(ref right, ref up, ref backward, ref o, out positive);
            TransformLocalExtremePoints(ref left, ref down, ref forward, ref o, out negative);

            //The positive and negative vectors represent the X, Y and Z coordinates of the extreme points in world space along the world space axes.
            boundingBox.Max.X = shapeTransform.Position.X + positive.X + collisionMargin;
            boundingBox.Max.Y = shapeTransform.Position.Y + positive.Y + collisionMargin;
            boundingBox.Max.Z = shapeTransform.Position.Z + positive.Z + collisionMargin;

            boundingBox.Min.X = shapeTransform.Position.X + negative.X - collisionMargin;
            boundingBox.Min.Y = shapeTransform.Position.Y + negative.Y - collisionMargin;
            boundingBox.Min.Z = shapeTransform.Position.Z + negative.Z - collisionMargin;
        }
Ejemplo n.º 15
0
		static void DrawBoundingBox( Display render, BoundingBox bb )
		{
			///Box box = e as Box;
			// = e.CollisionInformation.BoundingBox;
			//Vector3 corner = Matrix.TransformNormal( Vector3.One, e.WorldTransform );
			Vector3[] corners = new Vector3[8];
			//Vector3 half_size = new Vector3( box.HalfWidth, box.HalfHeight, box.HalfLength );
			corners[0] = bb.Min;
			corners[6] = bb.Max;
			corners[1] = corners[0];
			corners[1].X = corners[6].X;
			corners[2] = corners[0];
			corners[2].X = corners[6].X;
			corners[2].Y = corners[6].Y;
			corners[3] = corners[0];
			corners[3].Y = corners[6].Y;

			corners[4] = corners[0];
			corners[4].Z = corners[6].Z;

			corners[5] = corners[0];
			corners[5].X = corners[6].X;
			corners[5].Z = corners[6].Z;
			corners[7] = corners[0];
			corners[7].Y = corners[6].Y;
			corners[7].Z = corners[6].Z;
			Vector3 white = Vector3.One;
			white.Y = 0;
			white.Z = 0;
			drawLine( render, ref corners[0], ref corners[1], ref white, ref white );
			drawLine( render, ref corners[1], ref corners[2], ref white, ref white );
			drawLine( render, ref corners[2], ref corners[3], ref white, ref white );
			drawLine( render, ref corners[3], ref corners[0], ref white, ref white );
			drawLine( render, ref corners[0], ref corners[4], ref white, ref white );
			drawLine( render, ref corners[1], ref corners[5], ref white, ref white );
			drawLine( render, ref corners[2], ref corners[6], ref white, ref white );
			drawLine( render, ref corners[3], ref corners[7], ref white, ref white );
			drawLine( render, ref corners[4], ref corners[5], ref white, ref white );
			drawLine( render, ref corners[5], ref corners[6], ref white, ref white );
			drawLine( render, ref corners[6], ref corners[7], ref white, ref white );
			drawLine( render, ref corners[7], ref corners[4], ref white, ref white );
		}
Ejemplo n.º 16
0
        public static void Draw(this BEPUutilities.BoundingBox box)
        {
            if (RenderingDevice.HiDef)
            {
                effect.View       = MathConverter.Convert(Renderer.Camera.ViewMatrix);
                effect.Projection = MathConverter.Convert(Renderer.Camera.ProjectionMatrix);

                BEPUutilities.Vector3[] corners = box.GetCorners();
                for (int i = 0; i < 8; i++)
                {
                    verts[i].Position = corners[i];
                    verts[i].Color    = Color.Goldenrod;
                }

                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    Renderer.GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, verts, 0, 8, indices, 0, indices.Length / 2);
                }
            }
        }
Ejemplo n.º 17
0
        ///<summary>
        /// Computes the bounding box of the transformed mesh shape.
        ///</summary>
        ///<param name="transform">Transform to apply to the shape during the bounding box calculation.</param>
        ///<param name="boundingBox">Bounding box containing the transformed mesh shape.</param>
        public void ComputeBoundingBox(ref AffineTransform transform, out BoundingBox boundingBox)
        {
            #if !WINDOWS
            boundingBox = new BoundingBox();
            #endif
            float minX = float.MaxValue;
            float minY = float.MaxValue;
            float minZ = float.MaxValue;

            float maxX = -float.MaxValue;
            float maxY = -float.MaxValue;
            float maxZ = -float.MaxValue;
            for (int i = 0; i < triangleMesh.Data.vertices.Length; i++)
            {
                System.Numerics.Vector3 vertex;
                triangleMesh.Data.GetVertexPosition(i, out vertex);
                Matrix3x3.Transform(ref vertex, ref transform.LinearTransform, out vertex);
                if (vertex.X < minX)
                    minX = vertex.X;
                if (vertex.X > maxX)
                    maxX = vertex.X;

                if (vertex.Y < minY)
                    minY = vertex.Y;
                if (vertex.Y > maxY)
                    maxY = vertex.Y;

                if (vertex.Z < minZ)
                    minZ = vertex.Z;
                if (vertex.Z > maxZ)
                    maxZ = vertex.Z;
            }
            boundingBox.Min.X = transform.Translation.X + minX;
            boundingBox.Min.Y = transform.Translation.Y + minY;
            boundingBox.Min.Z = transform.Translation.Z + minZ;

            boundingBox.Max.X = transform.Translation.X + maxX;
            boundingBox.Max.Y = transform.Translation.Y + maxY;
            boundingBox.Max.Z = transform.Translation.Z + maxZ;
        }
        public void GetEntries(BoundingBox boundingShape, IList<BroadPhaseEntry> overlaps)
        {
            //Compute the min and max of the bounding box.
            //Loop through the cells and select bounding boxes which overlap the x axis.

            Int2 min, max;
            Grid2DSortAndSweep.ComputeCell(ref boundingShape.Min, out min);
            Grid2DSortAndSweep.ComputeCell(ref boundingShape.Max, out max);
            for (int i = min.Y; i <= max.Y; i++)
            {
                for (int j = min.Z; j <= max.Z; j++)
                {
                    //Grab the cell that we are currently in.
                    Int2 cellIndex;
                    cellIndex.Y = i;
                    cellIndex.Z = j;
                    GridCell2D cell;
                    if (owner.cellSet.TryGetCell(ref cellIndex, out cell))
                    {

                        //To fully accelerate this, the entries list would need to contain both min and max interval markers.
                        //Since it only contains the sorted min intervals, we can't just start at a point in the middle of the list.
                        //Consider some giant bounding box that spans the entire list.
                        for (int k = 0; k < cell.entries.Count
                            && cell.entries.Elements[k].item.boundingBox.Min.X <= boundingShape.Max.X; k++) //TODO: Try additional x axis pruning? A bit of optimization potential due to overlap with AABB test.
                        {
                            bool intersects;
                            var item = cell.entries.Elements[k].item;
                            boundingShape.Intersects(ref item.boundingBox, out intersects);
                            if (intersects && !overlaps.Contains(item))
                            {
                                overlaps.Add(item);
                            }
                        }
                    }
                }
            }
        }
        double RunTest(int splitOffset, IParallelLooper parallelLooper)
        {
            Entity toAdd;
            //BoundingBox box = new BoundingBox(new Vector3(-5, 1, 1), new Vector3(5, 7, 7));
            BoundingBox box = new BoundingBox(new Vector3(-500, -500, -500), new Vector3(500, 500, 500));

            int splitDepth = splitOffset + (int)Math.Ceiling(Math.Log(parallelLooper.ThreadCount, 2));

            DynamicHierarchy dh = new DynamicHierarchy(parallelLooper);

            Random rand = new Random(0);

            RawList<Entity> entities = new RawList<Entity>();
            for (int k = 0; k < 10000; k++)
            {
                Vector3 position = new Vector3((float)(rand.NextDouble() * (box.Max.X - box.Min.X) + box.Min.X),
                                               (float)(rand.NextDouble() * (box.Max.Y - box.Min.Y) + box.Min.Y),
                                               (float)(rand.NextDouble() * (box.Max.Z - box.Min.Z) + box.Min.Z));
                toAdd = new Box(position, 1, 1, 1, 1);
                toAdd.CollisionInformation.CollisionRules.Personal = CollisionRule.NoNarrowPhasePair;
                toAdd.CollisionInformation.UpdateBoundingBox(0);


                dh.Add(toAdd.CollisionInformation);
                entities.Add(toAdd);

            }


            Space.ForceUpdater.Gravity = new Vector3();

            int numRuns = 3000;
            //Prime the system.
            dh.Update();
            var testType = Test.Update;

            BroadPhaseOverlap[] overlapBasis = new BroadPhaseOverlap[dh.Overlaps.Count];
            dh.Overlaps.CopyTo(overlapBasis, 0);


            double time = 0;
            double startTime, endTime;


            switch (testType)
            {
                #region Update Timing
                case Test.Update:
                    for (int i = 0; i < numRuns; i++)
                    {
                        //DH4
                        startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                        //dh.Update();
                        //lock (dh.Locker)
                        //{
                        //    dh.Overlaps.Clear();
                        //    if (dh.ROOTEXISTS)
                        //    {
                        //        dh.MultithreadedRefitPhase(splitDepth);

                        //        dh.MultithreadedOverlapPhase(splitDepth);
                        //    }
                        //}

                        //dh.Update();

                        //lock (dh.Locker)
                        //{
                        //    dh.Overlaps.Clear();
                        //    if (dh.ROOTEXISTS)
                        //    {
                        //        dh.SingleThreadedRefitPhase();
                        //        dh.SingleThreadedOverlapPhase();
                        //    }
                        //}

                        endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                        time += endTime - startTime;

                        //if (dh.Overlaps.Count != overlapBasis.Length)
                        //    Debug.WriteLine("Failed Update.");
                        //for (int j = 0; j < overlapBasis.Length; j++)
                        //{
                        //    if (!dh.Overlaps.Contains(overlapBasis[j]))
                        //        Debug.WriteLine("Failed Update.");
                        //}


                        //MoveEntities(entities);
                    }
                    break;
                #endregion
                #region Refit Timing
                case Test.Refit:
                    for (int i = 0; i < numRuns; i++)
                    {

                        dh.Overlaps.Clear();

                        //DH4
                        startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                        //dh.MultithreadedRefitPhase(splitDepth);
                        //dh.SingleThreadedRefitPhase();
                        endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                        time += endTime - startTime;

                        //dh.SingleThreadedOverlapPhase();

                        //if (dh.Overlaps.Count != overlapBasis.Length)
                        //    Debug.WriteLine("Failed Refit.");
                        //for (int j = 0; j < overlapBasis.Length; j++)
                        //{
                        //    if (!dh.Overlaps.Contains(overlapBasis[j]))
                        //        Debug.WriteLine("Failed Refit.");
                        //}

                        //MoveEntities(entities);
                    }
                    break;
                #endregion
                #region Overlap Timing
                case Test.Overlap:
                    for (int i = 0; i < numRuns; i++)
                    {
                        dh.Overlaps.Clear();
                        //dh.MultithreadedRefitPhase(splitDepth);
                        //DH4
                        startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                        //dh.MultithreadedOverlapPhase(splitDepth);
                        //dh.SingleThreadedOverlapPhase();
                        endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                        time += endTime - startTime;


                        //if (dh.Overlaps.Count != overlapBasis.Length)
                        //    Debug.WriteLine("Failed Overlap.");
                        //for (int j = 0; j < overlapBasis.Length; j++)
                        //{
                        //    if (!dh.Overlaps.Contains(overlapBasis[j]))
                        //        Debug.WriteLine("Failed Overlap.");
                        //}

                        //MoveEntities(entities);
                    }
                    break;
                #endregion
                #region Ray cast timing
                case Test.RayCast:
                    float rayLength = 100;
                    RawList<Ray> rays = new RawList<Ray>();
                    for (int i = 0; i < numRuns; i++)
                    {
                        rays.Add(new Ray()
                        {
                            Position = new Vector3((float)(rand.NextDouble() * (box.Max.X - box.Min.X) + box.Min.X),
                                               (float)(rand.NextDouble() * (box.Max.Y - box.Min.Y) + box.Min.Y),
                                               (float)(rand.NextDouble() * (box.Max.Z - box.Min.Z) + box.Min.Z)),
                            Direction = Vector3.Normalize(new Vector3((float)(rand.NextDouble() - .5), (float)(rand.NextDouble() - .5), (float)(rand.NextDouble() - .5)))
                        });
                    }
                    RawList<BroadPhaseEntry> outputIntersections = new RawList<BroadPhaseEntry>();



                    //DH4
                    startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                    for (int i = 0; i < numRuns; i++)
                    {
                        dh.QueryAccelerator.RayCast(rays.Elements[i], rayLength, outputIntersections);
                        outputIntersections.Clear();
                    }

                    endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                    time = endTime - startTime;


                    break;
                #endregion
                #region Bounding box query timing
                case Test.BoundingBoxQuery:
                    float boundingBoxSize = 10;
                    var boundingBoxes = new RawList<BoundingBox>();
                    Vector3 offset = new Vector3(boundingBoxSize / 2, boundingBoxSize / 2, boundingBoxSize / 2);
                    for (int i = 0; i < numRuns; i++)
                    {
                        Vector3 center = new Vector3((float)(rand.NextDouble() * (box.Max.X - box.Min.X) + box.Min.X),
                                                     (float)(rand.NextDouble() * (box.Max.Y - box.Min.Y) + box.Min.Y),
                                                     (float)(rand.NextDouble() * (box.Max.Z - box.Min.Z) + box.Min.Z));
                        boundingBoxes.Add(new BoundingBox()
                        {
                            Min = center - offset,
                            Max = center + offset
                        });
                    }

                    outputIntersections = new RawList<BroadPhaseEntry>();


                    //DH4
                    startTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                    for (int i = 0; i < numRuns; i++)
                    {
                        dh.QueryAccelerator.GetEntries(boundingBoxes.Elements[i], outputIntersections);
                        outputIntersections.Clear();
                    }

                    endTime = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
                    time = endTime - startTime;


                    break;
                #endregion
            }


            return time / numRuns;
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Determines if and when the ray intersects the bounding box.
 /// </summary>
 /// <param name="boundingBox">Bounding box to test against.</param>
 /// <param name="result">The length along the ray to the impact, or null if no impact is found.</param>
 public void Intersects(ref BoundingBox boundingBox, out float? result)
 {
     if (System.Math.Abs(Direction.X) < Toolbox.Epsilon && (Position.X < boundingBox.Min.X || Position.X > boundingBox.Max.X))
     {
         //If the ray isn't pointing along the axis at all, and is outside of the box's interval, then it
         //can't be intersecting.
         result = null;
         return;
     }
     float tmin = 0, tmax = float.MaxValue;
     float inverseDirection = 1 / Direction.X;
     float t1 = (boundingBox.Min.X - Position.X) * inverseDirection;
     float t2 = (boundingBox.Max.X - Position.X) * inverseDirection;
     if (t1 > t2)
     {
         float temp = t1;
         t1 = t2;
         t2 = temp;
     }
     tmin = System.Math.Max(tmin, t1);
     tmax = System.Math.Min(tmax, t2);
     if (tmin > tmax)
     {
         result = null;
         return;
     }
     if (System.Math.Abs(Direction.Y) < Toolbox.Epsilon && (Position.Y < boundingBox.Min.Y || Position.Y > boundingBox.Max.Y))
     {
         //If the ray isn't pointing along the axis at all, and is outside of the box's interval, then it
         //can't be intersecting.
         result = null;
         return;
     }
     inverseDirection = 1 / Direction.Y;
     t1 = (boundingBox.Min.Y - Position.Y) * inverseDirection;
     t2 = (boundingBox.Max.Y - Position.Y) * inverseDirection;
     if (t1 > t2)
     {
         float temp = t1;
         t1 = t2;
         t2 = temp;
     }
     tmin = System.Math.Max(tmin, t1);
     tmax = System.Math.Min(tmax, t2);
     if (tmin > tmax)
     {
         result = null;
         return;
     }
     if (System.Math.Abs(Direction.Z) < Toolbox.Epsilon && (Position.Z < boundingBox.Min.Z || Position.Z > boundingBox.Max.Z))
     {
         //If the ray isn't pointing along the axis at all, and is outside of the box's interval, then it
         //can't be intersecting.
         result = null;
         return;
     }
     inverseDirection = 1 / Direction.Z;
     t1 = (boundingBox.Min.Z - Position.Z) * inverseDirection;
     t2 = (boundingBox.Max.Z - Position.Z) * inverseDirection;
     if (t1 > t2)
     {
         float temp = t1;
         t1 = t2;
         t2 = temp;
     }
     tmin = System.Math.Max(tmin, t1);
     tmax = System.Math.Min(tmax, t2);
     if (tmin > tmax)
     {
         result = null;
         return;
     }
     result = tmin;
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Determines if and when the ray intersects the bounding box.
 /// </summary>
 /// <param name="boundingBox">Bounding box to test against.</param>
 /// <returns>The length along the ray to the impact, or null if no impact is found.</returns>
 public float? Intersects(BoundingBox boundingBox)
 {
     float? toReturn;
     Intersects(ref boundingBox, out toReturn);
     return toReturn;
 }
Ejemplo n.º 22
0
        /// <summary>
        /// Computes a bounding box for the shape given the specified transform.
        /// </summary>
        /// <param name="transform">Transform to apply to the shape to compute the bounding box.</param>
        /// <param name="boundingBox">Bounding box for the shape given the transform.</param>
        public override void GetBoundingBox(ref RigidTransform transform, out BoundingBox boundingBox)
        {
            RigidTransform combinedTransform;
            RigidTransform.Transform(ref shapes.Elements[0].LocalTransform, ref transform, out combinedTransform);
            shapes.Elements[0].Shape.GetBoundingBox(ref combinedTransform, out boundingBox);

            for (int i = 0; i < shapes.Count; i++)
            {
                RigidTransform.Transform(ref shapes.Elements[i].LocalTransform, ref transform, out combinedTransform);
                BoundingBox childBoundingBox;
                shapes.Elements[i].Shape.GetBoundingBox(ref combinedTransform, out childBoundingBox);
                BoundingBox.CreateMerged(ref boundingBox, ref childBoundingBox, out boundingBox);
            }
        }
Ejemplo n.º 23
0
        void GetSamplingOrigin(ref BoundingBox entityBoundingBox, out System.Numerics.Vector3 xSpacing, out System.Numerics.Vector3 zSpacing, out float perColumnArea, out System.Numerics.Vector3 origin)
        {
            //Compute spacing and increment informaiton.
            float widthIncrement = (entityBoundingBox.Max.X - entityBoundingBox.Min.X) / samplePointsPerDimension;
            float lengthIncrement = (entityBoundingBox.Max.Z - entityBoundingBox.Min.Z) / samplePointsPerDimension;
            xSpacing = new System.Numerics.Vector3(widthIncrement, 0, 0);
            zSpacing = new System.Numerics.Vector3(0, 0, lengthIncrement);
            QuaternionEx.Transform(ref xSpacing, ref surfaceTransform.Orientation, out xSpacing);
            QuaternionEx.Transform(ref zSpacing, ref surfaceTransform.Orientation, out zSpacing);
            perColumnArea = widthIncrement * lengthIncrement;

            //Compute the origin.
            System.Numerics.Vector3 minimum;
            RigidTransform.Transform(ref entityBoundingBox.Min, ref surfaceTransform, out minimum);
            //Matrix3X3.TransformTranspose(ref entityBoundingBox.Min, ref surfaceOrientationTranspose, out minimum);
            System.Numerics.Vector3 offset;
            Vector3Ex.Multiply(ref xSpacing, .5f, out offset);
            Vector3Ex.Add(ref minimum, ref offset, out origin);
            Vector3Ex.Multiply(ref zSpacing, .5f, out offset);
            Vector3Ex.Add(ref origin, ref offset, out origin);

            //TODO: Could adjust the grid origin such that a ray always hits the deepest point.
            //The below code is a prototype of the idea, but has bugs.
            //var convexInfo = collidable as ConvexCollisionInformation;
            //if (convexInfo != null)
            //{
            //    System.Numerics.Vector3 dir;
            //    Vector3Ex.Negate(ref upVector, out dir);
            //    System.Numerics.Vector3 extremePoint;
            //    convexInfo.Shape.GetExtremePoint(dir, ref convexInfo.worldTransform, out extremePoint);
            //    //Use extreme point to snap to grid.
            //    Vector3Ex.Subtract(ref extremePoint, ref origin, out offset);
            //    float offsetX, offsetZ;
            //    Vector3Ex.Dot(ref offset, ref right, out offsetX);
            //    Vector3Ex.Dot(ref offset, ref backward, out offsetZ);
            //    offsetX %= widthIncrement;
            //    offsetZ %= lengthIncrement;

            //    if (offsetX > .5f * widthIncrement)
            //    {
            //        Vector3Ex.Multiply(ref right, 1 - offsetX, out offset);
            //    }
            //    else
            //    {
            //        Vector3Ex.Multiply(ref right, -offsetX, out offset);
            //    }

            //    if (offsetZ > .5f * lengthIncrement)
            //    {
            //        System.Numerics.Vector3 temp;
            //        Vector3Ex.Multiply(ref right, 1 - offsetZ, out temp);
            //        Vector3Ex.Add(ref temp, ref offset, out offset);
            //    }
            //    else
            //    {
            //        System.Numerics.Vector3 temp;
            //        Vector3Ex.Multiply(ref right, -offsetZ, out temp);
            //        Vector3Ex.Add(ref temp, ref offset, out offset);
            //    }

            //    Vector3Ex.Add(ref origin, ref offset, out origin);

            //}
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Builds and spawns the body into the world.
 /// </summary>
 public virtual void SpawnBody()
 {
     if (Body != null)
     {
         DestroyBody();
     }
     Body = new BEPUphysics.Entities.Entity(Shape, Mass);
     Body.CollisionInformation.CollisionRules.Group = CGroup;
     InternalOffset = new Location(Body.Position);
     Body.AngularVelocity = new Vector3((float)AVel.X, (float)AVel.Y, (float)AVel.Z);
     Body.LinearVelocity = new Vector3((float)LVel.X, (float)LVel.Y, (float)LVel.Z);
     Body.WorldTransform = WorldTransform; // TODO: Position + Quaternion
     Body.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Passive;
     if (!CanRotate)
     {
         Body.AngularDamping = 1;
     }
     // TODO: Other settings
     // TODO: Gravity
     Body.Tag = this;
     SetFriction(Friction);
     SetBounciness(Bounciness);
     TheRegion.PhysicsWorld.Add(Body);
     for (int i = 0; i < Joints.Count; i++)
     {
         if (Joints[i] is BaseJoint)
         {
             BaseJoint joint = (BaseJoint)Joints[i];
             joint.CurrentJoint = joint.GetBaseJoint();
             TheRegion.PhysicsWorld.Add(joint.CurrentJoint);
         }
     }
     ShadowCastShape = Shape.GetCollidableInstance().BoundingBox;
     ShadowMainDupe = Shape.GetCollidableInstance().BoundingBox;
     ShadowCenter = GetPosition();
 }
Ejemplo n.º 25
0
        /// <summary>
        /// Computes the bounding box of three points.
        /// </summary>
        /// <param name="a">First vertex of the triangle.</param>
        /// <param name="b">Second vertex of the triangle.</param>
        /// <param name="c">Third vertex of the triangle.</param>
        /// <param name="aabb">Bounding box of the triangle.</param>
        public static void GetTriangleBoundingBox(ref Vector3 a, ref Vector3 b, ref Vector3 c, out BoundingBox aabb)
        {
#if !WINDOWS
            aabb = new BoundingBox();
#endif
            //X axis
            if (a.X > b.X && a.X > c.X)
            {
                //A is max
                aabb.Max.X = a.X;
                aabb.Min.X = b.X > c.X ? c.X : b.X;
            }
            else if (b.X > c.X)
            {
                //B is max
                aabb.Max.X = b.X;
                aabb.Min.X = a.X > c.X ? c.X : a.X;
            }
            else
            {
                //C is max
                aabb.Max.X = c.X;
                aabb.Min.X = a.X > b.X ? b.X : a.X;
            }
            //Y axis
            if (a.Y > b.Y && a.Y > c.Y)
            {
                //A is max
                aabb.Max.Y = a.Y;
                aabb.Min.Y = b.Y > c.Y ? c.Y : b.Y;
            }
            else if (b.Y > c.Y)
            {
                //B is max
                aabb.Max.Y = b.Y;
                aabb.Min.Y = a.Y > c.Y ? c.Y : a.Y;
            }
            else
            {
                //C is max
                aabb.Max.Y = c.Y;
                aabb.Min.Y = a.Y > b.Y ? b.Y : a.Y;
            }
            //Z axis
            if (a.Z > b.Z && a.Z > c.Z)
            {
                //A is max
                aabb.Max.Z = a.Z;
                aabb.Min.Z = b.Z > c.Z ? c.Z : b.Z;
            }
            else if (b.Z > c.Z)
            {
                //B is max
                aabb.Max.Z = b.Z;
                aabb.Min.Z = a.Z > c.Z ? c.Z : a.Z;
            }
            else
            {
                //C is max
                aabb.Max.Z = c.Z;
                aabb.Min.Z = a.Z > b.Z ? b.Z : a.Z;
            }
        }
        int BuildPileSimulation(Space space)
        {
            Random rand = new Random(0);

#if WINDOWS
            NarrowPhaseHelper.Factories.BoxBox.EnsureCount(30000);
            BoundingBox box = new BoundingBox(new Vector3(-5, 10, -5), new Vector3(5, 300, 5));
            for (int k = 0; k < 5000; k++)
#else        
            NarrowPhaseHelper.Factories.BoxBox.EnsureCount(1500);
            BoundingBox box = new BoundingBox(new Vector3(-5, 10, -5), new Vector3(5, 20, 5));
            for (int k = 0; k < 250; k++)
#endif
            {
                Vector3 position = new Vector3((float)(rand.NextDouble() * (box.Max.X - box.Min.X) + box.Min.X),
                                               (float)(rand.NextDouble() * (box.Max.Y - box.Min.Y) + box.Min.Y),
                                               (float)(rand.NextDouble() * (box.Max.Z - box.Min.Z) + box.Min.Z));
                var toAdd = new Box(position, 1, 1, 1, 1);
                toAdd.ActivityInformation.IsAlwaysActive = true;

                space.Add(toAdd);


            }

            Box ground = new Box(new Vector3(0, 0, 0), 300, 10, 300);
            space.Add(ground);

#if WINDOWS
            return 700;
#else
            return 350;
#endif
        }
Ejemplo n.º 27
0
 public static void Validate(this BoundingBox b)
 {
     b.Min.Validate();
     b.Max.Validate();
 }
Ejemplo n.º 28
0
        /// <summary>
        /// Expands a bounding box by the given sweep.
        /// </summary>
        /// <param name="boundingBox">Bounding box to expand.</param>
        /// <param name="sweep">Sweep to expand the bounding box with.</param>
        public static void ExpandBoundingBox(ref BoundingBox boundingBox, ref Vector3 sweep)
        {
            if (sweep.X > 0)
                boundingBox.Max.X += sweep.X;
            else
                boundingBox.Min.X += sweep.X;

            if (sweep.Y > 0)
                boundingBox.Max.Y += sweep.Y;
            else
                boundingBox.Min.Y += sweep.Y;

            if (sweep.Z > 0)
                boundingBox.Max.Z += sweep.Z;
            else
                boundingBox.Min.Z += sweep.Z;
        }
Ejemplo n.º 29
0
 Location SkyMod(Location pos, Location norm, float light)
 {
     if (light > 0 && TheClient.CVars.r_treeshadows.ValueB)
     {
         BoundingBox bb = new BoundingBox(pos.ToBVector(), (pos + new Location(1, 1, 300)).ToBVector());
         if (GenShadowCasters != null)
         {
             for (int i = 0; i < GenShadowCasters.Length; i++)
             {
                 PhysicsEntity pe = GenShadowCasters[i];
                 if (pe.GenBlockShadows && pe.ShadowCenter.DistanceSquared_Flat(pos) < pe.ShadowRadiusSquaredXY)
                 {
                     light -= 0.05f;
                     if (pe.ShadowMainDupe.Intersects(bb))
                     {
                         light = 0;
                         break;
                     }
                     if (pe.ShadowCastShape.Intersects(bb))
                     {
                         light -= 0.1f;
                     }
                     if (light <= 0)
                     {
                         light = 0;
                         break;
                     }
                 }
             }
         }
     }
     return Math.Max(norm.Dot(SunLightPathNegative), 0.5) * new Location(light) * SkyLightMod;
 }
Ejemplo n.º 30
0
        /// <summary>
        /// Gets the bounding box of the shape given a transform.
        /// </summary>
        /// <param name="shapeTransform">Transform to use.</param>
        /// <param name="boundingBox">Bounding box of the transformed shape.</param>
        public override void GetBoundingBox(ref RigidTransform shapeTransform, out BoundingBox boundingBox)
        {
            #if !WINDOWS
            boundingBox = new BoundingBox();
            #endif

            Matrix3x3 o;
            Matrix3x3.CreateFromQuaternion(ref shapeTransform.Orientation, out o);
            //Sample the local directions from the orientation matrix, implicitly transposed.
            //Notice only three directions are used.  Due to box symmetry, 'left' is just -right.
            var right = new System.Numerics.Vector3(Math.Sign(o.M11) * halfWidth, Math.Sign(o.M21) * halfHeight, Math.Sign(o.M31) * halfLength);

            var up = new System.Numerics.Vector3(Math.Sign(o.M12) * halfWidth, Math.Sign(o.M22) * halfHeight, Math.Sign(o.M32) * halfLength);

            var backward = new System.Numerics.Vector3(Math.Sign(o.M13) * halfWidth, Math.Sign(o.M23) * halfHeight, Math.Sign(o.M33) * halfLength);

            //Rather than transforming each axis independently (and doing three times as many operations as required), just get the 3 required values directly.
            System.Numerics.Vector3 offset;
            TransformLocalExtremePoints(ref right, ref up, ref backward, ref o, out offset);

            //The positive and negative vectors represent the X, Y and Z coordinates of the extreme points in world space along the world space axes.
            Vector3Ex.Add(ref shapeTransform.Position, ref offset, out boundingBox.Max);
            Vector3Ex.Subtract(ref shapeTransform.Position, ref offset, out boundingBox.Min);
        }
Ejemplo n.º 31
0
        /// <summary>
        /// Gets the bounding box of the shape given a transform.
        /// </summary>
        /// <param name="shapeTransform">Transform to use.</param>
        /// <param name="boundingBox">Bounding box of the transformed shape.</param>
        public override void GetBoundingBox(ref RigidTransform shapeTransform, out BoundingBox boundingBox)
        {
            System.Numerics.Vector3 a, b, c;

            Matrix3x3 o;
            Matrix3x3.CreateFromQuaternion(ref shapeTransform.Orientation, out o);
            Matrix3x3.Transform(ref vA, ref o, out a);
            Matrix3x3.Transform(ref vB, ref o, out b);
            Matrix3x3.Transform(ref vC, ref o, out c);

            Vector3Ex.Min(ref a, ref b, out boundingBox.Min);
            Vector3Ex.Min(ref c, ref boundingBox.Min, out boundingBox.Min);

            Vector3Ex.Max(ref a, ref b, out boundingBox.Max);
            Vector3Ex.Max(ref c, ref boundingBox.Max, out boundingBox.Max);

            boundingBox.Min.X += shapeTransform.Position.X - collisionMargin;
            boundingBox.Min.Y += shapeTransform.Position.Y - collisionMargin;
            boundingBox.Min.Z += shapeTransform.Position.Z - collisionMargin;
            boundingBox.Max.X += shapeTransform.Position.X + collisionMargin;
            boundingBox.Max.Y += shapeTransform.Position.Y + collisionMargin;
            boundingBox.Max.Z += shapeTransform.Position.Z + collisionMargin;
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Creates the smallest bounding box which contains two other bounding boxes.
        /// </summary>
        /// <param name="a">First bounding box to be contained.</param>
        /// <param name="b">Second bounding box to be contained.</param>
        /// <param name="merged">Smallest bounding box which contains the two input bounding boxes.</param>
        public static void CreateMerged(ref BoundingBox a, ref BoundingBox b, out BoundingBox merged)
        {
            if (a.Min.X < b.Min.X)
                merged.Min.X = a.Min.X;
            else
                merged.Min.X = b.Min.X;
            if (a.Min.Y < b.Min.Y)
                merged.Min.Y = a.Min.Y;
            else
                merged.Min.Y = b.Min.Y;
            if (a.Min.Z < b.Min.Z)
                merged.Min.Z = a.Min.Z;
            else
                merged.Min.Z = b.Min.Z;

            if (a.Max.X > b.Max.X)
                merged.Max.X = a.Max.X;
            else
                merged.Max.X = b.Max.X;
            if (a.Max.Y > b.Max.Y)
                merged.Max.Y = a.Max.Y;
            else
                merged.Max.Y = b.Max.Y;
            if (a.Max.Z > b.Max.Z)
                merged.Max.Z = a.Max.Z;
            else
                merged.Max.Z = b.Max.Z;
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Recalculates the bounding box of the fluid based on its depth, surface normal, and surface triangles.
        /// </summary>
        public void RecalculateBoundingBox()
        {
            var points = CommonResources.GetVectorList();
            foreach (var tri in SurfaceTriangles)
            {
                points.Add(tri[0]);
                points.Add(tri[1]);
                points.Add(tri[2]);
                points.Add(tri[0] - upVector * MaxDepth);
                points.Add(tri[1] - upVector * MaxDepth);
                points.Add(tri[2] - upVector * MaxDepth);
            }
            boundingBox = BoundingBox.CreateFromPoints(points);
            CommonResources.GiveBack(points);

            //Compute the transforms used to pull objects into fluid local space.
            QuaternionEx.GetQuaternionBetweenNormalizedVectors(ref Toolbox.UpVector, ref upVector, out surfaceTransform.Orientation);
            Matrix3x3.CreateFromQuaternion(ref surfaceTransform.Orientation, out toSurfaceRotationMatrix);
            surfaceTransform.Position = surfaceTriangles[0][0];
        }