Exemplo n.º 1
0
void ParticleSystem::DrawParticle(particle *part, vec3_t &right, vec3_t &up)
{
	float fSize = part->m_fSize;
	vec3_t point1,point2,point3,point4;
	vec3_t origin = part->origin;

	// nothing to draw?
	if (fSize == 0) return;

	//frustrum visible check
	if(!ParticleIsVisible(part)) return;

	float fCosSize = CosLookup(part->m_fAngle)*fSize;
	float fSinSize = SinLookup(part->m_fAngle)*fSize;

	// calculate the four corners of the sprite
	VectorMA (origin, fSinSize, up, point1);
	VectorMA (point1, -fCosSize, right, point1);
	
	VectorMA (origin, fCosSize, up, point2);
	VectorMA (point2, fSinSize, right, point2);
	
	VectorMA (origin, -fSinSize, up, point3);
	VectorMA (point3, fCosSize, right, point3);

	VectorMA (origin, -fCosSize, up, point4);
	VectorMA (point4, -fSinSize, right, point4);

	struct model_s * pModel;
	int iContents = 0;

	for (particle *pDraw = part; pDraw; pDraw = pDraw->m_pOverlay)
	{
		if (pDraw->pType->m_hSprite == 0)
			continue;

		if (pDraw->pType->m_iDrawCond)
		{
			if (iContents == 0)
				iContents = gEngfuncs.PM_PointContents(origin, NULL);

			if (iContents != pDraw->pType->m_iDrawCond)
				continue;
		}

		pModel = (struct model_s *)gEngfuncs.GetSpritePointer( pDraw->pType->m_hSprite );

		// if we've reached the end of the sprite's frames, loop back
		while (pDraw->frame > pModel->numframes) pDraw->frame -= pModel->numframes;

		while (pDraw->frame < 0) pDraw->frame += pModel->numframes;

		if ( !gEngfuncs.pTriAPI->SpriteTexture( pModel, int(pDraw->frame) ))continue;

		gEngfuncs.pTriAPI->RenderMode(pDraw->pType->m_iRenderMode);
		gEngfuncs.pTriAPI->Color4f( pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue, pDraw->m_fAlpha );
		gEngfuncs.pTriAPI->Begin( TRI_QUADS );
			gEngfuncs.pTriAPI->TexCoord2f (0, 0);
			gEngfuncs.pTriAPI->Vertex3fv(point1);

			gEngfuncs.pTriAPI->TexCoord2f (1, 0);
			gEngfuncs.pTriAPI->Vertex3fv (point2);

			gEngfuncs.pTriAPI->TexCoord2f (1, 1);
			gEngfuncs.pTriAPI->Vertex3fv (point3);

			gEngfuncs.pTriAPI->TexCoord2f (0, 1);
			gEngfuncs.pTriAPI->Vertex3fv (point4);
		gEngfuncs.pTriAPI->End();
	}
}
Exemplo n.º 2
0
bool ParticleSystem::UpdateParticle(particle *part, float frametime)
{
	if (frametime == 0 ) return true;
	part->age += frametime;

	cl_entity_t *source = UTIL_GetClientEntityWithServerIndex( m_iEntIndex );

	// is this particle bound to an entity?
	if (part->m_iEntIndex)
	{
		if (enable)
		{
			if(m_iEntAttachment)
			{
				part->velocity = (source->attachment[m_iEntAttachment - 1] - part->origin)/frametime;
				part->origin = source->attachment[m_iEntAttachment - 1];
			}
			else
			{
				part->velocity = (source->curstate.origin - part->origin)/frametime;
				part->origin = source->curstate.origin;
			}
		}
		else
		{
			// entity is switched off, die
			return false;
		}
	}
	else
	{
		// not tied to an entity, check whether it's time to die
		if (part->age_death >= 0 && part->age > part->age_death)
			return false;

		// apply acceleration and velocity
		vec3_t vecOldPos = part->origin;
		if (part->m_fDrag)
			VectorMA(part->velocity, -part->m_fDrag*frametime, part->velocity - part->m_vecWind, part->velocity);
		VectorMA(part->velocity, frametime, part->accel, part->velocity);
		VectorMA(part->origin, frametime, part->velocity, part->origin);

		if (part->pType->m_bBouncing)
		{
			vec3_t vecTarget;
			VectorMA(part->origin, frametime, part->velocity, vecTarget);
			pmtrace_t *tr = gEngfuncs.PM_TraceLine( part->origin, vecTarget, PM_TRACELINE_PHYSENTSONLY, 2, -1 );
			if (tr->fraction < 1)
			{
				part->origin = tr->endpos;
				float bounceforce = DotProduct(tr->plane.normal, part->velocity);
				float newspeed = (1 - part->pType->m_BounceFriction.GetInstance());
				part->velocity = part->velocity * newspeed;
				VectorMA(part->velocity, -bounceforce*(newspeed+part->pType->m_Bounce.GetInstance()), tr->plane.normal, part->velocity);
			}
		}
	}

	// spray children
	if (part->age_spray && part->age > part->age_spray)
	{
		part->age_spray = part->age + 1/part->pType->m_SprayRate.GetInstance();

		//particle *pChild = ActivateParticle();
		if (part->pType->m_pSprayType)
		{
			particle *pChild = part->pType->m_pSprayType->CreateParticle(this);
			if (pChild)
			{
				pChild->origin = part->origin;
				float fSprayForce = part->pType->m_SprayForce.GetInstance();
				pChild->velocity = part->velocity;
				if (fSprayForce)
				{
					float fSprayPitch = part->pType->m_SprayPitch.GetInstance() - source->curstate.angles.x;
					float fSprayYaw = part->pType->m_SprayYaw.GetInstance() - source->curstate.angles.y;
					float fSprayRoll = source->curstate.angles.z;
					float fForceCosPitch = fSprayForce*CosLookup(fSprayPitch);
					pChild->velocity.x += CosLookup(fSprayYaw) * fForceCosPitch;
					pChild->velocity.y += SinLookup(fSprayYaw) * fForceCosPitch + SinLookup(fSprayYaw) * fSprayForce * SinLookup(fSprayRoll);
					pChild->velocity.z -= SinLookup(fSprayPitch) * fSprayForce * CosLookup(fSprayRoll);
				}
			}
		}
	}

	part->m_fSize += part->m_fSizeStep * frametime;
	part->m_fAlpha += part->m_fAlphaStep * frametime;
	part->m_fRed += part->m_fRedStep * frametime;
	part->m_fGreen += part->m_fGreenStep * frametime;
	part->m_fBlue += part->m_fBlueStep * frametime;
	part->frame += part->m_fFrameStep * frametime;
	if (part->m_fAngleStep)
	{
		part->m_fAngle += part->m_fAngleStep * frametime;
		while (part->m_fAngle < 0) part->m_fAngle += 360;
		while (part->m_fAngle > 360) part->m_fAngle -= 360;
	}
	return true;
}
Exemplo n.º 3
0
bool ParticleSystem::UpdateParticle( particle *part, float frametime )
{
	if( frametime == 0 ) return true;
	part->age += frametime;

	edict_t *source = GetEntityByIndex( m_iEntIndex );
	if( !source ) return false;	// total paranoia :)

	// is this particle bound to an entity?
	if( part->m_iEntIndex )
	{
		if ( enable )
		{
			if( m_iEntAttachment )
			{
				Vector	pos = Vector( 0, 0, 0 );

				GET_ATTACHMENT( source, m_iEntAttachment, pos, NULL );
				if( pos == Vector( 0, 0, 0 )) pos = source->v.origin; // missed attachment
				part->velocity = (pos - part->origin ) / frametime;
				part->origin = pos;
			}
			else
			{
				part->velocity = ( source->v.origin - part->origin ) / frametime;
				part->origin = source->v.origin;
			}
		}
		else
		{
			// entity is switched off, die
			return false;
		}
	}
	else
	{
		// not tied to an entity, check whether it's time to die
		if( part->age_death >= 0 && part->age > part->age_death )
			return false;

		// apply acceleration and velocity
		Vector vecOldPos = part->origin;

		if ( part->m_fDrag )
			part->velocity = part->velocity + (-part->m_fDrag * frametime) * ( part->velocity - part->m_vecWind );
		part->velocity = part->velocity + frametime * part->accel;
		part->origin = part->origin + frametime * part->velocity;

		if( part->pType->m_bBouncing )
		{
			Vector vecTarget = part->origin + frametime * part->velocity;
			TraceResult tr;
			TRACE_LINE( part->origin, vecTarget, true, source, &tr );

			if( tr.flFraction < 1.0f )
			{
				part->origin = tr.vecEndPos;
				float bounceforce = DotProduct( tr.vecPlaneNormal, part->velocity );
				float newspeed = (1.0f - part->pType->m_BounceFriction.GetInstance());
				part->velocity = part->velocity * newspeed;
				part->velocity = part->velocity + (-bounceforce * ( newspeed + part->pType->m_Bounce.GetInstance())) * tr.vecPlaneNormal;
			}
		}
	}


	// spray children
	if ( part->age_spray && part->age > part->age_spray )
	{
		part->age_spray = part->age + 1/part->pType->m_SprayRate.GetInstance();

		// particle *pChild = ActivateParticle();
		if (part->pType->m_pSprayType)
		{
			particle *pChild = part->pType->m_pSprayType->CreateParticle(this);
			if (pChild)
			{
				pChild->origin = part->origin;
				float fSprayForce = part->pType->m_SprayForce.GetInstance();
				pChild->velocity = part->velocity;
				if (fSprayForce)
				{
					float fSprayPitch = part->pType->m_SprayPitch.GetInstance() - source->v.angles.x;
					float fSprayYaw = part->pType->m_SprayYaw.GetInstance() - source->v.angles.y;
					float fSprayRoll = source->v.angles.z;
					float fForceCosPitch = fSprayForce*CosLookup(fSprayPitch);
					pChild->velocity.x += CosLookup(fSprayYaw) * fForceCosPitch;
					pChild->velocity.y += SinLookup(fSprayYaw) * fForceCosPitch + SinLookup(fSprayYaw) * fSprayForce * SinLookup(fSprayRoll);
					pChild->velocity.z -= SinLookup(fSprayPitch) * fSprayForce * CosLookup(fSprayRoll);
				}
			}
		}
	}

	part->m_fSize += part->m_fSizeStep * frametime;
	part->m_fAlpha += part->m_fAlphaStep * frametime;
	part->m_fRed += part->m_fRedStep * frametime;
	part->m_fGreen += part->m_fGreenStep * frametime;
	part->m_fBlue += part->m_fBlueStep * frametime;
	part->frame += part->m_fFrameStep * frametime;
	if ( part->m_fAngleStep )
	{
		part->m_fAngle += part->m_fAngleStep * frametime;
		while ( part->m_fAngle < 0 ) part->m_fAngle += 360;
		while ( part->m_fAngle > 360 ) part->m_fAngle -= 360;
	}
	return true;
}
Exemplo n.º 4
0
void ParticleSystem::DrawParticle( particle *part, Vector &right, Vector &up )
{
	float fSize = part->m_fSize;
	Vector point1, point2, point3, point4;
	Vector origin = part->origin;

	// nothing to draw?
	if ( fSize == 0 ) return;

	// frustrum visible check
	if( !ParticleIsVisible( part )) return;

	float fCosSize = CosLookup( part->m_fAngle ) * fSize;
	float fSinSize = SinLookup( part->m_fAngle ) * fSize;

	// calculate the four corners of the sprite
	point1 = origin + fSinSize * up;
	point1 = point1 + (-fCosSize) * right;
	
	point2 = origin + fCosSize * up;
	point2 = point2 + fSinSize * right;

	point3 = origin + (-fSinSize) * up;	
	point3 = point3 + fCosSize * right;

	point4 = origin + (-fCosSize) * up;
	point4 = point4 + (-fSinSize) * right;

	int iContents = 0;

	g_engfuncs.pTriAPI->Enable( TRI_SHADER );

	for ( particle *pDraw = part; pDraw; pDraw = pDraw->m_pOverlay )
	{
		if( pDraw->pType->m_SpriteIndex == 0 )
			continue;

		if ( pDraw->pType->m_iDrawCond )
		{
			if ( iContents == 0 )
				iContents = POINT_CONTENTS( origin );

			if ( iContents != pDraw->pType->m_iDrawCond )
				continue;
		}
                    
		int numFrames = GetModelFrames( pDraw->pType->m_SpriteIndex );

		// ALERT( at_console, "UpdParticle %d: age %f, life %f, R:%f G:%f, B, %f \n", pDraw->pType->m_hSprite, part->age, part->age_death, pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue);

		// if we've reached the end of the sprite's frames, loop back
		while ( pDraw->frame > numFrames )
			pDraw->frame -= numFrames;

		while ( pDraw->frame < 0 )
			pDraw->frame += numFrames;

		HSPRITE m_hSprite;

		m_hSprite = g_engfuncs.pTriAPI->GetSpriteTexture( pDraw->pType->m_SpriteIndex, int( pDraw->frame ));
		g_engfuncs.pTriAPI->RenderMode( pDraw->pType->m_iRenderMode );
		g_engfuncs.pTriAPI->Color4f( pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue, pDraw->m_fAlpha );
			
		g_engfuncs.pTriAPI->Bind( m_hSprite, int( pDraw->frame ));
		
		g_engfuncs.pTriAPI->Begin( TRI_QUADS );
		g_engfuncs.pTriAPI->TexCoord2f ( 0, 0 );
		g_engfuncs.pTriAPI->Vertex3fv( point1 );

		g_engfuncs.pTriAPI->TexCoord2f ( 1, 0 );
		g_engfuncs.pTriAPI->Vertex3fv ( point2 );

		g_engfuncs.pTriAPI->TexCoord2f ( 1, 1 );
		g_engfuncs.pTriAPI->Vertex3fv ( point3 );

		g_engfuncs.pTriAPI->TexCoord2f ( 0, 1 );
		g_engfuncs.pTriAPI->Vertex3fv ( point4 );
		g_engfuncs.pTriAPI->End();
	}
	g_engfuncs.pTriAPI->Disable( TRI_SHADER );
}
Exemplo n.º 5
0
void CParticleSystem :: DrawParticle( CParticle *part, Vector &right, Vector &up )
{
	float fSize = part->m_fSize;

	// nothing to draw?
	if( fSize <= 0 ) return;

	// frustrum visible check
	if( !ParticleIsVisible( part ))
		return;

	Vector point1, point2, point3, point4;
	Vector origin = part->origin;

	float fCosSize = CosLookup( part->m_fAngle ) * fSize;
	float fSinSize = SinLookup( part->m_fAngle ) * fSize;

	// calculate the four corners of the sprite
	point1 = origin + up * fSinSize + right * -fCosSize;
	point2 = origin + up * fCosSize + right * fSinSize;
	point3 = origin + up * -fSinSize + right * fCosSize;	
	point4 = origin + up * -fCosSize + right * -fSinSize;

	int iContents = CONTENTS_NONE;
	model_t *pModel;

	for( CParticle *pDraw = part; pDraw; pDraw = pDraw->m_pOverlay )
	{
		if( !pDraw->pType->m_hSprite )
			continue;

		if( pDraw->pType->m_iDrawCond )
		{
			if( pDraw->pType->m_iDrawCond == CONTENT_SPOTLIGHT )
			{
				if( !R_CountPlights( ))
					continue;	// fast reject

				for( int i = 0; i < MAX_PLIGHTS; i++ )
				{
					plight_t *pl = &cl_plights[i];

					if( pl->die < GET_CLIENT_TIME() || !pl->radius )
						continue;

					if( !R_CullSphereExt( pl->frustum, part->origin, part->m_fSize + 1, pl->clipflags ))
						break; // cone intersected with particle

				}

				if( i == MAX_PLIGHTS )
					continue;	// no intersection
			}
			else
			{
				if( iContents == CONTENTS_NONE )
					iContents = POINT_CONTENTS( origin );

				if( iContents != pDraw->pType->m_iDrawCond )
					continue;
			}
		}

		pModel = (model_t *)gEngfuncs.GetSpritePointer( pDraw->pType->m_hSprite );

		// if we've reached the end of the sprite's frames, loop back
		while (pDraw->frame > pModel->numframes)
			pDraw->frame -= pModel->numframes;

		while (pDraw->frame < 0)
			pDraw->frame += pModel->numframes;

		if( !TriSpriteTexture( pModel, (int)pDraw->frame ))
			continue;

		gEngfuncs.pTriAPI->RenderMode( pDraw->pType->m_iRenderMode );

		if( m_iLightingModel >= 1 )
		{
			color24 lightColor;
			Vector lightingColor;

			if( m_iLightingModel == 1 )
				R_LightForPoint( part->origin, &lightColor, false, true, fSize + 1 );
			else R_LightForPoint( part->origin, &lightColor, false, true, 0.0f );
			
			// FIXME: this code is totally wrong.
			// We need a fake lightmap here like in sprite implementation
			lightingColor.x = pDraw->m_fRed * lightColor.r * (1.0f / 255.0f);
			lightingColor.y = pDraw->m_fGreen * lightColor.g * (1.0f / 255.0f);
			lightingColor.z = pDraw->m_fBlue * lightColor.b * (1.0f / 255.0f);
			pglColor4f( lightingColor.x, lightingColor.y, lightingColor.z, pDraw->m_fAlpha );
		}
		else pglColor4f( pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue, pDraw->m_fAlpha );

		pglBegin( GL_QUADS );
			pglTexCoord2f( 0.0f, 0.0f );
			pglVertex3fv( point1 );

			pglTexCoord2f( 1.0f, 0.0f );
			pglVertex3fv( point2 );

			pglTexCoord2f( 1.0f, 1.0f );
			pglVertex3fv( point3 );

			pglTexCoord2f( 0.0f, 1.0f );
			pglVertex3fv( point4 );
		pglEnd();

		if( m_iLightingModel >=2 && R_CountPlights( ))
		{
			for( int i = 0; i < MAX_PLIGHTS; i++ )
			{
				plight_t *pl = &cl_plights[i];

				if( pl->die < GET_CLIENT_TIME() || !pl->radius )
					continue;

				if( R_CullSphereExt( pl->frustum, part->origin, part->m_fSize + 1, pl->clipflags ))
					continue;

				R_BeginDrawProjection( pl );

				pglBegin( GL_QUADS );
					pglVertex3fv( point1 );
					pglVertex3fv( point2 );
					pglVertex3fv( point3 );
					pglVertex3fv( point4 );
				pglEnd();

				R_EndDrawProjection();
			}
		}
	}
}