/** * Takes the x and y bounds of the box and queries the heightmap for the minimum and maximum height in the box. * * The values are returned in the query box itself as the Z bounds. * * This only works if all vertices of the box are in the same face. */ public unsafe void GetBounds(ref BoundingBox box) { int firstFace = -1; Vector3 *corners = stackalloc Vector3[8]; box.GetCornersUnsafe(corners); for (int i = 0; i < 8; ++i) { int face; MyCubemapHelpers.GetCubeFace(ref corners[i], out face); if (firstFace == -1) { firstFace = face; } } BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, 0), new Vector3(float.NegativeInfinity, float.NegativeInfinity, 0)); for (int i = 0; i < 8; ++i) { Vector2 tex; MyCubemapHelpers.CalculateTexcoordForFace(ref corners[i], firstFace, out tex); if (tex.X < query.Min.X) { query.Min.X = tex.X; } if (tex.X > query.Max.X) { query.Max.X = tex.X; } if (tex.Y < query.Min.Y) { query.Min.Y = tex.Y; } if (tex.Y > query.Max.Y) { query.Max.Y = tex.Y; } } m_heightmap.Faces[firstFace].GetBounds(ref query); box.Min.Z = query.Min.Z * m_heightRatio + InnerRadius; box.Max.Z = query.Max.Z * m_heightRatio + InnerRadius; }
public bool IntersectLineFace(ref LineD ll, int face, out double startOffset, out double endOffset) { Vector2 start, end; Vector3 from, to; from = ll.From; to = ll.To; MyCubemapHelpers.CalculateTexcoordForFace(ref from, face, out start); MyCubemapHelpers.CalculateTexcoordForFace(ref to, face, out end); int steps = (int)Math.Ceiling((end - start).Length() * m_heightmap.Resolution); double stepsR = 1d / steps; for (int i = 0; i < steps; i++) { from = ll.From + ll.Direction * ll.Length * i * stepsR; to = ll.From + ll.Direction * ll.Length * (i + 1) * stepsR; var flen = from.Length(); var tolen = to.Length(); MyCubemapHelpers.CalculateTexcoordForFace(ref from, face, out start); MyCubemapHelpers.CalculateTexcoordForFace(ref to, face, out end); from.X = start.X; from.Y = start.Y; from.Z = (flen - m_radius - m_minHillHeight) * m_heightRatioRecip; to.X = end.X; to.Y = end.Y; to.Z = (tolen - m_radius - m_minHillHeight) * m_heightRatioRecip; float newStart, newEnd; if (m_heightmap[face].QueryLine(ref from, ref to, out newStart, out newEnd)) { startOffset = Math.Max((i + newStart) * stepsR, 0); endOffset = 1.0; return(true); } } startOffset = 0; endOffset = 1; return(false); }
/// <summary> /// Get the minimum and maximum ranges of terrain height in the area determined by the provided points. /// </summary> /// <param name="localPoints">List of points to query</param> /// <param name="pointCount">Number of points</param> /// <param name="minHeight">The calculated minimum possible height of terrain</param> /// <param name="maxHeight">The calculated maximum possible height of terrain</param> public unsafe void GetBounds(Vector3 *localPoints, int pointCount, out float minHeight, out float maxHeight) { int firstFace = -1; for (int i = 0; i < pointCount; ++i) { int face; MyCubemapHelpers.GetCubeFace(ref localPoints[i], out face); if (firstFace == -1) { firstFace = face; } } BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, 0), new Vector3(float.NegativeInfinity, float.NegativeInfinity, 0)); for (int i = 0; i < pointCount; ++i) { Vector2 tex; MyCubemapHelpers.CalculateTexcoordForFace(ref localPoints[i], firstFace, out tex); if (tex.X < query.Min.X) { query.Min.X = tex.X; } if (tex.X > query.Max.X) { query.Max.X = tex.X; } if (tex.Y < query.Min.Y) { query.Min.Y = tex.Y; } if (tex.Y > query.Max.Y) { query.Max.Y = tex.Y; } } m_heightmap.Faces[firstFace].GetBounds(ref query); minHeight = query.Min.Z * m_heightRatio + InnerRadius; maxHeight = query.Max.Z * m_heightRatio + InnerRadius; }
public unsafe void GetBounds(Vector3D *localPoints, int pointCount, out float minHeight, out float maxHeight) { int face = -1; for (int i = 0; i < pointCount; i++) { int num3; Vector3 position = *((Vector3 *)(localPoints + i)); MyCubemapHelpers.GetCubeFace(ref position, out num3); if (face == -1) { face = num3; } } BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, 0f), new Vector3(float.NegativeInfinity, float.NegativeInfinity, 0f)); for (int j = 0; j < pointCount; j++) { Vector2 vector2; Vector3 localPos = *((Vector3 *)(localPoints + j)); MyCubemapHelpers.CalculateTexcoordForFace(ref localPos, face, out vector2); if (vector2.X < query.Min.X) { query.Min.X = vector2.X; } if (vector2.X > query.Max.X) { query.Max.X = vector2.X; } if (vector2.Y < query.Min.Y) { query.Min.Y = vector2.Y; } if (vector2.Y > query.Max.Y) { query.Max.Y = vector2.Y; } } this.m_heightmap.Faces[face].GetBounds(ref query); minHeight = (query.Min.Z * this.m_heightRatio) + this.InnerRadius; maxHeight = (query.Max.Z * this.m_heightRatio) + this.InnerRadius; }
protected unsafe ContainmentType IntersectBoundingBoxInternal(ref BoundingBox box, float lodLevel) { int firstFace = -1; uint faces = 0; bool complicated = false; float minHeight; float maxHeight; Vector3 *corners = stackalloc Vector3[8]; box.GetCornersUnsafe(corners); for (int i = 0; i < 8; ++i) { int face; MyCubemapHelpers.GetCubeFace(ref corners[i], out face); if (firstFace == -1) { firstFace = face; } else if (firstFace != face) { complicated = true; } faces |= (uint)(1 << face); } if (Vector3.Zero.IsInsideInclusive(ref box.Min, ref box.Max)) { minHeight = 0; } else { var clamp = Vector3.Clamp(Vector3.Zero, box.Min, box.Max); minHeight = clamp.Length(); } { // Calculate furthest point in BB Vector3 end; Vector3 c = box.Center; if (c.X < 0) { end.X = box.Min.X; } else { end.X = box.Max.X; } if (c.Y < 0) { end.Y = box.Min.Y; } else { end.Y = box.Max.Y; } if (c.Z < 0) { end.Z = box.Min.Z; } else { end.Z = box.Max.Z; } maxHeight = end.Length(); } if (complicated) { return(IntersectBoundingBoxCornerCase(ref box, faces, corners, minHeight, maxHeight)); } BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, minHeight), new Vector3(float.NegativeInfinity, float.NegativeInfinity, maxHeight)); for (int i = 0; i < 8; ++i) { Vector2 tex; MyCubemapHelpers.CalculateTexcoordForFace(ref corners[i], firstFace, out tex); if (tex.X < query.Min.X) { query.Min.X = tex.X; } if (tex.X > query.Max.X) { query.Max.X = tex.X; } if (tex.Y < query.Min.Y) { query.Min.Y = tex.Y; } if (tex.Y > query.Max.Y) { query.Max.Y = tex.Y; } } query.Min.Z = ((query.Min.Z - m_radius - m_detailScale) - m_minHillHeight) * m_heightRatioRecip; query.Max.Z = ((query.Max.Z - m_radius) - m_minHillHeight) * m_heightRatioRecip; return(m_heightmap.Faces[firstFace].QueryHeight(ref query)); }