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