Exemple #1
0
void CParticleEffectBinding::BBoxCalcStart( bool bFullBBoxUpdate, Vector &bbMin, Vector &bbMax )
{
	if ( !GetAutoUpdateBBox() )
		return;

	if ( bFullBBoxUpdate )
	{
		// We're going to fully recompute the bbox.
		bbMin.Init( FLT_MAX, FLT_MAX, FLT_MAX );
		bbMax.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX );
	}
	else
	{
		// We're going to push out the bbox using just some of the particles.
		if ( m_bLocalSpaceTransformIdentity )
		{
			bbMin = m_Min;
			bbMax = m_Max;
		}
		else
		{
			ITransformAABB( m_LocalSpaceTransform.As3x4(), m_Min, m_Max, bbMin, bbMax );
		}
	}
}
Exemple #2
0
void CParticleEffectBinding::BBoxCalcEnd( bool bFullBBoxUpdate, bool bboxSet, Vector &bbMin, Vector &bbMax )
{
	if ( !GetAutoUpdateBBox() )
		return;

	// Get the bbox into world space.
	Vector bbMinWorld, bbMaxWorld;
	if ( m_bLocalSpaceTransformIdentity )
	{
		bbMinWorld = bbMin;
		bbMaxWorld = bbMax;
	}
	else
	{
		TransformAABB( m_LocalSpaceTransform.As3x4(), bbMin, bbMax, bbMinWorld, bbMaxWorld );
	}
	
	if( bFullBBoxUpdate )
	{
		// If there were ANY particles in the system, then we've got a valid bbox here. Otherwise,
		// we don't have anything, so leave m_Min and m_Max at the sort origin.
		if ( bboxSet )
		{
			m_Min = bbMinWorld;
			m_Max = bbMaxWorld;
		}
		else
		{
			m_Min = m_Max = m_pSim->GetSortOrigin();
		}
	}
	else
	{
		// Take whatever our bbox was + pushing out from other particles.
		m_Min = bbMinWorld;
		m_Max = bbMaxWorld;
	}
}
//-----------------------------------------------------------------------------
// Rendering
//-----------------------------------------------------------------------------
int CNewParticleEffect::DrawModel( int flags, const RenderableInstance_t &instance )
{
	VPROF_BUDGET( "CNewParticleEffect::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
	if ( r_DrawParticles.GetBool() == false )
		return 0;

	if ( !GetClientMode()->ShouldDrawParticles() || !ParticleMgr()->ShouldRenderParticleSystems() )
		return 0;

	if( flags & STUDIO_SHADOWDEPTHTEXTURE )
		return 0;

	if ( m_hOwner && m_hOwner->IsDormant() )
		return 0;
	
	// do distance cull check here. We do it here instead of in particles so we can easily only do
	// it for root objects, not bothering to cull children individually
	CMatRenderContextPtr pRenderContext( materials );
	if ( !m_pDef->IsScreenSpaceEffect() && !m_pDef->IsViewModelEffect() )
	{
		Vector vecCamera;
		pRenderContext->GetWorldSpaceCameraPosition( &vecCamera );
		if ( ( CalcSqrDistanceToAABB( m_MinBounds, m_MaxBounds, vecCamera ) > ( m_pDef->m_flMaxDrawDistance * m_pDef->m_flMaxDrawDistance ) ) )
			return 0;
	}

	if ( ( flags & STUDIO_TRANSPARENCY ) || !IsBatchable() || !m_pDef->IsDrawnThroughLeafSystem() )
	{
		int viewentity = render->GetViewEntity();
		C_BaseEntity *pCameraObject = cl_entitylist->GetEnt( viewentity );
		// apply logic that lets you skip rendering a system if the camera is attached to its entity
		if   ( ( ( pCameraObject &&
			 ( m_pDef->m_nSkipRenderControlPoint != -1 ) &&
			 ( m_pDef->m_nSkipRenderControlPoint <= m_nHighestCP ) &&
			 ( GetControlPointEntity( m_pDef->m_nSkipRenderControlPoint ) == pCameraObject ) ) ) ||
			 ( ( pCameraObject &&
			 ( m_pDef->m_nAllowRenderControlPoint != -1 ) &&
			 ( m_pDef->m_nAllowRenderControlPoint <= m_nHighestCP ) &&
			 ( GetControlPointEntity( m_pDef->m_nAllowRenderControlPoint ) != pCameraObject ) ) ) )
			return 0;

		Vector4D vecDiffuseModulation( 1.0f, 1.0f, 1.0f, 1.0f ); //instance.m_nAlpha / 255.0f );
		pRenderContext->MatrixMode( MATERIAL_MODEL );
		pRenderContext->PushMatrix();
		pRenderContext->LoadIdentity();
		Render( pRenderContext, vecDiffuseModulation, ( flags & STUDIO_TRANSPARENCY ) ? IsTwoPass() : false, pCameraObject );
		pRenderContext->MatrixMode( MATERIAL_MODEL );
		pRenderContext->PopMatrix();
	}
	else
	{
		g_pParticleSystemMgr->AddToRenderCache( this );
	}

	if ( cl_particles_show_bbox.GetBool() )
	{
		Vector center = GetRenderOrigin();
		Vector mins   = m_MinBounds - center;
		Vector maxs   = m_MaxBounds - center;
	
		int r, g;
		if ( GetAutoUpdateBBox() )
		{
			// red is bad, the bbox update is costly
			r = 255;
			g = 0;
		}
		else
		{
			// green, this effect presents less cpu load 
			r = 0;
			g = 255;
		}
		Vector vecCurCPPos = GetControlPointAtCurrentTime( 0 );
		debugoverlay->AddBoxOverlay( center, mins, maxs, QAngle( 0, 0, 0 ), r, g, 0, 16, 0 );
		debugoverlay->AddTextOverlayRGB( center, 0, 0, r, g, 0, 64, "%s:(%d)", GetEffectName(),
										 m_nActiveParticles );
	}

	return 1;
}
void CNewParticleEffect::DebugDrawBbox ( bool bCulled )
{
	int nParticlesShowBboxCost = g_cl_particle_show_bbox_cost;
	bool bShowCheapSystems = false;
	if ( nParticlesShowBboxCost < 0 )
	{
		nParticlesShowBboxCost = -nParticlesShowBboxCost;
		bShowCheapSystems = true;
	}

	Vector center = GetRenderOrigin();
	Vector mins   = m_MinBounds - center;
	Vector maxs   = m_MaxBounds - center;
	
	int r, g, b;
	bool bDraw = true;
	if ( bCulled )
	{
		r = 64;
		g = 64;
		b = 64;
	}
	else if ( nParticlesShowBboxCost > 0 )
	{
		float fAmount = (float)m_nActiveParticles / (float)nParticlesShowBboxCost;
		if ( fAmount < 0.5f )
		{
			if ( bShowCheapSystems )
			{
				r = 0;
				g = 255;
				b = 0;
			}
			else
			{
				// Prevent the screen getting spammed with low-count particles which aren't that expensive.
				bDraw = false;
				r = 0;
				g = 0;
				b = 0;
			}
		}
		else if ( fAmount < 1.0f )
		{
			// green 0.5-1.0 blue
			int nBlend = (int)( 512.0f * ( fAmount - 0.5f ) );
			nBlend = MIN ( 255, MAX ( 0, nBlend ) );
			r = 0;
			g = 255 - nBlend;
			b = nBlend;
		}
		else if ( fAmount < 2.0f )
		{
			// blue 1.0-2.0 red
			int nBlend = (int)( 256.0f * ( fAmount - 1.0f ) );
			nBlend = MIN ( 255, MAX ( 0, nBlend ) );
			r = nBlend;
			g = 0;
			b = 255 - nBlend;
		}
		else
		{
			r = 255;
			g = 0;
			b = 0;
		}
	}
	else
	{
		if ( GetAutoUpdateBBox() )
		{
			// red is bad, the bbox update is costly
			r = 255;
			g = 0;
			b = 0;
		}
		else
		{
			// green, this effect presents less cpu load 
			r = 0;
			g = 255;
			b = 0;
		}
	}
		 
	if ( bDraw )
	{
		debugoverlay->AddBoxOverlay( center, mins, maxs, QAngle( 0, 0, 0 ), r, g, b, 16, 0 );
		debugoverlay->AddTextOverlayRGB( center, 0, 0, r, g, b, 64, "%s:(%d)", GetEffectName(), m_nActiveParticles );
	}
}
//-----------------------------------------------------------------------------
// Rendering
//-----------------------------------------------------------------------------
int CNewParticleEffect::DrawModel( int flags )
{
	VPROF_BUDGET( "CNewParticleEffect::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
	if ( r_DrawParticles.GetBool() == false )
		return 0;

	// City17: DX7? Don't draw.
	if( engine->GetDXSupportLevel() < 80 )
		return 0;

	if ( !g_pClientMode->ShouldDrawParticles() || !ParticleMgr()->ShouldRenderParticleSystems() )
		return 0;
	


	if( flags & STUDIO_SHADOWDEPTHTEXTURE )
		return 0;
	
	// do distance cull check here. We do it here instead of in particles so we can easily only do
	// it for root objects, not bothering to cull children individually
	CMatRenderContextPtr pRenderContext( materials );
	Vector vecCamera;
	pRenderContext->GetWorldSpaceCameraPosition( &vecCamera );
	if ( CalcSqrDistanceToAABB( m_MinBounds, m_MaxBounds, vecCamera ) > ( m_pDef->m_flMaxDrawDistance * m_pDef->m_flMaxDrawDistance ) )
		return 0;

	if ( flags & STUDIO_TRANSPARENCY )
	{
		int viewentity = render->GetViewEntity();
		C_BaseEntity *pCameraObject = cl_entitylist->GetEnt( viewentity );
		// apply logic that lets you skip rendering a system if the camera is attached to its entity
		if ( pCameraObject &&
			 ( m_pDef->m_nSkipRenderControlPoint != -1 ) &&
			 ( m_pDef->m_nSkipRenderControlPoint <= m_nHighestCP ) &&
			 ( GetControlPointEntity( m_pDef->m_nSkipRenderControlPoint ) == pCameraObject ) )
			return 0;

		pRenderContext->MatrixMode( MATERIAL_MODEL );
		pRenderContext->PushMatrix();
		pRenderContext->LoadIdentity();
		Render( pRenderContext, IsTwoPass(), pCameraObject );
		pRenderContext->MatrixMode( MATERIAL_MODEL );
		pRenderContext->PopMatrix();
	}
	else
	{
		g_pParticleSystemMgr->AddToRenderCache( this );
	}

	if ( !IsRetail() && cl_particles_show_bbox.GetBool() )
	{
		Vector center = GetRenderOrigin();
		Vector mins   = m_MinBounds - center;
		Vector maxs   = m_MaxBounds - center;
	
		int r, g;
		if ( GetAutoUpdateBBox() )
		{
			// red is bad, the bbox update is costly
			r = 255;
			g = 0;
		}
		else
		{
			// green, this effect presents less cpu load 
			r = 0;
			g = 255;
		}
		 
		debugoverlay->AddBoxOverlay( center, mins, maxs, QAngle( 0, 0, 0 ), r, g, 0, 16, 0 );
		debugoverlay->AddTextOverlayRGB( center, 0, 0, r, g, 0, 64, "%s:(%d)", GetEffectName(),
										 m_nActiveParticles );
	}

	return 1;
}