Esempio n. 1
0
        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]);
                            }
                        }
            }
        }
Esempio n. 2
0
        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]);
                            }
                        }
                    }
                }
            }
        }