Exemplo n.º 1
0
        public override bool IsAnyAabbCornerInside(BoundingBoxD worldAabb)
        {
            MyRenderProxy.DebugDrawAABB(worldAabb, Color.White, 1f, 1f, true);

            unsafe
            {
                const int cornerCount = 8;
                Vector3D *corners     = stackalloc Vector3D[cornerCount];
                worldAabb.GetCornersUnsafe(corners);
                return(IsAnyPointInside(corners, cornerCount));
            }
        }
Exemplo n.º 2
0
 private int CountCornersInside(ref MatrixD aabbWorldTransform, ref BoundingBoxD aabb)
 {
     unsafe
     {
         const int cornerCount = 8;
         Vector3D *corners     = stackalloc Vector3D[cornerCount];
         aabb.GetCornersUnsafe(corners);
         for (int i = 0; i < cornerCount; i++)
         {
             Vector3D.Transform(ref corners[i], ref aabbWorldTransform, out corners[i]);
         }
         return(CountPointsInside(corners, cornerCount));
     }
 }
Exemplo n.º 3
0
 public override bool IsAnyAabbCornerInside(ref MatrixD aabbWorldTransform, BoundingBoxD aabb)
 {
     unsafe
     {
         const int cornerCount = 8;
         Vector3D *corners     = stackalloc Vector3D[cornerCount];
         aabb.GetCornersUnsafe(corners);
         for (int i = 0; i < cornerCount; i++)
         {
             Vector3D.Transform(ref corners[i], ref aabbWorldTransform, out corners[i]);
         }
         return(IsAnyPointInside(corners, cornerCount));
     }
 }
        // Iterate over sector boxes in a range.
        // TODO: Dumb version of this for small boxes
        private unsafe void RasterSectorsForPhysics(BoundingBoxD range)
        {
            range.InflateToMinimum(EnvironmentDefinition.SectorSize);

            Vector2I top = new Vector2I(1 << m_clipmaps[0].Depth) - 1;

            Vector3D* pos = stackalloc Vector3D[8];

            range.GetCornersUnsafe(pos);

            // bitmask for faces, 7th bit is simple bit
            int markedFaces = 0;
            int firstFace = 0;

            for (var i = 0; i < 8; ++i)
            {
                Vector3D copy = pos[i];

                int index = MyPlanetCubemapHelper.FindCubeFace(ref copy);
                firstFace = index;
                index = 1 << index;

                if ((markedFaces & ~index) != 0) markedFaces |= 0x40;

                markedFaces |= index;
            }

            // This way we can ensure a single code path.
            int startFace = 0;
            int endFace = 5;

            // If we only encounter one face we narrow it down.
            if ((markedFaces & 0x40) == 0)
            {
                startFace = endFace = firstFace;
            }

            for (int face = startFace; face <= endFace; ++face)
            {
                if (((1 << face) & markedFaces) == 0)
                    continue;

                double size = m_clipmaps[face].LeafSize;

                // Offset 
                var offset = 1 << m_clipmaps[face].Depth - 1;

                BoundingBox2D bounds = BoundingBox2D.CreateInvalid();
                for (int i = 0; i < 8; ++i)
                {
                    Vector3D copy = pos[i];

                    Vector2D normCoords;
                    MyPlanetCubemapHelper.ProjectForFace(ref copy, face, out normCoords);
                    bounds.Include(normCoords);
                }

                bounds.Min += 1;
                bounds.Min *= offset;

                bounds.Max += 1;
                bounds.Max *= offset;

                // Calculate bounds in sectors.
                var start = new Vector2I((int)bounds.Min.X, (int)bounds.Min.Y);
                var end = new Vector2I((int)bounds.Max.X, (int)bounds.Max.Y);

                Vector2I.Max(ref start, ref Vector2I.Zero, out start);
                Vector2I.Min(ref end, ref top, out end);

                for (int x = start.X; x <= end.X; ++x)
                    for (int y = start.Y; y <= end.Y; ++y)
                    {
                        EnsurePhysicsSector(x, y, face);
                    }
            }
        }
