/// Returns true if any part of the two bounding boxes overlap. public bool Overlaps(BBox b2) { var x = Max.X >= b2.Min.X && Min.X <= b2.Max.X; var y = Max.Y >= b2.Min.Y && Min.Y <= b2.Max.Y; var z = Max.Z >= b2.Min.Z && Min.Z <= b2.Max.Z; return x && y && z; }
public Scene(Primitive aggregate, IEnumerable<Light> lights, VolumeRegion volumeRegion) { _aggregate = aggregate; _lights = lights; _volumeRegion = volumeRegion; _worldBound = aggregate.WorldBound; if (volumeRegion != null) _worldBound = BBox.Union(_worldBound, volumeRegion.WorldBound); }
public BBox TransformBBox(BBox b) { var ret = BBox.FromPoint(TransformPoint(new Point(b.Min.X, b.Min.Y, b.Min.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Max.X, b.Min.Y, b.Min.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Min.X, b.Max.Y, b.Min.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Min.X, b.Min.Y, b.Max.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Min.X, b.Max.Y, b.Max.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Max.X, b.Max.Y, b.Min.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Max.X, b.Min.Y, b.Max.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Max.X, b.Max.Y, b.Max.Z))); return(ret); }
public BBox MotionBounds(BBox b, bool useInverse) { if (!_actuallyAnimated) { return(Transform.Invert(_startTransform).TransformBBox(b)); } BBox ret = BBox.Empty; const int nSteps = 128; for (int i = 0; i < nSteps; ++i) { Transform t; float time = MathUtility.Lerp(i / (float)(nSteps - 1), _startTime, _endTime); Interpolate(time, out t); if (useInverse) { t = Transform.Invert(t); } ret = BBox.Union(ret, t.TransformBBox(b)); } return(ret); }
public BBox MotionBounds(BBox b, bool useInverse) { if (!_actuallyAnimated) return Transform.Invert(_startTransform).TransformBBox(b); BBox ret = BBox.Empty; const int nSteps = 128; for (int i = 0; i < nSteps; ++i) { Transform t; float time = MathUtility.Lerp(i / (float) (nSteps - 1), _startTime, _endTime); Interpolate(time, out t); if (useInverse) t = Transform.Invert(t); ret = BBox.Union(ret, t.TransformBBox(b)); } return ret; }
public GridAccelerator(IEnumerable<Primitive> primitives, bool refineImmediately) { // Initialize _primitives_ with primitives for grid _primitives = refineImmediately ? primitives.SelectMany(prim => prim.FullyRefine()).ToArray() : primitives.ToArray(); // Compute bounds and choose grid resolution _bounds = BBox.Empty; for (var i = 0; i < _primitives.Length; ++i) _bounds = BBox.Union(_bounds, _primitives[i].WorldBound); Vector delta = _bounds.Max - _bounds.Min; // Find _voxelsPerUnitDist_ for grid int maxAxis = _bounds.MaximumExtent(); float invMaxWidth = 1.0f / delta[maxAxis]; Debug.Assert(invMaxWidth > 0.0f); float cubeRoot = 3.0f * MathUtility.Pow(_primitives.Length, 1.0f / 3.0f); float voxelsPerUnitDist = cubeRoot * invMaxWidth; _numVoxels = new int[3]; for (int axis = 0; axis < 3; ++axis) { _numVoxels[axis] = MathUtility.Round(delta[axis] * voxelsPerUnitDist); _numVoxels[axis] = MathUtility.Clamp(_numVoxels[axis], 1, 64); } // Compute voxel widths and allocate voxels for (int axis = 0; axis < 3; ++axis) { _width[axis] = delta[axis] / _numVoxels[axis]; _inverseWidth[axis] = (_width[axis] == 0.0f) ? 0.0f : 1.0f / _width[axis]; } int nv = _numVoxels[0] * _numVoxels[1] * _numVoxels[2]; _voxels = new GridVoxel[nv]; // Add primitives to grid voxels for (var i = 0; i < _primitives.Length; ++i) { // Find voxel extent of primitive BBox pb = _primitives[i].WorldBound; int[] vmin = new int[3], vmax = new int[3]; for (int axis = 0; axis < 3; ++axis) { vmin[axis] = PosToVoxel(ref pb.Min, axis); vmax[axis] = PosToVoxel(ref pb.Max, axis); } // Add primitive to overlapping voxels for (int z = vmin[2]; z <= vmax[2]; ++z) for (int y = vmin[1]; y <= vmax[1]; ++y) for (int x = vmin[0]; x <= vmax[0]; ++x) { int o = Offset(x, y, z); if (_voxels[o] == null) { // Allocate new voxel and store primitive in it _voxels[o] = new GridVoxel(_primitives[i]); } else { // Add primitive to already-allocated voxel _voxels[o].AddPrimitive(_primitives[i]); } } } }
/// Creates a new bounding box padded by the given amount. public static BBox Expand(BBox b, float delta) { return new BBox( b.Min - new Vector(delta, delta, delta), b.Max + new Vector(delta, delta, delta)); }
/// Creates a new bounding box large enough to contain the given two /// bounding boxes. public static BBox Union(BBox b1, BBox b2) { var min = new Point(Math.Min(b1.Min.X, b2.Min.X), Math.Min(b1.Min.Y, b2.Min.Y), Math.Min(b1.Min.Z, b2.Min.Z)); var max = new Point(Math.Max(b1.Max.X, b2.Max.X), Math.Max(b1.Max.Y, b2.Max.Y), Math.Max(b1.Max.Z, b2.Max.Z)); return new BBox(min, max); }
/// Creates a new bounding box large enough to contain both the original /// bounding box and the given point. public static BBox Union(BBox b, Point p) { var min = new Point(Math.Min(b.Min.X, p.X), Math.Min(b.Min.Y, p.Y), Math.Min(b.Min.Z, p.Z)); var max = new Point(Math.Max(b.Max.X, p.X), Math.Max(b.Max.Y, p.Y), Math.Max(b.Max.Z, p.Z)); return new BBox(min, max); }
public AggregateVolume(IEnumerable<VolumeRegion> regions) { _regions = regions.ToList(); _worldBound = BBox.Union(_regions.Select(x => x.WorldBound)); }
public BBox TransformBBox(BBox b) { var ret = BBox.FromPoint(TransformPoint(new Point(b.Min.X, b.Min.Y, b.Min.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Max.X, b.Min.Y, b.Min.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Min.X, b.Max.Y, b.Min.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Min.X, b.Min.Y, b.Max.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Min.X, b.Max.Y, b.Max.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Max.X, b.Max.Y, b.Min.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Max.X, b.Min.Y, b.Max.Z))); ret = BBox.Union(ret, TransformPoint(new Point(b.Max.X, b.Max.Y, b.Max.Z))); return ret; }
/// Creates a new bounding box padded by the given amount. public static BBox Expand(BBox b, float delta) { return(new BBox( b.Min - new Vector(delta, delta, delta), b.Max + new Vector(delta, delta, delta))); }