public BVHNode(List <IHitable> l, int n, double time0, double time1) { AABB boxLeft, boxRight; int axis = 3 * (int)RandomDouble(); if (axis == 0) { l.Sort((a, b) => { if (!a.BoundingBox(0, 0, out boxLeft) || !b.BoundingBox(0, 0, out boxRight)) { throw new Exception(); } return(boxLeft.Min.X.CompareTo(boxRight.Min.X)); }); } else if (axis == 1) { l.Sort((a, b) => { if (!a.BoundingBox(0, 0, out boxLeft) || !b.BoundingBox(0, 0, out boxRight)) { throw new Exception(); } return(boxLeft.Min.Y.CompareTo(boxRight.Min.Y)); }); } else { l.Sort((a, b) => { if (!a.BoundingBox(0, 0, out boxLeft) || !b.BoundingBox(0, 0, out boxRight)) { throw new Exception(); } return(boxLeft.Min.Z.CompareTo(boxRight.Min.Z)); }); } if (n == 1) { left = right = l[0]; } else if (n == 2) { left = l[0]; right = l[1]; } else { left = new BVHNode(l, n / 2, time0, time1); right = new BVHNode(l.Skip(n / 2).ToList(), n - n / 2, time0, time1); } if (!left.BoundingBox(time0, time1, out boxLeft) || !right.BoundingBox(time0, time1, out boxRight)) { throw new Exception(); } box = SurroundingBox(boxLeft, boxRight); }
public bool BoundingBox(double t0, double t1, out AABB box) { if (_hitable.BoundingBox(t0, t1, out box)) { box = new AABB(box.Min + _offset, box.Max + _offset); return(true); } return(false); }
public bool BoundingBox(double t0, double t1, out AABB box) { if (ptr.BoundingBox(t0, t1, out box)) { return(true); } else { return(false); } }
public bool BoundingBox(double t0, double t1, out AABB box) { if (ptr.BoundingBox(t0, t1, out box)) { box = new AABB(box.Min + offset, box.Max + offset); return(true); } else { return(false); } }
private static int BoxXCompare(IHitable a, IHitable b) { if (!a.BoundingBox(0, 0, out AABB boxLeft) || !b.BoundingBox(0, 0, out AABB boxRight)) { throw new Exception("No bounding box in BVHNode"); } if (boxLeft.Min.X - boxRight.Min.X < 0) { return(-1); } return(1); }
public BVHNode(List <IHitable> hitables, float time0, float time1) { var axis = (int)(Rand.Float * 3); switch (axis) { case 0: // sort x hitables.Sort(BVHNode.BoxXCompare); break; case 1: // sort y hitables.Sort(BVHNode.BoxYCompare); break; default: // sprt z hitables.Sort(BVHNode.BoxZCompare); break; } switch (hitables.Count) { case 1: Left = Right = hitables[0]; break; case 2: Left = hitables[0]; Right = hitables[1]; break; default: Left = new BVHNode(hitables.Take(hitables.Count / 2).ToList(), time0, time1); Right = new BVHNode(hitables.Skip(hitables.Count / 2).ToList(), time0, time1); break; } if (!Left.BoundingBox(time0, time1, out AABB boxLeft) || !Right.BoundingBox(time0, time1, out AABB boxRight)) { throw new Exception("No bounding box in BVHNode"); } Box = AABB.SurroundingBox(boxRight, boxLeft); }
public RotateY(IHitable hitable, double angle) { _hitable = hitable; AABB box; _has_box = _hitable.BoundingBox(0, 1, out box); var radians = angle * Math.PI / 180; _sin_theta = Math.Sin(radians); _cos_theta = Math.Cos(radians); var rmin = Rotate(box.Min); _aabb = new AABB(rmin, rmin); _aabb = _aabb | Rotate(box.Max); _aabb = _aabb | Rotate(Vec3.Create(box.Min.X, box.Min.Y, box.Max.Z)); _aabb = _aabb | Rotate(Vec3.Create(box.Max.X, box.Max.Y, box.Min.Z)); }
public RotateY(IHitable p, double angle) { ptr = p; double radians = (Math.PI / 180) * angle; sinTheta = Math.Sin(radians); cosTheta = Math.Cos(radians); hasBox = ptr.BoundingBox(0, 1, out bBox); Vector3D min = new Vector3D(double.MaxValue, double.MaxValue, double.MaxValue); Vector3D max = new Vector3D(-double.MaxValue, -double.MaxValue, -double.MaxValue); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { double x = i * bBox.Max.X + (1 - i) * bBox.Min.X; double y = j * bBox.Max.Y + (1 - j) * bBox.Min.Y; double z = k * bBox.Max.Z + (1 - k) * bBox.Min.Z; double newx = cosTheta * x + sinTheta * z; double newz = -sinTheta * x + cosTheta * z; Vector3D tester = new Vector3D(newx, y, newz); for (int c = 0; c < 3; c++) { if (tester[c] > max[c]) { max[c] = tester[c]; } if (tester[c] < min[c]) { min[c] = tester[c]; } } } } } bBox = new AABB(min, max); }
public BVHNode(List <IHitable> world, int start, int length) { this.start = start; this.length = length; Random rng = new Random(); int axis = rng.Next() % 3; IComparer <IHitable> sorter; switch (axis) { case 0: sorter = new SortByX(); break; case 1: sorter = new SortByY(); break; default: sorter = new SortByZ(); break; } world.Sort(start, length, sorter); if (length == 1) { left = right = world[start]; } else if (length == 2) { left = world[start]; right = world[start + 1]; } else { left = new BVHNode(world, start, length / 2); right = new BVHNode(world, start + length / 2, length - length / 2); } box = AABB.CalculateSurroundBox(left.BoundingBox(), right.BoundingBox()); }
public BVHNode(IHitable[] hitables, double time0, double time1) { if (hitables.Length == 1) { _left = hitables[0]; _right = null; _left.BoundingBox(time0, time1, out _box); return; } int axis = _sampler.Next(0, 3); List <IHitable> list = new List <IHitable>(hitables); list.Sort((IHitable a, IHitable b) => { AABB sort_box_left, sort_box_right; if (!a.BoundingBox(time0, time1, out sort_box_left) || !b.BoundingBox(time0, time1, out sort_box_right)) { throw new InvalidOperationException("error computing AABB"); } return(sort_box_left.Min[axis] < sort_box_right.Min[axis] ? -1 : 1); }); int half = list.Count - list.Count / 2; _left = half == 1 ? list[0] : new BVHNode(list.GetRange(0, half).ToArray(), time0, time1); _right = half == list.Count - 1 ? list[list.Count - 1] : new BVHNode(list.GetRange(half, list.Count - half).ToArray(), time0, time1); AABB box_left, box_right; if (!_left.BoundingBox(time0, time1, out box_left) || !_right.BoundingBox(time0, time1, out box_right)) { throw new InvalidOperationException("error computing AABB"); } _box = box_left | box_right; }
public bool BoundingBox(double t0, double t1, out AABB box) { box = new AABB(new Vector3D(), new Vector3D()); return(ptr.BoundingBox(t0, t1, out box)); }
public bool BoundingBox(double t0, double t1, out AABB box) { return(_source.BoundingBox(t0, t1, out box)); }
public bool BoundingBox(double t0, double t1, out AABB box) { return(_boundary.BoundingBox(t0, t1, out box)); }
public static BoundingBox GetGenericBoundingBox(this IHitable hitable) { hitable.BoundingBox(float.MinValue, float.MaxValue, out BoundingBox bb); return(bb); }