// Returns the bounds relative to the origin (render bounds) virtual void GetRenderBounds( Vector& mins, Vector& maxs ) { ClearBounds( mins, maxs ); AddPointToBounds( m_worldPosition, mins, maxs ); AddPointToBounds( m_targetPosition, mins, maxs ); mins -= GetRenderOrigin(); maxs -= GetRenderOrigin(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CSpriteTrail::ComputeScreenPosition( Vector *pScreenPos ) { #if SCREEN_SPACE_TRAILS VMatrix viewMatrix; materials->GetMatrix( MATERIAL_VIEW, &viewMatrix ); *pScreenPos = viewMatrix * GetRenderOrigin(); #else *pScreenPos = GetRenderOrigin(); #endif }
void CNewParticleEffect::GetRenderBounds( Vector& mins, Vector& maxs ) { if ( !m_bBoundsValid ) { mins = vec3_origin; maxs = mins; return; } VectorSubtract( m_MinBounds, GetRenderOrigin(), mins ); VectorSubtract( m_MaxBounds, GetRenderOrigin(), maxs ); }
void GetRenderBoundsWorldspace( Vector& mins, Vector& maxs ) { BaseClass::GetRenderBoundsWorldspace( mins, maxs ); // add to the bounds, don't clear them. // ClearBounds( mins, maxs ); AddPointToBounds( vec3_origin, mins, maxs ); AddPointToBounds( m_targetPosition, mins, maxs ); AddPointToBounds( m_worldPosition, mins, maxs ); mins -= GetRenderOrigin(); maxs -= GetRenderOrigin(); }
void CASW_Target_Dummy::PaintHealthBar( CASWHud3DMarineNames *pSurface ) { char pText[64]; Q_snprintf( pText, sizeof( pText ), "DPS: %.2f", GetDPS() ); pSurface->PaintGenericText( GetRenderOrigin() + Vector( -20, -10, 0), pText, Color( 140, 240, 240, 255 ), 1.0f, Vector2D( 0, -6 ) ); Q_snprintf( pText, sizeof( pText ), "DAMAGE:%.2f", GetDamageTaken() ); pSurface->PaintGenericText( GetRenderOrigin() + Vector( -20, -10, 0), pText, Color( 140, 240, 240, 255 ), 1.0f, Vector2D( 0, -5 ) ); Q_snprintf( pText, sizeof( pText ), "LAST:%.2f", m_flLastHit.Get() ); pSurface->PaintGenericText( GetRenderOrigin() + Vector( -20, -10, 0), pText, Color( 140, 240, 240, 255 ), 1.0f, Vector2D( 0, -4 ) ); }
CWreckage* CDigitanksEntity::CreateWreckage() { // Figure out what to do about structures later. if (dynamic_cast<CDigitank*>(this) == NULL) return NULL; CWreckage* pWreckage = GameServer()->Create<CWreckage>("CWreckage"); pWreckage->SetGlobalOrigin(GetRenderOrigin()); pWreckage->SetGlobalAngles(GetRenderAngles()); pWreckage->SetModel(GetModelID()); pWreckage->SetGlobalGravity(Vector(0, 0, DigitanksGame()->GetGravity())); pWreckage->SetOldPlayer(GetDigitanksPlayer()); pWreckage->CalculateVisibility(); CDigitank* pTank = dynamic_cast<CDigitank*>(this); if (pTank) pWreckage->SetTurretModel(pTank->GetTurretModel()); bool bColorSwap = GetPlayerOwner() && (dynamic_cast<CDigitank*>(this)); if (bColorSwap) pWreckage->SetColorSwap(GetPlayerOwner()->GetColor()); return pWreckage; }
const matrix3x4_t& CBulletManager::CBullet::RenderableToWorldTransform() { static matrix3x4_t mat; SetIdentityMatrix( mat ); PositionMatrix( GetRenderOrigin(), mat ); return mat; }
//----------------------------------------------------------------------------- // 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; }
const matrix3x4_t & C_EnvelopeFX::RenderableToWorldTransform() { static matrix3x4_t mat; SetIdentityMatrix( mat ); PositionMatrix( GetRenderOrigin(), mat ); return mat; }
const matrix3x4_t & CParticleEffectBinding::RenderableToWorldTransform() { static matrix3x4_t mat; SetIdentityMatrix( mat ); PositionMatrix( GetRenderOrigin(), mat ); return mat; }
//----------------------------------------------------------------------------- // Purpose: // Input : bnewentity - //----------------------------------------------------------------------------- void C_EntityFlame::OnDataChanged( DataUpdateType_t updateType ) { if ( updateType == DATA_UPDATE_CREATED ) { C_BaseEntity *pEnt = m_hEntAttached; if ( !pEnt ) return; if ( m_bUseHitboxes && pEnt->GetBaseAnimating() != NULL ) { AttachToHitBoxes(); } else { m_vecLastPosition = GetRenderOrigin(); m_ParticleSpawn.Init( 60 ); //Events per second m_pEmitter = CEmberEffect::Create("C_EntityFlame::Create"); Assert( m_pEmitter.IsValid() ); if ( m_pEmitter.IsValid() ) { for ( int i = 1; i < NUM_FLAMELETS+1; i++ ) { m_MaterialHandle[i-1] = m_pEmitter->GetPMaterial( VarArgs( "sprites/flamelet%d", i ) ); } m_pEmitter->SetSortOrigin( GetAbsOrigin() ); } } } BaseClass::OnDataChanged( updateType ); }
//----------------------------------------------------------------------------- // Compute position + bounding box //----------------------------------------------------------------------------- void CSpriteTrail::UpdateBoundingBox( void ) { Vector vecRenderOrigin = GetRenderOrigin(); m_vecRenderMins = vecRenderOrigin; m_vecRenderMaxs = vecRenderOrigin; float flMaxWidth = m_flStartWidth; if (( m_flEndWidth >= 0.0f ) && ( m_flEndWidth > m_flStartWidth )) { flMaxWidth = m_flEndWidth; } Vector mins, maxs; for ( int i = 0; i < m_nStepCount; ++i ) { TrailPoint_t *pPoint = GetTrailPoint(i); float flActualWidth = (flMaxWidth + pPoint->m_flWidthVariance) * 0.5f; Vector size( flActualWidth, flActualWidth, flActualWidth ); VectorSubtract( pPoint->m_vecScreenPos, size, mins ); VectorAdd( pPoint->m_vecScreenPos, size, maxs ); VectorMin( m_vecRenderMins, mins, m_vecRenderMins ); VectorMax( m_vecRenderMaxs, maxs, m_vecRenderMaxs ); } m_vecRenderMins -= vecRenderOrigin; m_vecRenderMaxs -= vecRenderOrigin; }
bool C_BaseCombatWeapon::GetShootPosition( Vector &vOrigin, QAngle &vAngles ) { // Get the entity because the weapon doesn't have the right angles. C_BaseCombatCharacter *pEnt = ToBaseCombatCharacter( GetOwner() ); if ( pEnt ) { if ( pEnt == C_BasePlayer::GetLocalPlayer() ) { vAngles = pEnt->EyeAngles(); } else { vAngles = pEnt->GetRenderAngles(); } } else { vAngles.Init(); } C_BasePlayer *player = ToBasePlayer( pEnt ); bool bUseViewModel = false; if ( C_BasePlayer::IsLocalPlayer( pEnt ) ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD_ENT( pEnt ); bUseViewModel = !player->ShouldDrawLocalPlayer(); } QAngle vDummy; if ( IsActiveByLocalPlayer() && bUseViewModel ) { C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL; if ( vm ) { int iAttachment = vm->LookupAttachment( "muzzle" ); if ( vm->GetAttachment( iAttachment, vOrigin, vDummy ) ) { return true; } } } else { // Thirdperson int iAttachment = LookupAttachment( "muzzle" ); if ( GetAttachment( iAttachment, vOrigin, vDummy ) ) { return true; } } vOrigin = GetRenderOrigin(); return false; }
bool CNewParticleEffect::RecalculateBoundingBox() { BloatBoundsUsingControlPoint(); if ( !m_bBoundsValid ) { m_MaxBounds = m_MinBounds = GetRenderOrigin(); return false; } return true; }
void C_NPC_Surface::GetRenderBounds( Vector& theMins, Vector& theMaxs ) { // BaseClass::GetRenderBounds( theMins, theMaxs ); if(sv_surface_testshape.GetBool()) { theMins.Init(-300.0f, 0.0f, 100.0f); theMaxs.Init(0.0f, 100.0f, 200.0f); } else { theMins = m_vecSurfacePos[0]; theMaxs = m_vecSurfacePos[0]; float surfaceRadius = m_flRadius * 3.0f; for (int i = 0; i < m_nActiveParticles; i++) { VectorMin( m_vecSurfacePos[i] - Vector( surfaceRadius, surfaceRadius, surfaceRadius ), theMins, theMins ); VectorMax( m_vecSurfacePos[i] + Vector( surfaceRadius, surfaceRadius, surfaceRadius ), theMaxs, theMaxs ); } } theMins -= GetRenderOrigin(); theMaxs -= GetRenderOrigin(); #if 0 Vector avg = (theMins + theMaxs) * 0.5f; theMins = theMins - ((theMins - avg) * 0.75f); theMaxs = theMaxs - ((theMaxs - avg) * 0.75f); #endif #if 0 Vector fountainOrigin(-1980, -1792, 1); theMins = fountainOrigin + Vector(-10, -10, -20); theMaxs = fountainOrigin + Vector(10, 10, 50); #endif // Msg( "origin %.2f %.2f %.2f : mins %.2f %.2f %.2f : maxs %.2f %.2f %.2f\n", GetRenderOrigin().x, GetRenderOrigin().y, GetRenderOrigin().z, theMins.x, theMins.y, theMins.z, theMaxs.x, theMaxs.y, theMaxs.z ); //debugoverlay->AddBoxOverlay( GetRenderOrigin(), theMins, theMaxs, QAngle( 0, 0, 0 ), 0, 255, 0, 0, 0 ); }
int CBulletManager::CBullet::DrawModel( int flags ) { if (m_flCurrAlpha < 0) return 0; if (flags & STUDIO_SHADOWDEPTHTEXTURE) return 0; #ifdef __linux__ return 0; #endif if (!g_hBulletStreak.IsValid()) g_hBulletStreak.Init( "effects/tracer1.vmt", TEXTURE_GROUP_OTHER ); float flAlpha = 150.5f/255.0f * m_flCurrAlpha; Vector vecRight = Vector(0, 0, 1).Cross(m_vecDirection).Normalized(); Vector vecCross1 = (Vector(0, 0, 1) + vecRight).Normalized(); Vector vecCross2 = (Vector(0, 0, 1) - vecRight).Normalized(); CMeshBuilder meshBuilder; CMatRenderContextPtr pRenderContext( materials ); pRenderContext->Bind( g_hBulletStreak ); IMesh* pMesh = pRenderContext->GetDynamicMesh(); meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); DrawCross(meshBuilder, GetRenderOrigin(), vecCross1, m_vecDirection, flAlpha); DrawCross(meshBuilder, GetRenderOrigin(), vecCross2, m_vecDirection, flAlpha); meshBuilder.End(false, true); return 1; }
bool C_BaseCombatWeapon::GetShootPosition( Vector &vOrigin, QAngle &vAngles ) { // Get the entity because the weapon doesn't have the right angles. C_BaseCombatCharacter *pEnt = ToBaseCombatCharacter( GetOwner() ); if ( pEnt ) { if ( pEnt == C_BasePlayer::GetLocalPlayer() ) { vAngles = pEnt->EyeAngles(); } else { vAngles = pEnt->GetRenderAngles(); } } else { vAngles.Init(); } QAngle vDummy; if ( IsActiveByLocalPlayer() && !input->CAM_IsThirdPerson() ) { C_BasePlayer *player = ToBasePlayer( pEnt ); C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL; if ( vm ) { int iAttachment = vm->LookupAttachment( "muzzle" ); if ( vm->GetAttachment( iAttachment, vOrigin, vDummy ) ) { return true; } } } else { // Thirdperson int iAttachment = LookupAttachment( "muzzle" ); if ( GetAttachment( iAttachment, vOrigin, vDummy ) ) { return true; } } vOrigin = GetRenderOrigin(); return false; }
void CDeferredLight::ApplyDataToLight() { Assert( m_pLight != NULL ); ABS_QUERY_GUARD( true ); m_pLight->ang = GetRenderAngles(); m_pLight->pos = GetRenderOrigin(); m_pLight->col_diffuse = GetColor_Diffuse(); m_pLight->col_ambient = GetColor_Ambient(); m_pLight->flRadius = GetRadius(); m_pLight->flFalloffPower = GetFalloffPower(); m_pLight->flSpotCone_Inner = SPOT_DEGREE_TO_RAD( GetSpotCone_Inner() ); m_pLight->flSpotCone_Outer = SPOT_DEGREE_TO_RAD( GetSpotCone_Outer() ); m_pLight->iVisible_Dist = GetVisible_Distance(); m_pLight->iVisible_Range = GetVisible_FadeRange(); m_pLight->iShadow_Dist = GetShadow_Distance(); m_pLight->iShadow_Range = GetShadow_FadeRange(); m_pLight->iStyleSeed = GetStyle_Seed(); m_pLight->flStyle_Amount = GetStyle_Amount(); m_pLight->flStyle_Random = GetStyle_Random(); m_pLight->flStyle_Smooth = GetStyle_Smooth(); m_pLight->flStyle_Speed = GetStyle_Speed(); m_pLight->iLighttype = GetLight_Type(); m_pLight->iFlags >>= DEFLIGHTGLOBAL_FLAGS_MAX_SHARED_BITS; m_pLight->iFlags <<= DEFLIGHTGLOBAL_FLAGS_MAX_SHARED_BITS; m_pLight->iFlags |= GetLight_Flags(); m_pLight->iCookieIndex = GetCookieIndex(); #if DEFCFG_ADAPTIVE_VOLUMETRIC_LOD GetVolumeLODDistances( m_pLight->flVolumeLOD0Dist, m_pLight->flVolumeLOD1Dist, m_pLight->flVolumeLOD2Dist, m_pLight->flVolumeLOD3Dist ); #endif #if DEFCFG_CONFIGURABLE_VOLUMETRIC_LOD m_pLight->iVolumeSamples = GetVolumeSamples(); #endif }
void CDeferredLight::ClientThink() { if ( m_pLight == NULL ) return; Vector curOrig = GetRenderOrigin(); QAngle curAng = GetRenderAngles(); if ( VectorCompare( curOrig.Base(), m_pLight->pos.Base() ) == 0 || VectorCompare( curAng.Base(), m_pLight->ang.Base() ) == 0 ) { ApplyDataToLight(); if ( m_pLight->flSpotCone_Outer != GetSpotCone_Outer() ) m_pLight->MakeDirtyAll(); else m_pLight->MakeDirtyXForms(); } }
int C_PortalGhostRenderable::DrawModel( int flags ) { if( m_bSourceIsBaseAnimating ) { if( m_bLocalPlayer ) { C_Portal_Player *pPlayer = C_Portal_Player::GetLocalPlayer(); if ( !pPlayer->IsAlive() ) { // Dead player uses a ragdoll to draw, so don't ghost the dead entity return 0; } else if( g_pPortalRender->GetViewRecursionLevel() == 0 ) { if( pPlayer->m_bEyePositionIsTransformedByPortal ) return 0; } else if( g_pPortalRender->GetViewRecursionLevel() == 1 ) { if( !pPlayer->m_bEyePositionIsTransformedByPortal ) return 0; } } return C_BaseAnimating::DrawModel( flags ); } else { render->DrawBrushModel( m_pGhostedRenderable, (model_t *)m_pGhostedRenderable->GetModel(), GetRenderOrigin(), GetRenderAngles(), flags & STUDIO_TRANSPARENCY ? true : false ); return 1; } return 0; }
//----------------------------------------------------------------------------- // Purpose: Setup the emitters we'll be using //----------------------------------------------------------------------------- bool C_HopwireExplosion::SetupEmitters( void ) { // Setup the basic core emitter if ( m_pSimpleEmitter.IsValid() == false ) { m_pSimpleEmitter = CSimpleEmitter::Create( "hopwirecore" ); if ( m_pSimpleEmitter.IsValid() == false ) return false; } // Setup the attractor emitter if ( m_pAttractorEmitter.IsValid() == false ) { m_pAttractorEmitter = CParticleAttractor::Create( GetRenderOrigin(), "hopwireattractor" ); if ( m_pAttractorEmitter.IsValid() == false ) return false; } return true; }
//----------------------------------------------------------------------------- // Deal with dynamic lighting //----------------------------------------------------------------------------- void C_WeaponCombat_ChargeablePlasma::ClientThink( ) { BaseClass::ClientThink(); C_BaseTFPlayer *pPlayer = (C_BaseTFPlayer *)GetOwner(); if ( !pPlayer || (pPlayer->GetHealth() <= 0)) { SetNextClientThink( CLIENT_THINK_NEVER ); return; } if (!m_bCharging) return; // Determine the ball size... m_flPower = (gpGlobals->curtime - m_flChargeStartTime) / BALL_GROW_TIME; m_flPower = clamp( m_flPower, 0, 1 ); // FIXME: dl->origin should be based on the attachment point dlight_t *dl = effects->CL_AllocDlight( entindex() ); dl->origin = GetRenderOrigin(); if (GetTeamNumber() == 1) { dl->color.r = 40; dl->color.g = 60; dl->color.b = 250; } else { dl->color.r = 250; dl->color.g = 60; dl->color.b = 40; } dl->color.exponent = 5; dl->radius = 20 * m_flPower + 10; dl->die = gpGlobals->curtime + 0.01; }
//----------------------------------------------------------------------------- // Purpose: Get the rendered extents of the sprite //----------------------------------------------------------------------------- void CSprite::GetRenderBounds( Vector &vecMins, Vector &vecMaxs ) { float flScale = GetRenderScale() * 0.5f; // If our scale is normalized we need to convert that to actual world units if ( m_bWorldSpaceScale == false ) { CEngineSprite *psprite = (CEngineSprite *) modelinfo->GetModelExtraData( GetModel() ); if ( psprite ) { float flSize = MAX( psprite->GetWidth(), psprite->GetHeight() ); flScale *= flSize; } } vecMins.Init( -flScale, -flScale, -flScale ); vecMaxs.Init( flScale, flScale, flScale ); #if 0 // Visualize the bounds debugoverlay->AddBoxOverlay( GetRenderOrigin(), vecMins, vecMaxs, GetRenderAngles(), 255, 255, 255, 0, 0.01f ); #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_HL2MP_Player::CalculateIKLocks( float currentTime ) { if (!m_pIk) return; int targetCount = m_pIk->m_target.Count(); if ( targetCount == 0 ) return; // In TF, we might be attaching a player's view to a walking model that's using IK. If we are, it can // get in here during the view setup code, and it's not normally supposed to be able to access the spatial // partition that early in the rendering loop. So we allow access right here for that special case. SpatialPartitionListMask_t curSuppressed = partition->GetSuppressedLists(); partition->SuppressLists( PARTITION_ALL_CLIENT_EDICTS, false ); CBaseEntity::PushEnableAbsRecomputations( false ); for (int i = 0; i < targetCount; i++) { trace_t trace; CIKTarget *pTarget = &m_pIk->m_target[i]; if (!pTarget->IsActive()) continue; switch( pTarget->type) { case IK_GROUND: { pTarget->SetPos( Vector( pTarget->est.pos.x, pTarget->est.pos.y, GetRenderOrigin().z )); pTarget->SetAngles( GetRenderAngles() ); } break; case IK_ATTACHMENT: { C_BaseEntity *pEntity = NULL; float flDist = pTarget->est.radius; // FIXME: make entity finding sticky! // FIXME: what should the radius check be? for ( CEntitySphereQuery sphere( pTarget->est.pos, 64 ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() ) { C_BaseAnimating *pAnim = pEntity->GetBaseAnimating( ); if (!pAnim) continue; int iAttachment = pAnim->LookupAttachment( pTarget->offset.pAttachmentName ); if (iAttachment <= 0) continue; Vector origin; QAngle angles; pAnim->GetAttachment( iAttachment, origin, angles ); // debugoverlay->AddBoxOverlay( origin, Vector( -1, -1, -1 ), Vector( 1, 1, 1 ), QAngle( 0, 0, 0 ), 255, 0, 0, 0, 0 ); float d = (pTarget->est.pos - origin).Length(); if ( d >= flDist) continue; flDist = d; pTarget->SetPos( origin ); pTarget->SetAngles( angles ); // debugoverlay->AddBoxOverlay( pTarget->est.pos, Vector( -pTarget->est.radius, -pTarget->est.radius, -pTarget->est.radius ), Vector( pTarget->est.radius, pTarget->est.radius, pTarget->est.radius), QAngle( 0, 0, 0 ), 0, 255, 0, 0, 0 ); } if (flDist >= pTarget->est.radius) { // debugoverlay->AddBoxOverlay( pTarget->est.pos, Vector( -pTarget->est.radius, -pTarget->est.radius, -pTarget->est.radius ), Vector( pTarget->est.radius, pTarget->est.radius, pTarget->est.radius), QAngle( 0, 0, 0 ), 0, 0, 255, 0, 0 ); // no solution, disable ik rule pTarget->IKFailed( ); } } break; } } CBaseEntity::PopEnableAbsRecomputations(); partition->SuppressLists( curSuppressed, true ); }
void CNewParticleEffect::GetRenderBounds( Vector& mins, Vector& maxs ) { VectorSubtract( m_MinBounds, GetRenderOrigin(), mins ); VectorSubtract( m_MaxBounds, GetRenderOrigin(), maxs ); }
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 ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_EntityFlame::Simulate( void ) { if ( gpGlobals->frametime <= 0.0f ) return; #ifdef HL2_EPISODIC // Server side flames need to shrink and die if ( !m_bCreatedClientside && !m_bStartedFading ) { float flTTL = (m_flLifetime - gpGlobals->curtime); if ( flTTL < 2.0 ) { for (int i = 0; i < NUM_HITBOX_FIRES; i++) { if ( m_pFireSmoke[i] ) { m_pFireSmoke[i]->m_flScaleStart = m_pFireSmoke[i]->m_flScaleEnd; m_pFireSmoke[i]->m_flScaleEnd = 0.00001; m_pFireSmoke[i]->m_flScaleTimeStart = gpGlobals->curtime; m_pFireSmoke[i]->m_flScaleTimeEnd = m_flLifetime; m_pFireSmoke[i]->m_flScaleRegister = -1; } } m_bStartedFading = true; } } if ( IsEffectActive(EF_BRIGHTLIGHT) || IsEffectActive(EF_DIMLIGHT) ) { dlight_t *dl = effects->CL_AllocDlight ( index ); dl->origin = GetAbsOrigin(); dl->origin[2] += 16; dl->color.r = 254; dl->color.g = 174; dl->color.b = 10; dl->radius = random->RandomFloat(400,431); dl->die = gpGlobals->curtime + 0.001; if ( m_pFireSmoke[0] ) { if ( m_pFireSmoke[0]->m_flScaleRegister == -1 ) { // We've started shrinking, but UpdateScale() hasn't been // called since then. We want to use the Start scale instead. dl->radius *= m_pFireSmoke[0]->m_flScaleStart; } else { dl->radius *= m_pFireSmoke[0]->m_flScaleRegister; } } } #endif // HL2_EPISODIC if ( m_bAttachedToHitboxes ) { UpdateHitBoxFlames(); } else if ( !!m_pEmitter ) { m_pEmitter->SetSortOrigin( GetAbsOrigin() ); SimpleParticle *pParticle; Vector offset; Vector moveDiff = GetAbsOrigin() - m_vecLastPosition; float moveLength = VectorNormalize( moveDiff ); int numPuffs = moveLength / (m_flSize*0.5f); numPuffs = clamp( numPuffs, 1, 8 ); Vector offsetColor; float step = moveLength / numPuffs; //Fill in the gaps for ( int i = 1; i < numPuffs+1; i++ ) { offset = m_vecLastPosition + ( moveDiff * step * i ); pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle[random->RandomInt( 0, NUM_FLAMELETS-1 )], offset ); if ( pParticle ) { pParticle->m_flDieTime = 0.4f; pParticle->m_flLifetime = 0.0f; pParticle->m_flRoll = random->RandomInt( 0, 360 ); pParticle->m_flRollDelta= random->RandomFloat( -2.0f, 2.0f ); pParticle->m_uchStartSize = random->RandomInt( m_flSize*0.25f, m_flSize*0.5f ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2.0f; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 0; pParticle->m_uchColor[0] = pParticle->m_uchColor[1] = pParticle->m_uchColor[2] = 255; Vector dir; dir.x = random->RandomFloat( -1.0f, 1.0f ); dir.y = random->RandomFloat( -1.0f, 1.0f ); dir.z = random->RandomFloat( 0.5f, 1.0f ); pParticle->m_vecVelocity = dir * random->RandomInt( 4, 32 ); pParticle->m_vecVelocity[2] = random->RandomInt( 32, 64 ); } } } m_vecLastPosition = GetRenderOrigin(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBasePlasmaProjectile::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs) { m_pParticleMgr = pParticleMgr; m_pParticleMgr->AddEffect( &m_ParticleEffect, this ); PMaterialHandle HeadMaterial, TrailMaterial; // Load the projectile material if ( GetTeamNumber() == TEAM_HUMANS ) { HeadMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/human_tracers/human_sparksprite_A1" ); TrailMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/human_tracers/human_sparktracer_A_" ); } else { HeadMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/alien_tracers/alien_pbsprite_A1" ); TrailMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/alien_tracers/alien_pbtracer_A_" ); } // Create the head & trail m_pHeadParticle = (SimpleParticle *)m_ParticleEffect.AddParticle(sizeof(SimpleParticle), HeadMaterial ); m_pTrailParticle = (TrailParticle *)m_ParticleEffect.AddParticle(sizeof(TrailParticle), TrailMaterial ); if ( !m_pHeadParticle || !m_pTrailParticle ) return; // 3rd person particles are larger bool bFirst = (GetOwnerEntity() == C_BasePlayer::GetLocalPlayer()); m_pHeadParticle->m_Pos = GetRenderOrigin(); m_pHeadParticle->m_uchColor[0] = 255; m_pHeadParticle->m_uchColor[1] = 255; m_pHeadParticle->m_uchColor[2] = 255; if ( bFirst ) { m_pHeadParticle->m_uchStartSize = 6; } else { m_pHeadParticle->m_uchStartSize = shot_head_size.GetInt(); } m_pHeadParticle->m_uchEndSize = m_pHeadParticle->m_uchStartSize; m_pHeadParticle->m_uchStartAlpha = 255; m_pHeadParticle->m_uchEndAlpha = 255; m_pHeadParticle->m_flRoll = 0; m_pHeadParticle->m_flRollDelta = 10; m_pHeadParticle->m_iFlags = 0; m_pTrailParticle->m_flLifetime = 0; m_pTrailParticle->m_Pos = GetRenderOrigin(); if ( bFirst ) { m_pTrailParticle->m_flWidth = 25; m_pTrailParticle->m_flLength = 140; } else { m_pTrailParticle->m_flWidth = shot_width.GetFloat(); m_pTrailParticle->m_flLength = shot_length.GetFloat(); } Color32Init( m_pTrailParticle->m_color, 255, 255, 255, 255 ); m_flNextSparkEffect = gpGlobals->curtime + RandomFloat( 0.05, 0.4 ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_HopwireExplosion::AddParticles( void ) { // Make sure the emitters are setup properly if ( SetupEmitters() == false ) return; float tempDelta = gpGlobals->frametime; while( m_ParticleTimer.NextEvent( tempDelta ) ) { // ======================== // Attracted dust particles // ======================== // Update our attractor point m_pAttractorEmitter->SetAttractorOrigin( GetRenderOrigin() ); Vector offset; SimpleParticle *sParticle; offset = GetRenderOrigin() + RandomVector( -256.0f, 256.0f ); sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_Fleck_Cement[0], offset ); if ( sParticle == NULL ) return; 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 = 1.0f; float alpha = random->RandomFloat( 128.0f, 200.0f ); sParticle->m_uchColor[0] = alpha; sParticle->m_uchColor[1] = alpha; sParticle->m_uchColor[2] = alpha; sParticle->m_uchStartAlpha = alpha; sParticle->m_uchEndAlpha = alpha; sParticle->m_uchStartSize = random->RandomInt( 1, 4 ); sParticle->m_uchEndSize = 0; // ======================== // Core effects // ======================== // Reset our sort origin m_pSimpleEmitter->SetSortOrigin( GetRenderOrigin() ); // Base of the core effect sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetRenderOrigin() ); if ( sParticle == NULL ) return; sParticle->m_vecVelocity = vec3_origin; sParticle->m_flDieTime = 0.2f; sParticle->m_flLifetime = 0.0f; sParticle->m_flRoll = Helper_RandomInt( 0, 360 ); sParticle->m_flRollDelta = 4.0f; alpha = random->RandomInt( 32, 200 ); sParticle->m_uchColor[0] = alpha; sParticle->m_uchColor[1] = alpha; sParticle->m_uchColor[2] = alpha; sParticle->m_uchStartAlpha = 0; sParticle->m_uchEndAlpha = alpha; sParticle->m_uchStartSize = 255; sParticle->m_uchEndSize = 0; // Make sure we encompass the complete particle here! m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize ); // ========================= // Dust ring effect // ========================= if ( random->RandomInt( 0, 5 ) != 1 ) return; Vector vecDustColor; vecDustColor.x = 0.35f; vecDustColor.y = 0.3f; vecDustColor.z = 0.25f; Vector color; int numRingSprites = 8; float yaw; Vector forward, vRight, vForward; vForward = Vector( 0, 1, 0 ); vRight = Vector( 1, 0, 0 ); float yawOfs = random->RandomFloat( 0, 359 ); for ( int i = 0; i < numRingSprites; i++ ) { yaw = ( (float) i / (float) numRingSprites ) * 360.0f; yaw += yawOfs; forward = ( vRight * sin( DEG2RAD( yaw) ) ) + ( vForward * cos( DEG2RAD( yaw ) ) ); VectorNormalize( forward ); trace_t tr; UTIL_TraceLine( GetRenderOrigin(), GetRenderOrigin()+(Vector(0, 0, -1024)), MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr ); offset = ( RandomVector( -4.0f, 4.0f ) + tr.endpos ) + ( forward * 512.0f ); sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[random->RandomInt(0,1)], offset ); if ( sParticle != NULL ) { sParticle->m_flLifetime = 0.0f; sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f ); sParticle->m_vecVelocity = forward * -random->RandomFloat( 1000, 1500 ); sParticle->m_vecVelocity[2] += 128.0f; #if __EXPLOSION_DEBUG debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + sParticle->m_vecVelocity, 255, 0, 0, false, 3 ); #endif sParticle->m_uchColor[0] = vecDustColor.x * 255.0f; sParticle->m_uchColor[1] = vecDustColor.y * 255.0f; sParticle->m_uchColor[2] = vecDustColor.z * 255.0f; sParticle->m_uchStartSize = random->RandomInt( 32, 128 ); sParticle->m_uchEndSize = 200; sParticle->m_uchStartAlpha = random->RandomFloat( 16, 64 ); sParticle->m_uchEndAlpha = 0; sParticle->m_flRoll = random->RandomInt( 0, 360 ); sParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f ); } } } }
//----------------------------------------------------------------------------- // Purpose: Render the weapon. Draw the Viewmodel if the weapon's being carried // by this player, otherwise draw the worldmodel. //----------------------------------------------------------------------------- int C_BaseViewModel::DrawModel( int flags, const RenderableInstance_t &instance ) { if ( !m_bReadyToDraw ) return 0; if ( flags & STUDIO_RENDER ) { // Determine blending amount and tell engine float blend = (float)( instance.m_nAlpha / 255.0f ); // Totally gone if ( blend <= 0.0f ) return 0; // Tell engine render->SetBlend( blend ); float color[3]; GetColorModulation( color ); render->SetColorModulation( color ); } CMatRenderContextPtr pRenderContext( materials ); if ( ShouldFlipViewModel() ) pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); int ret = 0; C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); C_BaseCombatWeapon *pWeapon = GetOwningWeapon(); // If the local player's overriding the viewmodel rendering, let him do it if ( pPlayer && pPlayer->IsOverridingViewmodel() ) { ret = pPlayer->DrawOverriddenViewmodel( this, flags, instance ); } else if ( pWeapon && pWeapon->IsOverridingViewmodel() ) { ret = pWeapon->DrawOverriddenViewmodel( this, flags, instance ); } else { ret = BaseClass::DrawModel( flags, instance ); } pRenderContext->CullMode( MATERIAL_CULLMODE_CCW ); // Now that we've rendered, reset the animation restart flag if ( flags & STUDIO_RENDER ) { if ( m_nOldAnimationParity != m_nAnimationParity ) { m_nOldAnimationParity = m_nAnimationParity; } // Tell the weapon itself that we've rendered, in case it wants to do something if ( pWeapon ) { pWeapon->ViewModelDrawn( this ); } if ( vm_debug.GetBool() ) { MDLCACHE_CRITICAL_SECTION(); int line = 16; CStudioHdr *hdr = GetModelPtr(); engine->Con_NPrintf( line++, "%s: %s(%d), cycle: %.2f cyclerate: %.2f playbackrate: %.2f\n", (hdr)?hdr->pszName():"(null)", GetSequenceName( GetSequence() ), GetSequence(), GetCycle(), GetSequenceCycleRate( hdr, GetSequence() ), GetPlaybackRate() ); if ( hdr ) { for( int i=0; i < hdr->GetNumPoseParameters(); ++i ) { const mstudioposeparamdesc_t &Pose = hdr->pPoseParameter( i ); engine->Con_NPrintf( line++, "pose_param %s: %f", Pose.pszName(), GetPoseParameter( i ) ); } } // Determine blending amount and tell engine float blend = (float)( instance.m_nAlpha / 255.0f ); float color[3]; GetColorModulation( color ); engine->Con_NPrintf( line++, "blend=%f, color=%f,%f,%f", blend, color[0], color[1], color[2] ); engine->Con_NPrintf( line++, "GetRenderMode()=%d", GetRenderMode() ); engine->Con_NPrintf( line++, "m_nRenderFX=0x%8.8X", GetRenderFX() ); color24 c = GetRenderColor(); unsigned char a = GetRenderAlpha(); engine->Con_NPrintf( line++, "rendercolor=%d,%d,%d,%d", c.r, c.g, c.b, a ); engine->Con_NPrintf( line++, "origin=%f, %f, %f", GetRenderOrigin().x, GetRenderOrigin().y, GetRenderOrigin().z ); engine->Con_NPrintf( line++, "angles=%f, %f, %f", GetRenderAngles()[0], GetRenderAngles()[1], GetRenderAngles()[2] ); if ( IsEffectActive( EF_NODRAW ) ) { engine->Con_NPrintf( line++, "EF_NODRAW" ); } } } return ret; }