本文整理汇总了C++中Bounds3f类的典型用法代码示例。如果您正苦于以下问题:C++ Bounds3f类的具体用法?C++ Bounds3f怎么用?C++ Bounds3f使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Bounds3f类的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: WorldToMedium
Spectrum GridDensityMedium::Sample(const Ray &rWorld, Sampler &sampler,
MemoryArena &arena,
MediumInteraction *mi) const {
Ray ray = WorldToMedium(
Ray(rWorld.o, Normalize(rWorld.d), rWorld.tMax * rWorld.d.Length()));
// Compute $[\tmin, \tmax]$ interval of _ray_'s overlap with medium bounds
const Bounds3f b(Point3f(0, 0, 0), Point3f(1, 1, 1));
Float tMin, tMax;
if (!b.IntersectP(ray, &tMin, &tMax)) return Spectrum(1.f);
// Run delta-tracking iterations to sample a medium interaction
Float t = tMin;
while (true) {
t -= std::log(1 - sampler.Get1D()) * invMaxDensity;
if (t >= tMax) break;
if (Density(ray(t)) * invMaxDensity * sigma_t > sampler.Get1D()) {
// Populate _mi_ with medium interaction information and return
PhaseFunction *phase = ARENA_ALLOC(arena, HenyeyGreenstein)(g);
*mi = MediumInteraction(rWorld(t), -rWorld.d, rWorld.time, this,
phase);
return sigma_s / sigma_t;
}
}
return Spectrum(1.f);
}
示例2: AddBounds
//==============================
// OvrDebugLinesLocal::AddBounds
void OvrDebugLinesLocal::AddBounds( Posef const & pose, Bounds3f const & bounds, Vector4f const & color )
{
Vector3f const & mins = bounds.GetMins();
Vector3f const & maxs = bounds.GetMaxs();
Vector3f corners[8];
corners[0] = mins;
corners[7] = maxs;
corners[1] = Vector3f( mins.x, maxs.y, mins.z );
corners[2] = Vector3f( mins.x, maxs.y, maxs.z );
corners[3] = Vector3f( mins.x, mins.y, maxs.z );
corners[4] = Vector3f( maxs.x, mins.y, mins.z );
corners[5] = Vector3f( maxs.x, maxs.y, mins.z );
corners[6] = Vector3f( maxs.x, mins.y, maxs.z );
// transform points
for ( int i = 0; i < 8; ++i )
{
corners[i] = pose.Orientation.Rotate( corners[i] );
corners[i] += pose.Position;
}
AddLine( corners[0], corners[1], color, color, 1, true );
AddLine( corners[1], corners[2], color, color, 1, true );
AddLine( corners[2], corners[3], color, color, 1, true );
AddLine( corners[3], corners[0], color, color, 1, true );
AddLine( corners[7], corners[6], color, color, 1, true );
AddLine( corners[6], corners[4], color, color, 1, true );
AddLine( corners[4], corners[5], color, color, 1, true );
AddLine( corners[5], corners[7], color, color, 1, true );
AddLine( corners[0], corners[4], color, color, 1, true );
AddLine( corners[1], corners[5], color, color, 1, true );
AddLine( corners[2], corners[7], color, color, 1, true );
AddLine( corners[3], corners[6], color, color, 1, true );
}
示例3: dataBounds
Spectrum GridDensityMedium::Sample(const Ray &_ray, Sampler &sampler,
MemoryArena &arena,
MediumInteraction *mi) const {
// Transform the ray into local coordinates and determine overlap interval
// [_tMin, tMax_]
const Bounds3f dataBounds(Point3f(0.f, 0.f, 0.f), Point3f(1.f, 1.f, 1.f));
Ray ray = WorldToMedium(
Ray(_ray.o, Normalize(_ray.d), _ray.tMax * _ray.d.Length()));
Float tMin, tMax;
if (!dataBounds.IntersectP(ray, &tMin, &tMax)) return Spectrum(1.f);
tMin = std::max(tMin, (Float)0.f);
tMax = std::min(tMax, ray.tMax);
if (tMin >= tMax) return Spectrum(1.f);
// Run Delta-Tracking iterations to sample a medium interaction
Float t = tMin;
while (true) {
t -= std::log(1 - sampler.Get1D()) * invMaxDensity;
if (t >= tMax) break;
Float density = Density(ray(t));
if (density * invMaxDensity * sigma_t > sampler.Get1D()) {
// Populate _mi_ with medium interaction information and return
PhaseFunction *phase = ARENA_ALLOC(arena, HenyeyGreenstein)(g);
*mi = MediumInteraction(_ray(t), -_ray.d, _ray.time, this, phase);
return sigma_s / sigma_t;
}
}
return Spectrum(1.0f);
}
示例4: scene
SpatialLightDistribution::SpatialLightDistribution(const Scene &scene,
int maxVoxels)
: scene(scene) {
// Compute the number of voxels so that the widest scene bounding box
// dimension has maxVoxels voxels and the other dimensions have a number
// of voxels so that voxels are roughly cube shaped.
Bounds3f b = scene.WorldBound();
Vector3f diag = b.Diagonal();
Float bmax = diag[b.MaximumExtent()];
for (int i = 0; i < 3; ++i) {
nVoxels[i] = std::max(1, int(std::round(diag[i] / bmax * maxVoxels)));
// In the Lookup() method, we require that 20 or fewer bits be
// sufficient to represent each coordinate value. It's fairly hard
// to imagine that this would ever be a problem.
CHECK_LT(nVoxels[i], 1 << 20);
}
hashTableSize = 4 * nVoxels[0] * nVoxels[1] * nVoxels[2];
hashTable.reset(new HashEntry[hashTableSize]);
for (int i = 0; i < hashTableSize; ++i) {
hashTable[i].packedPos.store(invalidPackedPos);
hashTable[i].distribution.store(nullptr);
}
LOG(INFO) << "SpatialLightDistribution: scene bounds " << b <<
", voxel res (" << nVoxels[0] << ", " << nVoxels[1] << ", " <<
nVoxels[2] << ")";
}
示例5: LOG
void MoviePlayerView::OnOpen()
{
LOG( "OnOpen" );
CurViewState = VIEWSTATE_OPEN;
Cinema.SceneMgr.ClearMovie();
SeekSpeed = 0;
PlaybackPos = 0;
NextSeekTime = 0;
SetSeekIcon( SeekSpeed );
ScrubBar.SetProgress( 0.0f );
RepositionScreen = false;
MoveScreenAlpha.Set( 0, 0, 0, 0.0f );
HideUI();
Cinema.SceneMgr.LightsOff( 1.5f );
Cinema.StartMoviePlayback();
MovieTitleLabel.SetText( Cinema.GetCurrentMovie()->Title );
Bounds3f titleBounds = MovieTitleLabel.GetTextLocalBounds( Cinema.app->GetDefaultFont() ) * VRMenuObject::TEXELS_PER_METER;
MovieTitleLabel.SetImage( 0, SURFACE_TEXTURE_DIFFUSE, BackgroundTintTexture, titleBounds.GetSize().x + 88, titleBounds.GetSize().y + 32 );
PlayButton.SetButtonImages( PauseTexture, PauseHoverTexture, PausePressedTexture );
}
示例6: OnClick
void ScrubBarComponent::OnClick( App * app, VrFrame const & vrFrame, VRMenuEvent const & event )
{
if ( OnClickFunction == NULL )
{
return;
}
Vector3f hitPos = event.HitResult.RayStart + event.HitResult.RayDir * event.HitResult.t;
// move hit position into local space
const Posef modelPose = Background->GetWorldPose();
Vector3f localHit = modelPose.Orientation.Inverted().Rotate( hitPos - modelPose.Position );
Bounds3f bounds = Background->GetMenuObject()->GetLocalBounds( app->GetDefaultFont() ) * Background->GetParent()->GetWorldScale();
const float progress = ( localHit.x - bounds.GetMins().x ) / bounds.GetSize().x;
if ( ( progress >= 0.0f ) && ( progress <= 1.0f ) )
{
( *OnClickFunction )( this, OnClickObject, progress );
}
}
示例7: scene
SpatialLightDistribution::SpatialLightDistribution(const Scene &scene,
int maxVoxels)
: scene(scene) {
// Compute the number of voxels so that the widest scene bounding box
// dimension has maxVoxels voxels and the other dimensions have a number
// of voxels so that voxels are roughly cube shaped.
Bounds3f b = scene.WorldBound();
Vector3f diag = b.Diagonal();
Float bmax = diag[b.MaximumExtent()];
for (int i = 0; i < 3; ++i)
nVoxels[i] = std::max(1, int(std::round(diag[i] / bmax * maxVoxels)));
LOG(INFO) << "SpatialLightDistribution: scene bounds " << b <<
", voxel res (" << nVoxels[0] << ", " << nVoxels[1] << ", " <<
nVoxels[2] << ")";
// It's important to pre-size the localVoxelDistributions vector, to
// avoid race conditions with one thread resizing the vector while
// another is reading from it.
localVoxelDistributions.resize(MaxThreadIndex());
}
示例8: fwd
//.........这里部分代码省略.........
Menu->InitWithItems( menuMgr, font, 0.0f, VRMenuFlags_t(), parms );
parms.Clear();
// the centerroot item will get touch relative and touch absolute events and use them to rotate the centerRoot
menuHandle_t centerRootHandle = Menu->HandleForId( menuMgr, ID_CENTER_ROOT );
VRMenuObject * centerRoot = menuMgr.ToObject( centerRootHandle );
OVR_ASSERT( centerRoot != NULL );
// ==============================================================================
//
// title
//
{
Posef panelPose( Quatf( up, 0.0f ), Vector3f( 0.0f, 2.2f, -3.0f ) );
VRMenuObjectParms p( VRMENU_STATIC, Array< VRMenuComponent* >(),
VRMenuSurfaceParms(), Strings::ResumeMenu_Title, panelPose, defaultScale, fontParms, VRMenuId_t( ID_TITLE.Get() ),
VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
parms.PushBack( &p );
Menu->AddItems( menuMgr, font, parms, centerRootHandle, false );
parms.Clear();
}
// ==============================================================================
//
// options
//
Array<const char *> options;
options.PushBack( Strings::ResumeMenu_Resume );
options.PushBack( Strings::ResumeMenu_Restart );
Array<const char *> icons;
icons.PushBack( "assets/resume.png" );
icons.PushBack( "assets/restart.png" );
Array<PanelPose> optionPositions;
optionPositions.PushBack( PanelPose( Quatf( up, 0.0f / 180.0f * Mathf::Pi ), Vector3f( -0.5f, 1.7f, -3.0f ), Vector4f( 1.0f, 1.0f, 1.0f, 1.0f ) ) );
optionPositions.PushBack( PanelPose( Quatf( up, 0.0f / 180.0f * Mathf::Pi ), Vector3f( 0.5f, 1.7f, -3.0f ), Vector4f( 1.0f, 1.0f, 1.0f, 1.0f ) ) );
int borderWidth = 0, borderHeight = 0;
GLuint borderTexture = LoadTextureFromApplicationPackage( "assets/resume_restart_border.png", TextureFlags_t( TEXTUREFLAG_NO_DEFAULT ), borderWidth, borderHeight );
for ( int i = 0; i < optionPositions.GetSizeI(); ++i )
{
ResumeMovieComponent * resumeMovieComponent = new ResumeMovieComponent( this, i );
Array< VRMenuComponent* > optionComps;
optionComps.PushBack( resumeMovieComponent );
VRMenuSurfaceParms panelSurfParms( "",
borderTexture, borderWidth, borderHeight, SURFACE_TEXTURE_ADDITIVE,
0, 0, 0, SURFACE_TEXTURE_MAX,
0, 0, 0, SURFACE_TEXTURE_MAX );
Posef panelPose( optionPositions[ i ].Orientation, optionPositions[ i ].Position );
VRMenuObjectParms * p = new VRMenuObjectParms( VRMENU_BUTTON, optionComps,
panelSurfParms, options[ i ], panelPose, defaultScale, fontParms, VRMenuId_t( ID_OPTIONS.Get() + i ),
VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
parms.PushBack( p );
Menu->AddItems( menuMgr, font, parms, centerRootHandle, false );
DeletePointerArray( parms );
parms.Clear();
// add icon
menuHandle_t optionHandle = centerRoot->ChildHandleForId( menuMgr, VRMenuId_t( ID_OPTIONS.Get() + i ) );
VRMenuObject * optionObject = menuMgr.ToObject( optionHandle );
OVR_ASSERT( optionObject != NULL );
int iconWidth = 0, iconHeight = 0;
GLuint iconTexture = LoadTextureFromApplicationPackage( icons[ i ], TextureFlags_t( TEXTUREFLAG_NO_DEFAULT ), iconWidth, iconHeight );
VRMenuSurfaceParms iconSurfParms( "",
iconTexture, iconWidth, iconHeight, SURFACE_TEXTURE_DIFFUSE,
0, 0, 0, SURFACE_TEXTURE_MAX,
0, 0, 0, SURFACE_TEXTURE_MAX );
Bounds3f textBounds = optionObject->GetTextLocalBounds( font );
optionObject->SetTextLocalPosition( Vector3f( iconWidth * VRMenuObject::DEFAULT_TEXEL_SCALE * 0.5f, 0.0f, 0.0f ) );
Posef iconPose( optionPositions[ i ].Orientation, optionPositions[ i ].Position + Vector3f( textBounds.GetMins().x, 0.0f, 0.01f ) );
p = new VRMenuObjectParms( VRMENU_STATIC, Array< VRMenuComponent* >(),
iconSurfParms, NULL, iconPose, defaultScale, fontParms, VRMenuId_t( ID_OPTION_ICONS.Get() + i ),
VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_ALL ), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
parms.PushBack( p );
Menu->AddItems( menuMgr, font, parms, centerRootHandle, false );
DeletePointerArray( parms );
parms.Clear();
menuHandle_t iconHandle = centerRoot->ChildHandleForId( menuMgr, VRMenuId_t( ID_OPTION_ICONS.Get() + i ) );
resumeMovieComponent->Icon = menuMgr.ToObject( iconHandle );
}
Cinema.app->GetGuiSys().AddMenu( Menu );
}
示例9: bounds
BVHItem::BVHItem( const Bounds3f &i_bounds )
: bounds( i_bounds )
, center( ( i_bounds.getMax() + i_bounds.getMin() ) / 2.0f )
, index( 0 )
{}
示例10: BoundEdge
void KdTreeAccel::buildTree(KdAccelNode* node, const Bounds3f &bound, vector<int> &prims,
int depth, BoundEdge* edges[3])
{
node->bbox = bound;
int np = prims.size();
//If not enough primitives or reach max depth of a tree
//Create a leaf node
if (np <= maxPrims || depth == 0)
{
node->initLeaf(prims);
return;
}
//Interior node parameters
int bestAxis = -1, bestOffest = -1;//Split axis and split index*2
Float bestCost = INFINITY;
Float oldCost = np;
Float totalSA = bound.surfaceArea();
Float invTotalSA = 1.0 / totalSA;
Vector3f bbDiag = bound.pMax - bound.pMin;
//choose max extension axis of bounding box
int axis = bound.maxExtent();//axis is the longest edge of bounding box
int retries = 0;
RETRY_SPLIT:
//
//Calculate surface cost
for (int i = 0; i < np; ++i)
{
int prmIdx = prims[i];
const Bounds3f tmpBox = primitives[prmIdx]->ObjBound;
edges[axis][i * 2] = BoundEdge(tmpBox.pMin[axis], prmIdx, true);
edges[axis][i * 2 + 1] = BoundEdge(tmpBox.pMax[axis], prmIdx, false);
}
sort(&edges[axis][0], &edges[axis][2 * np]);
int nBelow(0), nAbove(np);
for (int i = 0; i < 2 * np; ++i)
{
if (edges[axis][i].type == BoundEdge::END)
{
--nAbove;
}
Float edget = edges[axis][i].t;
//when t is in between the boundary
if (edget > bound.pMin[axis] && edget < bound.pMax[axis])
{
//Compute cost for split at ith edge
//get other two axes
int axis0 = (axis + 1) % 3, axis1 = (axis + 2) % 3;
Float belowSA = 2 * (bbDiag[axis0] * bbDiag[axis1] +
(edget - bound.pMin[axis]) *
(bbDiag[axis0] + bbDiag[axis1]));
Float aboveSA = 2 * (bbDiag[axis0] * bbDiag[axis1] +
(bound.pMax[axis] - edget) *
(bbDiag[axis0] + bbDiag[axis1]));
Float pBelow = belowSA * invTotalSA;
Float pAbove = aboveSA * invTotalSA;
Float eb = (nAbove == 0 || nBelow == 0) ? emptyBonus : 0;
Float cost = (1.0 - eb) * (pBelow * nBelow + pAbove * nAbove);
//cout << "cost at i:" << i << " is " << cost << endl;
if (cost < bestCost)
{
bestCost = cost;
bestAxis = axis;
bestOffest = i;// edges[axis][i].type ? i + 1 : i;//When end use next node
}
}
if (edges[axis][i].type == BoundEdge::START)
{
++nBelow;
}
}
if (retries < 2)//(bestAxis == -1 && retries < 2)//
{
++retries;
axis = (axis + 1) % 3;
goto RETRY_SPLIT;
}
//if no good split, init as leaf
if (bestAxis == -1)
{
node->initLeaf(prims);
return;
}
//recursively build subtree
vector<int> primsBelow;
vector<int> primsAbove;
//Store indices of below primitives
for (int i = 0; i < bestOffest; ++i)
{
if (edges[bestAxis][i].type == BoundEdge::START)
{
primsBelow.push_back(edges[bestAxis][i].primNum);
}
}
//Store indices of above primitives
//.........这里部分代码省略.........
示例11: GetLTM_
//----------------------------------------------------------------------------------------------
void IDrawInterface::DoBuildWorldTransform_(const Matrix &WTM)
{
m_WorldMatrixTransform = GetLTM_() * WTM * GetSTM_();
m_Bounds.SetUnvalid(); // invalidate
std::vector<IRenderInterface*> &vecRenderEntities = const_cast<CActor*>(m_pNode->m_pKey)->m_VecRenderEntities;
for (std::vector<IRenderInterface*>::const_iterator iter = vecRenderEntities.begin(); iter != vecRenderEntities.end(); ++iter)
{
(*iter)->SetRWTM(m_WorldMatrixTransform);
Bounds3f BBox = (*iter)->GetRBounds_();
if (BBox.IsValid())
{
const unsigned int BBOX_POINTS = 8;
Vector BoxPoints[BBOX_POINTS] =
{
/*Vector(BBox.bound_min.x, BBox.bound_min.y, BBox.bound_min.z),
Vector(BBox.bound_min.x, BBox.bound_min.y, BBox.bound_max.z),
Vector(BBox.bound_max.x, BBox.bound_min.y, BBox.bound_max.z),
Vector(BBox.bound_max.x, BBox.bound_min.y, BBox.bound_min.z),
Vector(BBox.bound_min.x, BBox.bound_max.y, BBox.bound_min.z),
Vector(BBox.bound_min.x, BBox.bound_max.y, BBox.bound_max.z),
Vector(BBox.bound_max.x, BBox.bound_max.y, BBox.bound_max.z),
Vector(BBox.bound_max.x, BBox.bound_max.y, BBox.bound_min.z),*/
// TODO make homogeneous with exporter tool
Vector(BBox.bound_min.z, BBox.bound_min.y, BBox.bound_min.x),
Vector(BBox.bound_max.z, BBox.bound_min.y, BBox.bound_min.x),
Vector(BBox.bound_max.z, BBox.bound_min.y, BBox.bound_max.x),
Vector(BBox.bound_min.z, BBox.bound_min.y, BBox.bound_max.x),
Vector(BBox.bound_min.z, BBox.bound_max.y, BBox.bound_min.x),
Vector(BBox.bound_max.z, BBox.bound_max.y, BBox.bound_min.x),
Vector(BBox.bound_max.z, BBox.bound_max.y, BBox.bound_max.x),
Vector(BBox.bound_min.z, BBox.bound_max.y, BBox.bound_max.x),
};
Matrix MT = m_WorldMatrixTransform;
MT.t = Vector(0.f, 0.f, 0.f);
Bounds3f tmpBound;
for (int Index = 0; Index < BBOX_POINTS; ++Index)
{
Vector point = transform_coord(BoxPoints[Index], MT);
if (Index == 0)
{
tmpBound.SetBounds(point, point);
continue;
}
tmpBound.Add(point);
}
const Vector bound_min = m_WorldMatrixTransform.t + tmpBound.bound_min;
const Vector bound_max = m_WorldMatrixTransform.t + tmpBound.bound_max;
(*iter)->SetWBounds(Bounds3f(bound_min, bound_max));
if (iter == vecRenderEntities.begin())
{
m_Bounds.SetBounds(bound_min, bound_max);
continue;
}
else
{
m_Bounds.Add(bound_min);
m_Bounds.Add(bound_max);
}
}
}
// invalidate composite bounds
m_CompositeBounds = m_Bounds;
}
示例12: Assert
BVHBuildNode *BVHAccel::buildUpperSAH(MemoryArena &arena,
std::vector<BVHBuildNode *> &treeletRoots,
int start, int end,
int *totalNodes) const {
Assert(start < end);
int nNodes = end - start;
if (nNodes == 1) return treeletRoots[start];
(*totalNodes)++;
BVHBuildNode *node = arena.Alloc<BVHBuildNode>();
// Compute bounds of all nodes under this HLBVH node
Bounds3f bounds;
for (int i = start; i < end; ++i)
bounds = Union(bounds, treeletRoots[i]->bounds);
// Compute bound of HLBVH node centroids, choose split dimension _dim_
Bounds3f centroidBounds;
for (int i = start; i < end; ++i) {
Point3f centroid =
(treeletRoots[i]->bounds.pMin + treeletRoots[i]->bounds.pMax) *
0.5f;
centroidBounds = Union(centroidBounds, centroid);
}
int dim = centroidBounds.MaximumExtent();
// FIXME: if this hits, what do we need to do?
// Make sure the SAH split below does something... ?
Assert(centroidBounds.pMax[dim] != centroidBounds.pMin[dim]);
// Allocate _BucketInfo_ for SAH partition buckets
constexpr int nBuckets = 12;
struct BucketInfo {
int count = 0;
Bounds3f bounds;
};
BucketInfo buckets[nBuckets];
// Initialize _BucketInfo_ for HLBVH SAH partition buckets
for (int i = start; i < end; ++i) {
Float centroid = (treeletRoots[i]->bounds.pMin[dim] +
treeletRoots[i]->bounds.pMax[dim]) *
0.5f;
int b =
nBuckets * ((centroid - centroidBounds.pMin[dim]) /
(centroidBounds.pMax[dim] - centroidBounds.pMin[dim]));
if (b == nBuckets) b = nBuckets - 1;
Assert(b >= 0 && b < nBuckets);
buckets[b].count++;
buckets[b].bounds = Union(buckets[b].bounds, treeletRoots[i]->bounds);
}
// Compute costs for splitting after each bucket
Float cost[nBuckets - 1];
for (int i = 0; i < nBuckets - 1; ++i) {
Bounds3f b0, b1;
int count0 = 0, count1 = 0;
for (int j = 0; j <= i; ++j) {
b0 = Union(b0, buckets[j].bounds);
count0 += buckets[j].count;
}
for (int j = i + 1; j < nBuckets; ++j) {
b1 = Union(b1, buckets[j].bounds);
count1 += buckets[j].count;
}
cost[i] = .125f +
(count0 * b0.SurfaceArea() + count1 * b1.SurfaceArea()) /
bounds.SurfaceArea();
}
// Find bucket to split at that minimizes SAH metric
Float minCost = cost[0];
int minCostSplitBucket = 0;
for (int i = 1; i < nBuckets - 1; ++i) {
if (cost[i] < minCost) {
minCost = cost[i];
minCostSplitBucket = i;
}
}
// Split nodes and create interior HLBVH SAH node
BVHBuildNode **pmid = std::partition(
&treeletRoots[start], &treeletRoots[end - 1] + 1,
[=](const BVHBuildNode *node) {
Float centroid =
(node->bounds.pMin[dim] + node->bounds.pMax[dim]) * 0.5f;
int b = nBuckets *
((centroid - centroidBounds.pMin[dim]) /
(centroidBounds.pMax[dim] - centroidBounds.pMin[dim]));
if (b == nBuckets) b = nBuckets - 1;
Assert(b >= 0 && b < nBuckets);
return b <= minCostSplitBucket;
});
int mid = pmid - &treeletRoots[0];
Assert(mid > start && mid < end);
node->InitInterior(
dim, buildUpperSAH(arena, treeletRoots, start, mid, totalNodes),
buildUpperSAH(arena, treeletRoots, mid, end, totalNodes));
return node;
}
示例13: buildUpperSAH
BVHBuildNode *BVHAccel::HLBVHBuild(
MemoryArena &arena, const std::vector<BVHPrimitiveInfo> &primitiveInfo,
int *totalNodes,
std::vector<std::shared_ptr<Primitive>> &orderedPrims) const {
// Compute bounding box of all primitive centroids
Bounds3f bounds;
for (const BVHPrimitiveInfo &pi : primitiveInfo)
bounds = Union(bounds, pi.centroid);
// Compute Morton indices of primitives
std::vector<MortonPrimitive> mortonPrims(primitiveInfo.size());
ParallelFor([&](int i) {
// Initialize _mortionPrims[i]_ for _i_th primitive
constexpr int mortonBits = 10;
constexpr int mortonScale = 1 << mortonBits;
mortonPrims[i].primitiveIndex = primitiveInfo[i].primitiveNumber;
Vector3f centroidOffset = bounds.Offset(primitiveInfo[i].centroid);
mortonPrims[i].mortonCode = EncodeMorton3(centroidOffset * mortonScale);
}, primitiveInfo.size(), 512);
// Radix sort primitive Morton indices
RadixSort(&mortonPrims);
// Create LBVH treelets at bottom of BVH
// Find intervals of primitives for each treelet
std::vector<LBVHTreelet> treeletsToBuild;
for (int start = 0, end = 1; end <= (int)mortonPrims.size(); ++end) {
uint32_t mask = 0b00111111111111000000000000000000;
if (end == (int)mortonPrims.size() ||
((mortonPrims[start].mortonCode & mask) !=
(mortonPrims[end].mortonCode & mask))) {
// Add entry to _treeletsToBuild_ for this treelet
int nPrimitives = end - start;
int maxBVHNodes = 2 * nPrimitives;
BVHBuildNode *nodes = arena.Alloc<BVHBuildNode>(maxBVHNodes, false);
treeletsToBuild.push_back({start, nPrimitives, nodes});
start = end;
}
}
// Create LBVHs for treelets in parallel
std::atomic<int> atomicTotal(0), orderedPrimsOffset(0);
orderedPrims.resize(primitives.size());
ParallelFor([&](int i) {
// Generate _i_th LBVH treelet
int nodesCreated = 0;
const int firstBitIndex = 29 - 12;
LBVHTreelet &tr = treeletsToBuild[i];
tr.buildNodes =
emitLBVH(tr.buildNodes, primitiveInfo, &mortonPrims[tr.startIndex],
tr.nPrimitives, &nodesCreated, orderedPrims,
&orderedPrimsOffset, firstBitIndex);
atomicTotal += nodesCreated;
}, treeletsToBuild.size());
*totalNodes = atomicTotal;
// Create and return SAH BVH from LBVH treelets
std::vector<BVHBuildNode *> finishedTreelets;
finishedTreelets.reserve(treeletsToBuild.size());
for (LBVHTreelet &treelet : treeletsToBuild)
finishedTreelets.push_back(treelet.buildNodes);
return buildUpperSAH(arena, finishedTreelets, 0, finishedTreelets.size(),
totalNodes);
}
示例14: buildNode
void BVH::buildNode( SplitMethod i_method, BVHItems &i_buildItems, size_t i_start, size_t i_end )
{
Bounds3f bounds;
Bounds3f centerBounds;
// Save the index for later access of the node
size_t nodeIndex = m_nodes.size();
// Push back a node, we will initialize it later
m_nodes.push_back( BVHNode() );
// Calculate bounds
for ( size_t i = i_start; i < i_end; i++ )
{
const BVHItem &item = i_buildItems[ i ];
bounds = boundsUnion( bounds, item.bounds );
centerBounds = boundsUnion( centerBounds, item.center );
}
size_t count = i_end - i_start;
// Create a leaf
if ( count == 1 )
{
m_nodes[ nodeIndex ].initLeaf( bounds, m_items.size(), 1 );
m_items.push_back( i_buildItems[ i_start ] );
}
// Split
else
{
int dim = static_cast< int >( bounds.maximumExtent() );
const vec3f &min = centerBounds.getMin();
const vec3f &max = centerBounds.getMax();
// Cannot split, create leaf items
if ( min[ dim ] == max[ dim ] )
{
m_nodes[ nodeIndex ].initLeaf( bounds, m_items.size(), count );
for ( size_t i = i_start; i < i_end; i++ )
{
m_items.push_back( i_buildItems[ i ] );
}
}
// Split by method
else
{
size_t mid = ( i_start + i_end ) / 2.0;
switch ( i_method ) {
case SplitMethod::MIDDLE:
{
// Split the items at the midpoint of the axis
float dimMid = ( centerBounds.getMin()[ dim ] + centerBounds.getMax()[ dim ] ) / 2.0;
BVHItem* midPtr = std::partition(
&i_buildItems[ i_start ],
&i_buildItems[ i_end - 1 ] + 1,
[ dim, dimMid ]( const BVHItem &item ) {
return item.center[ dim ] < dimMid;
} );
mid = midPtr - &i_buildItems[0];
// Continue onto splitting equally if failed
if ( mid != i_start && mid != i_end )
{
break;
}
}
case SplitMethod::EQUAL:
default:
{
// Reset mid in case we are defaulting to equal splitting
mid = ( i_start + i_end ) / 2.0;
// Split into equal sized subsets
std::nth_element(
&i_buildItems[ i_start ],
&i_buildItems[ mid ],
&i_buildItems[ i_end - 1 ] + 1,
[ dim ]( const BVHItem &i0, const BVHItem &i1 ) {
return i0.center[ dim ] < i1.center[ dim ];
} );
break;
}
}
// Build left tree
buildNode( i_method, i_buildItems, i_start, mid );
size_t offset = m_nodes.size();
// Build right tree
buildNode( i_method, i_buildItems, mid, i_end );
// Initialize the interior node
m_nodes[ nodeIndex ].initInterior( bounds, offset, dim );
}
}
//.........这里部分代码省略.........