void CGlowObjectManager::GlowObjectDefinition_t::DrawModel() { C_BaseEntity *pEntity = m_hEntity.Get(); if ( !pEntity ) return; if ( pEntity->GetMoveParent() != NULL ) { C_BaseAnimating *pBaseAnimating = pEntity->GetBaseAnimating(); if ( pBaseAnimating ) { pBaseAnimating->InvalidateBoneCache(); } } pEntity->DrawModel( STUDIO_RENDER ); C_BaseEntity *pAttachment = pEntity->FirstMoveChild(); while ( pAttachment != NULL ) { if ( !g_GlowObjectManager.HasGlowEffect( pAttachment ) && pAttachment->ShouldDraw() ) { C_BaseAnimating *pBaseAnimating = pAttachment->GetBaseAnimating(); if ( pBaseAnimating ) { pBaseAnimating->InvalidateBoneCache(); } pAttachment->DrawModel( STUDIO_RENDER ); } pAttachment = pAttachment->NextMovePeer(); } }
//----------------------------------------------------------------------------- // Purpose: Tesla effect //----------------------------------------------------------------------------- void FX_BuildTeslaHitbox( const CEffectData &data ) { Vector vColor( 1, 1, 1 ); C_BaseEntity *pEntity = ClientEntityList().GetEnt( data.entindex() ); C_BaseAnimating *pAnimating = pEntity ? pEntity->GetBaseAnimating() : NULL; if (!pAnimating) return; studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); if (!pStudioHdr) return; mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); if ( !set ) return; matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) ) return; int nBeamCount = (int)(data.m_flMagnitude + 0.5f); for ( int i = 0; i < nBeamCount; ++i ) { int nStartHitBox = random->RandomInt( 1, set->numhitboxes ); int nEndHitBox = random->RandomInt( 1, set->numhitboxes ); FX_BuildTeslaHitbox( pEntity, nStartHitBox, nEndHitBox, data.m_flScale, vColor, random->RandomFloat( 0.05f, 0.2f ) ); } }
//----------------------------------------------------------------------------- // 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 ); }
int CCollisionEvent::ShouldSolvePenetration( IPhysicsObject *pObj0, IPhysicsObject *pObj1, void *pGameData0, void *pGameData1, float dt ) { CallbackContext callback(this); // solve it yourself here and return 0, or have the default implementation do it if ( pGameData0 == pGameData1 ) { if ( pObj0->GetGameFlags() & FVPHYSICS_PART_OF_RAGDOLL ) { // this is a ragdoll, self penetrating C_BaseEntity *pEnt = reinterpret_cast<C_BaseEntity *>(pGameData0); C_BaseAnimating *pAnim = pEnt->GetBaseAnimating(); if ( pAnim && pAnim->m_pRagdoll ) { IPhysicsConstraintGroup *pGroup = pAnim->m_pRagdoll->GetConstraintGroup(); if ( pGroup ) { pGroup->SolvePenetration( pObj0, pObj1 ); return false; } } } } return true; }
int CCollisionEvent::ShouldSolvePenetration( IPhysicsObject *pObj0, IPhysicsObject *pObj1, void *pGameData0, void *pGameData1, float dt ) { CallbackContext callback(this); C_BaseEntity *pEntity0 = static_cast<C_BaseEntity *>(pGameData0); C_BaseEntity *pEntity1 = static_cast<C_BaseEntity *>(pGameData1); // solve it yourself here and return 0, or have the default implementation do it if ( pEntity0 > pEntity1 ) { // swap sort CBaseEntity *pTmp = pEntity0; pEntity0 = pEntity1; pEntity1 = pTmp; IPhysicsObject *pTmpObj = pObj0; pObj0 = pObj1; pObj1 = pTmpObj; } if ( !pEntity0 || !pEntity1 ) return 1; unsigned short gameFlags0 = pObj0->GetGameFlags(); unsigned short gameFlags1 = pObj1->GetGameFlags(); // solve it yourself here and return 0, or have the default implementation do it if ( pGameData0 == pGameData1 ) { if ( gameFlags0 & FVPHYSICS_PART_OF_RAGDOLL ) { // this is a ragdoll, self penetrating C_BaseEntity *pEnt = reinterpret_cast<C_BaseEntity *>(pGameData0); C_BaseAnimating *pAnim = pEnt->GetBaseAnimating(); if ( pAnim && pAnim->m_pRagdoll ) { IPhysicsConstraintGroup *pGroup = pAnim->m_pRagdoll->GetConstraintGroup(); if ( pGroup ) { pGroup->SolvePenetration( pObj0, pObj1 ); return false; } } } } else if ( (gameFlags0|gameFlags1) & FVPHYSICS_PART_OF_RAGDOLL ) { // ragdoll penetrating shadow object, just give up for now if ( pObj0->GetShadowController() || pObj1->GetShadowController() ) { FindOrAddPenetrateEvent( pEntity0, pEntity1 ); return true; } } return true; }
//----------------------------------------------------------------------------- // Purpose: // Input : fTimeDelta - //----------------------------------------------------------------------------- void C_EntityParticleTrail::Update( float fTimeDelta ) { float tempDelta = fTimeDelta; studiohdr_t *pStudioHdr; mstudiohitboxset_t *set; matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; C_BaseEntity *pMoveParent = GetMoveParent(); if ( !pMoveParent ) return; C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); if (!pAnimating) goto trailNoHitboxes; if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) ) goto trailNoHitboxes; pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); if (!pStudioHdr) goto trailNoHitboxes; set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); if ( !set ) goto trailNoHitboxes; //Add new particles while ( m_teParticleSpawn.NextEvent( tempDelta ) ) { int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 ); mstudiobbox_t *pBox = set->pHitbox(nHitbox); AddParticle( tempDelta, pBox->bbmin, pBox->bbmax, *hitboxbones[pBox->bone] ); } return; trailNoHitboxes: while ( m_teParticleSpawn.NextEvent( tempDelta ) ) { AddParticle( tempDelta, pMoveParent->CollisionProp()->OBBMins(), pMoveParent->CollisionProp()->OBBMaxs(), pMoveParent->EntityToWorldTransform() ); } }
void C_CFPlayer::CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov ) { if (gpGlobals->curtime < m_flCameraCinematicUntil) { C_BaseEntity* pEnt = m_hCameraCinematic; if (pEnt) { C_BaseAnimating* pCamera = pEnt->GetBaseAnimating(); if (pCamera) { Vector vecCamera; QAngle angCamera; pCamera->GetBonePosition(pCamera->LookupBone("cin_Camera.camera"), vecCamera, angCamera); eyeOrigin = vecCamera; eyeAngles = angCamera; if (pCamera->LookupBone("cin_Camera.fov") >= 0) { Vector vecFOV; QAngle angFOV; pCamera->GetBonePosition(pCamera->LookupBone("cin_Camera.fov"), vecFOV, angFOV); Vector vecDistance = vecFOV - vecCamera; fov = RemapValClamped(vecDistance.Length(), 5, 100, 5, 100); } return; } } } BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov ); zNear = 3; }
//----------------------------------------------------------------------------- // 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 ); }
bool CClientTools::IsViewModelOrAttachment( EntitySearchResult currentEnt ) { C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt ); C_BaseAnimating *pBaseAnimating = ent ? ent->GetBaseAnimating() : NULL; return pBaseAnimating ? pBaseAnimating->IsViewModelOrAttachment() : false; }
bool CClientTools::IsRagdoll( EntitySearchResult currentEnt ) { C_BaseEntity *ent = reinterpret_cast< C_BaseEntity* >( currentEnt ); C_BaseAnimating *pBaseAnimating = ent ? ent->GetBaseAnimating() : NULL; return pBaseAnimating ? pBaseAnimating->IsClientRagdoll() : false; }
//----------------------------------------------------------------------------- // Purpose: // Output : int //----------------------------------------------------------------------------- int C_SpriteRenderer::DrawSprite( IClientEntity *entity, const model_t *model, const Vector& origin, const QAngle& angles, float frame, IClientEntity *attachedto, int attachmentindex, int rendermode, int renderfx, int alpha, int r, int g, int b, float scale, float flHDRColorScale ) { VPROF_BUDGET( "C_SpriteRenderer::DrawSprite", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); if ( !r_drawsprites.GetBool() || !model || modelinfo->GetModelType( model ) != mod_sprite ) return 0; // Get extra data CEngineSprite *psprite = (CEngineSprite *)modelinfo->GetModelExtraData(model); if ( !psprite ) return 0; Vector effect_origin; VectorCopy(origin, effect_origin); // Use attachment point if ( attachedto ) { C_BaseEntity *ent = attachedto->GetBaseEntity(); if ( ent ) { if ( ent->GetBaseAnimating() && ent->GetBaseAnimating()->IsViewModel() && ::input->CAM_IsThirdPersonOverShoulder() ) { C_BaseViewModel *pVm = (C_BaseViewModel*)ent; C_BasePlayer *pOwner = ( pVm->GetOwner() && pVm->GetOwner()->IsPlayer() ) ? (C_BasePlayer*)pVm->GetOwner() : NULL; if ( pOwner && pOwner->GetActiveWeapon() ) return 0; //worldmodels don't have the same attachments, so just get out (crossbow) } // don't draw viewmodel effects in reflections if ( CurrentViewID() == VIEW_REFLECTION ) { int group = ent->GetRenderGroup(); if ( group == RENDER_GROUP_VIEW_MODEL_TRANSLUCENT || group == RENDER_GROUP_VIEW_MODEL_OPAQUE ) return 0; } QAngle temp; ent->GetAttachment(attachmentindex, effect_origin, temp); } } if ( rendermode != kRenderNormal ) { float blend = render->GetBlend(); // kRenderGlow and kRenderWorldGlow have a special blending function if (( rendermode == kRenderGlow ) || ( rendermode == kRenderWorldGlow )) { blend *= GlowBlend( psprite, effect_origin, rendermode, renderfx, alpha, &scale ); // Fade out the sprite depending on distance from the view origin. r *= blend; g *= blend; b *= blend; } render->SetBlend( blend ); if ( blend <= 0.0f ) { return 0; } } // Get orthonormal basis Vector forward, right, up; GetSpriteAxes( (SPRITETYPE)psprite->GetOrientation(), origin, angles, forward, right, up ); // Draw DrawSpriteModel( entity, psprite, effect_origin, scale, frame, rendermode, r, g, b, alpha, forward, right, up, flHDRColorScale ); return 1; }
void C_Camera::CalcChaseCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov) { C_SDKPlayer *pLocal = C_SDKPlayer::GetLocalSDKPlayer(); C_BaseEntity *pTarget = NULL; if ((pLocal->m_nButtons & IN_ZOOM) && !pLocal->IsObserver() && g_PR->GetTeamPosType(GetLocalPlayerIndex()) == POS_GK && GetMatchBall() && Sign(GetMatchBall()->GetLocalOrigin().y - SDKGameRules()->m_vKickOff.GetY()) == pLocal->GetTeam()->m_nForward) { CalcHawkEyeView(eyeOrigin, eyeAngles, fov); return; } if (pLocal->IsObserver()) pTarget = GetTarget(); else pTarget = pLocal; if (!pTarget || !pTarget->GetBaseAnimating() && !pTarget->GetModel()) { CalcRoamingView( eyeOrigin, eyeAngles, fov ); return; } eyeOrigin = pTarget->EyePosition(); eyeAngles = pTarget->EyeAngles(); const QAngle camAngles = ::input->GetCameraAngles(); Vector &camOffset = ::input->GetCameraOffset(); float dist = cl_cam_firstperson.GetBool() ? -10 : cl_cam_dist.GetFloat(); float height = cl_cam_firstperson.GetBool() ? 8 : cl_cam_height.GetFloat(); if (pLocal->IsObserver() && GetCamMode() == CAM_MODE_LOCKED_CHASE && !dynamic_cast<C_MatchBall *>(pTarget)) { camOffset[PITCH] = eyeAngles[PITCH]; camOffset[YAW] = eyeAngles[YAW]; } else { camOffset[PITCH] = camAngles[PITCH]; camOffset[YAW] = camAngles[YAW]; } if (camOffset[PITCH] >= 0) { camOffset[ROLL] = dist; } else { float coeff = clamp(cos(DEG2RAD(camOffset[PITCH] + 90)), 0.001f, 1.0f); camOffset[ROLL] = min((VEC_VIEW.z + height - 5) / coeff, dist); } eyeAngles[PITCH] = camOffset[PITCH]; eyeAngles[YAW] = camOffset[YAW]; eyeAngles[ROLL] = 0; Vector camForward, camRight, camUp; AngleVectors(eyeAngles, &camForward, &camRight, &camUp); VectorMA(eyeOrigin, -camOffset[ROLL], camForward, eyeOrigin); eyeOrigin.z += height; if (!pLocal->IsObserver()) { // Apply a smoothing offset to smooth out prediction errors. Vector vSmoothOffset; pLocal->GetPredictionErrorSmoothingVector( vSmoothOffset ); eyeOrigin += Vector(vSmoothOffset.x, vSmoothOffset.y, 0); } fov = pLocal->GetFOV(); }