예제 #1
0
            static std::vector<NearestPhoton>::iterator nearest(std::vector<Photon>::const_iterator begin, std::vector<Photon>::const_iterator end, Segment3f const& bound, Point3f const& position, std::vector<NearestPhoton>::iterator nearestBegin, std::vector<NearestPhoton>::iterator nearestNext, std::vector<NearestPhoton>::iterator nearestEnd) {
                if (begin == end) {
                    return nearestNext;
                }
                
                std::vector<Photon>::const_iterator median = begin + (end - begin) / 2;
                float medianSqrDistance = sqrDistance(median->position, position);

                if (nearestNext == nearestEnd) {
                    if (medianSqrDistance < nearestBegin->sqrDistance) {
                        std::pop_heap(nearestBegin, nearestNext--, SqrDistanceLess());
                        nearestNext->photon = median;
                        nearestNext->sqrDistance = medianSqrDistance;
                        std::push_heap(nearestBegin, ++nearestNext, SqrDistanceLess());
                    }
                } else {
                    nearestNext->photon = median;
                    nearestNext->sqrDistance = medianSqrDistance;
                    std::push_heap(nearestBegin, ++nearestNext, SqrDistanceLess());
                }

                int splitAxis = maxAxis(bound);
                if (position[splitAxis] <= median->position[splitAxis]) {
                    Segment3f belowBound = bound;
                    belowBound.max[splitAxis] = median->position[splitAxis];
                    nearestNext = nearest(begin, median, belowBound, position, nearestBegin, nearestNext, nearestEnd);
                } else {
                    Segment3f aboveBound = bound;
                    aboveBound.min[splitAxis] = median->position[splitAxis];
                    nearestNext = nearest(median + 1, end, aboveBound, position, nearestBegin, nearestNext, nearestEnd);
                }

                if (nearestNext != nearestEnd || sqr(median->position[splitAxis] - position[splitAxis]) < nearestBegin->sqrDistance) {
                    if (position[splitAxis] <= median->position[splitAxis]) {
                        Segment3f aboveBound = bound;
                        aboveBound.min[splitAxis] = median->position[splitAxis];
                        nearestNext = nearest(median + 1, end, aboveBound, position, nearestBegin, nearestNext, nearestEnd);
                    } else {
                        Segment3f belowBound = bound;
                        belowBound.max[splitAxis] = median->position[splitAxis];
                        nearestNext = nearest(begin, median, belowBound, position, nearestBegin, nearestNext, nearestEnd);
                    }
                }
                return nearestNext;
            }
예제 #2
0
 void buildLevelOnSubtree(int level, int subtree, std::vector<Photon>::iterator begin, std::vector<Photon>::iterator end, Segment3f const& bound) {
     if (begin == end) {
         return;
     }
     int splitAxis = maxAxis(bound);
     if (level == 0) {
         std::sort(begin, end, [=](Photon const& a, Photon const& b) {
             return a.position[splitAxis] < b.position[splitAxis];
         });
         return;
     }
     std::vector<Photon>::iterator median = begin + (end - begin) / 2;
     int mask = 1 << (level - 1);
     if ((subtree & mask) == 0) {
         Segment3f belowBound = bound;
         belowBound.max[splitAxis] = median->position[splitAxis];
         buildLevelOnSubtree(level - 1, subtree & ~mask, begin, median, belowBound);
     } else {
         Segment3f aboveBound = bound;
         aboveBound.min[splitAxis] = median->position[splitAxis];
         buildLevelOnSubtree(level - 1, subtree & ~mask, median + 1, end, aboveBound);
     }
 }
예제 #3
0
 /**
  * Get the maximum component in the vector (according to signed comparison). To compare absolute values, use maxAbs()
  * instead.
  */
 T const & max() const { return values[maxAxis()]; }
예제 #4
0
 int maxAxis(Segment3<T> const& segment) {
     return maxAxis(extent(segment));
 }