//----------------------------------------------------------------------------- // Purpose: Calculate our body lean based on our delta velocity //----------------------------------------------------------------------------- void CAI_PassengerBehaviorZombie::CalculateBodyLean( void ) { // Calculate our lateral displacement from a perfectly centered start float flLateralDisp = SimpleSplineRemapVal( m_vehicleState.m_vecLastAngles.z, 100.0f, -100.0f, -1.0f, 1.0f ); flLateralDisp = clamp( flLateralDisp, -1.0f, 1.0f ); // FIXME: Framerate dependant! m_flLastLateralLean = ( m_flLastLateralLean * 0.2f ) + ( flLateralDisp * 0.8f ); // Factor in a "stun" if the zombie was moved too far off course if ( fabs( m_flLastLateralLean ) > 0.75f ) { SuppressAttack( 0.5f ); } // Calc our vertical displacement float flVerticalDisp = SimpleSplineRemapVal( m_vehicleState.m_vecDeltaVelocity.z, -50.0f, 50.0f, -1.0f, 1.0f ); flVerticalDisp = clamp( flVerticalDisp, -1.0f, 1.0f ); // FIXME: Framerate dependant! m_flLastVerticalLean = ( m_flLastVerticalLean * 0.75f ) + ( flVerticalDisp * 0.25f ); // Set these parameters GetOuter()->SetPoseParameter( "lean_lateral", m_flLastLateralLean ); GetOuter()->SetPoseParameter( "lean_vertical", m_flLastVerticalLean ); }
void CGrabController::ComputeMaxSpeed( CBaseEntity *pEntity, IPhysicsObject *pPhysics ) { m_shadow.maxSpeed = 1000; m_shadow.maxAngular = DEFAULT_MAX_ANGULAR; // Compute total mass... float flMass = PhysGetEntityMass( pEntity ); float flMaxMass = playerpickup_maxmass.GetFloat(); if ( flMass <= flMaxMass ) return; float flLerpFactor = clamp( flMass, flMaxMass, 500.0f ); flLerpFactor = SimpleSplineRemapVal( flLerpFactor, flMaxMass, 500.0f, 0.0f, 1.0f ); float invMass = pPhysics->GetInvMass(); float invInertia = pPhysics->GetInvInertia().Length(); float invMaxMass = 1.0f / MAX_MASS; float ratio = invMaxMass / invMass; invMass = invMaxMass; invInertia *= ratio; float maxSpeed = invMass * MASS_SPEED_SCALE * 200; float maxAngular = invInertia * MASS_SPEED_SCALE * 360; m_shadow.maxSpeed = Lerp( flLerpFactor, m_shadow.maxSpeed, maxSpeed ); m_shadow.maxAngular = Lerp( flLerpFactor, m_shadow.maxAngular, maxAngular ); }
void CEnvHeadcrabCanister::TestForCollisionsAgainstWorld( const Vector &vecEndPosition ) { // Splash damage! // Iterate on all entities in the vicinity. float flDamageRadius = m_flDamageRadius; float flDamage = m_flDamage; CBaseEntity *pEntity; for ( CEntitySphereQuery sphere( vecEndPosition, flDamageRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() ) { if ( pEntity == this ) continue; if ( !pEntity->IsSolid() ) continue; // Get distance to object and use it as a scale value. Vector vecSegment; VectorSubtract( pEntity->GetAbsOrigin(), vecEndPosition, vecSegment ); float flDistance = VectorNormalize( vecSegment ); float flFactor = 1.0f / ( flDamageRadius * (INNER_RADIUS_FRACTION - 1) ); flFactor *= flFactor; float flScale = flDistance - flDamageRadius; flScale *= flScale * flFactor; if ( flScale > 1.0f ) { flScale = 1.0f; } // Check for a physics object and apply force! Vector vecForceDir = vecSegment; IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject(); if ( pPhysObject ) { // Send it flying!!! float flMass = PhysGetEntityMass( pEntity ); vecForceDir *= flMass * 750 * flScale; pPhysObject->ApplyForceCenter( vecForceDir ); } if ( pEntity->m_takedamage && ( m_flDamage != 0.0f ) ) { CTakeDamageInfo info( this, this, flDamage * flScale, DMG_BLAST ); CalculateExplosiveDamageForce( &info, vecSegment, pEntity->GetAbsOrigin() ); pEntity->TakeDamage( info ); } if ( pEntity->IsPlayer() && !(static_cast<CBasePlayer*>(pEntity)->IsInAVehicle()) ) { if (vecSegment.z < 0.1f) { vecSegment.z = 0.1f; VectorNormalize( vecSegment ); } float flAmount = SimpleSplineRemapVal( flScale, 0.0f, 1.0f, 250.0f, 1000.0f ); pEntity->ApplyAbsVelocityImpulse( vecSegment * flAmount ); } } }
void C_PropCoreBall::ApplyBoneMatrixTransform( matrix3x4_t& transform ) { BaseClass::ApplyBoneMatrixTransform( transform ); float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] }; float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] }; float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ }; float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ }; float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ }; bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] }; for ( int i = 0; i < 3; i++ ) { if ( *flTargetScale[i] != flScale[i] ) { float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i]; float flRemapVal = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] ); *bRunning[i] = true; if ( deltaTime >= 1.0f ) { *flTargetScale[i] = flScale[i]; *bRunning[i] = false; } flVal[i] = flRemapVal; m_flCurrentScale[i] = flVal[i]; } } VectorScale( transform[0], flVal[0], transform[0] ); VectorScale( transform[1], flVal[1], transform[1] ); VectorScale( transform[2], flVal[2], transform[2] ); }
// Find our interpolated value at the given point in time float CInterpolatedValue::Interp( float curTime ) { switch( m_nInterpType ) { case INTERP_LINEAR: { if ( curTime >= m_flEndTime ) return m_flEndValue; if ( curTime <= m_flStartTime ) return m_flStartValue; return RemapVal( curTime, m_flStartTime, m_flEndTime, m_flStartValue, m_flEndValue ); } case INTERP_SPLINE: { if ( curTime >= m_flEndTime ) return m_flEndValue; if ( curTime <= m_flStartTime ) return m_flStartValue; return SimpleSplineRemapVal( curTime, m_flStartTime, m_flEndTime, m_flStartValue, m_flEndValue ); } } // NOTENOTE: You managed to pass in a bogus interpolation type! Assert(0); return -1.0f; }
//----------------------------------------------------------------------------- // Purpose: Calculate the FOV for the intro sequence (needed by both server and client) //----------------------------------------------------------------------------- float ScriptInfo_CalculateFOV( float flFOVBlendStartTime, float flNextFOVBlendTime, int nFOV, int nNextFOV, bool bSplineRamp ) { // Handle the spline case if ( bSplineRamp ) { //If we're past the zoom time, just take the new value and stop transitioning float deltaTime = (float)( gpGlobals->curtime - flFOVBlendStartTime ) / ( flNextFOVBlendTime - flFOVBlendStartTime ); if ( deltaTime >= 1.0f ) return nNextFOV; float flResult = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, (float) nFOV, (float) nNextFOV ); // Msg("FOV BLENDING: curtime %.2f StartedAt %.2f FinishAt: %.2f\n", gpGlobals->curtime, flFOVBlendStartTime, flNextFOVBlendTime ); // Msg(" Perc: %.2f Start: %d End: %d FOV: %.2f\n", SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, nFOV, nNextFOV ), nFOV, nNextFOV, flResult ); return flResult; } // Common, linear blend if ( (flNextFOVBlendTime - flFOVBlendStartTime) != 0 ) { float flResult = RemapValClamped( gpGlobals->curtime, flFOVBlendStartTime, flNextFOVBlendTime, (float) nFOV, (float) nNextFOV ); // Msg("FOV BLENDING: curtime %.2f StartedAt %.2f FinishAt: %.2f\n", gpGlobals->curtime, flFOVBlendStartTime, flNextFOVBlendTime ); // Msg(" Perc: %.2f Start: %d End: %d FOV: %.2f\n", RemapValClamped( gpGlobals->curtime, flFOVBlendStartTime, flNextFOVBlendTime, 0.0, 1.0 ), nFOV, nNextFOV, flResult ); return flResult; } // Msg("FOV BLENDING: JUMPED TO NEXT FOV (%d)\n", nNextFOV ); return nNextFOV; }
void CSDKGameMovement::SetProneEyeOffset( float proneFraction ) { Vector vecPropViewOffset = VEC_PRONE_VIEW; Vector vecStandViewOffset = GetPlayerViewOffset( player->m_Local.m_bDucked || m_pSDKPlayer->m_bUnProneToDuck ); Vector temp = player->GetViewOffset(); temp.z = SimpleSplineRemapVal( proneFraction, 1.0, 0.0, vecPropViewOffset.z, vecStandViewOffset.z ); player->SetViewOffset( temp ); }
void CAI_Spotlight::UpdateSpotlightDirection( void ) { if ( !m_hSpotlight ) { CreateSpotlightEntities(); } // Compute the current beam direction Vector vTargetDir; VectorSubtract( m_vSpotlightTargetPos, m_hSpotlight->GetAbsStartPos(), vTargetDir ); VectorNormalize(vTargetDir); ConstrainToCone( &vTargetDir ); // Compute the amount to rotate float flDot = DotProduct( vTargetDir, m_vSpotlightDir ); flDot = clamp( flDot, -1.0f, 1.0f ); float flAngle = AngleNormalize( RAD2DEG( acos( flDot ) ) ); float flClampedAngle = clamp( flAngle, 0.0f, 45.0f ); float flBeamTurnRate = SimpleSplineRemapVal( flClampedAngle, 0.0f, 45.0f, 10.0f, 45.0f ); if ( fabs(flAngle) > flBeamTurnRate * gpGlobals->frametime ) { flAngle = flBeamTurnRate * gpGlobals->frametime; } // Compute the rotation axis Vector vecRotationAxis; CrossProduct( m_vSpotlightDir, vTargetDir, vecRotationAxis ); if ( VectorNormalize( vecRotationAxis ) < 1e-3 ) { vecRotationAxis.Init( 0, 0, 1 ); } // Compute the actual rotation amount, using quat slerp blending Quaternion desiredQuat, resultQuat; AxisAngleQuaternion( vecRotationAxis, flAngle, desiredQuat ); QuaternionSlerp( m_vAngularVelocity, desiredQuat, QUAT_BLEND_FACTOR, resultQuat ); m_vAngularVelocity = resultQuat; // If we're really close, and we're not moving very quickly, slam. float flActualRotation = AngleNormalize( RAD2DEG(2 * acos(m_vAngularVelocity.w)) ); if (( flActualRotation < 1e-3 ) && (flAngle < 1e-3 )) { m_vSpotlightDir = vTargetDir; m_vAngularVelocity.Init( 0, 0, 0, 1 ); return; } // Update the desired direction matrix3x4_t rot; Vector vecNewDir; QuaternionMatrix( m_vAngularVelocity, rot ); VectorRotate( m_vSpotlightDir, rot, vecNewDir ); m_vSpotlightDir = vecNewDir; VectorNormalize(m_vSpotlightDir); }
//----------------------------------------------------------------------------- // Sparks! //----------------------------------------------------------------------------- void C_EntityDissolve::DoSparks( mstudiohitboxset_t *set, matrix3x4_t *hitboxbones[MAXSTUDIOBONES] ) { if ( m_flNextSparkTime > gpGlobals->curtime ) return; float dt = m_flStartTime + m_flFadeOutStart - gpGlobals->curtime; dt = clamp( dt, 0.0f, m_flFadeOutStart ); float flNextTime; if (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) { flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 2.0f * TICK_INTERVAL, 0.4f ); } else { // m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT); flNextTime = SimpleSplineRemapVal( dt, 0.0f, m_flFadeOutStart, 0.3f, 1.0f ); } m_flNextSparkTime = gpGlobals->curtime + flNextTime; // Send out beams around us int iNumBeamsAround = 2; int iNumRandomBeams = 1; int iTotalBeams = iNumBeamsAround + iNumRandomBeams; float flYawOffset = RandomFloat(0,360); for ( int i = 0; i < iTotalBeams; i++ ) { int nHitbox = random->RandomInt( 0, set->numhitboxes - 1 ); mstudiobbox_t *pBox = set->pHitbox(nHitbox); float flActualYawOffset = 0; bool bRandom = ( i >= iNumBeamsAround ); if ( !bRandom ) { flActualYawOffset = anglemod( flYawOffset + ((360 / iTotalBeams) * i) ); } BuildTeslaEffect( pBox, *hitboxbones[pBox->bone], bRandom, flActualYawOffset ); } }
//----------------------------------------------------------------------------- // Purpose: Burn targets around us //----------------------------------------------------------------------------- void CRagdollBoogie::BoogieThink( void ) { CRagdollProp *pRagdoll = dynamic_cast< CRagdollProp* >( GetMoveParent() ); if ( !pRagdoll ) { UTIL_Remove( this ); return; } float flMagnitude = m_flMagnitude; if ( m_flBoogieLength != 0 ) { float dt = gpGlobals->curtime - m_flStartTime; if ( dt >= m_flBoogieLength ) { // Don't remove while suppressed... this helps if we try to start another boogie if ( m_nSuppressionCount == 0 ) { UTIL_Remove( this ); } SetThink( NULL ); return; } if ( dt < 0 ) { SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) ); return; } flMagnitude = SimpleSplineRemapVal( dt, 0.0f, m_flBoogieLength, m_flMagnitude, 0.0f ); } #ifndef _XBOX if ( m_nSuppressionCount == 0 ) { ragdoll_t *pRagdollPhys = pRagdoll->GetRagdoll( ); for ( int j = 0; j < pRagdollPhys->listCount; ++j ) { float flMass = pRagdollPhys->list[j].pObject->GetMass(); float flForce = m_flMagnitude * flMass; Vector vecForce; vecForce = RandomVector( -flForce, flForce ); pRagdollPhys->list[j].pObject->ApplyForceCenter( vecForce ); } } #endif // !_XBOX SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.1, 0.2f ) ); }
void CBaseHelicopter::DoWashPushOnAirboat( CBaseEntity *pAirboat, const Vector &vecWashToAirboat, float flWashAmount ) { // For the airboat, simply produce a small roll and a push outwards. // But don't produce a roll if we're too rolled in that direction already. // Get the actual up direction vector Vector vecUp; pAirboat->GetVectors( NULL, NULL, &vecUp ); if ( vecUp.z < MAX_AIRBOAT_ROLL_COSANGLE ) return; // Compute roll direction so that we get pushed down on the side where the rotor wash is. Vector vecRollNormal; CrossProduct( vecWashToAirboat, Vector( 0, 0, 1 ), vecRollNormal ); // Project it into the plane of the roll normal VectorMA( vecUp, -DotProduct( vecUp, vecRollNormal ), vecRollNormal, vecUp ); VectorNormalize( vecUp ); // Compute a vector which is the max direction we can roll given the roll constraint Vector vecExtremeUp; VMatrix rot; MatrixBuildRotationAboutAxis( rot, vecRollNormal, MAX_AIRBOAT_ROLL_ANGLE ); MatrixGetColumn( rot, 2, &vecExtremeUp ); // Find the angle between how vertical we are and how vertical we should be float flCosDelta = DotProduct( vecExtremeUp, vecUp ); float flDelta = acos(flCosDelta) * 180.0f / M_PI; flDelta = clamp( flDelta, 0.0f, MAX_AIRBOAT_ROLL_ANGLE ); flDelta = SimpleSplineRemapVal( flDelta, 0.0f, MAX_AIRBOAT_ROLL_ANGLE, 0.0f, 1.0f ); float flForce = 12.0f * flWashAmount * flDelta; Vector vecWashOrigin; Vector vecForce; VectorMultiply( Vector( 0, 0, -1 ), flForce, vecForce ); VectorMA( pAirboat->GetAbsOrigin(), -200.0f, vecWashToAirboat, vecWashOrigin ); pAirboat->VPhysicsTakeDamage( CTakeDamageInfo( this, this, vecForce, vecWashOrigin, flWashAmount, DMG_BLAST ) ); }
//----------------------------------------------------------------------------- // Purpose: // Output : float //----------------------------------------------------------------------------- float C_BaseHLPlayer::GetZoom( void ) { float fFOV = m_flZoomEnd; //See if we need to lerp the values if ( ( m_flZoomStart != m_flZoomEnd ) && ( m_flZoomRate > 0.0f ) ) { float deltaTime = (float)( gpGlobals->curtime - m_flZoomStartTime ) / m_flZoomRate; if ( deltaTime >= 1.0f ) { //If we're past the zoom time, just take the new value and stop lerping fFOV = m_flZoomStart = m_flZoomEnd; } else { fFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_flZoomStart, m_flZoomEnd ); } } return fFOV; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_ScriptIntro::CalculateFOV( void ) { // Calculate the FOV if ( m_flNextFOVBlendTime >= gpGlobals->curtime ) { if ( m_bAlternateFOV == true ) { float deltaTime = (float)( gpGlobals->curtime - m_flFOVBlendStartTime ) / ( m_flNextFOVBlendTime - m_flFOVBlendStartTime ); if ( deltaTime >= 1.0f ) { //If we're past the zoom time, just take the new value and stop transitioning m_IntroData.m_playerViewFOV = m_iNextFOV; } else { m_IntroData.m_playerViewFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_iFOVAtStartBlend, m_iNextFOV ); } } else { if ( (m_flNextFOVBlendTime - m_flFOVBlendStartTime) != 0 ) { m_IntroData.m_playerViewFOV = RemapValClamped( gpGlobals->curtime, m_flFOVBlendStartTime, m_flNextFOVBlendTime, m_iFOVAtStartBlend, m_iNextFOV ); //Msg("FOV BLENDING: curtime %.2f StartedAt %.2f FinishAt: %.2f\n", gpGlobals->curtime, m_flFOVBlendStartTime, m_flNextFOVBlendTime ); //Msg(" Perc: %.2f Start: %d End: %d FOV: %.2f\n", RemapValClamped( gpGlobals->curtime, m_flFOVBlendStartTime, m_flNextFOVBlendTime, 0.0, 1.0 ), m_iFOVAtStartBlend, m_iNextFOV, m_IntroData.m_playerViewFOV ); } else { //Msg("FOV BLENDING: JUMPED TO NEXT FOV (%d)\n", m_iNextFOV ); m_IntroData.m_playerViewFOV = m_iNextFOV; } } } }
//----------------------------------------------------------------------------- // Purpose: Do the headlight //----------------------------------------------------------------------------- void CFlashlightEffect::UpdateLightNew(const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp ) { VPROF_BUDGET( "CFlashlightEffect::UpdateLightNew", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); FlashlightState_t state; // We will lock some of the flashlight params if player is on a ladder, to prevent oscillations due to the trace-rays bool bPlayerOnLadder = ( C_BasePlayer::GetLocalPlayer()->GetMoveType() == MOVETYPE_LADDER ); const float flEpsilon = 0.1f; // Offset flashlight position along vecUp const float flDistCutoff = 128.0f; const float flDistDrag = 0.2; CTraceFilterSkipPlayerAndViewModel traceFilter; float flOffsetY = r_flashlightoffsety.GetFloat(); if( r_swingflashlight.GetBool() ) { // This projects the view direction backwards, attempting to raise the vertical // offset of the flashlight, but only when the player is looking down. Vector vecSwingLight = vecPos + vecForward * -12.0f; if( vecSwingLight.z > vecPos.z ) { flOffsetY += (vecSwingLight.z - vecPos.z); } } Vector vOrigin = vecPos + flOffsetY * vecUp; // Not on ladder...trace a hull if ( !bPlayerOnLadder ) { trace_t pmOriginTrace; UTIL_TraceHull( vecPos, vOrigin, Vector(-4, -4, -4), Vector(4, 4, 4), MASK_SOLID & ~(CONTENTS_HITBOX), &traceFilter, &pmOriginTrace ); if ( pmOriginTrace.DidHit() ) { vOrigin = vecPos; } } else // on ladder...skip the above hull trace { vOrigin = vecPos; } // Now do a trace along the flashlight direction to ensure there is nothing within range to pull back from int iMask = MASK_OPAQUE_AND_NPCS; iMask &= ~CONTENTS_HITBOX; iMask |= CONTENTS_WINDOW; // VR SOURCE - Use weap angle forward vector here Vector vTarget; /*if ( VR_Controller()->initialized() && VR_Controller()->hasWeaponTracking() ) { vTarget = vecPos + } else {*/ vTarget = vecPos + vecForward * r_flashlightfar.GetFloat(); // } // Work with these local copies of the basis for the rest of the function Vector vDir = vTarget - vOrigin; Vector vRight = vecRight; Vector vUp = vecUp; VectorNormalize( vDir ); VectorNormalize( vRight ); VectorNormalize( vUp ); // Orthonormalize the basis, since the flashlight texture projection will require this later... vUp -= DotProduct( vDir, vUp ) * vDir; VectorNormalize( vUp ); vRight -= DotProduct( vDir, vRight ) * vDir; VectorNormalize( vRight ); vRight -= DotProduct( vUp, vRight ) * vUp; VectorNormalize( vRight ); AssertFloatEquals( DotProduct( vDir, vRight ), 0.0f, 1e-3 ); AssertFloatEquals( DotProduct( vDir, vUp ), 0.0f, 1e-3 ); AssertFloatEquals( DotProduct( vRight, vUp ), 0.0f, 1e-3 ); trace_t pmDirectionTrace; UTIL_TraceHull( vOrigin, vTarget, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), iMask, &traceFilter, &pmDirectionTrace ); if ( r_flashlightvisualizetrace.GetBool() == true ) { debugoverlay->AddBoxOverlay( pmDirectionTrace.endpos, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), QAngle( 0, 0, 0 ), 0, 0, 255, 16, 0 ); debugoverlay->AddLineOverlay( vOrigin, pmDirectionTrace.endpos, 255, 0, 0, false, 0 ); } float flDist = (pmDirectionTrace.endpos - vOrigin).Length(); if ( flDist < flDistCutoff ) { // We have an intersection with our cutoff range // Determine how far to pull back, then trace to see if we are clear float flPullBackDist = bPlayerOnLadder ? r_flashlightladderdist.GetFloat() : flDistCutoff - flDist; // Fixed pull-back distance if on ladder m_flDistMod = Lerp( flDistDrag, m_flDistMod, flPullBackDist ); if ( !bPlayerOnLadder ) { trace_t pmBackTrace; UTIL_TraceHull( vOrigin, vOrigin - vDir*(flPullBackDist-flEpsilon), Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), iMask, &traceFilter, &pmBackTrace ); if( pmBackTrace.DidHit() ) { // We have an intersection behind us as well, so limit our m_flDistMod float flMaxDist = (pmBackTrace.endpos - vOrigin).Length() - flEpsilon; if( m_flDistMod > flMaxDist ) m_flDistMod = flMaxDist; } } } else { m_flDistMod = Lerp( flDistDrag, m_flDistMod, 0.0f ); } vOrigin = vOrigin - vDir * m_flDistMod; state.m_vecLightOrigin = vOrigin; BasisToQuaternion( vDir, vRight, vUp, state.m_quatOrientation ); state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat(); bool bFlicker = false; #ifdef HL2_EPISODIC C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if ( pPlayer ) { float flBatteryPower = ( pPlayer->m_HL2Local.m_flFlashBattery >= 0.0f ) ? ( pPlayer->m_HL2Local.m_flFlashBattery ) : pPlayer->m_HL2Local.m_flSuitPower; if ( flBatteryPower <= 10.0f ) { float flScale; if ( flBatteryPower >= 0.0f ) { flScale = ( flBatteryPower <= 4.5f ) ? SimpleSplineRemapVal( flBatteryPower, 4.5f, 0.0f, 1.0f, 0.0f ) : 1.0f; } else { flScale = SimpleSplineRemapVal( flBatteryPower, 10.0f, 4.8f, 1.0f, 0.0f ); } flScale = clamp( flScale, 0.0f, 1.0f ); if ( flScale < 0.35f ) { float flFlicker = cosf( gpGlobals->curtime * 6.0f ) * sinf( gpGlobals->curtime * 15.0f ); if ( flFlicker > 0.25f && flFlicker < 0.75f ) { // On state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale; } else { // Off state.m_fLinearAtten = 0.0f; } } else { float flNoise = cosf( gpGlobals->curtime * 7.0f ) * sinf( gpGlobals->curtime * 25.0f ); state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale + 1.5f * flNoise; } state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) ); state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) ); bFlicker = true; } } #endif // HL2_EPISODIC if ( bFlicker == false ) { state.m_fLinearAtten = r_flashlightlinear.GetFloat(); state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat(); state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat(); } state.m_fConstantAtten = r_flashlightconstant.GetFloat(); state.m_Color[0] = 1.0f; state.m_Color[1] = 1.0f; state.m_Color[2] = 1.0f; state.m_Color[3] = r_flashlightambient.GetFloat(); state.m_NearZ = r_flashlightnear.GetFloat() + m_flDistMod; // Push near plane out so that we don't clip the world when the flashlight pulls back state.m_FarZ = r_flashlightfar.GetFloat(); state.m_bEnableShadows = r_flashlightdepthtexture.GetBool(); state.m_flShadowMapResolution = r_flashlightdepthres.GetInt(); state.m_pSpotlightTexture = m_FlashlightTexture; state.m_nSpotlightTextureFrame = 0; state.m_flShadowAtten = r_flashlightshadowatten.GetFloat(); state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat(); state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat(); if( m_FlashlightHandle == CLIENTSHADOW_INVALID_HANDLE ) { m_FlashlightHandle = g_pClientShadowMgr->CreateFlashlight( state ); } else { if( !r_flashlightlockposition.GetBool() ) { g_pClientShadowMgr->UpdateFlashlightState( m_FlashlightHandle, state ); } } g_pClientShadowMgr->UpdateProjectedTexture( m_FlashlightHandle, true ); // Kill the old flashlight method if we have one. LightOffOld(); #ifndef NO_TOOLFRAMEWORK if ( clienttools->IsInRecordingMode() ) { KeyValues *msg = new KeyValues( "FlashlightState" ); msg->SetFloat( "time", gpGlobals->curtime ); msg->SetInt( "entindex", m_nEntIndex ); msg->SetInt( "flashlightHandle", m_FlashlightHandle ); msg->SetPtr( "flashlightState", &state ); ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg ); msg->deleteThis(); } #endif }
bool CFlashlightEffect::UpdateDefaultFlashlightState( FlashlightState_t& state, const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp, bool castsShadows, bool bTracePlayers ) { VPROF_BUDGET( __FUNCTION__, VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING ); if ( !m_bIsOn ) { // return; } if ( ComputeLightPosAndOrientation( vecPos, vecForward, vecRight, vecUp, state.m_vecLightOrigin, state.m_quatOrientation, bTracePlayers ) == false ) { return false; } state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat(); bool bFlicker = false; #ifdef HL2_EPISODIC C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if ( pPlayer ) { float flBatteryPower = ( pPlayer->m_HL2Local.m_flFlashBattery >= 0.0f ) ? ( pPlayer->m_HL2Local.m_flFlashBattery ) : pPlayer->m_HL2Local.m_flSuitPower; if ( flBatteryPower <= 10.0f ) { float flScale; if ( flBatteryPower >= 0.0f ) { flScale = ( flBatteryPower <= 4.5f ) ? SimpleSplineRemapVal( flBatteryPower, 4.5f, 0.0f, 1.0f, 0.0f ) : 1.0f; } else { flScale = SimpleSplineRemapVal( flBatteryPower, 10.0f, 4.8f, 1.0f, 0.0f ); } flScale = clamp( flScale, 0.0f, 1.0f ); if ( flScale < 0.35f ) { float flFlicker = cosf( gpGlobals->curtime * 6.0f ) * sinf( gpGlobals->curtime * 15.0f ); if ( flFlicker > 0.25f && flFlicker < 0.75f ) { // On state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale; } else { // Off state.m_fLinearAtten = 0.0f; } } else { float flNoise = cosf( gpGlobals->curtime * 7.0f ) * sinf( gpGlobals->curtime * 25.0f ); state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale + 1.5f * flNoise; } state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) ); state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) ); bFlicker = true; } } #endif // HL2_EPISODIC if ( bFlicker == false ) { if ( m_flLinearAtten > 0.0f ) { state.m_fLinearAtten = m_flLinearAtten; } else { state.m_fLinearAtten = r_flashlightlinear.GetFloat(); } if ( m_flFov > 0.0f ) { state.m_fHorizontalFOVDegrees = m_flFov; state.m_fVerticalFOVDegrees = m_flFov; } else { state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat(); state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat(); } if ( m_bMuzzleFlashEnabled ) { state.m_fHorizontalFOVDegrees = state.m_fVerticalFOVDegrees = r_flashlightmuzzleflashfov.GetFloat(); } } state.m_fConstantAtten = r_flashlightconstant.GetFloat(); state.m_Color[0] = 1.0f; state.m_Color[1] = 1.0f; state.m_Color[2] = 1.0f; state.m_Color[3] = r_flashlightambient.GetFloat(); state.m_NearZ = r_flashlightnear.GetFloat() + r_flashlightnearoffsetscale.GetFloat() * m_flCurrentPullBackDist; // Optionally push near plane out so that we don't clip the world when the flashlight pulls back if ( m_flFarZ > 0.0f ) { state.m_FarZ = state.m_FarZAtten = m_flFarZ; // Strictly speaking, these are different, but the game can treat them the same } else { state.m_FarZ = state.m_FarZAtten = r_flashlightfar.GetFloat(); // Strictly speaking, these are different, but the game can treat them the same } state.m_bEnableShadows = castsShadows && r_flashlightdepthtexture.GetBool(); state.m_flShadowMapResolution = r_flashlightdepthres.GetInt(); state.m_flShadowFilterSize = 3.0f; // uberlight state.m_bUberlight = r_flashlightuberlight.GetBool(); state.m_uberlightState.m_fRoundness = 1.0f; if ( m_bMuzzleFlashEnabled ) { state.m_pSpotlightTexture = m_MuzzleFlashTexture; state.m_pProjectedMaterial = NULL; state.m_Color[0] = m_flMuzzleFlashBrightness; state.m_Color[1] = m_flMuzzleFlashBrightness; state.m_Color[2] = m_flMuzzleFlashBrightness; } else { state.m_pSpotlightTexture = m_FlashlightTexture; state.m_pProjectedMaterial = NULL; } state.m_nSpotlightTextureFrame = 0; state.m_flShadowAtten = r_flashlightshadowatten.GetFloat(); state.m_flShadowSlopeScaleDepthBias = g_pMaterialSystemHardwareConfig->GetShadowSlopeScaleDepthBias(); state.m_flShadowDepthBias = g_pMaterialSystemHardwareConfig->GetShadowDepthBias(); state.m_bVolumetric = r_flashlightvolumetrics.GetBool(); state.m_flAmbientOcclusion = r_flashlightAO.GetFloat(); return true; }
//----------------------------------------------------------------------------- // Purpose: Do the headlight //----------------------------------------------------------------------------- void CFlashlightEffect::UpdateLightNew(const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp) { FlashlightState_t state; Vector end = vecPos + r_flashlightoffsety.GetFloat() * vecUp; trace_t pmEye, pmEyeBack; CTraceFilterSkipPlayerAndViewModel traceFilter; UTIL_TraceHull( vecPos, end, Vector( -4, -4, -4 ), Vector ( 4, 4, 4 ), MASK_SOLID & ~(CONTENTS_HITBOX), &traceFilter, &pmEye ); if ( pmEye.fraction != 1.0f ) { end = vecPos; } int iMask = MASK_OPAQUE_AND_NPCS; iMask &= ~CONTENTS_HITBOX; iMask |= CONTENTS_WINDOW; // Trace a line outward, skipping the player model and the view model. //Eye -> EyeForward UTIL_TraceHull( end, vecPos + vecForward * r_flashlightfar.GetFloat(), Vector( -4, -4, -4 ), Vector ( 4, 4, 4 ), iMask, &traceFilter, &pmEye ); UTIL_TraceHull( end, vecPos - vecForward * 128, Vector( -4, -4, -4 ), Vector ( 4, 4, 4 ), iMask, &traceFilter, &pmEyeBack ); float flDist; float flLength = (pmEye.endpos - end).Length(); if ( flLength <= 128 ) { flDist = ( ( 1.0f - ( flLength / 128 ) ) * 128.0f ); } else { flDist = 0.0f; } m_flDistMod = Lerp( 0.3f, m_flDistMod, flDist ); float flMaxDist = (pmEyeBack.endpos - end).Length(); if( m_flDistMod > flMaxDist ) m_flDistMod = flMaxDist; Vector vStartPos = end; Vector vEndPos = pmEye.endpos; Vector vDir = vEndPos - vStartPos; VectorNormalize( vDir ); if ( vDir == vec3_origin ) { vDir = vecForward; } vStartPos = vStartPos - vDir * m_flDistMod; if ( r_flashlightvisualizetrace.GetBool() == true ) { debugoverlay->AddBoxOverlay( vEndPos, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), QAngle( 0, 0, 0 ), 0, 0, 255, 16, 0 ); debugoverlay->AddLineOverlay( vStartPos, vEndPos, 255, 0, 0, false, 0 ); } state.m_vecLightOrigin = vStartPos; state.m_vecLightDirection = vDir; state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat(); bool bFlicker = false; #ifdef HL2_EPISODIC C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if ( pPlayer && pPlayer->m_HL2Local.m_flSuitPower <= 10.0f ) { float flScale = SimpleSplineRemapVal( pPlayer->m_HL2Local.m_flSuitPower, 10.0f, 4.8f, 1.0f, 0.0f ); flScale = clamp( flScale, 0.0f, 1.0f ); if ( flScale < 0.35f ) { float flFlicker = cosf( gpGlobals->curtime * 6.0f ) * sinf( gpGlobals->curtime * 15.0f ); if ( flFlicker > 0.25f && flFlicker < 0.75f ) { // On state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale; } else { // Off state.m_fLinearAtten = 0.0f; } } else { float flNoise = cosf( gpGlobals->curtime * 7.0f ) * sinf( gpGlobals->curtime * 25.0f ); state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale + 1.5f * flNoise; } state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) ); state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) ); bFlicker = true; } #endif if ( bFlicker == false ) { state.m_fLinearAtten = r_flashlightlinear.GetFloat(); state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat(); state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat(); } state.m_fConstantAtten = r_flashlightconstant.GetFloat(); state.m_Color.Init( 1.0f, 1.0f, 1.0f ); state.m_NearZ = r_flashlightnear.GetFloat(); state.m_FarZ = r_flashlightfar.GetFloat(); if( m_FlashlightHandle == CLIENTSHADOW_INVALID_HANDLE ) { m_FlashlightHandle = g_pClientShadowMgr->CreateFlashlight( state ); } else { if( !r_flashlightlockposition.GetBool() ) { g_pClientShadowMgr->UpdateFlashlightState( m_FlashlightHandle, state ); } } g_pClientShadowMgr->UpdateProjectedTexture( m_FlashlightHandle, true ); // Kill the old flashlight method if we have one. LightOffOld(); }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CNPC_CombineDropship::Flight( void ) { // Only run pose params in some flight states bool bRunPoseParams = ( m_iLandState == LANDING_NO || m_iLandState == LANDING_LEVEL_OUT || m_iLandState == LANDING_LIFTOFF || m_iLandState == LANDING_SWOOPING ); if ( bRunPoseParams ) { if( GetFlags() & FL_ONGROUND ) { //This would be really bad. RemoveFlag( FL_ONGROUND ); } // NDebugOverlay::Line(GetLocalOrigin(), GetDesiredPosition(), 0,0,255, true, 0.1); Vector deltaPos = GetDesiredPosition() - GetLocalOrigin(); // calc desired acceleration float dt = 1.0f; Vector accel; float accelRate = DROPSHIP_ACCEL_RATE; float maxSpeed = m_flMaxSpeed; if ( m_lifeState == LIFE_DYING ) { accelRate *= 5.0; maxSpeed *= 5.0; } float flDist = min( GetAbsVelocity().Length() + accelRate, maxSpeed ); // Only decelerate to our goal if we're going to hit it if ( deltaPos.Length() > flDist * dt ) { float scale = flDist * dt / deltaPos.Length(); deltaPos = deltaPos * scale; } // If we're swooping, floor it if ( m_iLandState == LANDING_SWOOPING ) { VectorNormalize( deltaPos ); deltaPos *= maxSpeed; } // calc goal linear accel to hit deltaPos in dt time. accel.x = 2.0 * (deltaPos.x - GetAbsVelocity().x * dt) / (dt * dt); accel.y = 2.0 * (deltaPos.y - GetAbsVelocity().y * dt) / (dt * dt); accel.z = 2.0 * (deltaPos.z - GetAbsVelocity().z * dt + 0.5 * 384 * dt * dt) / (dt * dt); //NDebugOverlay::Line(GetLocalOrigin(), GetLocalOrigin() + deltaPos, 255,0,0, true, 0.1); //NDebugOverlay::Line(GetLocalOrigin(), GetLocalOrigin() + accel, 0,255,0, true, 0.1); // don't fall faster than 0.2G or climb faster than 2G if ( m_iLandState != LANDING_SWOOPING ) { accel.z = clamp( accel.z, 384 * 0.2, 384 * 2.0 ); } Vector forward, right, up; GetVectors( &forward, &right, &up ); Vector goalUp = accel; VectorNormalize( goalUp ); // calc goal orientation to hit linear accel forces float goalPitch = RAD2DEG( asin( DotProduct( forward, goalUp ) ) ); float goalYaw = UTIL_VecToYaw( m_vecDesiredFaceDir ); float goalRoll = RAD2DEG( asin( DotProduct( right, goalUp ) ) ); // clamp goal orientations goalPitch = clamp( goalPitch, -45, 60 ); goalRoll = clamp( goalRoll, -45, 45 ); // calc angular accel needed to hit goal pitch in dt time. dt = 0.6; QAngle goalAngAccel; goalAngAccel.x = 2.0 * (AngleDiff( goalPitch, AngleNormalize( GetLocalAngles().x ) ) - GetLocalAngularVelocity().x * dt) / (dt * dt); goalAngAccel.y = 2.0 * (AngleDiff( goalYaw, AngleNormalize( GetLocalAngles().y ) ) - GetLocalAngularVelocity().y * dt) / (dt * dt); goalAngAccel.z = 2.0 * (AngleDiff( goalRoll, AngleNormalize( GetLocalAngles().z ) ) - GetLocalAngularVelocity().z * dt) / (dt * dt); goalAngAccel.x = clamp( goalAngAccel.x, -300, 300 ); //goalAngAccel.y = clamp( goalAngAccel.y, -60, 60 ); goalAngAccel.y = clamp( goalAngAccel.y, -120, 120 ); goalAngAccel.z = clamp( goalAngAccel.z, -300, 300 ); // limit angular accel changes to simulate mechanical response times dt = 0.1; QAngle angAccelAccel; angAccelAccel.x = (goalAngAccel.x - m_vecAngAcceleration.x) / dt; angAccelAccel.y = (goalAngAccel.y - m_vecAngAcceleration.y) / dt; angAccelAccel.z = (goalAngAccel.z - m_vecAngAcceleration.z) / dt; angAccelAccel.x = clamp( angAccelAccel.x, -1000, 1000 ); angAccelAccel.y = clamp( angAccelAccel.y, -1000, 1000 ); angAccelAccel.z = clamp( angAccelAccel.z, -1000, 1000 ); m_vecAngAcceleration += angAccelAccel * 0.1; // Msg( "pitch %6.1f (%6.1f:%6.1f) ", goalPitch, GetLocalAngles().x, m_vecAngVelocity.x ); // Msg( "roll %6.1f (%6.1f:%6.1f) : ", goalRoll, GetLocalAngles().z, m_vecAngVelocity.z ); // Msg( "%6.1f %6.1f %6.1f : ", goalAngAccel.x, goalAngAccel.y, goalAngAccel.z ); // Msg( "%6.0f %6.0f %6.0f\n", angAccelAccel.x, angAccelAccel.y, angAccelAccel.z ); ApplySidewaysDrag( right ); ApplyGeneralDrag(); QAngle angVel = GetLocalAngularVelocity(); angVel += m_vecAngAcceleration * 0.1; //angVel.y = clamp( angVel.y, -60, 60 ); //angVel.y = clamp( angVel.y, -120, 120 ); angVel.y = clamp( angVel.y, -120, 120 ); SetLocalAngularVelocity( angVel ); m_flForce = m_flForce * 0.8 + (accel.z + fabs( accel.x ) * 0.1 + fabs( accel.y ) * 0.1) * 0.1 * 0.2; Vector vecImpulse = m_flForce * up; if ( m_lifeState == LIFE_DYING ) { vecImpulse.z = -38.4; // 64ft/sec } else { vecImpulse.z -= 38.4; // 32ft/sec } // Find our acceleration direction Vector vecAccelDir = vecImpulse; VectorNormalize( vecAccelDir ); // Find our current velocity Vector vecVelDir = GetAbsVelocity(); VectorNormalize( vecVelDir ); // Level out our plane of movement vecAccelDir.z = 0.0f; vecVelDir.z = 0.0f; forward.z = 0.0f; right.z = 0.0f; // Find out how "fast" we're moving in relation to facing and acceleration float speed = m_flForce * DotProduct( vecVelDir, vecAccelDir );// * DotProduct( forward, vecVelDir ); // Use the correct pose params char *sBodyAccel; char *sBodySway; if ( m_hContainer || m_iLandState == LANDING_SWOOPING ) { sBodyAccel = "cargo_body_accel"; sBodySway = "cargo_body_sway"; SetPoseParameter( "body_accel", 0 ); SetPoseParameter( "body_sway", 0 ); } else { sBodyAccel = "body_accel"; sBodySway = "body_sway"; SetPoseParameter( "cargo_body_accel", 0 ); SetPoseParameter( "cargo_body_sway", 0 ); } // Apply the acceleration blend to the fins float finAccelBlend = SimpleSplineRemapVal( speed, -60, 60, -1, 1 ); float curFinAccel = GetPoseParameter( sBodyAccel ); curFinAccel = UTIL_Approach( finAccelBlend, curFinAccel, 0.5f ); SetPoseParameter( sBodyAccel, curFinAccel ); speed = m_flForce * DotProduct( vecVelDir, right ); // Apply the spin sway to the fins float finSwayBlend = SimpleSplineRemapVal( speed, -60, 60, -1, 1 ); float curFinSway = GetPoseParameter( sBodySway ); curFinSway = UTIL_Approach( finSwayBlend, curFinSway, 0.5f ); SetPoseParameter( sBodySway, curFinSway ); // Add in our velocity pulse for this frame ApplyAbsVelocityImpulse( vecImpulse ); //Msg("FinAccel: %f, Finsway: %f\n", curFinAccel, curFinSway ); } else { SetPoseParameter( "body_accel", 0 ); SetPoseParameter( "body_sway", 0 ); SetPoseParameter( "cargo_body_accel", 0 ); SetPoseParameter( "cargo_body_sway", 0 ); } }