cleanups
parent
84cff419f8
commit
baa41a195a
|
@ -174,7 +174,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(MTS_KD_DEBUG)
|
#if defined(MTS_KD_DEBUG)
|
||||||
/* Uh oh, allocation could not be found. Check if it has size==0 */
|
/* Uh oh, allocation could not be found. Check if it has size == 0 */
|
||||||
if (newSize == 0) {
|
if (newSize == 0) {
|
||||||
for (std::vector<Chunk>::iterator it = m_chunks.begin();
|
for (std::vector<Chunk>::iterator it = m_chunks.begin();
|
||||||
it != m_chunks.end(); ++it) {
|
it != m_chunks.end(); ++it) {
|
||||||
|
@ -476,9 +476,12 @@ public:
|
||||||
m_exactPrimThreshold = 65536;
|
m_exactPrimThreshold = 65536;
|
||||||
m_maxDepth = 0;
|
m_maxDepth = 0;
|
||||||
m_retract = true;
|
m_retract = true;
|
||||||
m_parallel = true;
|
m_parallelBuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Release all memory
|
||||||
|
*/
|
||||||
virtual ~GenericKDTree() {
|
virtual ~GenericKDTree() {
|
||||||
if (m_indices)
|
if (m_indices)
|
||||||
delete[] m_indices;
|
delete[] m_indices;
|
||||||
|
@ -486,6 +489,160 @@ public:
|
||||||
delete[] m_nodes;
|
delete[] m_nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the traversal cost used by the surface area heuristic
|
||||||
|
*/
|
||||||
|
inline void setTraversalCost(Float traversalCost) {
|
||||||
|
m_traversalCost = traversalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the traversal cost used by the surface area heuristic
|
||||||
|
*/
|
||||||
|
inline Float getTraversalCost() const {
|
||||||
|
return m_traversalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the intersection cost used by the surface area heuristic
|
||||||
|
*/
|
||||||
|
inline void setIntersectionCost(Float intersectionCost) {
|
||||||
|
m_intersectionCost = intersectionCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the intersection cost used by the surface area heuristic
|
||||||
|
*/
|
||||||
|
inline Float getIntersectionCost() const {
|
||||||
|
return m_intersectionCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the bonus factor for empty space used by the
|
||||||
|
* surface area heuristic
|
||||||
|
*/
|
||||||
|
inline void setEmptySpaceBonus(Float emptySpaceBonus) {
|
||||||
|
m_emptySpaceBonus = emptySpaceBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the bonus factor for empty space used by the
|
||||||
|
* surface area heuristic
|
||||||
|
*/
|
||||||
|
inline Float getEmptySpaceBonus() const {
|
||||||
|
return m_emptySpaceBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the maximum tree depth (0 = use heuristic)
|
||||||
|
*/
|
||||||
|
inline void setMaxDepth(size_type maxDepth) {
|
||||||
|
m_maxDepth = maxDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return maximum tree depth (0 = use heuristic)
|
||||||
|
*/
|
||||||
|
inline size_type getMaxDepth() const {
|
||||||
|
return m_maxDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Specify whether or not to use primitive clipping will
|
||||||
|
* be used in the tree construction.
|
||||||
|
*/
|
||||||
|
inline void setClip(bool clip) {
|
||||||
|
m_clip = clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return whether or not to use primitive clipping will
|
||||||
|
* be used in the tree construction.
|
||||||
|
*/
|
||||||
|
inline bool getClip() const {
|
||||||
|
return m_clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Specify whether or not bad splits can be "retracted".
|
||||||
|
*/
|
||||||
|
inline void setRetract(bool retract) {
|
||||||
|
m_retract = retract;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return whether or not bad splits can be "retracted".
|
||||||
|
*/
|
||||||
|
inline bool getRetract() const {
|
||||||
|
return m_retract;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the number of bad refines allowed to happen
|
||||||
|
* in succession before a leaf node will be created.
|
||||||
|
*/
|
||||||
|
inline void setMaxBadRefines(size_type maxBadRefines) {
|
||||||
|
m_maxBadRefines = maxBadRefines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the number of bad refines allowed to happen
|
||||||
|
* in succession before a leaf node will be created.
|
||||||
|
*/
|
||||||
|
inline size_type getMaxBadRefines() const {
|
||||||
|
return m_maxBadRefines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the number of primitives, at which recursion will
|
||||||
|
* stop when building the tree.
|
||||||
|
*/
|
||||||
|
inline void setStopPrims(size_type stopPrims) {
|
||||||
|
m_stopPrims = stopPrims;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the number of primitives, at which recursion will
|
||||||
|
* stop when building the tree.
|
||||||
|
*/
|
||||||
|
inline size_type getStopPrims() const {
|
||||||
|
return m_stopPrims;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Specify whether or not tree construction
|
||||||
|
* should run in parallel.
|
||||||
|
*/
|
||||||
|
inline void setParallelBuild(bool parallel) {
|
||||||
|
m_parallelBuild = parallel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return whether or not tree construction
|
||||||
|
* will run in parallel.
|
||||||
|
*/
|
||||||
|
inline bool getParallelBuild() const {
|
||||||
|
return m_parallelBuild;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Specify the number of primitives, at which the builder will switch
|
||||||
|
* from (approximate) Min-Max binning to the accurate O(n log n) SAH-based
|
||||||
|
* optimization method.
|
||||||
|
*/
|
||||||
|
inline void setExactPrimitiveThreshold(bool exactPrimThreshold) {
|
||||||
|
m_exactPrimThreshold = exactPrimThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the number of primitives, at which the builder will switch
|
||||||
|
* from (approximate) Min-Max binning to the accurate O(n log n) SAH-based
|
||||||
|
* optimization method.
|
||||||
|
*/
|
||||||
|
inline bool getExactPrimitiveThreshold() const {
|
||||||
|
return m_exactPrimThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Build a KD-tree over supplied geometry
|
* \brief Build a KD-tree over supplied geometry
|
||||||
*/
|
*/
|
||||||
|
@ -525,7 +682,8 @@ 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 : use for <= %i primitives", m_exactPrimThreshold);
|
Log(EDebug, " Greedy SAH optimization : use for <= %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, " Retract bad splits : %s", m_retract ? "yes" : "no");
|
||||||
Log(EDebug, " Stopping primitive count : %i", m_stopPrims);
|
Log(EDebug, " Stopping primitive count : %i", m_stopPrims);
|
||||||
|
@ -533,9 +691,9 @@ public:
|
||||||
|
|
||||||
size_type procCount = getProcessorCount();
|
size_type procCount = getProcessorCount();
|
||||||
if (procCount == 1)
|
if (procCount == 1)
|
||||||
m_parallel = false;
|
m_parallelBuild = false;
|
||||||
|
|
||||||
if (m_parallel) {
|
if (m_parallelBuild) {
|
||||||
m_builders.resize(procCount);
|
m_builders.resize(procCount);
|
||||||
for (size_type i=0; i<procCount; ++i) {
|
for (size_type i=0; i<procCount; ++i) {
|
||||||
m_builders[i] = new SAHTreeBuilder(i, this);
|
m_builders[i] = new SAHTreeBuilder(i, this);
|
||||||
|
@ -555,7 +713,7 @@ public:
|
||||||
KDAssert(ctx.leftAlloc.used() == 0);
|
KDAssert(ctx.leftAlloc.used() == 0);
|
||||||
KDAssert(ctx.rightAlloc.used() == 0);
|
KDAssert(ctx.rightAlloc.used() == 0);
|
||||||
|
|
||||||
if (m_parallel) {
|
if (m_parallelBuild) {
|
||||||
m_interface.done = true;
|
m_interface.done = true;
|
||||||
m_interface.cond->broadcast();
|
m_interface.cond->broadcast();
|
||||||
for (size_type i=0; i<m_builders.size(); ++i)
|
for (size_type i=0; i<m_builders.size(); ++i)
|
||||||
|
@ -652,7 +810,8 @@ public:
|
||||||
float split = node->getSplit();
|
float split = node->getSplit();
|
||||||
bool result = target->initInnerNode(axis, split, children - target);
|
bool result = target->initInnerNode(axis, split, children - target);
|
||||||
if (!result)
|
if (!result)
|
||||||
Log(EError, "Cannot represent relative pointer -- too many primitives?");
|
Log(EError, "Cannot represent relative pointer -- "
|
||||||
|
"too many primitives?");
|
||||||
|
|
||||||
Float tmp = aabb.min[axis];
|
Float tmp = aabb.min[axis];
|
||||||
aabb.min[axis] = split;
|
aabb.min[axis] = split;
|
||||||
|
@ -861,10 +1020,12 @@ protected:
|
||||||
leftAlloc.getChunkCount(), memString(leftAlloc.size()).c_str());
|
leftAlloc.getChunkCount(), memString(leftAlloc.size()).c_str());
|
||||||
Log(EDebug, " Right events : " SIZE_T_FMT " chunks (%s)",
|
Log(EDebug, " Right events : " SIZE_T_FMT " chunks (%s)",
|
||||||
rightAlloc.getChunkCount(), memString(rightAlloc.size()).c_str());
|
rightAlloc.getChunkCount(), memString(rightAlloc.size()).c_str());
|
||||||
Log(EDebug, " kd-tree nodes : " SIZE_T_FMT " entries, " SIZE_T_FMT " blocks (%s)",
|
Log(EDebug, " kd-tree nodes : " SIZE_T_FMT " entries, " SIZE_T_FMT
|
||||||
nodes.size(), nodes.blockCount(), memString(nodes.capacity() * sizeof(KDNode)).c_str());
|
" blocks (%s)", nodes.size(), nodes.blockCount(),
|
||||||
Log(EDebug, " Indices : " SIZE_T_FMT " entries, " SIZE_T_FMT " blocks (%s)",
|
memString(nodes.capacity() * sizeof(KDNode)).c_str());
|
||||||
indices.size(), indices.blockCount(), memString(indices.capacity() * sizeof(index_type)).c_str());
|
Log(EDebug, " Indices : " SIZE_T_FMT " entries, " SIZE_T_FMT
|
||||||
|
" blocks (%s)", indices.size(), indices.blockCount(),
|
||||||
|
memString(indices.capacity() * sizeof(index_type)).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void accumulateStatisticsFrom(const BuildContext &ctx) {
|
void accumulateStatisticsFrom(const BuildContext &ctx) {
|
||||||
|
@ -915,7 +1076,8 @@ protected:
|
||||||
/* Bit layout:
|
/* Bit layout:
|
||||||
31 : False (inner node)
|
31 : False (inner node)
|
||||||
30 : Indirection node flag
|
30 : Indirection node flag
|
||||||
29-3 : Offset to the left child
|
29-3 : Offset to the left child
|
||||||
|
or indirection table entry
|
||||||
2-0 : Split axis
|
2-0 : Split axis
|
||||||
*/
|
*/
|
||||||
uint32_t combined;
|
uint32_t combined;
|
||||||
|
@ -972,8 +1134,11 @@ protected:
|
||||||
* they lie in different memory chunks. In this case, the node
|
* they lie in different memory chunks. In this case, the node
|
||||||
* stores an index into a globally shared pointer list.
|
* stores an index into a globally shared pointer list.
|
||||||
*/
|
*/
|
||||||
inline void initIndirectionNode(int axis, float split, uint32_t indirectionEntry) {
|
inline void initIndirectionNode(int axis, float split,
|
||||||
inner.combined = EIndirectionMask | axis | ((uint32_t) indirectionEntry << 2);
|
uint32_t indirectionEntry) {
|
||||||
|
inner.combined = EIndirectionMask
|
||||||
|
| ((uint32_t) indirectionEntry << 2)
|
||||||
|
| axis;
|
||||||
inner.split = split;
|
inner.split = split;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1069,7 +1234,8 @@ protected:
|
||||||
int badRefines = m_interface.badRefines;
|
int badRefines = m_interface.badRefines;
|
||||||
EdgeEvent *eventStart = leftAlloc.allocate<EdgeEvent>(eventCount),
|
EdgeEvent *eventStart = leftAlloc.allocate<EdgeEvent>(eventCount),
|
||||||
*eventEnd = eventStart + eventCount;
|
*eventEnd = eventStart + eventCount;
|
||||||
memcpy(eventStart, m_interface.eventStart, eventCount * sizeof(EdgeEvent));
|
memcpy(eventStart, m_interface.eventStart,
|
||||||
|
eventCount * sizeof(EdgeEvent));
|
||||||
m_interface.threadMap[node] = m_id;
|
m_interface.threadMap[node] = m_id;
|
||||||
m_interface.node = NULL;
|
m_interface.node = NULL;
|
||||||
m_interface.condJobTaken->signal();
|
m_interface.condJobTaken->signal();
|
||||||
|
@ -1110,7 +1276,8 @@ protected:
|
||||||
* accurate SAH-based optimizier.
|
* accurate SAH-based optimizier.
|
||||||
*/
|
*/
|
||||||
boost::tuple<EdgeEvent *, EdgeEvent *, size_type> createEventList(
|
boost::tuple<EdgeEvent *, EdgeEvent *, size_type> createEventList(
|
||||||
OrderedChunkAllocator &alloc, const AABB &nodeAABB, index_type *prims, size_type primCount) {
|
OrderedChunkAllocator &alloc, const AABB &nodeAABB,
|
||||||
|
index_type *prims, size_type primCount) {
|
||||||
size_type initialSize = primCount * 6, actualPrimCount = 0;
|
size_type initialSize = primCount * 6, actualPrimCount = 0;
|
||||||
EdgeEvent *eventStart = alloc.allocate<EdgeEvent>(initialSize);
|
EdgeEvent *eventStart = alloc.allocate<EdgeEvent>(initialSize);
|
||||||
EdgeEvent *eventEnd = eventStart;
|
EdgeEvent *eventEnd = eventStart;
|
||||||
|
@ -1296,11 +1463,12 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primCount <= m_exactPrimThreshold) {
|
if (primCount <= m_exactPrimThreshold) {
|
||||||
OrderedChunkAllocator &alloc = isLeftChild ? ctx.leftAlloc : ctx.rightAlloc;
|
OrderedChunkAllocator &alloc = isLeftChild
|
||||||
|
? ctx.leftAlloc : ctx.rightAlloc;
|
||||||
boost::tuple<EdgeEvent *, EdgeEvent *, size_type> events
|
boost::tuple<EdgeEvent *, EdgeEvent *, size_type> events
|
||||||
= createEventList(alloc, nodeAABB, indices, primCount);
|
= createEventList(alloc, nodeAABB, indices, primCount);
|
||||||
Float sahCost;
|
Float sahCost;
|
||||||
if (m_parallel) {
|
if (m_parallelBuild) {
|
||||||
m_interface.mutex->lock();
|
m_interface.mutex->lock();
|
||||||
m_interface.depth = depth;
|
m_interface.depth = depth;
|
||||||
m_interface.node = node;
|
m_interface.node = node;
|
||||||
|
@ -1320,10 +1488,11 @@ protected:
|
||||||
// Never tear down this subtree (return a SAH cost of -infinity)
|
// Never tear down this subtree (return a SAH cost of -infinity)
|
||||||
sahCost = -std::numeric_limits<Float>::infinity();
|
sahCost = -std::numeric_limits<Float>::infinity();
|
||||||
} else {
|
} else {
|
||||||
std::sort(boost::get<0>(events), boost::get<1>(events), EdgeEventOrdering());
|
std::sort(boost::get<0>(events), boost::get<1>(events),
|
||||||
|
EdgeEventOrdering());
|
||||||
|
|
||||||
sahCost = buildTreeSAH(ctx, depth, node, nodeAABB,
|
sahCost = buildTreeSAH(ctx, depth, node, nodeAABB,
|
||||||
boost::get<0>(events), boost::get<1>(events), boost::get<2>(events),
|
boost::get<0>(events), boost::get<1>(events), boost::get<2>(events),
|
||||||
isLeftChild, badRefines);
|
isLeftChild, badRefines);
|
||||||
}
|
}
|
||||||
alloc.release(boost::get<0>(events));
|
alloc.release(boost::get<0>(events));
|
||||||
|
@ -1572,7 +1741,8 @@ protected:
|
||||||
sahCostPlanarLeft *= m_emptySpaceBonus;
|
sahCostPlanarLeft *= m_emptySpaceBonus;
|
||||||
if (nL == 0 || nR + numPlanar == 0)
|
if (nL == 0 || nR + numPlanar == 0)
|
||||||
sahCostPlanarRight *= m_emptySpaceBonus;
|
sahCostPlanarRight *= m_emptySpaceBonus;
|
||||||
if (sahCostPlanarLeft < bestSplit.sahCost || sahCostPlanarRight < bestSplit.sahCost) {
|
if (sahCostPlanarLeft < bestSplit.sahCost ||
|
||||||
|
sahCostPlanarRight < bestSplit.sahCost) {
|
||||||
bestSplit.pos = pos;
|
bestSplit.pos = pos;
|
||||||
bestSplit.axis = axis;
|
bestSplit.axis = axis;
|
||||||
if (sahCostPlanarLeft < sahCostPlanarRight) {
|
if (sahCostPlanarLeft < sahCostPlanarRight) {
|
||||||
|
@ -1660,8 +1830,8 @@ protected:
|
||||||
storage.set(event->index, ELeftSide);
|
storage.set(event->index, ELeftSide);
|
||||||
primsBoth--;
|
primsBoth--;
|
||||||
primsLeft++;
|
primsLeft++;
|
||||||
} else if (event->pos > bestSplit.pos || (event->pos == bestSplit.pos &&
|
} else if (event->pos > bestSplit.pos
|
||||||
!bestSplit.planarLeft)) {
|
|| (event->pos == bestSplit.pos && !bestSplit.planarLeft)) {
|
||||||
storage.set(event->index, ERightSide);
|
storage.set(event->index, ERightSide);
|
||||||
primsBoth--;
|
primsBoth--;
|
||||||
primsRight++;
|
primsRight++;
|
||||||
|
@ -1701,10 +1871,11 @@ protected:
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
|
|
||||||
if (m_clip) {
|
if (m_clip) {
|
||||||
EdgeEvent *leftEventsTempStart = leftAlloc.allocate<EdgeEvent>(primsLeft * 6),
|
EdgeEvent
|
||||||
*rightEventsTempStart = rightAlloc.allocate<EdgeEvent>(primsRight * 6),
|
*leftEventsTempStart = leftAlloc.allocate<EdgeEvent>(primsLeft * 6),
|
||||||
*newEventsLeftStart = leftAlloc.allocate<EdgeEvent>(primsBoth * 6),
|
*rightEventsTempStart = rightAlloc.allocate<EdgeEvent>(primsRight * 6),
|
||||||
*newEventsRightStart = rightAlloc.allocate<EdgeEvent>(primsBoth * 6);
|
*newEventsLeftStart = leftAlloc.allocate<EdgeEvent>(primsBoth * 6),
|
||||||
|
*newEventsRightStart = rightAlloc.allocate<EdgeEvent>(primsBoth * 6);
|
||||||
|
|
||||||
EdgeEvent *leftEventsTempEnd = leftEventsTempStart,
|
EdgeEvent *leftEventsTempEnd = leftEventsTempStart,
|
||||||
*rightEventsTempEnd = rightEventsTempStart,
|
*rightEventsTempEnd = rightEventsTempStart,
|
||||||
|
@ -1732,13 +1903,17 @@ protected:
|
||||||
|
|
||||||
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) {
|
||||||
float min = (float) clippedLeft.min[axis], max = (float) clippedLeft.max[axis];
|
float min = (float) clippedLeft.min[axis],
|
||||||
|
max = (float) clippedLeft.max[axis];
|
||||||
|
|
||||||
if (min == max) {
|
if (min == max) {
|
||||||
*newEventsLeftEnd++ = EdgeEvent(EdgeEvent::EEdgePlanar, axis, min, index);
|
*newEventsLeftEnd++ = EdgeEvent(EdgeEvent::EEdgePlanar,
|
||||||
|
axis, min, index);
|
||||||
} else {
|
} else {
|
||||||
*newEventsLeftEnd++ = EdgeEvent(EdgeEvent::EEdgeStart, axis, min, index);
|
*newEventsLeftEnd++ = EdgeEvent(EdgeEvent::EEdgeStart,
|
||||||
*newEventsLeftEnd++ = EdgeEvent(EdgeEvent::EEdgeEnd, axis, max, index);
|
axis, min, index);
|
||||||
|
*newEventsLeftEnd++ = EdgeEvent(EdgeEvent::EEdgeEnd,
|
||||||
|
axis, max, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1747,13 +1922,17 @@ protected:
|
||||||
|
|
||||||
if (clippedRight.isValid() && clippedRight.getSurfaceArea() > 0) {
|
if (clippedRight.isValid() && clippedRight.getSurfaceArea() > 0) {
|
||||||
for (int axis=0; axis<3; ++axis) {
|
for (int axis=0; axis<3; ++axis) {
|
||||||
float min = (float) clippedRight.min[axis], max = (float) clippedRight.max[axis];
|
float min = (float) clippedRight.min[axis],
|
||||||
|
max = (float) clippedRight.max[axis];
|
||||||
|
|
||||||
if (min == max) {
|
if (min == max) {
|
||||||
*newEventsRightEnd++ = EdgeEvent(EdgeEvent::EEdgePlanar, axis, min, index);
|
*newEventsRightEnd++ = EdgeEvent(EdgeEvent::EEdgePlanar,
|
||||||
|
axis, min, index);
|
||||||
} else {
|
} else {
|
||||||
*newEventsRightEnd++ = EdgeEvent(EdgeEvent::EEdgeStart, axis, min, index);
|
*newEventsRightEnd++ = EdgeEvent(EdgeEvent::EEdgeStart,
|
||||||
*newEventsRightEnd++ = EdgeEvent(EdgeEvent::EEdgeEnd, axis, max, index);
|
axis, min, index);
|
||||||
|
*newEventsRightEnd++ = EdgeEvent(EdgeEvent::EEdgeEnd,
|
||||||
|
axis, max, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1922,8 +2101,10 @@ protected:
|
||||||
* invBinSize[axis]);
|
* invBinSize[axis]);
|
||||||
int maxIdx = (int) ((aabb.max[axis] - m_aabb.min[axis])
|
int maxIdx = (int) ((aabb.max[axis] - m_aabb.min[axis])
|
||||||
* invBinSize[axis]);
|
* invBinSize[axis]);
|
||||||
m_maxBins[axis * BinCount + std::max(0, std::min(maxIdx, BinCount-1))]++;
|
m_maxBins[axis * BinCount
|
||||||
m_minBins[axis * BinCount + std::max(0, std::min(minIdx, BinCount-1))]++;
|
+ std::max(0, std::min(maxIdx, BinCount-1))]++;
|
||||||
|
m_minBins[axis * BinCount
|
||||||
|
+ std::max(0, std::min(minIdx, BinCount-1))]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2025,7 +2206,8 @@ protected:
|
||||||
if (idx == leftBin && idxNext > leftBin)
|
if (idx == leftBin && idxNext > leftBin)
|
||||||
break;
|
break;
|
||||||
if (idx < leftBin && idxNext > leftBin) {
|
if (idx < leftBin && idxNext > leftBin) {
|
||||||
/* Insufficient floating point resolution -- a leaf will be created. */
|
/* Insufficient floating point resolution
|
||||||
|
-> a leaf will be created. */
|
||||||
candidate.sahCost = std::numeric_limits<Float>::infinity();
|
candidate.sahCost = std::numeric_limits<Float>::infinity();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2035,7 +2217,8 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (split <= m_aabb.min[axis] || split > m_aabb.max[axis]) {
|
if (split <= m_aabb.min[axis] || split > m_aabb.max[axis]) {
|
||||||
/* Insufficient floating point resolution -- a leaf will be created. */
|
/* Insufficient floating point resolution
|
||||||
|
-> a leaf will be created. */
|
||||||
candidate.sahCost = std::numeric_limits<Float>::infinity();
|
candidate.sahCost = std::numeric_limits<Float>::infinity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2051,7 +2234,8 @@ protected:
|
||||||
*/
|
*/
|
||||||
boost::tuple<AABB, index_type *, AABB, index_type *> partition(
|
boost::tuple<AABB, index_type *, AABB, index_type *> partition(
|
||||||
BuildContext &ctx, const Derived *derived, index_type *primIndices,
|
BuildContext &ctx, const Derived *derived, index_type *primIndices,
|
||||||
SplitCandidate &split, bool isLeftChild, Float traversalCost, Float intersectionCost) {
|
SplitCandidate &split, bool isLeftChild, Float traversalCost,
|
||||||
|
Float intersectionCost) {
|
||||||
const float splitPos = split.pos;
|
const float splitPos = split.pos;
|
||||||
const int axis = split.axis;
|
const int axis = split.axis;
|
||||||
size_type numLeft = 0, numRight = 0;
|
size_type numLeft = 0, numRight = 0;
|
||||||
|
@ -2155,7 +2339,7 @@ private:
|
||||||
Float m_traversalCost;
|
Float m_traversalCost;
|
||||||
Float m_intersectionCost;
|
Float m_intersectionCost;
|
||||||
Float m_emptySpaceBonus;
|
Float m_emptySpaceBonus;
|
||||||
bool m_clip, m_retract, m_parallel;
|
bool m_clip, m_retract, m_parallelBuild;
|
||||||
AABB m_aabb;
|
AABB m_aabb;
|
||||||
size_type m_maxDepth;
|
size_type m_maxDepth;
|
||||||
size_type m_stopPrims;
|
size_type m_stopPrims;
|
||||||
|
|
|
@ -112,7 +112,7 @@ public:
|
||||||
|
|
||||||
void test02_buildSimple() {
|
void test02_buildSimple() {
|
||||||
Properties bunnyProps("ply");
|
Properties bunnyProps("ply");
|
||||||
bunnyProps.setString("filename", "tools/tests/lucy.ply");
|
bunnyProps.setString("filename", "tools/tests/happy.ply");
|
||||||
|
|
||||||
ref<TriMesh> mesh = static_cast<TriMesh *> (PluginManager::getInstance()->
|
ref<TriMesh> mesh = static_cast<TriMesh *> (PluginManager::getInstance()->
|
||||||
createObject(TriMesh::m_theClass, bunnyProps));
|
createObject(TriMesh::m_theClass, bunnyProps));
|
||||||
|
|
Loading…
Reference in New Issue