//-----------------------------------------------------------------------------
// Purpose: Draw targeting reticle
//-----------------------------------------------------------------------------
void C_WeaponCombat_ChargeablePlasma::DrawCrosshair( void )
{
	BaseClass::DrawCrosshair();

	// Find enemy players in front of me
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return;

	trace_t tr;
	Vector vecStart, vecEnd;
	VectorMA( CurrentViewOrigin(), 1500, CurrentViewForward(), vecEnd );
	VectorMA( CurrentViewOrigin(), 48, CurrentViewForward(), vecStart );
	UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, NULL, COLLISION_GROUP_NONE, &tr );

	if ( tr.DidHitNonWorldEntity() )
	{
		C_BaseEntity *pEntity = tr.m_pEnt;
		if ( pEntity && pEntity->IsPlayer() && !pPlayer->InSameTeam( pEntity ) )
		{
			// Draw a reticle
			vgui::Color clr = gHUD.m_clrYellowish;
			clr[3] = 128;

			// Calculate circle size
			int iRatio = 30;

			// Draw the circle 
			int iDegrees = 0;
			Vector vecPoint, vecLastPoint(0,0,0);
			vecPoint.z = 0.0f;
			for ( int i = 0; i < 360; i++ )
			{
				float flRadians = DEG2RAD( iDegrees );
				iDegrees += (360 / 360);

				float ca = cos( flRadians );
				float sa = sin( flRadians );
							 
				// Rotate it around the circle
				vecPoint.x = (int)((ScreenWidth() / 2) + (iRatio * sa));
				vecPoint.y = (int)((ScreenHeight() / 2) - (iRatio * ca));

				// Draw the point, if it's not on the previous point, to avoid smaller circles being brighter
				if ( vecLastPoint != vecPoint )
				{
					vgui::surface()->DrawSetColor( clr );
					vgui::surface()->DrawFilledRect( vecPoint.x, vecPoint.y, vecPoint.x + 1, vecPoint.y + 1 );
				}

				vecLastPoint = vecPoint;
			}
		}
	}
}
float GlowSightDistance( const Vector &glowOrigin, bool bShouldTrace )
{
	float dist = (glowOrigin - CurrentViewOrigin()).Length();
	C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
	if ( local )
	{
		dist *= local->GetFOVDistanceAdjustFactor();
	}

	if ( bShouldTrace )
	{
		Vector end = glowOrigin;
		// HACKHACK: trace 4" from destination in case the glow is inside some parent object
		//			allow a little error...
		if ( dist > 4 )
		{
			end -= CurrentViewForward()*4;
		}
		int traceFlags = MASK_OPAQUE|CONTENTS_MONSTER|CONTENTS_DEBRIS;
		
		CTraceFilterGlow filter(NULL, COLLISION_GROUP_NONE);
		trace_t tr;
		UTIL_TraceLine( CurrentViewOrigin(), end, traceFlags, &filter, &tr );
		if ( tr.fraction != 1.0f )
			return -1;
	}

	return dist;
}
//-----------------------------------------------------------------------------
// Purpose: Updates and renders all effects
//-----------------------------------------------------------------------------
int C_HopwireExplosion::DrawModel( int flags )
{
	AddParticles();

#ifndef C17
	CMatRenderContextPtr pRenderContext( materials );
	pRenderContext->Flush();
	UpdateRefractTexture();

	IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );

	float refract = m_FXCoreAlpha.Interp( gpGlobals->curtime );
	float scale = m_FXCoreScale.Interp( gpGlobals->curtime );

	IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
	pVar->SetFloatValue( refract );

	pRenderContext->Bind( pMat, (IClientRenderable*)this );
	
	float sin1 = sinf( gpGlobals->curtime * 10 );
	float sin2 = sinf( gpGlobals->curtime );

	float scaleY = ( sin1 * sin2 ) * 32.0f;
	float scaleX = (sin2 * sin2) * 32.0f;

	// FIXME: The ball needs to sort properly at all times
	static color32 white = {255,255,255,255};
	DrawSpriteTangentSpace( GetRenderOrigin() + ( CurrentViewForward() * 128.0f ), scale+scaleX, scale+scaleY, white );
