// 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)); } } } }