本文整理汇总了C++中BBox::MaximumExtent方法的典型用法代码示例。如果您正苦于以下问题:C++ BBox::MaximumExtent方法的具体用法?C++ BBox::MaximumExtent怎么用?C++ BBox::MaximumExtent使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BBox
的用法示例。
在下文中一共展示了BBox::MaximumExtent方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: BuildTree
void QBVHAccel::BuildTree(u_int start, u_int end, u_int *primsIndexes,
BBox *primsBboxes, Point *primsCentroids, const BBox &nodeBbox,
const BBox ¢roidsBbox, int32_t parentIndex, int32_t childIndex, int depth) {
maxDepth = (depth >= maxDepth) ? depth : maxDepth; // Set depth so we know how much stack we need later.
// Create a leaf ?
//********
if (depth > 64 || end - start <= maxPrimsPerLeaf) {
if (depth > 64) {
// LR_LOG(ctx, "Maximum recursion depth reached while constructing QBVH, forcing a leaf node");
if (end - start > 64) {
//LR_LOG(ctx, "QBVH unable to handle geometry, too many primitives in leaf");
}
}
CreateTempLeaf(parentIndex, childIndex, start, end, nodeBbox);
return;
}
int32_t currentNode = parentIndex;
int32_t leftChildIndex = childIndex;
int32_t rightChildIndex = childIndex + 1;
// Number of primitives in each bin
int bins[NB_BINS];
// Bbox of the primitives in the bin
BBox binsBbox[NB_BINS];
//--------------
// Fill in the bins, considering all the primitives when a given
// threshold is reached, else considering only a portion of the
// primitives for the binned-SAH process. Also compute the bins bboxes
// for the primitives.
for (u_int i = 0; i < NB_BINS; ++i)
bins[i] = 0;
u_int step = (end - start < fullSweepThreshold) ? 1 : skipFactor;
// Choose the split axis, taking the axis of maximum extent for the
// centroids (else weird cases can occur, where the maximum extent axis
// for the nodeBbox is an axis of 0 extent for the centroids one.).
const int axis = centroidsBbox.MaximumExtent();
// Precompute values that are constant with respect to the current
// primitive considered.
const float k0 = centroidsBbox.pMin[axis];
const float k1 = NB_BINS / (centroidsBbox.pMax[axis] - k0);
// If the bbox is a point, create a leaf, hoping there are not more
// than 64 primitives that share the same center.
if (k1 == INFINITY) {
if (end - start > 64) {}
//LR_LOG(ctx, "QBVH unable to handle geometry, too many primitives with the same centroid");
CreateTempLeaf(parentIndex, childIndex, start, end, nodeBbox);
return;
}
// Create an intermediate node if the depth indicates to do so.
// Register the split axis.
if (depth % 2 == 0) {
currentNode = CreateIntermediateNode(parentIndex, childIndex, nodeBbox);
leftChildIndex = 0;
rightChildIndex = 2;
}
for (u_int i = start; i < end; i += step) {
u_int primIndex = primsIndexes[i];
// Binning is relative to the centroids bbox and to the
// primitives' centroid.
const int binId = Min(NB_BINS - 1, Floor2Int(k1 * (primsCentroids[primIndex][axis] - k0)));
bins[binId]++;
binsBbox[binId] = Union(binsBbox[binId], primsBboxes[primIndex]);
}
//--------------
// Evaluate where to split.
// Cumulative number of primitives in the bins from the first to the
// ith, and from the last to the ith.
int nbPrimsLeft[NB_BINS];
int nbPrimsRight[NB_BINS];
// The corresponding cumulative bounding boxes.
BBox bboxesLeft[NB_BINS];
BBox bboxesRight[NB_BINS];
// The corresponding volumes.
float vLeft[NB_BINS];
float vRight[NB_BINS];
BBox currentBboxLeft, currentBboxRight;
int currentNbLeft = 0, currentNbRight = 0;
for (int i = 0; i < NB_BINS; ++i) {
//-----
// Left side
// Number of prims
currentNbLeft += bins[i];
nbPrimsLeft[i] = currentNbLeft;
//.........这里部分代码省略.........
示例2: Assert
BVHBuildNode *BVHAccel::recursiveBuild(MemoryArena &buildArena,
vector<BVHPrimitiveInfo> &buildData, uint32_t start,
uint32_t end, uint32_t *totalNodes,
vector<Reference<Primitive> > &orderedPrims) {
Assert(start != end);
(*totalNodes)++;
BVHBuildNode *node = buildArena.Alloc<BVHBuildNode>();
// Compute bounds of all primitives in BVH node
BBox bbox;
for (uint32_t i = start; i < end; ++i)
bbox = Union(bbox, buildData[i].bounds);
uint32_t nPrimitives = end - start;
if (nPrimitives == 1) {
// Create leaf _BVHBuildNode_
uint32_t firstPrimOffset = orderedPrims.size();
for (uint32_t i = start; i < end; ++i) {
uint32_t primNum = buildData[i].primitiveNumber;
orderedPrims.push_back(primitives[primNum]);
}
node->InitLeaf(firstPrimOffset, nPrimitives, bbox);
}
else {
// Compute bound of primitive centroids, choose split dimension _dim_
BBox centroidBounds;
for (uint32_t i = start; i < end; ++i)
centroidBounds = Union(centroidBounds, buildData[i].centroid);
int dim = centroidBounds.MaximumExtent();
// Partition primitives into two sets and build children
uint32_t mid = (start + end) / 2;
if (centroidBounds.pMax[dim] == centroidBounds.pMin[dim]) {
// If nPrimitives is no greater than maxPrimsInNode,
// then all the nodes can be stored in a compact bvh node.
if (nPrimitives <= maxPrimsInNode) {
// Create leaf _BVHBuildNode_
uint32_t firstPrimOffset = orderedPrims.size();
for (uint32_t i = start; i < end; ++i) {
uint32_t primNum = buildData[i].primitiveNumber;
orderedPrims.push_back(primitives[primNum]);
}
node->InitLeaf(firstPrimOffset, nPrimitives, bbox);
return node;
}
else {
// else if nPrimitives is greater than maxPrimsInNode, we
// need to split it further to guarantee each node contains
// no more than maxPrimsInNode primitives.
node->InitInterior(dim,
recursiveBuild(buildArena, buildData, start, mid,
totalNodes, orderedPrims),
recursiveBuild(buildArena, buildData, mid, end,
totalNodes, orderedPrims));
return node;
}
}
// Partition primitives based on _splitMethod_
switch (splitMethod) {
case SPLIT_MIDDLE: {
// Partition primitives through node's midpoint
float pmid = .5f * (centroidBounds.pMin[dim] + centroidBounds.pMax[dim]);
BVHPrimitiveInfo *midPtr = std::partition(&buildData[start],
&buildData[end-1]+1,
CompareToMid(dim, pmid));
mid = midPtr - &buildData[0];
if (mid != start && mid != end)
// for lots of prims with large overlapping bounding boxes, this
// may fail to partition; in that case don't break and fall through
// to SPLIT_EQUAL_COUNTS
break;
}
case SPLIT_EQUAL_COUNTS: {
// Partition primitives into equally-sized subsets
mid = (start + end) / 2;
std::nth_element(&buildData[start], &buildData[mid],
&buildData[end-1]+1, ComparePoints(dim));
break;
}
case SPLIT_SAH: default: {
// Partition primitives using approximate SAH
if (nPrimitives <= 4) {
// Partition primitives into equally-sized subsets
mid = (start + end) / 2;
std::nth_element(&buildData[start], &buildData[mid],
&buildData[end-1]+1, ComparePoints(dim));
}
else {
// Allocate _BucketInfo_ for SAH partition buckets
const int nBuckets = 12;
struct BucketInfo {
BucketInfo() { count = 0; }
int count;
BBox bounds;
};
BucketInfo buckets[nBuckets];
// Initialize _BucketInfo_ for SAH partition buckets
for (uint32_t i = start; i < end; ++i) {
int b = nBuckets *
((buildData[i].centroid[dim] - centroidBounds.pMin[dim]) /
//.........这里部分代码省略.........
示例3: BuildTree
void KDTree::BuildTree(int nodeNum, const BBox &nodeBounds,
const vector<BBox> &allPrimBounds, uint32_t *primNums,
int nPrimitives, int depth, BoundEdge *edges[3],
uint32_t *prims0, uint32_t *prims1, int badRefines) {
Assert(nodeNum == nextFreeNode);
totalNodes++;
// Get next free node from _nodes_ array
if (nextFreeNode == nAllocedNodes)
{
int nAlloc = max(2 * nAllocedNodes, 512);
KdNode *n = AllocAligned<KdNode>(nAlloc);
if (nAllocedNodes > 0)
{
memcpy(n, nodes, nAllocedNodes * sizeof(KdNode));
FreeAligned(nodes);
}
nodes = n;
nAllocedNodes = nAlloc;
}
++nextFreeNode;
// Initialize leaf node if termination criteria met
if (nPrimitives <= maxPrims || depth == 0) {
nodes[nodeNum].initLeaf(primNums, nPrimitives, arena);
return;
}
// Initialize interior node and continue recursion
// Choose split axis position for interior node
int bestAxis = -1, bestOffset = -1;
float bestCost = INFINITY;
float oldCost = isectCost * float(nPrimitives);
float totalSA = nodeBounds.SurfaceArea();
float invTotalSA = 1.f / totalSA;
Vector d = nodeBounds.pMax - nodeBounds.pMin;
// Choose which axis to split along
uint32_t axis = nodeBounds.MaximumExtent();
int retries = 0;
bool retrySplit = true;
while (retrySplit) {
retrySplit=false;
// Initialize edges for _axis_
for (int i = 0; i < nPrimitives; ++i) {
int pn = primNums[i];
const BBox &bbox = allPrimBounds[pn];
edges[axis][2*i] = BoundEdge(bbox.pMin[axis], pn, true);
edges[axis][2*i+1] = BoundEdge(bbox.pMax[axis], pn, false);
}
sort(&edges[axis][0], &edges[axis][2*nPrimitives]);
// Compute cost of all splits for _axis_ to find best
int nBelow = 0, nAbove = nPrimitives;
for (int i = 0; i < 2*nPrimitives; ++i) {
if (edges[axis][i].type == BoundEdge::END) --nAbove;
float edget = edges[axis][i].t;
if (edget > nodeBounds.pMin[axis] &&
edget < nodeBounds.pMax[axis]) {
// Compute cost for split at _i_th edge
uint32_t otherAxis0 = (axis + 1) % 3, otherAxis1 = (axis + 2) % 3;
float belowSA = 2 * (d[otherAxis0] * d[otherAxis1] +
(edget - nodeBounds.pMin[axis]) *
(d[otherAxis0] + d[otherAxis1]));
float aboveSA = 2 * (d[otherAxis0] * d[otherAxis1] +
(nodeBounds.pMax[axis] - edget) *
(d[otherAxis0] + d[otherAxis1]));
float pBelow = belowSA * invTotalSA;
float pAbove = aboveSA * invTotalSA;
float eb = (nAbove == 0 || nBelow == 0) ? emptyBonus : 0.f;
float cost = traversalCost +
isectCost * (1.f - eb) * (pBelow * nBelow + pAbove * nAbove);
// Update best split if this is lowest cost so far
if (cost < bestCost) {
bestCost = cost;
bestAxis = axis;
bestOffset = i;
}
}
if (edges[axis][i].type == BoundEdge::START) ++nBelow;
}
Assert(nBelow == nPrimitives && nAbove == 0);
// Create leaf if no good splits were found
if (bestAxis == -1 && retries < 2) {
++retries;
axis = (axis+1) % 3;
retrySplit=true;
}
}
if (bestCost > oldCost) ++badRefines;
if ((bestCost > 4.f * oldCost && nPrimitives < 16) ||
bestAxis == -1 || badRefines == 3) {
nodes[nodeNum].initLeaf(primNums, nPrimitives, arena);
return;
}
//.........这里部分代码省略.........