#endif

	return 1;
}
void CPixelVisibilityQuery::IssueCountingQuery( IMatRenderContext *pRenderContext, float proxySize, float proxyAspect, IMaterial *pMaterial, bool sizeIsScreenSpace )
{
	if ( !m_failed )
	{
		Assert( IsValid() );
#if 0
		// this centers it on the screen.
		// This is nice because it makes the glows fade as they get partially clipped by the view frustum
		// But it introduces sub-pixel errors (off by one row/column of pixels) so the glows shimmer
		// UNDONE: Compute an offset center coord that matches sub-pixel coords with the real glow position
		// UNDONE: Or frustum clip the sphere/geometry and fade based on proxy size
		Vector origin = m_origin - CurrentViewOrigin();
		float dot = DotProduct(CurrentViewForward(), origin);
		origin = CurrentViewOrigin() + dot * CurrentViewForward();
#endif
		PixelVisibility_DrawProxy( pRenderContext, m_queryHandleCount, m_origin, proxySize, proxyAspect, pMaterial, sizeIsScreenSpace );
	}
}
예제 #5
0
//-----------------------------------------------------------------------------
// Compute vectors perpendicular to the beam
//-----------------------------------------------------------------------------
static void ComputeBeamPerpendicular( const Vector &vecBeamDelta, Vector *pPerp )
{
	// Direction in worldspace of the center of the beam
	Vector vecBeamCenter = vecBeamDelta;
	VectorNormalize( vecBeamCenter );

	CrossProduct( CurrentViewForward(), vecBeamCenter, *pPerp );
	VectorNormalize( *pPerp );
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : flags - 
// Output : int
//-----------------------------------------------------------------------------
int C_PropCombineBall::DrawModel( int flags )
{
	if ( !m_bEmit )
		return 0;
	
	// Make sure our materials are cached
	if ( !InitMaterials() )
	{
		//NOTENOTE: This means that a material was not found for the combine ball, so it may not render!
		AssertOnce( 0 );
		return 0;
	}

	// Draw the flickering overlay
	DrawFlicker();
	
	// Draw the motion blur from movement
	if ( m_bHeld || m_bLaunched )
	{
		DrawMotionBlur();
	}

	// Draw the model if we're being held
	if ( m_bHeld )
	{
		QAngle	angles;
		VectorAngles( -CurrentViewForward(), angles );

		// Always orient towards the camera!
		SetAbsAngles( angles );

		BaseClass::DrawModel( flags );
	}
	else
	{
		float color[3];
		color[0] = color[1] = color[2] = 1.0f;

		float sinOffs = 1.0f * sin( gpGlobals->curtime * 25 );

		float roll = SpawnTime();

		// Draw the main ball body
		CMatRenderContextPtr pRenderContext( materials );
		pRenderContext->Bind( m_pBodyMaterial, (C_BaseEntity*) this );
		DrawHaloOriented( GetAbsOrigin(), m_flRadius + sinOffs, color, roll );
	}
	
	m_vecLastOrigin = GetAbsOrigin();

	return 1;
}
void CSimple3DEmitter::RenderParticles( CParticleRenderIterator *pIterator )
{
    const Particle3D *pParticle = (const Particle3D *)pIterator->GetFirst();
    while ( pParticle )
    {
        float sortKey = CurrentViewForward().Dot( CurrentViewOrigin() - pParticle->m_Pos );

        // -------------------------------------------------------
        //  Set color based on direction towards camera
        // -------------------------------------------------------
        Vector	color;
        Vector vFaceNorm;
        Vector vCameraToFace = (pParticle->m_Pos - CurrentViewOrigin());
        AngleVectors(pParticle->m_vAngles,&vFaceNorm);
        float flFacing = DotProduct(vCameraToFace,vFaceNorm);

        if (flFacing <= 0)
        {
            color[0] = pParticle->m_uchFrontColor[0] / 255.0f;
            color[1] = pParticle->m_uchFrontColor[1] / 255.0f;
            color[2] = pParticle->m_uchFrontColor[2] / 255.0f;
        }
        else
        {
            color[0] = pParticle->m_uchBackColor[0] / 255.0f;
            color[1] = pParticle->m_uchBackColor[1] / 255.0f;
            color[2] = pParticle->m_uchBackColor[2] / 255.0f;
        }

        //Render it in world space
        RenderParticle_ColorSizeAngles(
            pIterator->GetParticleDraw(),
            pParticle->m_Pos,
            color,
            pParticle->GetFadeFraction(),
            pParticle->m_uchSize,
            pParticle->m_vAngles);

        pParticle = (const Particle3D *)pIterator->GetNext( sortKey );
    }
}
예제 #8
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : flags - 
// Output : int
//-----------------------------------------------------------------------------
int C_WeaponPhysCannon::DrawModel( int flags )
{
	// If we're not ugrading, don't do anything special
	if ( m_bIsCurrentlyUpgrading == false && m_bWasUpgraded == false )
		return BaseClass::DrawModel( flags );

	if ( gpGlobals->frametime == 0 )
		return BaseClass::DrawModel( flags );

	if ( !m_bReadyToDraw )
		return 0;

	m_bWasUpgraded = true;

	// Create the particle emitter if it's not already
	if ( SetupEmitter() )
	{
		// Add the power-up particles

		// See if we should draw
		if ( m_bReadyToDraw == false )
			return 0;

		C_BaseAnimating *pAnimating = GetBaseAnimating();
		if (!pAnimating)
			return 0;

		matrix3x4_t	*hitboxbones[MAXSTUDIOBONES];
		if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) )
			return 0;

		studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
		if (!pStudioHdr)
			return false;

		mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
		if ( !set )
			return false;

		int i;

		float fadePerc = 1.0f;

		if ( m_bIsCurrentlyUpgrading )
		{
			Vector	vecSkew = vec3_origin;

			// Skew the particles in front or in back of their targets
			vecSkew = CurrentViewForward() * 4.0f;

			float spriteScale = 1.0f;
			spriteScale = clamp( spriteScale, 0.75f, 1.0f );

			SimpleParticle *sParticle;

			for ( i = 0; i < set->numhitboxes; ++i )
			{
				Vector vecAbsOrigin, xvec, yvec;
				mstudiobbox_t *pBox = set->pHitbox(i);
				ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );

				Vector offset;
				Vector	xDir, yDir;

				xDir = xvec;
				float xScale = VectorNormalize( xDir ) * 0.75f;

				yDir = yvec;
				float yScale = VectorNormalize( yDir ) * 0.75f;

				int numParticles = clamp( 4.0f * fadePerc, 1, 3 );

				for ( int j = 0; j < numParticles; j++ )
				{
					offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
					offset += vecSkew;

					sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/combinemuzzle1" ), vecAbsOrigin + offset );

					if ( sParticle == NULL )
						return 1;
					
					sParticle->m_vecVelocity	= vec3_origin;
					sParticle->m_uchStartSize	= 16.0f * spriteScale;
					sParticle->m_flDieTime		= 0.2f;
					sParticle->m_flLifetime		= 0.0f;

					sParticle->m_flRoll			= Helper_RandomInt( 0, 360 );
					sParticle->m_flRollDelta	= Helper_RandomFloat( -2.0f, 2.0f );

					float alpha = 40;

					sParticle->m_uchColor[0]	= alpha;
					sParticle->m_uchColor[1]	= alpha;
					sParticle->m_uchColor[2]	= alpha;
					sParticle->m_uchStartAlpha	= alpha;
					sParticle->m_uchEndAlpha	= 0;
					sParticle->m_uchEndSize		= sParticle->m_uchStartSize * 2;
				}
			}
		}
	}

	int		attachment = LookupAttachment( "core" );
	Vector	coreOrigin;
	QAngle	coreAngles;

	GetAttachment( attachment, coreOrigin, coreAngles );

	SimpleParticle *sParticle;

	// Do the core effects
	for ( int i = 0; i < 4; i++ )
	{
		sParticle = (SimpleParticle *) m_pLocalEmitter->AddParticle( sizeof(SimpleParticle), m_pLocalEmitter->GetPMaterial( "effects/strider_muzzle" ), vec3_origin );

		if ( sParticle == NULL )
			return 1;
		
		sParticle->m_vecVelocity	= vec3_origin;
		sParticle->m_flDieTime		= 0.1f;
		sParticle->m_flLifetime		= 0.0f;

		sParticle->m_flRoll			= Helper_RandomInt( 0, 360 );
		sParticle->m_flRollDelta	= 0.0f;

		float alpha = 255;

		sParticle->m_uchColor[0]	= alpha;
		sParticle->m_uchColor[1]	= alpha;
		sParticle->m_uchColor[2]	= alpha;
		sParticle->m_uchStartAlpha	= alpha;
		sParticle->m_uchEndAlpha	= 0;

		if ( i < 2 )
		{
			sParticle->m_uchStartSize	= random->RandomFloat( 1, 2 ) * (i+1);
			sParticle->m_uchEndSize		= sParticle->m_uchStartSize * 2.0f;
		}
		else
		{
			if ( random->RandomInt( 0, 20 ) == 0 )
			{
				sParticle->m_uchStartSize	= random->RandomFloat( 1, 2 ) * (i+1);
				sParticle->m_uchEndSize		= sParticle->m_uchStartSize * 4.0f;
				sParticle->m_flDieTime		= 0.25f;
			}
			else
			{
				sParticle->m_uchStartSize	= random->RandomFloat( 1, 2 ) * (i+1);
				sParticle->m_uchEndSize		= sParticle->m_uchStartSize * 2.0f;
			}
		}
	}

	if ( m_bWasUpgraded && m_bIsCurrentlyUpgrading )
	{
		// Update our attractor point
		m_pAttractor->SetAttractorOrigin( coreOrigin );

		Vector offset;

		for ( int i = 0; i < 4; i++ )
		{
			offset = coreOrigin + RandomVector( -32.0f, 32.0f );

			sParticle = (SimpleParticle *) m_pAttractor->AddParticle( sizeof(SimpleParticle), m_pAttractor->GetPMaterial( "effects/strider_muzzle" ), offset );

			if ( sParticle == NULL )
				return 1;
			
			sParticle->m_vecVelocity	= Vector(0,0,8);
			sParticle->m_flDieTime		= 0.5f;
			sParticle->m_flLifetime		= 0.0f;

			sParticle->m_flRoll			= Helper_RandomInt( 0, 360 );
			sParticle->m_flRollDelta	= 0.0f;

			float alpha = 255;

			sParticle->m_uchColor[0]	= alpha;
			sParticle->m_uchColor[1]	= alpha;
			sParticle->m_uchColor[2]	= alpha;
			sParticle->m_uchStartAlpha	= alpha;
			sParticle->m_uchEndAlpha	= 0;

			sParticle->m_uchStartSize	= random->RandomFloat( 1, 2 );
			sParticle->m_uchEndSize		= 0;
		}
	}

	return BaseClass::DrawModel( flags );
}
float PixelVisibility_DrawProxy( IMatRenderContext *pRenderContext, OcclusionQueryObjectHandle_t queryHandle, Vector origin, float scale, float proxyAspect, IMaterial *pMaterial, bool screenspace )
{
	Vector point;

	// don't expand this with distance to fit pixels or the sprite will poke through
	// only expand the parts perpendicular to the view
	float forwardScale = scale;
	// draw a pyramid of points touching a sphere of radius "scale" at origin
	float pixelsPerUnit = pRenderContext->ComputePixelDiameterOfSphere( origin, 1.0f );
	pixelsPerUnit = MAX( pixelsPerUnit, 1e-4f );
	if ( screenspace )
	{
		// Force this to be the size of a sphere of diameter "scale" at some reference distance (1.0 unit)
		float pixelsPerUnit2 = pRenderContext->ComputePixelDiameterOfSphere( CurrentViewOrigin() + CurrentViewForward()*1.0f, scale*0.5f );
		// force drawing of "scale" pixels
		scale = pixelsPerUnit2 / pixelsPerUnit;
	}
	else
	{
		float pixels = scale * pixelsPerUnit;
		
		// make the radius larger to ensure a minimum screen space size of the proxy geometry
		if ( pixels < MIN_PROXY_PIXELS )
		{
			scale = MIN_PROXY_PIXELS / pixelsPerUnit;
		}
	}

	// collapses the pyramid to a plane - so this could be a quad instead
	Vector dir = origin - CurrentViewOrigin();
	VectorNormalize(dir);
	origin -= dir * forwardScale;
	forwardScale = 0.0f;
	// 

	Vector verts[5];
	const float sqrt2 = 0.707106781f; // sqrt(2) - keeps all vectors the same length from origin
	scale *= sqrt2;
	float scale45x = scale;
	float scale45y = scale / proxyAspect;
	verts[0] = origin - CurrentViewForward() * forwardScale;					  // the apex of the pyramid
	verts[1] = origin + CurrentViewUp() * scale45y - CurrentViewRight() * scale45x; // these four form the base
	verts[2] = origin + CurrentViewUp() * scale45y + CurrentViewRight() * scale45x; // the pyramid is a sprite with a point that
	verts[3] = origin - CurrentViewUp() * scale45y + CurrentViewRight() * scale45x; // pokes back toward the camera through any nearby 
	verts[4] = origin - CurrentViewUp() * scale45y - CurrentViewRight() * scale45x; // geometry

	// get screen coords of edges
	Vector screen[4];
	for ( int i = 0; i < 4; i++ )
	{
		extern int ScreenTransform( const Vector& point, Vector& screen );
		if ( ScreenTransform( verts[i+1], screen[i] ) )
			return -1;
	}

	// compute area and screen-clipped area
	float w = screen[1].x - screen[0].x;
	float h = screen[0].y - screen[3].y;
	float ws = MIN(1.0f, screen[1].x) - MAX(-1.0f, screen[0].x);
	float hs = MIN(1.0f, screen[0].y) - MAX(-1.0f, screen[3].y);
	float area = w*h; // area can be zero when we ALT-TAB
	float areaClipped = ws*hs;
	float ratio = 0.0f;
	if ( area != 0 )
	{
		// compute the ratio of the area not clipped by the frustum to total area
		ratio = areaClipped / area;
		ratio = clamp(ratio, 0.0f, 1.0f);
	}

	pRenderContext->BeginOcclusionQueryDrawing( queryHandle );
	CMeshBuilder meshBuilder;
	IMesh* pMesh = pRenderContext->GetDynamicMesh( false, NULL, NULL, pMaterial );
	meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 4 );
	// draw a pyramid
	for ( int i = 0; i < 4; i++ )
	{
		int a = i+1;
		int b = (a%4)+1;
		meshBuilder.Position3fv( verts[0].Base() );
		meshBuilder.AdvanceVertex();
		meshBuilder.Position3fv( verts[a].Base() );
		meshBuilder.AdvanceVertex();
		meshBuilder.Position3fv( verts[b].Base() );
		meshBuilder.AdvanceVertex();
	}
	meshBuilder.End();
	pMesh->Draw();

	// sprite/quad proxy
