当前位置: 首页>>代码示例>>C++>>正文


C++ Bounds3f类代码示例

本文整理汇总了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);
}
开发者ID:AndreaLoforte,项目名称:pbrt-v3,代码行数:25,代码来源:grid.cpp

示例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 );
}
开发者ID:amyvmiwei,项目名称:UnrealEngine4,代码行数:36,代码来源:DebugLines.cpp

示例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);
}
开发者ID:KojiNakamaru,项目名称:pbrt-v3,代码行数:29,代码来源:grid.cpp

示例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] << ")";
}
开发者ID:dbadb,项目名称:pbrt-v3,代码行数:28,代码来源:lightdistrib.cpp

示例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 );
}
开发者ID:li-zheng,项目名称:thirdparty,代码行数:29,代码来源:MoviePlayerView.cpp

示例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 );
	}
}
开发者ID:li-zheng,项目名称:thirdparty,代码行数:20,代码来源:MoviePlayerView.cpp

示例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());
}
开发者ID:wjakob,项目名称:pbrt-v3,代码行数:21,代码来源:lightdistrib.cpp

示例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 );
}
开发者ID:1107979819,项目名称:OculusVRStudy,代码行数:101,代码来源:ResumeMovieView.cpp

示例9: bounds

BVHItem::BVHItem( const Bounds3f &i_bounds )
    : bounds( i_bounds )
    , center( ( i_bounds.getMax() + i_bounds.getMin() ) / 2.0f )
    , index( 0 )
{}
开发者ID:JonCG90,项目名称:GraphicsEngine,代码行数:5,代码来源:bvh.cpp

示例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
//.........这里部分代码省略.........
开发者ID:ShenyaoKe,项目名称:Kaguya,代码行数:101,代码来源:KdTreeAccel.cpp

示例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;
}
开发者ID:innovatelogic,项目名称:ilogic-vm,代码行数:79,代码来源:IDrawInterface.cpp

示例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;
}
开发者ID:nuxping,项目名称:pbrt-v3,代码行数:98,代码来源:bvh.cpp

示例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);
}
开发者ID:nuxping,项目名称:pbrt-v3,代码行数:65,代码来源:bvh.cpp

示例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 );
        }
    }
//.........这里部分代码省略.........
开发者ID:JonCG90,项目名称:GraphicsEngine,代码行数:101,代码来源:bvh.cpp


注:本文中的Bounds3f类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。