Exemplo n.º 5
0
 private int CountCornersInside(ref MatrixD aabbWorldTransform, ref BoundingBoxD aabb)
 {
     unsafe
     {
         const int cornerCount = 8;
         Vector3D* corners = stackalloc Vector3D[cornerCount];
         aabb.GetCornersUnsafe(corners);
         for (int i = 0; i < cornerCount; i++)
         {
             Vector3D.Transform(ref corners[i], ref aabbWorldTransform, out corners[i]);
         }
         return CountPointsInside(corners, cornerCount);
     }
 }
        // Iterate over sector boxes in a range.
        // TODO: Dumb version of this for small boxes
        private unsafe void RasterSectorsForPhysics(BoundingBoxD range)
        {
            range.InflateToMinimum(EnvironmentDefinition.SectorSize);

            Vector2I top = new Vector2I(1 << m_clipmaps[0].Depth) - 1;

            Vector3D *pos = stackalloc Vector3D[8];

            range.GetCornersUnsafe(pos);

            // bitmask for faces, 7th bit is simple bit
            int markedFaces = 0;
            int firstFace   = 0;

            for (var i = 0; i < 8; ++i)
            {
                Vector3D copy = pos[i];

                int index = MyPlanetCubemapHelper.FindCubeFace(ref copy);
                firstFace = index;
                index     = 1 << index;

                if ((markedFaces & ~index) != 0)
                {
                    markedFaces |= 0x40;
                }

                markedFaces |= index;
            }

            // This way we can ensure a single code path.
            int startFace = 0;
            int endFace   = 5;

            // If we only encounter one face we narrow it down.
            if ((markedFaces & 0x40) == 0)
            {
                startFace = endFace = firstFace;
            }

            for (int face = startFace; face <= endFace; ++face)
            {
                if (((1 << face) & markedFaces) == 0)
                {
                    continue;
                }

                double size = m_clipmaps[face].LeafSize;

                // Offset
                var offset = 1 << m_clipmaps[face].Depth - 1;

                BoundingBox2D bounds = BoundingBox2D.CreateInvalid();
                for (int i = 0; i < 8; ++i)
                {
                    Vector3D copy = pos[i];

                    Vector2D normCoords;
                    MyPlanetCubemapHelper.ProjectForFace(ref copy, face, out normCoords);
                    bounds.Include(normCoords);
                }

                bounds.Min += 1;
                bounds.Min *= offset;

                bounds.Max += 1;
                bounds.Max *= offset;

                // Calculate bounds in sectors.
                var start = new Vector2I((int)bounds.Min.X, (int)bounds.Min.Y);
                var end   = new Vector2I((int)bounds.Max.X, (int)bounds.Max.Y);

                Vector2I.Max(ref start, ref Vector2I.Zero, out start);
                Vector2I.Min(ref end, ref top, out end);

                for (int x = start.X; x <= end.X; ++x)
                {
                    for (int y = start.Y; y <= end.Y; ++y)
                    {
                        EnsurePhysicsSector(x, y, face);
                    }
                }
            }
        }
        private unsafe void RasterSectorsForCollision(MyEntity entity)
        {
            if (!(entity is MyCubeGrid))
            {
                return;
            }

            BoundingBoxD range = entity.PositionComp.WorldAABB;

            range.Inflate(8);
            range.Translate(-PlanetTranslation);

            Vector2I top = new Vector2I(1 << m_clipmaps[0].Depth) - 1;

            Vector3D *pos = stackalloc Vector3D[8];

            range.GetCornersUnsafe(pos);

            // bitmask for faces, 7th bit is simple bit
            int markedFaces = 0;
            int firstFace   = 0;

            for (var i = 0; i < 8; ++i)
            {
                Vector3D copy = pos[i];

                int index = MyPlanetCubemapHelper.FindCubeFace(ref copy);
                firstFace = index;
                index     = 1 << index;

                if ((markedFaces & ~index) != 0)
                {
                    markedFaces |= 0x40;
                }

                markedFaces |= index;
            }

            // This way we can ensure a single code path.
            int startFace = 0;
            int endFace   = 5;

            // If we only encounter one face we narrow it down.
            if ((markedFaces & 0x40) == 0)
            {
                startFace = endFace = firstFace;
            }

            for (int face = startFace; face <= endFace; ++face)
            {
                if (((1 << face) & markedFaces) == 0)
                {
                    continue;
                }

                // Offset
                var offset = 1 << m_clipmaps[face].Depth - 1;

                BoundingBox2D bounds = BoundingBox2D.CreateInvalid();
                for (int i = 0; i < 8; ++i)
                {
                    Vector3D copy = pos[i];

                    Vector2D normCoords;
                    MyPlanetCubemapHelper.ProjectForFace(ref copy, face, out normCoords);
                    bounds.Include(normCoords);
                }

                bounds.Min += 1;
                bounds.Min *= offset;

                bounds.Max += 1;
                bounds.Max *= offset;

                // Calculate bounds in sectors.
                var start = new Vector2I((int)bounds.Min.X, (int)bounds.Min.Y);
                var end   = new Vector2I((int)bounds.Max.X, (int)bounds.Max.Y);

                Vector2I.Max(ref start, ref Vector2I.Zero, out start);
                Vector2I.Min(ref end, ref top, out end);

                for (int x = start.X; x <= end.X; ++x)
                {
                    for (int y = start.Y; y <= end.Y; ++y)
                    {
                        long sect = MyPlanetSectorId.MakeSectorId(x, y, face);

                        List <MyOrientedBoundingBoxD> boxes;
                        if (!m_obstructorsPerSector.TryGetValue(sect, out boxes))
                        {
                            boxes = new List <MyOrientedBoundingBoxD>();
                            m_obstructorsPerSector.Add(sect, boxes);
                        }

                        var bb = entity.PositionComp.LocalAABB;
                        bb.Inflate(8); // inflate by 8m to increase the likellyhood of overlap with trees' roots.

                        boxes.Add(new MyOrientedBoundingBoxD((BoundingBoxD)bb, entity.PositionComp.WorldMatrix));
                    }
                }
            }
        }