#if 0
	meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

	VectorMA (origin, -scale, CurrentViewUp(), point);
	VectorMA (point, -scale, CurrentViewRight(), point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	VectorMA (origin, scale, CurrentViewUp(), point);
	VectorMA (point, -scale, CurrentViewRight(), point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	VectorMA (origin, scale, CurrentViewUp(), point);
	VectorMA (point, scale, CurrentViewRight(), point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	VectorMA (origin, -scale, CurrentViewUp(), point);
	VectorMA (point, scale, CurrentViewRight(), point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();
	
	meshBuilder.End();
	pMesh->Draw();
#endif
	pRenderContext->EndOcclusionQueryDrawing( queryHandle );

	// fraction clipped by frustum
	return ratio;
}
예제 #10
0
void CGlowOverlay::Draw( bool bCacheFullSceneState )
{
	extern ConVar	r_drawsprites;
	if( !r_drawsprites.GetBool() )
		return;
	
	// Get the vector to the sun.
	Vector vToGlow;
	
	if( m_bDirectional )
		vToGlow = m_vDirection;
	else
		vToGlow = m_vPos - CurrentViewOrigin();

	VectorNormalize( vToGlow );

	float flDot = vToGlow.Dot( CurrentViewForward() );

	UpdateGlowObstruction( vToGlow, bCacheFullSceneState );
	if( m_flGlowObstructionScale == 0 )
		return;
	
	bool bWireframe = ShouldDrawInWireFrameMode() || (r_drawsprites.GetInt() == 2);
	
	CMatRenderContextPtr pRenderContext( materials );

	for( int iSprite=0; iSprite < m_nSprites; iSprite++ )
	{
		CGlowSprite *pSprite = &m_Sprites[iSprite];
 
		// Figure out the color and size to draw it.
		float flHorzSize, flVertSize;
		Vector vColor;
		CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor );
	
		// If we're alpha'd out, then don't bother
		if ( vColor.LengthSqr() < 0.00001f )
			continue;
		
		// Setup the basis to draw the sprite.
		Vector vBasePt, vUp, vRight;
		CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight );

		//Get our diagonal radius
		float radius = (vRight+vUp).Length();
		if ( R_CullSphere( view->GetFrustum(), 5, &vBasePt, radius ) )
			continue;

		// Get our material (deferred default load)
		if ( m_Sprites[iSprite].m_pMaterial == NULL )
		{
			m_Sprites[iSprite].m_pMaterial = materials->FindMaterial( "sprites/light_glow02_add_noz", TEXTURE_GROUP_CLIENT_EFFECTS );
		}

		Assert( m_Sprites[iSprite].m_pMaterial );
		static unsigned int		nHDRColorScaleCache = 0;
		IMaterialVar *pHDRColorScaleVar = m_Sprites[iSprite].m_pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache );
		if( pHDRColorScaleVar )
		{
			pHDRColorScaleVar->SetFloatValue( m_flHDRColorScale );
		}

		// Draw the sprite.
		IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, m_Sprites[iSprite].m_pMaterial );

		CMeshBuilder builder;
		builder.Begin( pMesh, MATERIAL_QUADS, 1 );
		
		Vector vPt;
		
		vPt = vBasePt - vRight + vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 0, 1 );
		builder.AdvanceVertex();
		
		vPt = vBasePt + vRight + vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 1, 1 );
		builder.AdvanceVertex();
		
		vPt = vBasePt + vRight - vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 1, 0 );
		builder.AdvanceVertex();
		
		vPt = vBasePt - vRight - vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 0, 0 );
		builder.AdvanceVertex();
		
		builder.End( false, true );

		if( bWireframe )
		{
			IMaterial *pWireframeMaterial = materials->FindMaterial( "debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER );
			pRenderContext->Bind( pWireframeMaterial );
			
			// Draw the sprite.
			IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pWireframeMaterial );
			
			CMeshBuilder builder;
			builder.Begin( pMesh, MATERIAL_QUADS, 1 );
			
			Vector vPt;
			
			vPt = vBasePt - vRight + vUp;
			builder.Position3fv( vPt.Base() );
			builder.Color3f( 1.0f, 0.0f, 0.0f );
			builder.AdvanceVertex();
			
			vPt = vBasePt + vRight + vUp;
			builder.Position3fv( vPt.Base() );
			builder.Color3f( 1.0f, 0.0f, 0.0f );
			builder.AdvanceVertex();
			
			vPt = vBasePt + vRight - vUp;
			builder.Position3fv( vPt.Base() );
			builder.Color3f( 1.0f, 0.0f, 0.0f );
			builder.AdvanceVertex();
			
			vPt = vBasePt - vRight - vUp;
			builder.Position3fv( vPt.Base() );
			builder.Color3f( 1.0f, 0.0f, 0.0f );
			builder.AdvanceVertex();
			
			builder.End( false, true );
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: Simulate and render the particle in this system
// Input  : *pInParticle - particle to consider
//			*pDraw - drawing utilities
//			&sortKey - sorting key
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CSimple3DEmitter::SimulateAndRender( Particle *pInParticle, ParticleDraw *pDraw, float &sortKey )
{
	Particle3D *pParticle = (Particle3D *) pInParticle;

	const float	timeDelta = pDraw->GetTimeDelta();

	//Should this particle die?
	pParticle->m_flLifetime += timeDelta;

	if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
		return false;
	
	sortKey = CurrentViewForward().Dot( CurrentViewOrigin() - pParticle->m_Pos );

	// -------------------------------------------------------
	//  Set color based on direction towards camera
	// -------------------------------------------------------
	Vector	color;
	Vector vFaceNorm;
	Vector vCameraToFace = (pParticle->m_Pos - CurrentViewOrigin());
	AngleVectors(pParticle->m_vAngles,&vFaceNorm);
	float flFacing = DotProduct(vCameraToFace,vFaceNorm);

	if (flFacing <= 0)
	{
		color[0] = pParticle->m_uchFrontColor[0] / 255.0f;
		color[1] = pParticle->m_uchFrontColor[1] / 255.0f;
		color[2] = pParticle->m_uchFrontColor[2] / 255.0f;
	}
	else
	{
		color[0] = pParticle->m_uchBackColor[0] / 255.0f;
		color[1] = pParticle->m_uchBackColor[1] / 255.0f;
		color[2] = pParticle->m_uchBackColor[2] / 255.0f;
	}

	// Angular rotation
	pParticle->m_vAngles.x += pParticle->m_flAngSpeed * timeDelta;
	pParticle->m_vAngles.y += pParticle->m_flAngSpeed * timeDelta;
	pParticle->m_vAngles.z += pParticle->m_flAngSpeed * timeDelta;

	//Render it in world space
	RenderParticle_ColorSizeAngles(
		pDraw,
		pParticle->m_Pos,
		color,
		1.0f - (pParticle->m_flLifetime / pParticle->m_flDieTime),
		pParticle->m_uchSize,
		pParticle->m_vAngles);

	//Simulate the movement with collision
	trace_t trace;
	m_ParticleCollision.MoveParticle( pParticle->m_Pos, pParticle->m_vecVelocity, &pParticle->m_flAngSpeed, timeDelta, &trace );

	// ---------------------------------------
	// Decay towards flat
	// ---------------------------------------
	if (pParticle->m_flAngSpeed == 0 || trace.fraction != 1.0)
	{
		pParticle->m_vAngles.x = anglemod(pParticle->m_vAngles.x);
		if (pParticle->m_vAngles.x < 180)
		{
			if (fabs(pParticle->m_vAngles.x - 90) > 0.5)
			{
				pParticle->m_vAngles.x = 0.5*pParticle->m_vAngles.x + 46;
			}
		}
		else
		{
			if (fabs(pParticle->m_vAngles.x - 270) > 0.5)
			{
				pParticle->m_vAngles.x = 0.5*pParticle->m_vAngles.x + 135;
			}
		}

		pParticle->m_vAngles.y = anglemod(pParticle->m_vAngles.y);
		if (fabs(pParticle->m_vAngles.y) > 0.5)
		{
			pParticle->m_vAngles.y = 0.5*pParticle->m_vAngles.z;
		}
	}
	return true;
}
예제 #12
0
//-----------------------------------------------------------------------------
// Purpose: Special draw for the warped overlay
//-----------------------------------------------------------------------------
void CWarpOverlay::Draw( bool bCacheFullSceneState )
{
	// Get the vector to the sun.
	Vector vToGlow;
	
	if( m_bDirectional )
		vToGlow = m_vDirection;
	else
		vToGlow = m_vPos - CurrentViewOrigin();

	VectorNormalize( vToGlow );

	float flDot = vToGlow.Dot( CurrentViewForward() );

	if( flDot <= g_flOverlayRange )
		return;

	UpdateGlowObstruction( vToGlow, bCacheFullSceneState );
	if( m_flGlowObstructionScale == 0 )
		return;
	
	CMatRenderContextPtr pRenderContext( materials );
	
	//FIXME: Allow multiple?
	for( int iSprite=0; iSprite < m_nSprites; iSprite++ )
	{
		CGlowSprite *pSprite = &m_Sprites[iSprite];

		// Figure out the color and size to draw it.
		float flHorzSize, flVertSize;
		Vector vColor;
		CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor );
	
		// Setup the basis to draw the sprite.
		Vector vBasePt, vUp, vRight;
		CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight );

		// Draw the sprite.
		IMaterial *pMaterial = materials->FindMaterial( "sun/overlay", TEXTURE_GROUP_CLIENT_EFFECTS );
		IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pMaterial );

		CMeshBuilder builder;
		builder.Begin( pMesh, MATERIAL_QUADS, 1 );
		
		Vector vPt;

		vPt = vBasePt - vRight + vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 0, 1 );
		builder.AdvanceVertex();

		vPt = vBasePt + vRight + vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 1, 1 );
		builder.AdvanceVertex();

		vPt = vBasePt + vRight - vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 1, 0 );
		builder.AdvanceVertex();

		vPt = vBasePt - vRight - vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 0, 0 );
		builder.AdvanceVertex();
		
		builder.End( false, true );
	}
}
예제 #13
0
//-----------------------------------------------------------------------------
// Purpose: 
// TFTODO: Make the sniper dot get brighter the more damage it will do.
//-----------------------------------------------------------------------------
int CSniperDot::DrawModel( int flags )
{
	// Get the owning player.
	C_TFPlayer *pPlayer = ToTFPlayer( GetOwnerEntity() );
	if ( !pPlayer )
		return -1;

	// Get the sprite rendering position.
	Vector vecEndPos;

	float flSize = 6.0;

	if ( !pPlayer->IsDormant() )
	{
		Vector vecAttachment, vecDir;
		QAngle angles;

		float flDist = MAX_TRACE_LENGTH;

		// Always draw the dot in front of our faces when in first-person.
		if ( pPlayer->IsLocalPlayer() )
		{
			// Take our view position and orientation
			vecAttachment = CurrentViewOrigin();
			vecDir = CurrentViewForward();

			// Clamp the forward distance for the sniper's firstperson
			flDist = 384;

			flSize = 2.0;
		}
		else
		{
			// Take the owning player eye position and direction.
			vecAttachment = pPlayer->EyePosition();
			QAngle angles = pPlayer->EyeAngles();
			AngleVectors( angles, &vecDir );
		}

		trace_t tr;
		UTIL_TraceLine( vecAttachment, vecAttachment + ( vecDir * flDist ), MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr );

		// Backup off the hit plane, towards the source
		vecEndPos = tr.endpos + vecDir * -4;
	}
	else
	{
		// Just use our position if we can't predict it otherwise.
		vecEndPos = GetAbsOrigin();
	}

	// Draw our laser dot in space.
	CMatRenderContextPtr pRenderContext( materials );
	pRenderContext->Bind( m_hSpriteMaterial, this );

	float flLifeTime = gpGlobals->curtime - m_flChargeStartTime;
	float flStrength = RemapValClamped( flLifeTime, 0.0, TF_WEAPON_SNIPERRIFLE_DAMAGE_MAX / TF_WEAPON_SNIPERRIFLE_CHARGE_PER_SEC, 0.1, 1.0 );

	color32 innercolor = { 255, 255, 255, 255 };
	color32 outercolor = { 255, 255, 255, 128 };

	DrawSprite( vecEndPos, flSize, flSize, outercolor );
	DrawSprite( vecEndPos, flSize * flStrength, flSize * flStrength, innercolor );

	// Successful.
	return 1;
}
예제 #14
0
//-----------------------------------------------------------------------------
// Purpose: 
// TFTODO: Make the sniper dot get brighter the more damage it will do.
//-----------------------------------------------------------------------------
int CSniperDot::DrawModel( int flags )
{
	// Get the owning player.
	C_TFPlayer *pPlayer = ToTFPlayer( GetOwnerEntity() );
	if ( !pPlayer )
		return -1;

	// Get the sprite rendering position.
	Vector vecEndPos;

	float flSize = 6.0;

	if ( !pPlayer->IsDormant() )
	{
		Vector vecAttachment, vecDir;
		QAngle angles;

		float flDist = MAX_TRACE_LENGTH;

		// Always draw the dot in front of our faces when in first-person.
		if ( pPlayer->IsLocalPlayer() )
		{
			// Take our view position and orientation
			vecAttachment = CurrentViewOrigin();
			vecDir = CurrentViewForward();

			// Clamp the forward distance for the sniper's firstperson
			flDist = 384;

			flSize = 2.0;
		}
		else
		{
			// Take the owning player eye position and direction.
			vecAttachment = pPlayer->EyePosition();
			QAngle angles = pPlayer->EyeAngles();
			AngleVectors( angles, &vecDir );
		}

		trace_t tr;
		UTIL_TraceLine( vecAttachment, vecAttachment + ( vecDir * flDist ), MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr );

		// Backup off the hit plane, towards the source
		vecEndPos = tr.endpos + vecDir * -4;
	}
	else
	{
		// Just use our position if we can't predict it otherwise.
		vecEndPos = GetAbsOrigin();
	}

	// Draw our laser dot in space.
	CMatRenderContextPtr pRenderContext( materials );
	pRenderContext->Bind( m_hSpriteMaterial, this );

	float flLifeTime = gpGlobals->curtime - m_flChargeStartTime;
	float flStrength = RemapValClamped( flLifeTime, 0.0, TF_WEAPON_SNIPERRIFLE_DAMAGE_MAX / TF_WEAPON_SNIPERRIFLE_CHARGE_PER_SEC, 0.1, 1.0 );
	
	color32 innercolor = { 255, 255, 255, 255 };
	color32 outercolor = { 255, 255, 255, 128 };

	// PistonMiner: DM sniper point coloring
	if (TFGameRules()->IsDeathmatch())
	{
		// Get the color of the mercenary we are drawing the dot of.
		C_TF_PlayerResource *tf_PR = dynamic_cast<C_TF_PlayerResource *>(g_PR);
		Color ownercolor = tf_PR->GetPlayerColor(pPlayer->index);

		// Convert to HSV so we can edit the color better.
		Vector hsv, rgb;
		RGBtoHSV(Vector(ownercolor.r() / 255.f, ownercolor.g() / 255.f, ownercolor.b() / 255.f), hsv);

		// Set the Value to max for constant brightness.
		hsv.z = 1.0;

		// Convert back to RGB
		HSVtoRGB(hsv, rgb);

		// Apply the color to our sprite.
		m_hSpriteMaterial->ColorModulate( rgb.x, rgb.y, rgb.z );
	}

	DrawSprite( vecEndPos, flSize, flSize, outercolor );
	DrawSprite( vecEndPos, flSize * flStrength, flSize * flStrength, innercolor );

	// Successful.
	return 1;
}
예제 #15
0
//-----------------------------------------------------------------------------
// Purpose: Determine sprite orientation axes
// Input  : type - 
//			forward - 
//			right - 
//			up - 
//-----------------------------------------------------------------------------
void C_SpriteRenderer::GetSpriteAxes( SPRITETYPE type, 
	const Vector& origin,
	const QAngle& angles,
	Vector& forward, 
	Vector& right, 
	Vector& up )
{
	int				i;
	float			dot, angle, sr, cr;
	Vector			tvec;

	// Automatically roll parallel sprites if requested
	if ( angles[2] != 0 && type == SPR_VP_PARALLEL )
	{
		type = SPR_VP_PARALLEL_ORIENTED;
	}

	switch( type )
	{
	case SPR_FACING_UPRIGHT:
		{
			// generate the sprite's axes, with vup straight up in worldspace, and
			// r_spritedesc.vright perpendicular to modelorg.
			// This will not work if the view direction is very close to straight up or
			// down, because the cross product will be between two nearly parallel
			// vectors and starts to approach an undefined state, so we don't draw if
			// the two vectors are less than 1 degree apart
			tvec[0] = -origin[0];
			tvec[1] = -origin[1];
			tvec[2] = -origin[2];
			VectorNormalize (tvec);
			dot = tvec[2];	// same as DotProduct (tvec, r_spritedesc.vup) because
			//  r_spritedesc.vup is 0, 0, 1
			if ((dot > 0.999848f) || (dot < -0.999848f))	// cos(1 degree) = 0.999848
				return;
			up[0] = 0;
			up[1] = 0;
			up[2] = 1;
			right[0] = tvec[1];
			// CrossProduct(r_spritedesc.vup, -modelorg,
			right[1] = -tvec[0];
			//              r_spritedesc.vright)
			right[2] = 0;
			VectorNormalize (right);
			forward[0] = -right[1];
			forward[1] = right[0];
			forward[2] = 0;
			// CrossProduct (r_spritedesc.vright, r_spritedesc.vup,
			//  r_spritedesc.vpn)
		}
		break;

	case SPR_VP_PARALLEL:
		{
			// generate the sprite's axes, completely parallel to the viewplane. There
			// are no problem situations, because the sprite is always in the same
			// position relative to the viewer
			for (i=0 ; i<3 ; i++)
			{
				up[i]		= CurrentViewUp()[i];
				right[i]	= CurrentViewRight()[i];
				forward[i]	= CurrentViewForward()[i];
			}
		}
		break;

	case SPR_VP_PARALLEL_UPRIGHT:
		{
			// generate the sprite's axes, with g_vecVUp straight up in worldspace, and
			// r_spritedesc.vright parallel to the viewplane.
			// This will not work if the view direction is very close to straight up or
			// down, because the cross product will be between two nearly parallel
			// vectors and starts to approach an undefined state, so we don't draw if
			// the two vectors are less than 1 degree apart
			dot = CurrentViewForward()[2];	// same as DotProduct (vpn, r_spritedesc.g_vecVUp) because
			//  r_spritedesc.vup is 0, 0, 1
			if ((dot > 0.999848f) || (dot < -0.999848f))	// cos(1 degree) = 0.999848
				return;
			up[0] = 0;
			up[1] = 0;
			up[2] = 1;
			right[0] = CurrentViewForward()[1];
			// CrossProduct (r_spritedesc.vup, vpn,
			right[1] = -CurrentViewForward()[0];	//  r_spritedesc.vright)
			right[2] = 0;
			VectorNormalize (right);
			forward[0] = -right[1];
			forward[1] = right[0];
			forward[2] = 0;
			// CrossProduct (r_spritedesc.vright, r_spritedesc.vup,
			//  r_spritedesc.vpn)
		}
		break;

	case SPR_ORIENTED:
		{
			// generate the sprite's axes, according to the sprite's world orientation
			AngleVectors( angles, &forward, &right, &up );
		}
		break;
		
	case SPR_VP_PARALLEL_ORIENTED:
		{
			// generate the sprite's axes, parallel to the viewplane, but rotated in
			// that plane around the center according to the sprite entity's roll
			// angle. So vpn stays the same, but vright and vup rotate
			angle = angles[ROLL] * (M_PI*2.0f/360.0f);
			SinCos( angle, &sr, &cr );
			
			for (i=0 ; i<3 ; i++)
			{
				forward[i] = CurrentViewForward()[i];
				right[i] = CurrentViewRight()[i] * cr + CurrentViewUp()[i] * sr;
				up[i] = CurrentViewRight()[i] * -sr + CurrentViewUp()[i] * cr;
			}
		}
		break;

	default:
		Warning( "GetSpriteAxes: Bad sprite type %d\n", type );
		break;
	}
}
예제 #16
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : flags - 
// Output : int
//-----------------------------------------------------------------------------
int C_EntityDissolve::DrawModel( int flags )
{
	// See if we should draw
	if ( gpGlobals->frametime == 0 || m_bReadyToDraw == false )
		return 0;

	C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL;
	if ( pAnimating == NULL )
		return 0;

	matrix3x4_t	*hitboxbones[MAXSTUDIOBONES];
	if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) == false )
		return 0;

	studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
	if ( pStudioHdr == NULL )
		return false;

	mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
	if ( set == NULL )
		return false;

	// Make sure the emitter is setup properly
	SetupEmitter();
	
	// Get fade percentages for the effect
	float fadeInPerc = GetFadeInPercentage();
	float fadeOutPerc = GetFadeOutPercentage();

	float fadePerc = ( fadeInPerc >= 1.0f ) ? fadeOutPerc : fadeInPerc;

	Vector vecSkew = vec3_origin;

	// Do extra effects under certain circumstances
	if ( ( fadePerc < 0.99f ) && ( (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) )
	{
		DoSparks( set, hitboxbones );
	}

	// Skew the particles in front or in back of their targets
	vecSkew = CurrentViewForward() * ( 8.0f - ( ( 1.0f - fadePerc ) * 32.0f ) );

	float spriteScale = ( ( gpGlobals->curtime - m_flStartTime ) / m_flFadeOutLength );
	spriteScale = clamp( spriteScale, 0.75f, 1.0f );

	// Cache off this material reference
	if ( g_Material_Spark == NULL )
	{
		g_Material_Spark = ParticleMgr()->GetPMaterial( "effects/spark" );
	}

	if ( g_Material_AR2Glow == NULL )
	{
		g_Material_AR2Glow = ParticleMgr()->GetPMaterial( "effects/combinemuzzle2" );
	}

	SimpleParticle *sParticle;

	for ( int i = 0; i < set->numhitboxes; ++i )
	{
		Vector vecAbsOrigin, xvec, yvec;
		mstudiobbox_t *pBox = set->pHitbox(i);
		ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );

		Vector offset;
		Vector	xDir, yDir;

		xDir = xvec;
		float xScale = VectorNormalize( xDir ) * 0.75f;

		yDir = yvec;
		float yScale = VectorNormalize( yDir ) * 0.75f;

		int numParticles = clamp( 3.0f * fadePerc, 0.f, 3.f );

		int iTempParts = 2;

		if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
		{
			if ( m_bCoreExplode == true )
			{
				numParticles = 15;
				iTempParts = 20;
			}
		}

		for ( int j = 0; j < iTempParts; j++ )
		{
			// Skew the origin
			offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
			offset += vecSkew;

			if ( random->RandomInt( 0, 2 ) != 0 )
				continue;

			sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_Spark, vecAbsOrigin + offset );
			
			if ( sParticle == NULL )
				return 1;

			sParticle->m_vecVelocity	= Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 16.0f, 64.0f ) );
			
			if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
			{
				if ( m_bCoreExplode == true )
				{
					Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;
					VectorNormalize( vDirection );
					sParticle->m_vecVelocity = vDirection * m_nMagnitude;
				}
			}

			if ( sParticle->m_vecVelocity.z > 0 )
			{
				sParticle->m_uchStartSize	= random->RandomFloat( 4, 6 ) * spriteScale;
			}
			else
			{
				sParticle->m_uchStartSize	= 2 * spriteScale;
			}

			sParticle->m_flDieTime = random->RandomFloat( 0.4f, 0.5f );
			
			// If we're the last particles, last longer
			if ( numParticles == 0 )
			{
				sParticle->m_flDieTime *= 2.0f;
				sParticle->m_uchStartSize = 2 * spriteScale;
				sParticle->m_flRollDelta	= Helper_RandomFloat( -4.0f, 4.0f );

				if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
				{
					if ( m_bCoreExplode == true )
					{
						sParticle->m_flDieTime *= 2.0f;
						sParticle->m_flRollDelta	= Helper_RandomFloat( -1.0f, 1.0f );
					}
				}
			}
			else
			{
				sParticle->m_flRollDelta	= Helper_RandomFloat( -8.0f, 8.0f );
			}
			
			sParticle->m_flLifetime		= 0.0f;

			sParticle->m_flRoll			= Helper_RandomInt( 0, 360 );

			float alpha = 255;

			sParticle->m_uchColor[0]	= m_vEffectColor.x;
			sParticle->m_uchColor[1]	= m_vEffectColor.y;
			sParticle->m_uchColor[2]	= m_vEffectColor.z;
			sParticle->m_uchStartAlpha	= alpha;
			sParticle->m_uchEndAlpha	= 0;
			sParticle->m_uchEndSize		= 0;
		}
			
		for ( int j = 0; j < numParticles; j++ )
		{
			offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
			offset += vecSkew;

			sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_AR2Glow, vecAbsOrigin + offset );

			if ( sParticle == NULL )
				return 1;
			
			sParticle->m_vecVelocity	= Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -64.0f, 128.0f ) );
			sParticle->m_uchStartSize	= random->RandomFloat( 8, 12 ) * spriteScale;
			sParticle->m_flDieTime		= 0.1f;
			sParticle->m_flLifetime		= 0.0f;

			sParticle->m_flRoll			= Helper_RandomInt( 0, 360 );
			sParticle->m_flRollDelta	= Helper_RandomFloat( -2.0f, 2.0f );

			float alpha = 255;

			sParticle->m_uchColor[0]	= m_vEffectColor.x;
			sParticle->m_uchColor[1]	= m_vEffectColor.y;
			sParticle->m_uchColor[2]	= m_vEffectColor.z;
			sParticle->m_uchStartAlpha	= alpha;
			sParticle->m_uchEndAlpha	= 0;
			sParticle->m_uchEndSize		= 0;

			if ( m_nDissolveType == ENTITY_DISSOLVE_CORE )
			{
				if ( m_bCoreExplode == true )
				{
					Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin;

					VectorNormalize( vDirection );

					sParticle->m_vecVelocity = vDirection * m_nMagnitude;

					sParticle->m_flDieTime		= 0.5f;
				}
			}
		}
	}

	return 1;
}
예제 #17
0
void CFXDiscreetLine::Draw( double frametime )
{
	Vector			lineDir, viewDir, cross;

	Vector			vecEnd, vecStart;
	Vector tmp;

	// Update the effect
	Update( frametime );

	// Calculate our distance along our path
	float	sDistance = m_fVelocity * m_fStartTime;
	float	eDistance = sDistance - m_fLength;
	
	//Clip to start
	sDistance = MAX( 0.0f, sDistance );
	eDistance = MAX( 0.0f, eDistance );

	if ( ( sDistance == 0.0f ) && ( eDistance == 0.0f ) )
		return;

	// Clip it
	if ( m_fClipLength != 0.0f )
	{
		sDistance = MIN( sDistance, m_fClipLength );
		eDistance = MIN( eDistance, m_fClipLength );
	}

	// Get our delta to calculate the tc offset
	float	dDistance	= fabs( sDistance - eDistance );
	float	dTotal		= ( m_fLength != 0.0f ) ? m_fLength : 0.01f;
	float	fOffset		= ( dDistance / dTotal );

	// Find our points along our path
	VectorMA( m_vecOrigin, sDistance, m_vecDirection, vecEnd );
	VectorMA( m_vecOrigin, eDistance, m_vecDirection, vecStart );

	//Setup our info for drawing the line
	VectorSubtract( vecEnd, vecStart, lineDir );
	VectorSubtract( vecEnd, CurrentViewOrigin(), viewDir );
	
	cross = lineDir.Cross( viewDir );
	VectorNormalize( cross );

	CMeshBuilder meshBuilder;
	IMesh *pMesh;

	CMatRenderContextPtr pRenderContext( materials );
		
	// Better, more visible tracers
	if ( tracer_extra.GetBool() )
	{
		float flScreenWidth = ScreenWidth();
		float flHalfScreenWidth = flScreenWidth * 0.5f;
		
		float zCoord = CurrentViewForward().Dot( vecStart - CurrentViewOrigin() );
		float flScreenSpaceWidth = m_fScale * flHalfScreenWidth / zCoord;

		float flAlpha;
		float flScale;

		if ( flScreenSpaceWidth < 0.5f )
		{
			flAlpha = RemapVal( flScreenSpaceWidth, 0.25f, 2.0f, 0.3f, 1.0f );
			flAlpha = clamp( flAlpha, 0.25f, 1.0f );
			flScale = 0.5f * zCoord / flHalfScreenWidth;
		}
		else
		{
			flAlpha = 1.0f;
			flScale = m_fScale;
		}

		//Bind the material
		pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial );

		meshBuilder.Begin( pMesh, MATERIAL_QUADS, 2 );

		float color = (int) 255.0f * flAlpha;

		//FIXME: for now no coloration
		VectorMA( vecStart, -flScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
		meshBuilder.Color4ub( color, color, color, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecStart,  flScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
		meshBuilder.Color4ub( color, color, color, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecEnd, flScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 0.0f, fOffset );
		meshBuilder.Color4ub( color, color, color, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecEnd, -flScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 1.0f, fOffset );
		meshBuilder.Color4ub( color, color, color, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		flScale = flScale * 2.0f;
		color = (int) 64.0f * flAlpha;

		// Soft outline
		VectorMA( vecStart, -flScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
		meshBuilder.Color4ub( color, color, color, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecStart,  flScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
		meshBuilder.Color4ub( color, color, color, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecEnd, flScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 0.0f, fOffset );
		meshBuilder.Color4ub( color, color, color, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecEnd, -flScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 1.0f, fOffset );
		meshBuilder.Color4ub( color, color, color, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();
	}
	else
	{
		//Bind the material
		pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial );

		meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

		//FIXME: for now no coloration
		VectorMA( vecStart, -m_fScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
		meshBuilder.Color4ub( 255, 255, 255, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecStart,  m_fScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
		meshBuilder.Color4ub( 255, 255, 255, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecEnd, m_fScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 0.0f, fOffset );
		meshBuilder.Color4ub( 255, 255, 255, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();

		VectorMA( vecEnd, -m_fScale, cross, tmp );
		meshBuilder.Position3fv( tmp.Base() );
		meshBuilder.TexCoord2f( 0, 1.0f, fOffset );
		meshBuilder.Color4ub( 255, 255, 255, 255 );
		meshBuilder.Normal3fv( cross.Base() );
		meshBuilder.AdvanceVertex();
	}

	meshBuilder.End();
	pMesh->Draw();
}