do a better job at keeping track of statistics
parent
87b82cc5e1
commit
a1ca92bda2
|
@ -28,6 +28,14 @@
|
||||||
#define MTS_KD_MINMAX_BINS 32 ///< Min-max bin count
|
#define MTS_KD_MINMAX_BINS 32 ///< Min-max bin count
|
||||||
#define MTS_KD_MIN_ALLOC 128 ///< Allocate memory in 128 KB chunks
|
#define MTS_KD_MIN_ALLOC 128 ///< Allocate memory in 128 KB chunks
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#define KDAssert(expr) Assert(expr)
|
||||||
|
#define KDAssertEx(expr, text) AssertEx(expr, text)
|
||||||
|
#else
|
||||||
|
#define KDAssert(expr)
|
||||||
|
#define KDAssertEx(expr, text)
|
||||||
|
#endif
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,7 +151,8 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SLog(EError, "OrderedChunkAllocator: Internal error in shrinkAllocation");
|
SLog(EError, "OrderedChunkAllocator: Internal error while"
|
||||||
|
" releasing memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t getChunkCount() const { return m_chunks.size(); }
|
inline size_t getChunkCount() const { return m_chunks.size(); }
|
||||||
|
@ -279,8 +288,9 @@ public:
|
||||||
m_clip = true;
|
m_clip = true;
|
||||||
m_stopPrims = 1;
|
m_stopPrims = 1;
|
||||||
m_maxBadRefines = 2;
|
m_maxBadRefines = 2;
|
||||||
m_exactDepth = 1;
|
m_exactPrimThreshold = 1024;
|
||||||
m_maxDepth = 100;
|
m_maxDepth = 0;
|
||||||
|
m_retract = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -323,8 +333,9 @@ public:
|
||||||
Log(EDebug, " Scene bounding box (min) : %s", m_aabb.min.toString().c_str());
|
Log(EDebug, " Scene bounding box (min) : %s", m_aabb.min.toString().c_str());
|
||||||
Log(EDebug, " Scene bounding box (max) : %s", m_aabb.max.toString().c_str());
|
Log(EDebug, " Scene bounding box (max) : %s", m_aabb.max.toString().c_str());
|
||||||
Log(EDebug, " Min-max bins : %i", MTS_KD_MINMAX_BINS);
|
Log(EDebug, " Min-max bins : %i", MTS_KD_MINMAX_BINS);
|
||||||
Log(EDebug, " Greedy SAH optimization : >= level %i", m_exactDepth);
|
Log(EDebug, " Greedy SAH optimization : <= %i primitives", m_exactPrimThreshold);
|
||||||
Log(EDebug, " Perfect splits : %s", m_clip ? "yes" : "no");
|
Log(EDebug, " Perfect splits : %s", m_clip ? "yes" : "no");
|
||||||
|
Log(EDebug, " Retract bad splits : %s", m_retract ? "yes" : "no");
|
||||||
Log(EDebug, "");
|
Log(EDebug, "");
|
||||||
|
|
||||||
size_type procCount = getProcessorCount();
|
size_type procCount = getProcessorCount();
|
||||||
|
@ -342,8 +353,8 @@ public:
|
||||||
m_aabb, m_aabb, indices, primCount, true, 0);
|
m_aabb, m_aabb, indices, primCount, true, 0);
|
||||||
ctx.leftAlloc.release(indices);
|
ctx.leftAlloc.release(indices);
|
||||||
|
|
||||||
Assert(ctx.leftAlloc.getUsed() == 0);
|
KDAssert(ctx.leftAlloc.getUsed() == 0);
|
||||||
Assert(ctx.rightAlloc.getUsed() == 0);
|
KDAssert(ctx.rightAlloc.getUsed() == 0);
|
||||||
|
|
||||||
m_interface.done = true;
|
m_interface.done = true;
|
||||||
m_interface.cond->broadcast();
|
m_interface.cond->broadcast();
|
||||||
|
@ -738,14 +749,14 @@ protected:
|
||||||
* accurate SAH-based optimizier.
|
* accurate SAH-based optimizier.
|
||||||
*/
|
*/
|
||||||
boost::tuple<EdgeEvent *, EdgeEvent *> createEventList(
|
boost::tuple<EdgeEvent *, EdgeEvent *> createEventList(
|
||||||
OrderedChunkAllocator &alloc, index_type *prims, size_type primCount) {
|
OrderedChunkAllocator &alloc, const AABB &nodeAABB, index_type *prims, size_type primCount) {
|
||||||
size_type initialSize = primCount * 6;
|
size_type initialSize = primCount * 6;
|
||||||
EdgeEvent *eventStart = alloc.allocate<EdgeEvent>(initialSize);
|
EdgeEvent *eventStart = alloc.allocate<EdgeEvent>(initialSize);
|
||||||
EdgeEvent *eventEnd = eventStart;
|
EdgeEvent *eventEnd = eventStart;
|
||||||
|
|
||||||
for (size_type i=0; i<primCount; ++i) {
|
for (size_type i=0; i<primCount; ++i) {
|
||||||
index_type index = prims[i];
|
index_type index = prims[i];
|
||||||
AABB aabb = downCast()->getAABB(index);
|
AABB aabb = downCast()->getClippedAABB(index, nodeAABB);
|
||||||
|
|
||||||
for (int axis=0; axis<3; ++axis) {
|
for (int axis=0; axis<3; ++axis) {
|
||||||
float min = (float) aabb.min[axis], max = (float) aabb.max[axis];
|
float min = (float) aabb.min[axis], max = (float) aabb.max[axis];
|
||||||
|
@ -818,7 +829,7 @@ protected:
|
||||||
Float buildTreeMinMax(BuildContext &ctx, unsigned int depth, KDNode *node,
|
Float buildTreeMinMax(BuildContext &ctx, unsigned int depth, KDNode *node,
|
||||||
const AABB &nodeAABB, const AABB &tightAABB, index_type *indices,
|
const AABB &nodeAABB, const AABB &tightAABB, index_type *indices,
|
||||||
size_type primCount, bool isLeftChild, size_type badRefines) {
|
size_type primCount, bool isLeftChild, size_type badRefines) {
|
||||||
Assert(nodeAABB.contains(tightAABB));
|
KDAssert(nodeAABB.contains(tightAABB));
|
||||||
|
|
||||||
Float leafCost = primCount * m_intersectionCost;
|
Float leafCost = primCount * m_intersectionCost;
|
||||||
if (primCount <= m_stopPrims || depth >= m_maxDepth) {
|
if (primCount <= m_stopPrims || depth >= m_maxDepth) {
|
||||||
|
@ -826,10 +837,10 @@ protected:
|
||||||
return leafCost;
|
return leafCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth == m_exactDepth) {
|
if (primCount <= m_exactPrimThreshold) {
|
||||||
OrderedChunkAllocator &alloc = isLeftChild ? ctx.leftAlloc : ctx.rightAlloc;
|
OrderedChunkAllocator &alloc = isLeftChild ? ctx.leftAlloc : ctx.rightAlloc;
|
||||||
boost::tuple<EdgeEvent *, EdgeEvent *> events
|
boost::tuple<EdgeEvent *, EdgeEvent *> events
|
||||||
= createEventList(alloc, indices, primCount);
|
= createEventList(alloc, nodeAABB, indices, primCount);
|
||||||
|
|
||||||
std::sort(boost::get<0>(events), boost::get<1>(events), EdgeEventOrdering());
|
std::sort(boost::get<0>(events), boost::get<1>(events), EdgeEventOrdering());
|
||||||
|
|
||||||
|
@ -888,6 +899,7 @@ protected:
|
||||||
initialIndirectionTableSize);
|
initialIndirectionTableSize);
|
||||||
m_indirectionTable.push_back(children);
|
m_indirectionTable.push_back(children);
|
||||||
}
|
}
|
||||||
|
ctx.innerNodeCount++;
|
||||||
|
|
||||||
AABB childAABB(nodeAABB);
|
AABB childAABB(nodeAABB);
|
||||||
childAABB.max[bestSplit.axis] = bestSplit.pos;
|
childAABB.max[bestSplit.axis] = bestSplit.pos;
|
||||||
|
@ -921,9 +933,8 @@ protected:
|
||||||
/* Final decision */
|
/* Final decision */
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
|
|
||||||
if (finalSAHCost < primCount * m_intersectionCost) {
|
if (!m_retract || finalSAHCost < primCount * m_intersectionCost) {
|
||||||
ctx.expTraversalSteps += nodeAABB.getSurfaceArea();
|
ctx.expTraversalSteps += nodeAABB.getSurfaceArea();
|
||||||
ctx.innerNodeCount++;
|
|
||||||
return finalSAHCost;
|
return finalSAHCost;
|
||||||
} else {
|
} else {
|
||||||
/* In the end, splitting didn't help to reduce the SAH cost.
|
/* In the end, splitting didn't help to reduce the SAH cost.
|
||||||
|
@ -1027,7 +1038,7 @@ protected:
|
||||||
|
|
||||||
/* Keep track of the beginning of dimensions */
|
/* Keep track of the beginning of dimensions */
|
||||||
if (event < eventEnd && event->axis != axis) {
|
if (event < eventEnd && event->axis != axis) {
|
||||||
Assert(eventsByAxisCtr < 3);
|
KDAssert(eventsByAxisCtr < 3);
|
||||||
eventsByAxis[eventsByAxisCtr++] = event;
|
eventsByAxis[eventsByAxisCtr++] = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1073,7 +1084,7 @@ protected:
|
||||||
} else {
|
} else {
|
||||||
/* When primitive clipping is active, this should
|
/* When primitive clipping is active, this should
|
||||||
never happen! */
|
never happen! */
|
||||||
AssertEx(!m_clip, "Internal error: edge event is out of bounds");
|
KDAssertEx(!m_clip, "Internal error: edge event is out of bounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The split plane is moved past 't'. All prims,
|
/* The split plane is moved past 't'. All prims,
|
||||||
|
@ -1084,14 +1095,14 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity checks. Everything should now be left of the split plane */
|
/* Sanity checks. Everything should now be left of the split plane */
|
||||||
Assert(numRight[0] == 0 && numLeft[0] == primCount &&
|
KDAssert(numRight[0] == 0 && numLeft[0] == primCount &&
|
||||||
numRight[1] == 0 && numLeft[1] == primCount &&
|
numRight[1] == 0 && numLeft[1] == primCount &&
|
||||||
numRight[2] == 0 && numLeft[2] == primCount);
|
numRight[2] == 0 && numLeft[2] == primCount);
|
||||||
|
|
||||||
Assert(eventsByAxis[1]->axis == 1 && (eventsByAxis[1]-1)->axis == 0);
|
KDAssert(eventsByAxis[1]->axis == 1 && (eventsByAxis[1]-1)->axis == 0);
|
||||||
Assert(eventsByAxis[2]->axis == 2 && (eventsByAxis[2]-1)->axis == 1);
|
KDAssert(eventsByAxis[2]->axis == 2 && (eventsByAxis[2]-1)->axis == 1);
|
||||||
|
|
||||||
Assert(bestSplit.sahCost != std::numeric_limits<Float>::infinity());
|
KDAssert(bestSplit.sahCost != std::numeric_limits<Float>::infinity());
|
||||||
|
|
||||||
/* "Bad refines" heuristic from PBRT */
|
/* "Bad refines" heuristic from PBRT */
|
||||||
if (bestSplit.sahCost >= leafCost) {
|
if (bestSplit.sahCost >= leafCost) {
|
||||||
|
@ -1121,7 +1132,7 @@ protected:
|
||||||
if (event->type == EdgeEvent::EEdgeEnd && event->pos <= bestSplit.pos) {
|
if (event->type == EdgeEvent::EEdgeEnd && event->pos <= bestSplit.pos) {
|
||||||
/* The primitive's interval ends before or on the split plane
|
/* The primitive's interval ends before or on the split plane
|
||||||
-> classify to the left side */
|
-> classify to the left side */
|
||||||
Assert(storage.get(event->index) == EBothSides);
|
KDAssert(storage.get(event->index) == EBothSides);
|
||||||
storage.set(event->index, ELeftSide);
|
storage.set(event->index, ELeftSide);
|
||||||
primsBoth--;
|
primsBoth--;
|
||||||
primsLeft++;
|
primsLeft++;
|
||||||
|
@ -1129,7 +1140,7 @@ protected:
|
||||||
&& event->pos >= bestSplit.pos) {
|
&& event->pos >= bestSplit.pos) {
|
||||||
/* The primitive's interval starts after or on the split plane
|
/* The primitive's interval starts after or on the split plane
|
||||||
-> classify to the right side */
|
-> classify to the right side */
|
||||||
Assert(storage.get(event->index) == EBothSides);
|
KDAssert(storage.get(event->index) == EBothSides);
|
||||||
storage.set(event->index, ERightSide);
|
storage.set(event->index, ERightSide);
|
||||||
primsBoth--;
|
primsBoth--;
|
||||||
primsRight++;
|
primsRight++;
|
||||||
|
@ -1137,7 +1148,7 @@ protected:
|
||||||
/* If the planar primitive is not on the split plane, the
|
/* If the planar primitive is not on the split plane, the
|
||||||
classification is easy. Otherwise, place it on the side with
|
classification is easy. Otherwise, place it on the side with
|
||||||
the better SAH score */
|
the better SAH score */
|
||||||
Assert(storage.get(event->index) == EBothSides);
|
KDAssert(storage.get(event->index) == EBothSides);
|
||||||
if (event->pos < bestSplit.pos || (event->pos == bestSplit.pos
|
if (event->pos < bestSplit.pos || (event->pos == bestSplit.pos
|
||||||
&& bestSplit.planarLeft)) {
|
&& bestSplit.planarLeft)) {
|
||||||
storage.set(event->index, ELeftSide);
|
storage.set(event->index, ELeftSide);
|
||||||
|
@ -1149,15 +1160,15 @@ protected:
|
||||||
primsBoth--;
|
primsBoth--;
|
||||||
primsRight++;
|
primsRight++;
|
||||||
} else {
|
} else {
|
||||||
AssertEx(false, "Internal error!");
|
KDAssertEx(false, "Internal error!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some sanity checks */
|
/* Some sanity checks */
|
||||||
Assert(primsLeft + primsRight + primsBoth == primCount);
|
KDAssert(primsLeft + primsRight + primsBoth == primCount);
|
||||||
Assert(primsLeft + primsBoth == bestSplit.numLeft);
|
KDAssert(primsLeft + primsBoth == bestSplit.numLeft);
|
||||||
Assert(primsRight + primsBoth == bestSplit.numRight);
|
KDAssert(primsRight + primsBoth == bestSplit.numRight);
|
||||||
|
|
||||||
OrderedChunkAllocator &leftAlloc = ctx.leftAlloc,
|
OrderedChunkAllocator &leftAlloc = ctx.leftAlloc,
|
||||||
&rightAlloc = ctx.rightAlloc;
|
&rightAlloc = ctx.rightAlloc;
|
||||||
|
@ -1207,11 +1218,11 @@ protected:
|
||||||
generate new events for each side */
|
generate new events for each side */
|
||||||
const index_type index = event->index;
|
const index_type index = event->index;
|
||||||
|
|
||||||
AABB clippedLeft = downCast()->clip(index, leftNodeAABB);
|
AABB clippedLeft = downCast()->getClippedAABB(index, leftNodeAABB);
|
||||||
AABB clippedRight = downCast()->clip(index, rightNodeAABB);
|
AABB clippedRight = downCast()->getClippedAABB(index, rightNodeAABB);
|
||||||
|
|
||||||
Assert(leftNodeAABB.contains(clippedLeft));
|
KDAssert(leftNodeAABB.contains(clippedLeft));
|
||||||
Assert(rightNodeAABB.contains(clippedRight));
|
KDAssert(rightNodeAABB.contains(clippedRight));
|
||||||
|
|
||||||
if (clippedLeft.isValid() && clippedLeft.getSurfaceArea() > 0) {
|
if (clippedLeft.isValid() && clippedLeft.getSurfaceArea() > 0) {
|
||||||
for (int axis=0; axis<3; ++axis) {
|
for (int axis=0; axis<3; ++axis) {
|
||||||
|
@ -1249,10 +1260,10 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(leftEventsTempEnd - leftEventsTempStart <= primsLeft * 6);
|
KDAssert(leftEventsTempEnd - leftEventsTempStart <= primsLeft * 6);
|
||||||
Assert(rightEventsTempEnd - rightEventsTempStart <= primsRight * 6);
|
KDAssert(rightEventsTempEnd - rightEventsTempStart <= primsRight * 6);
|
||||||
Assert(newEventsLeftEnd - newEventsLeftStart <= primsBoth * 6);
|
KDAssert(newEventsLeftEnd - newEventsLeftStart <= primsBoth * 6);
|
||||||
Assert(newEventsRightEnd - newEventsRightStart <= primsBoth * 6);
|
KDAssert(newEventsRightEnd - newEventsRightStart <= primsBoth * 6);
|
||||||
ctx.pruned += prunedLeft + prunedRight;
|
ctx.pruned += prunedLeft + prunedRight;
|
||||||
|
|
||||||
/* Sort the events from overlapping prims */
|
/* Sort the events from overlapping prims */
|
||||||
|
@ -1290,8 +1301,8 @@ protected:
|
||||||
*rightEventsEnd++ = *event;
|
*rightEventsEnd++ = *event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Assert(leftEventsEnd - leftEventsStart <= bestSplit.numLeft * 6);
|
KDAssert(leftEventsEnd - leftEventsStart <= bestSplit.numLeft * 6);
|
||||||
Assert(rightEventsEnd - rightEventsStart <= bestSplit.numRight * 6);
|
KDAssert(rightEventsEnd - rightEventsStart <= bestSplit.numRight * 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shrink the edge event storage now that we know exactly how
|
/* Shrink the edge event storage now that we know exactly how
|
||||||
|
@ -1317,6 +1328,7 @@ protected:
|
||||||
initialIndirectionTableSize);
|
initialIndirectionTableSize);
|
||||||
m_indirectionTable.push_back(children);
|
m_indirectionTable.push_back(children);
|
||||||
}
|
}
|
||||||
|
ctx.innerNodeCount++;
|
||||||
|
|
||||||
Float leftSAHCost = buildTreeSAH(ctx, depth+1, children,
|
Float leftSAHCost = buildTreeSAH(ctx, depth+1, children,
|
||||||
leftNodeAABB, leftEventsStart, leftEventsEnd,
|
leftNodeAABB, leftEventsStart, leftEventsEnd,
|
||||||
|
@ -1344,9 +1356,8 @@ protected:
|
||||||
/* Final decision */
|
/* Final decision */
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
|
|
||||||
if (finalSAHCost < primCount * m_intersectionCost) {
|
if (!m_retract || finalSAHCost < primCount * m_intersectionCost) {
|
||||||
ctx.expTraversalSteps += nodeAABB.getSurfaceArea();
|
ctx.expTraversalSteps += nodeAABB.getSurfaceArea();
|
||||||
ctx.innerNodeCount++;
|
|
||||||
return finalSAHCost;
|
return finalSAHCost;
|
||||||
} else {
|
} else {
|
||||||
/* In the end, splitting didn't help to reduce the SAH cost.
|
/* In the end, splitting didn't help to reduce the SAH cost.
|
||||||
|
@ -1367,9 +1378,13 @@ protected:
|
||||||
*/
|
*/
|
||||||
void tearUp(BuildContext &ctx, KDNode *node) {
|
void tearUp(BuildContext &ctx, KDNode *node) {
|
||||||
if (node->isLeaf()) {
|
if (node->isLeaf()) {
|
||||||
|
if (node->getPrimStart() != node->getPrimEnd())
|
||||||
|
ctx.nonemptyLeafNodeCount--;
|
||||||
|
ctx.leafNodeCount--;
|
||||||
/// XXX Create primitive list for leaf
|
/// XXX Create primitive list for leaf
|
||||||
} else {
|
} else {
|
||||||
KDNode *left;
|
KDNode *left;
|
||||||
|
ctx.innerNodeCount--;
|
||||||
if (EXPECT_TAKEN(!node->isIndirection()))
|
if (EXPECT_TAKEN(!node->isIndirection()))
|
||||||
left = node->getLeft();
|
left = node->getLeft();
|
||||||
else
|
else
|
||||||
|
@ -1472,7 +1487,7 @@ protected:
|
||||||
binIdx++;
|
binIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(candidate.sahCost != std::numeric_limits<Float>::infinity());
|
KDAssert(candidate.sahCost != std::numeric_limits<Float>::infinity());
|
||||||
|
|
||||||
const int axis = candidate.axis;
|
const int axis = candidate.axis;
|
||||||
const float min = m_aabb.min[axis];
|
const float min = m_aabb.min[axis];
|
||||||
|
@ -1570,18 +1585,18 @@ protected:
|
||||||
const AABB aabb = derived->getAABB(primIndex);
|
const AABB aabb = derived->getAABB(primIndex);
|
||||||
|
|
||||||
if (aabb.max[axis] <= splitPos) {
|
if (aabb.max[axis] <= splitPos) {
|
||||||
Assert(numLeft < split.numLeft);
|
KDAssert(numLeft < split.numLeft);
|
||||||
leftBounds.expandBy(aabb);
|
leftBounds.expandBy(aabb);
|
||||||
leftIndices[numLeft++] = primIndex;
|
leftIndices[numLeft++] = primIndex;
|
||||||
} else if (aabb.min[axis] > splitPos) {
|
} else if (aabb.min[axis] > splitPos) {
|
||||||
Assert(numRight < split.numRight);
|
KDAssert(numRight < split.numRight);
|
||||||
rightBounds.expandBy(aabb);
|
rightBounds.expandBy(aabb);
|
||||||
rightIndices[numRight++] = primIndex;
|
rightIndices[numRight++] = primIndex;
|
||||||
} else {
|
} else {
|
||||||
leftBounds.expandBy(aabb);
|
leftBounds.expandBy(aabb);
|
||||||
rightBounds.expandBy(aabb);
|
rightBounds.expandBy(aabb);
|
||||||
Assert(numLeft < split.numLeft);
|
KDAssert(numLeft < split.numLeft);
|
||||||
Assert(numRight < split.numRight);
|
KDAssert(numRight < split.numRight);
|
||||||
leftIndices[numLeft++] = primIndex;
|
leftIndices[numLeft++] = primIndex;
|
||||||
rightIndices[numRight++] = primIndex;
|
rightIndices[numRight++] = primIndex;
|
||||||
}
|
}
|
||||||
|
@ -1590,8 +1605,8 @@ protected:
|
||||||
leftBounds.clip(m_aabb);
|
leftBounds.clip(m_aabb);
|
||||||
rightBounds.clip(m_aabb);
|
rightBounds.clip(m_aabb);
|
||||||
|
|
||||||
Assert(numLeft == split.numLeft);
|
KDAssert(numLeft == split.numLeft);
|
||||||
Assert(numRight == split.numRight);
|
KDAssert(numRight == split.numRight);
|
||||||
|
|
||||||
/// Release the unused memory regions
|
/// Release the unused memory regions
|
||||||
if (isLeftChild)
|
if (isLeftChild)
|
||||||
|
@ -1652,12 +1667,12 @@ private:
|
||||||
Float m_traversalCost;
|
Float m_traversalCost;
|
||||||
Float m_intersectionCost;
|
Float m_intersectionCost;
|
||||||
Float m_emptySpaceBonus;
|
Float m_emptySpaceBonus;
|
||||||
bool m_clip;
|
bool m_clip, m_retract;
|
||||||
AABB m_aabb;
|
AABB m_aabb;
|
||||||
size_type m_maxDepth;
|
size_type m_maxDepth;
|
||||||
size_type m_stopPrims;
|
size_type m_stopPrims;
|
||||||
size_type m_maxBadRefines;
|
size_type m_maxBadRefines;
|
||||||
size_type m_exactDepth;
|
size_type m_exactPrimThreshold;
|
||||||
std::vector<SAHTreeBuilder *> m_builders;
|
std::vector<SAHTreeBuilder *> m_builders;
|
||||||
BuildInterface m_interface;
|
BuildInterface m_interface;
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,7 +95,7 @@ public:
|
||||||
return m_triangles[idx].getAABB(m_vertexBuffer);
|
return m_triangles[idx].getAABB(m_vertexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AABB clip(index_type idx, const AABB &aabb) const {
|
inline AABB getClippedAABB(index_type idx, const AABB &aabb) const {
|
||||||
return m_triangles[idx].getClippedAABB(m_vertexBuffer, aabb);
|
return m_triangles[idx].getClippedAABB(m_vertexBuffer, aabb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue