private static bool PointInBox(Vector3 v, Box3D node) { return v.X >= node.MinEdge.X && v.Y >= node.MinEdge.Y && v.Z >= node.MinEdge.Z && v.X <= node.MaxEdge.X && v.Y <= node.MaxEdge.Y && v.Z <= node.MaxEdge.Z; }
public static BlockPosSide? CheckLineBoxExact(Line3D line, Box3D box) { if (PointInBox(line.Start, box)) { return new BlockPosSide() { pos = line.Start }; } Vector3 big = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 closest = big; TileSide side = TileSide.Top; foreach (Triangle3DAndSide t in BoxTrianglesAndSides(box.MinEdge, box.MaxEdge)) { Vector3 i; if (RayTriangle(line, t.t, out i) != 0) { if ((line.Start - i).Length < (line.Start - closest).Length) { closest = i; side = t.side; } } } //if (closest == big) { throw new Exception(); } if (closest == big) { return null; } return new BlockPosSide() { pos = closest, side = side }; //if (PointInBox(line.End, box)) { return new TilePosSide() { pos = line.End }; } throw new Exception(); }
/// <summary> /// Warning: randomly returns incorrect hit position (back side of box). /// </summary> /// <param name="box"></param> /// <param name="line"></param> /// <param name="hit"></param> /// <returns></returns> public static bool CheckLineBox(Box3D box, Line3D line, out Vector3 hit) { return CheckLineBox(box.MinEdge, box.MaxEdge, line.Start, line.End, out hit); }
IEnumerable<Box3D> SearchPrivate(Predicate<Box3D> query, Box3D box) { if (box.LengthX == 1) { yield return box; yield break; } foreach (Box3D child in Children(box)) { if (query(child)) { foreach (Box3D n in SearchPrivate(query, child)) { yield return n; } } } }
IEnumerable<Box3D> Children(Box3D box) { float x = box.MinEdge.X; float y = box.MinEdge.Y; float z = box.MinEdge.Z; float size = box.LengthX / 2; yield return new Box3D(x, y, z, size); yield return new Box3D(x + size, y, z, size); yield return new Box3D(x, y, z + size, size); yield return new Box3D(x + size, y, z + size, size); yield return new Box3D(x, y + size, z, size); yield return new Box3D(x + size, y + size, z, size); yield return new Box3D(x, y + size, z + size, size); yield return new Box3D(x + size, y + size, z + size, size); }
bool BoxHit(Box3D box) { return Intersection.CheckLineBox(box, currentLine, out currentHit); }