//----------------------------------------------------------------------------- // Purpose: // Output : float //----------------------------------------------------------------------------- float CWeaponRainbowBase_CombatWeapon::CalcViewmodelBob( void ) { static float bobtime; static float lastbobtime; float cycle; CBasePlayer *player = ToBasePlayer( GetOwner() ); //Assert( player ); //NOTENOTE: For now, let this cycle continue when in the air, because it snaps badly without it if ( ( !gpGlobals->frametime ) || ( player == NULL ) ) { //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!) return 0.0f;// just use old value } //Find the speed of the player float speed = player->GetLocalVelocity().Length2D(); //FIXME: This maximum speed value must come from the server. // MaxSpeed() is not sufficient for dealing with sprinting - jdw speed = clamp( speed, -320, 320 ); float bob_offset = RemapVal( speed, 0, 320, 0.0f, 1.0f ); bobtime += ( gpGlobals->curtime - lastbobtime ) * bob_offset; lastbobtime = gpGlobals->curtime; //Calculate the vertical bob cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX)*HL2_BOB_CYCLE_MAX; cycle /= HL2_BOB_CYCLE_MAX; if ( cycle < HL2_BOB_UP ) { cycle = M_PI * cycle / HL2_BOB_UP; } else { cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP); } g_verticalBob = speed*0.005f; g_verticalBob = g_verticalBob*0.3 + g_verticalBob*0.7*sin(cycle); g_verticalBob = clamp( g_verticalBob, -7.0f, 4.0f ); //Calculate the lateral bob cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX*2)*HL2_BOB_CYCLE_MAX*2; cycle /= HL2_BOB_CYCLE_MAX*2; if ( cycle < HL2_BOB_UP ) { cycle = M_PI * cycle / HL2_BOB_UP; } else { cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP); } g_lateralBob = speed*0.005f; g_lateralBob = g_lateralBob*0.3 + g_lateralBob*0.7*sin(cycle); g_lateralBob = clamp( g_lateralBob, -7.0f, 4.0f ); //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!) return 0.0f; }
void CSystemInstance::Simulate() { double flGameTime = GameServer()->GetGameTime(); double flFrameTime = GameServer()->GetFrameTime(); if (m_hFollow != NULL) { m_vecOrigin = m_hFollow->BaseGetRenderOrigin(); m_vecInheritedVelocity = m_hFollow->GetGlobalVelocity(); } for (size_t i = 0; i < m_aParticles.size(); i++) { CParticle* pParticle = &m_aParticles[i]; if (!pParticle->m_bActive) continue; float flLifeTime = (float)(flGameTime - pParticle->m_flSpawnTime); if (flLifeTime > m_pSystem->GetLifeTime()) { pParticle->m_bActive = false; m_iNumParticlesAlive--; continue; } pParticle->m_vecOrigin += pParticle->m_vecVelocity * (float)flFrameTime; pParticle->m_vecVelocity += m_pSystem->GetGravity() * (float)flFrameTime; pParticle->m_vecVelocity *= (1-((1-m_pSystem->GetDrag()) * (float)flFrameTime)); if (m_pSystem->GetRandomAngleVelocity()) pParticle->m_angAngles = (pParticle->m_angAngles + pParticle->m_angAngleVelocity*(float)GameServer()->GetFrameTime()); float flLifeTimeRamp = flLifeTime / m_pSystem->GetLifeTime(); float flFadeIn = 1; float flFadeOut = 1; if (flLifeTimeRamp < m_pSystem->GetFadeIn()) flFadeIn = RemapVal(flLifeTimeRamp, 0, m_pSystem->GetFadeIn(), 0, 1); if (flLifeTimeRamp > 1-m_pSystem->GetFadeOut()) flFadeOut = RemapVal(flLifeTimeRamp, 1-m_pSystem->GetFadeOut(), 1, 1, 0); pParticle->m_flAlpha = flFadeIn * flFadeOut * m_pSystem->GetAlpha(); pParticle->m_flRadius = RemapVal(flLifeTimeRamp, 0, 1, m_pSystem->GetStartRadius(), m_pSystem->GetEndRadius()); } if (!m_bStopped && m_pSystem->IsRenderable()) { while (flGameTime - m_flLastEmission > m_pSystem->GetEmissionRate()) { SpawnParticle(); if (m_pSystem->GetEmissionMax() && m_iTotalEmitted >= m_pSystem->GetEmissionMax()) break; m_flLastEmission += m_pSystem->GetEmissionRate(); } } for (size_t i = 0; i < m_apChildren.size(); i++) m_apChildren[i]->Simulate(); if (m_pSystem->GetEmissionMax() && m_iTotalEmitted >= m_pSystem->GetEmissionMax() || !m_pSystem->IsRenderable()) m_bStopped = true; if (!m_bStopped && m_aParticles.size()) { auto& oParticle = m_aParticles[0]; float& flRadius = oParticle.m_flRadius; Vector vecRadius = Vector(flRadius, flRadius, flRadius); m_aabbBounds.m_vecMins = oParticle.m_vecOrigin - vecRadius; m_aabbBounds.m_vecMaxs = oParticle.m_vecOrigin + vecRadius; for (size_t i = 1; i < m_aParticles.size(); i++) { auto& oParticle = m_aParticles[i]; if (!oParticle.m_bActive) continue; float& flRadius = oParticle.m_flRadius; Vector vecRadius = Vector(flRadius, flRadius, flRadius); m_aabbBounds.Expand(AABB(oParticle.m_vecOrigin - vecRadius, oParticle.m_vecOrigin + vecRadius)); } } }
void CHudRadar::DrawIconOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a ) { float x, y, z_delta; int wide, tall; // for 'ghosting' CRT effects: int xmod; int ymod; int xoffset; int yoffset; // Assume we're going to use the player's location and orientation QAngle viewAngle = pLocalPlayer->EyeAngles(); Vector viewOrigin = pLocalPlayer->GetAbsOrigin(); // However, happily use those of the vehicle if available! if( m_pVehicle != NULL ) { viewAngle = m_pVehicle->GetAbsAngles(); viewAngle.y += 90.0f; viewOrigin = m_pVehicle->WorldSpaceCenter(); } float flScale; WorldToRadar( vecPos, viewOrigin, viewAngle, x, y, z_delta, flScale ); flScale = RemapVal( flScale, 1.0f, 0.0f, RADAR_ICON_MIN_SCALE, RADAR_ICON_MAX_SCALE ); // Get the correct icon for this type of contact int iTextureID_Icon = -1; switch( type ) { case RADAR_CONTACT_GENERIC: iTextureID_Icon = m_textureID_IconLambda; break; case RADAR_CONTACT_MAGNUSSEN_RDU: iTextureID_Icon = m_textureID_IconBuster; break; case RADAR_CONTACT_LARGE_ENEMY: case RADAR_CONTACT_ENEMY: iTextureID_Icon = m_textureID_IconStrider; break; case RADAR_CONTACT_DOG: iTextureID_Icon = m_textureID_IconDog; break; case RADAR_CONTACT_ALLY_INSTALLATION: iTextureID_Icon = m_textureID_IconBase; break; default: return; break; } vgui::surface()->DrawSetColor( r, g, b, a ); vgui::surface()->DrawSetTexture( iTextureID_Icon ); vgui::surface()->DrawGetTextureSize( iTextureID_Icon, wide, tall ); wide = ( int((float)wide * flScale) ); tall = ( int((float)tall * flScale) ); if( type == RADAR_CONTACT_LARGE_ENEMY ) { wide *= 2; tall *= 2; } // Center the icon around its position. x -= (wide >> 1); y -= (tall >> 1); vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall); // Draw the crt 'ghost' if the icon is not pegged to the outer rim if( flScale > RADAR_ICON_MIN_SCALE && m_ghostAlpha > 0 ) { vgui::surface()->DrawSetColor( r, g, b, m_ghostAlpha ); xmod = RandomInt( 1, 4 ); ymod = RandomInt( 1, 4 ); xoffset = RandomInt( -1, 1 ); yoffset = RandomInt( -1, 1 ); x -= (xmod - xoffset); y -= (ymod - yoffset); wide += (xmod + xoffset); tall += (ymod + yoffset); vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - // *pMoveData - //----------------------------------------------------------------------------- void CPropCrane::RunCraneMovement( float flTime ) { if ( m_flExtensionRate ) { // Extend / Retract the crane m_flExtension = clamp( m_flExtension + (m_flExtensionRate * 10 * flTime), 0, 2 ); SetPoseParameter( "armextensionpose", m_flExtension ); StudioFrameAdvance(); } // Drop the magnet until it hits the ground if ( m_bDropping ) { // Drop until the magnet hits something if ( m_hCraneMagnet->HasHitSomething() ) { // We hit the ground, stop dropping m_hCraneTip->m_pSpring->SetSpringConstant( CRANE_SPRING_CONSTANT_INITIAL_RAISING ); m_bDropping = false; m_flNextDropAllowedTime = gpGlobals->curtime + 3.0; m_flSlowRaiseTime = gpGlobals->curtime; m_ServerVehicle.PlaySound( VS_MISC2 ); } } else if ( (m_flSlowRaiseTime + CRANE_SLOWRAISE_TIME) > gpGlobals->curtime ) { float flDelta = (gpGlobals->curtime - m_flSlowRaiseTime); flDelta = clamp( flDelta, 0, CRANE_SLOWRAISE_TIME ); float flCurrentSpringConstant = RemapVal( flDelta, 0, CRANE_SLOWRAISE_TIME, CRANE_SPRING_CONSTANT_INITIAL_RAISING, CRANE_SPRING_CONSTANT_HANGING ); m_hCraneTip->m_pSpring->SetSpringConstant( flCurrentSpringConstant ); } // If we've moved in any way, update the tip if ( m_bDropping || m_flExtensionRate || GetLocalAngularVelocity() != vec3_angle ) { RecalculateCraneTip(); } // Make danger sounds underneath the magnet if we have something attached to it /* if ( (m_flNextDangerSoundTime < gpGlobals->curtime) && (m_hCraneMagnet->GetTotalMassAttachedObjects() > 0) ) { // Trace down from the magnet and make a danger sound on the ground trace_t tr; Vector vecSource = m_hCraneMagnet->GetAbsOrigin(); UTIL_TraceLine( vecSource, vecSource - Vector(0,0,2048), MASK_SOLID_BRUSHONLY, m_hCraneMagnet, 0, &tr ); if ( tr.fraction < 1.0 ) { // Make the volume proportional to the amount of mass on the magnet float flVolume = clamp( (m_hCraneMagnet->GetTotalMassAttachedObjects() * 0.5), 100.f, 600.f ); CSoundEnt::InsertSound( SOUND_DANGER, tr.endpos, flVolume, 0.2, this ); //Msg("Total: %.2f Volume: %.2f\n", m_hCraneMagnet->GetTotalMassAttachedObjects(), flVolume ); //Vector vecVolume = Vector(flVolume,flVolume,flVolume) * 0.5; //NDebugOverlay::Box( tr.endpos, -vecVolume, vecVolume, 255,0,0, false, 0.3 ); //NDebugOverlay::Cross3D( tr.endpos, -Vector(10,10,10), Vector(10,10,10), 255,0,0, false, 0.3 ); } m_flNextDangerSoundTime = gpGlobals->curtime + 0.3; } */ // Play creak sounds on the magnet if there's heavy weight on it if ( (m_flNextCreakSound < gpGlobals->curtime) && (m_hCraneMagnet->GetTotalMassAttachedObjects() > 100) ) { // Randomly play creaks from the magnet, and increase the chance based on the turning speed float flSpeedPercentage = clamp( fabs(m_flTurn) / m_flMaxTurnSpeed, 0, 1 ); if ( RandomFloat(0,1) > (0.95 - (0.1 * flSpeedPercentage)) ) { if ( m_ServerVehicle.m_vehicleSounds.iszSound[VS_MISC4] != NULL_STRING ) { CPASAttenuationFilter filter( m_hCraneMagnet ); EmitSound_t ep; ep.m_nChannel = CHAN_VOICE; ep.m_pSoundName = STRING(m_ServerVehicle.m_vehicleSounds.iszSound[VS_MISC4]); ep.m_flVolume = 1.0f; ep.m_SoundLevel = SNDLVL_NORM; CBaseEntity::EmitSound( filter, m_hCraneMagnet->entindex(), ep ); } m_flNextCreakSound = gpGlobals->curtime + 5.0; } } }
float RemapGainedValClamped( float flInput, float flGain, float flInLo, float flInHi, float flOutLo, float flOutHi) { float flNormalized = RemapValClamped(flInput, flInLo, flInHi, 0, 1); float flLerped = Gain(flNormalized, flGain); return RemapVal(flLerped, 0, 1, flOutLo, flOutHi); }
//----------------------------------------------- // Response curve function for the move axes //----------------------------------------------- static float ResponseCurve( int curve, float x, int axis, float sensitivity ) { switch ( curve ) { case 1: // quadratic if ( x < 0 ) return -(x*x) * sensitivity; return x*x * sensitivity; case 2: // cubic return x*x*x*sensitivity; case 3: { // quadratic extreme float extreme = 1.0f; if ( fabs( x ) >= 0.95f ) { extreme = 1.5f; } if ( x < 0 ) return -extreme * x*x*sensitivity; return extreme * x*x*sensitivity; } case 4: { float flScale = sensitivity < 0.0f ? -1.0f : 1.0f; sensitivity = clamp( fabs( sensitivity ), 1.0e-8f, 1000.0f ); float oneOverSens = 1.0f / sensitivity; if ( x < 0.0f ) { flScale = -flScale; } float retval = clamp( powf( fabs( x ), oneOverSens ), 0.0f, 1.0f ); return retval * flScale; } break; case 5: { float out = x; if( fabs(out) <= 0.6f ) { out *= 0.5f; } out = out * sensitivity; return out; } break; case 6: // Custom for driving a vehicle! { if( axis == YAW ) { // This code only wants to affect YAW axis (the left and right axis), which // is used for turning in the car. We fall-through and use a linear curve on // the PITCH axis, which is the vehicle's throttle. REALLY, these are the 'forward' // and 'side' axes, but we don't have constants for those, so we re-use the same // axis convention as the look stick. (sjb) float sign = 1; if( x < 0.0 ) sign = -1; x = fabs(x); if( x <= joy_vehicle_turn_lowend.GetFloat() ) x = RemapVal( x, 0.0f, joy_vehicle_turn_lowend.GetFloat(), 0.0f, joy_vehicle_turn_lowmap.GetFloat() ); else x = RemapVal( x, joy_vehicle_turn_lowend.GetFloat(), 1.0f, joy_vehicle_turn_lowmap.GetFloat(), 1.0f ); return x * sensitivity * sign; } //else // fall through and just return x*sensitivity below (as if using default curve) } } // linear return x*sensitivity; }
int C_CFPlayer::DrawModel( int flags ) { // if local player is spectating this player in first person mode, don't draw it C_CFPlayer * pPlayer = GetLocalCFPlayer(); if (m_bIsDecapitated) SetBodygroup(1, 1); else if ((!input->CAM_IsThirdPerson() && pPlayer == this) || pPlayer->IsFirstPersonSpectating(this)) SetBodygroup(1, 1); else SetBodygroup(1, 0); if (IsFuse()) { if ((!input->CAM_IsThirdPerson() && pPlayer == this) || pPlayer->IsFirstPersonSpectating(this)) SetBodygroup(2, 0); else SetBodygroup(2, 1); } // Skip C_BasePlayer::DrawModel() because it has a bunch of logic we don't care for. int iResult = C_BaseCombatCharacter::DrawModel( flags ); if (C_CFPlayer::GetLocalCFPlayer() == this || pPlayer->IsObserver() && pPlayer->GetObserverTarget() && ToCFPlayer(pPlayer->GetObserverTarget()) == this) DrawTargets(); // Put submodels back where they are supposed to be so that shadows and such render them properly. SetBodygroup(1, m_bIsDecapitated); if (IsFuse()) SetBodygroup(2, 1); if (gpGlobals->curtime - m_flShieldTime < 0.5f) { Vector vecDmgDirection = m_vecShieldDmgOrigin - GetCentroid(); QAngle angShield; VectorAngles(vecDmgDirection, angShield); m_pBarrier->SetAbsAngles(angShield); m_pBarrier->SetAbsOrigin(GetAbsOrigin()); float flAlpha = 0; if ((gpGlobals->curtime - m_flShieldTime) < 0.2f) flAlpha = RemapVal(gpGlobals->curtime - m_flShieldTime, 0.0f, 0.2f, 0, 255); else flAlpha = RemapVal(gpGlobals->curtime - m_flShieldTime, 0.2f, 0.5f, 255, 0); flAlpha *= m_flShieldStrength; if (C_CFPlayer::GetLocalCFPlayer() == this) flAlpha /= 2; if (flAlpha) { m_pBarrier->SetBodygroup(0, m_bShieldPhysical); m_pBarrier->SetRenderColorA(flAlpha); m_pBarrier->DrawModel(flags); } } return iResult; }
//----------------------------------------------- // Response curve function for the move axes //----------------------------------------------- static float ResponseCurve( int curve, float x, int axis, float sensitivity ) { switch ( curve ) { case 1: // quadratic if ( x < 0 ) return -(x*x) * sensitivity; return x*x * sensitivity; case 2: // cubic return x*x*x*sensitivity; case 3: { // quadratic extreme float extreme = 1.0f; if ( fabs( x ) >= 0.95f ) { extreme = 1.5f; } if ( x < 0 ) return -extreme * x*x*sensitivity; return extreme * x*x*sensitivity; } case 4: { float flScale = sensitivity < 0.0f ? -1.0f : 1.0f; sensitivity = clamp( fabs( sensitivity ), 1.0e-8f, 1000.0f ); float oneOverSens = 1.0f / sensitivity; if ( x < 0.0f ) { flScale = -flScale; } float retval = clamp( powf( fabs( x ), oneOverSens ), 0.0f, 1.0f ); return retval * flScale; } break; case 5: { float out = x; if( fabs(out) <= 0.6f ) { out *= 0.5f; } out = out * sensitivity; return out; } break; case 6: // Custom for driving a vehicle! { if( axis == YAW ) { // This code only wants to affect YAW axis (the left and right axis), which // is used for turning in the car. We fall-through and use a linear curve on // the PITCH axis, which is the vehicle's throttle. REALLY, these are the 'forward' // and 'side' axes, but we don't have constants for those, so we re-use the same // axis convention as the look stick. (sjb) float sign = 1; if( x < 0.0 ) sign = -1; x = fabs(x); if( x <= joy_vehicle_turn_lowend.GetFloat() ) x = RemapVal( x, 0.0f, joy_vehicle_turn_lowend.GetFloat(), 0.0f, joy_vehicle_turn_lowmap.GetFloat() ); else x = RemapVal( x, joy_vehicle_turn_lowend.GetFloat(), 1.0f, joy_vehicle_turn_lowmap.GetFloat(), 1.0f ); return x * sensitivity * sign; } //else // fall through and just return x*sensitivity below (as if using default curve) } //The idea is to create a max large walk zone surrounded by a max run zone. case 7: { float xAbs = fabs(x); if(xAbs < joy_sensitive_step0.GetFloat()) { return 0; } else if (xAbs < joy_sensitive_step2.GetFloat()) { return (85.0f/cl_forwardspeed.GetFloat()) * ((x < 0)? -1.0f : 1.0f); } else { return ((x < 0)? -1.0f : 1.0f); } } break; case 8: //same concept as above but with smooth speeds { float xAbs = fabs(x); if(xAbs < joy_sensitive_step0.GetFloat()) { return 0; } else if (xAbs < joy_sensitive_step2.GetFloat()) { float maxSpeed = (85.0f/cl_forwardspeed.GetFloat()); float t = (xAbs-joy_sensitive_step0.GetFloat()) / (joy_sensitive_step2.GetFloat()-joy_sensitive_step0.GetFloat()); float speed = t*maxSpeed; return speed * ((x < 0)? -1.0f : 1.0f); } else { float maxSpeed = 1.0f; float minSpeed = (85.0f/cl_forwardspeed.GetFloat()); float t = (xAbs-joy_sensitive_step2.GetFloat()) / (1.0f-joy_sensitive_step2.GetFloat()); float speed = t*(maxSpeed-minSpeed) + minSpeed; return speed * ((x < 0)? -1.0f : 1.0f); } } break; case 9: //same concept as above but with smooth speeds for walking and a hard speed for running { float xAbs = fabs(x); if(xAbs < joy_sensitive_step0.GetFloat()) { return 0; } else if (xAbs < joy_sensitive_step1.GetFloat()) { float maxSpeed = (85.0f/cl_forwardspeed.GetFloat()); float t = (xAbs-joy_sensitive_step0.GetFloat()) / (joy_sensitive_step1.GetFloat()-joy_sensitive_step0.GetFloat()); float speed = t*maxSpeed; return speed * ((x < 0)? -1.0f : 1.0f); } else if (xAbs < joy_sensitive_step2.GetFloat()) { return (85.0f/cl_forwardspeed.GetFloat()) * ((x < 0)? -1.0f : 1.0f); } else { return ((x < 0)? -1.0f : 1.0f); } } break; } // linear return x*sensitivity; }
void CAOGenerator::GenerateShadowMaps() { double flProcessSceneRead = 0; double flProgress = 0; size_t iShadowMapSize = 1024; // A frame buffer for holding the depth buffer shadow render CFrameBuffer oDepthFB = SMAKRenderer()->CreateFrameBuffer(iShadowMapSize, iShadowMapSize, (fb_options_e)(FB_DEPTH_TEXTURE|FB_RENDERBUFFER)); // RB unused // A frame buffer for holding the UV layout once it is rendered flat with the shadow CFrameBuffer oUVFB = SMAKRenderer()->CreateFrameBuffer(m_iWidth, m_iHeight, (fb_options_e)(FB_TEXTURE|FB_LINEAR|FB_DEPTH)); // Depth unused // A frame buffer for holding the completed AO map m_oAOFB = SMAKRenderer()->CreateFrameBuffer(m_iWidth, m_iHeight, (fb_options_e)(FB_TEXTURE|FB_TEXTURE_HALF_FLOAT|FB_LINEAR|FB_DEPTH)); // Depth unused CRenderingContext c(SMAKRenderer()); c.UseFrameBuffer(&m_oAOFB); c.ClearColor(Color(0, 0, 0, 0)); c.SetDepthFunction(DF_LEQUAL); c.SetDepthTest(true); c.SetBackCulling(false); Matrix4x4 mBias( 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f); // Bias from [-1, 1] to [0, 1] AABB oBox = m_pScene->m_oExtends; Vector vecCenter = oBox.Center(); float flSize = oBox.Size().Length(); // Length of the box's diagonal Matrix4x4 mLightProjection = Matrix4x4::ProjectOrthographic(-flSize/2, flSize/2, -flSize/2, flSize/2, 1, flSize*2); size_t iSamples = (size_t)sqrt((float)m_iSamples); m_pWorkListener->SetAction("Taking exposures", m_iSamples); for (size_t x = 0; x <= iSamples; x++) { float flPitch = -asin(RemapVal((float)x, 0, (float)iSamples, -1, 1)) * 90 / (M_PI/2); for (size_t y = 0; y < iSamples; y++) { if (x == 0 || x == iSamples) { // Don't do a bunch of samples from the same spot on the poles. if (y != 0) continue; } float flYaw = RemapVal((float)y, 0, (float)iSamples, -180, 180); // Randomize the direction a tad to help fight moire Vector vecDir = AngleVector(EAngle(flPitch+RandomFloat(-1, 1)/2, flYaw+RandomFloat(-1, 1)/2, 0)); Vector vecLightPosition = vecDir*flSize + vecCenter; // Puts us twice as far from the closest vertex if (ao_debug.GetInt() > 1) SMAKWindow()->AddDebugLine(vecLightPosition, vecLightPosition-vecDir); Matrix4x4 mLightView = Matrix4x4::ConstructCameraView(vecLightPosition, (vecCenter-vecLightPosition).Normalized(), Vector(0, 1, 0)); c.SetProjection(mLightProjection); c.SetView(mLightView); // If we're looking from below and ground occlusion is on, don't bother with this render. if (!(flPitch < -10 && m_bGroundOcclusion)) { c.UseProgram("model"); c.UseFrameBuffer(&oDepthFB); c.SetViewport(Rect(0, 0, iShadowMapSize, iShadowMapSize)); c.SetBackCulling(false); c.ClearDepth(); c.BeginRenderVertexArray(m_iSceneDepth); c.SetPositionBuffer((size_t)0, 8*sizeof(float)); c.SetNormalsBuffer((size_t)3*sizeof(float), 8*sizeof(float)); c.SetTexCoordBuffer((size_t)6*sizeof(float), 8*sizeof(float)); c.EndRenderVertexArray(m_iSceneDepthVerts); c.UseFrameBuffer(nullptr); if (ao_debug.GetBool()) { CRenderingContext c(SMAKRenderer()); c.SetViewport(Rect(0, 0, iShadowMapSize/2, iShadowMapSize/2)); DrawTexture(oDepthFB.m_iDepthTexture, 1, c); } } Matrix4x4 mTextureMatrix = mBias*mLightProjection*mLightView; { CRenderingContext c(SMAKRenderer(), true); c.UseFrameBuffer(&oUVFB); c.SetViewport(Rect(0, 0, m_iWidth, m_iHeight)); c.ClearColor(Color(0, 0, 0, 0)); c.ClearDepth(); c.UseProgram("flat_shadow"); c.SetUniform("mBiasedLightMatrix", mTextureMatrix); c.SetUniform("iShadowMap", 0); c.SetUniform("vecLightNormal", -vecDir); c.SetUniform("bOccludeAll", (flPitch < -10 && m_bGroundOcclusion)); c.SetUniform("flTime", (float)Application()->GetTime()); c.BindTexture(oDepthFB.m_iDepthTexture); c.BeginRenderVertexArray(m_iScene); c.SetPositionBuffer((size_t)0, 8*sizeof(float)); c.SetNormalsBuffer((size_t)3*sizeof(float), 8*sizeof(float)); c.SetTexCoordBuffer((size_t)6*sizeof(float), 8*sizeof(float)); c.EndRenderVertexArray(m_iSceneVerts); } if (ao_debug.GetBool()) { CRenderingContext c(SMAKRenderer()); c.SetViewport(Rect(iShadowMapSize/2, 0, m_iWidth, m_iHeight)); DrawTexture(oUVFB.m_iMap, 1, c); } double flTimeBefore = SMAKWindow()->GetTime(); c.SetViewport(Rect(0, 0, m_iWidth, m_iHeight)); c.UseFrameBuffer(&m_oAOFB); AccumulateTexture(oUVFB.m_iMap); c.UseFrameBuffer(nullptr); if (ao_debug.GetBool()) { CRenderingContext c(SMAKRenderer()); c.UseProgram("ao"); c.SetViewport(Rect(iShadowMapSize/2+m_iWidth, 0, m_iWidth, m_iHeight)); c.SetUniform("iAOMap", 0); c.SetBlend(BLEND_ALPHA); DrawTexture(m_oAOFB.m_iMap, 1, c); } flProcessSceneRead += (SMAKWindow()->GetTime() - flTimeBefore); flTimeBefore = SMAKWindow()->GetTime(); m_pWorkListener->WorkProgress(x*iSamples + y); flProgress += (SMAKWindow()->GetTime() - flTimeBefore); if (m_bStopGenerating) break; } if (m_bStopGenerating) break; } c.UseFrameBuffer(&m_oAOFB); c.ReadPixels(0, 0, m_iWidth, m_iHeight, m_pvecPixels); c.UseFrameBuffer(nullptr); if (!m_bStopGenerating) { size_t iBufferSize = m_iWidth*m_iHeight; m_pWorkListener->SetAction("Reading pixels", iBufferSize); for (size_t p = 0; p < iBufferSize; p++) { Vector4D& vecPixel = m_pvecPixels[p]; if (vecPixel.w == 0.0f) continue; m_avecShadowValues[p].x = vecPixel.x; m_aiShadowReads[p] = (size_t)vecPixel.w; m_bPixelMask[p] = true; m_pWorkListener->WorkProgress(p); } } oDepthFB.Destroy(); oUVFB.Destroy(); // Don't destroy m_oAOFB yet, we need it in a bit. It gets destroyed later. }
void CNormalGenerator::NormalizeHeightValue(size_t x, size_t y) { if (!m_avecTextureTexels.size()) return; float flHiScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/200.0f * m_flNormalTextureDepth; float flMidScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/100.0f * m_flNormalTextureDepth; float flLowScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/50.0f * m_flNormalTextureDepth; size_t iTexel; Texel(x, y, iTexel, m_iNormal2Width, m_iNormal2Height, false); tvector<Vector> avecHeights; float flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; float flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; float flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecCenter((float)x, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); Vector vecNormal(0,0,0); if (Texel(x+1, y, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor(x+1.0f, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(0, 1, 0)); } if (Texel(x-1, y, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor(x-1.0f, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(0, -1, 0)); } if (Texel(x, y+1, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor((float)x, y+1.0f, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(-1, 0, 0)); } if (Texel(x, y-1, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor((float)x, y-1.0f, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(1, 0, 0)); } vecNormal.Normalize(); for (size_t i = 0; i < 3; i++) vecNormal[i] = RemapVal(vecNormal[i], -1.0f, 1.0f, 0.0f, 0.99f); // Don't use 1.0 because of integer overflow. // Don't need to lock the data because we're guaranteed never to access the same texel twice due to the generation method. m_avecNormal2Texels[iTexel] = vecNormal; }
void CFXDiscreetLine::Draw( double frametime ) { Vector lineDir, viewDir, cross; Vector vecEnd, vecStart; Vector tmp; // Update the effect Update( frametime ); // Calculate our distance along our path float sDistance = m_fVelocity * m_fStartTime; float eDistance = sDistance - m_fLength; //Clip to start sDistance = MAX( 0.0f, sDistance ); eDistance = MAX( 0.0f, eDistance ); if ( ( sDistance == 0.0f ) && ( eDistance == 0.0f ) ) return; // Clip it if ( m_fClipLength != 0.0f ) { sDistance = MIN( sDistance, m_fClipLength ); eDistance = MIN( eDistance, m_fClipLength ); } // Get our delta to calculate the tc offset float dDistance = fabs( sDistance - eDistance ); float dTotal = ( m_fLength != 0.0f ) ? m_fLength : 0.01f; float fOffset = ( dDistance / dTotal ); // Find our points along our path VectorMA( m_vecOrigin, sDistance, m_vecDirection, vecEnd ); VectorMA( m_vecOrigin, eDistance, m_vecDirection, vecStart ); //Setup our info for drawing the line VectorSubtract( vecEnd, vecStart, lineDir ); VectorSubtract( vecEnd, CurrentViewOrigin(), viewDir ); cross = lineDir.Cross( viewDir ); VectorNormalize( cross ); CMeshBuilder meshBuilder; IMesh *pMesh; CMatRenderContextPtr pRenderContext( materials ); // Better, more visible tracers if ( tracer_extra.GetBool() ) { float flScreenWidth = ScreenWidth(); float flHalfScreenWidth = flScreenWidth * 0.5f; float zCoord = CurrentViewForward().Dot( vecStart - CurrentViewOrigin() ); float flScreenSpaceWidth = m_fScale * flHalfScreenWidth / zCoord; float flAlpha; float flScale; if ( flScreenSpaceWidth < 0.5f ) { flAlpha = RemapVal( flScreenSpaceWidth, 0.25f, 2.0f, 0.3f, 1.0f ); flAlpha = clamp( flAlpha, 0.25f, 1.0f ); flScale = 0.5f * zCoord / flHalfScreenWidth; } else { flAlpha = 1.0f; flScale = m_fScale; } //Bind the material pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial ); meshBuilder.Begin( pMesh, MATERIAL_QUADS, 2 ); float color = (int) 255.0f * flAlpha; //FIXME: for now no coloration VectorMA( vecStart, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecStart, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); flScale = flScale * 2.0f; color = (int) 64.0f * flAlpha; // Soft outline VectorMA( vecStart, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecStart, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); } else { //Bind the material pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial ); meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); //FIXME: for now no coloration VectorMA( vecStart, -m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecStart, m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); VectorMA( vecEnd, -m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); } meshBuilder.End(); pMesh->Draw(); }
void CGeneralWindow::Paint(float x, float y, float w, float h) { if (m_flFadeToBlack) { float flAlpha = (float)RemapVal(GameServer()->GetGameTime(), m_flFadeToBlack, m_flFadeToBlack+1.5f, 0.0, 1.0); glgui::CRootPanel::PaintRect(0, 0, glgui::CRootPanel::Get()->GetWidth(), glgui::CRootPanel::Get()->GetHeight(), Color(0, 0, 0, (int)(255*flAlpha))); return; } Rect recAntivirus = m_hAntivirus.GetArea("Antivirus"); glgui::CBaseControl::PaintSheet(m_hAntivirus.GetSheet("Antivirus"), x, y, w, h, recAntivirus.x, recAntivirus.y, recAntivirus.w, recAntivirus.h, m_hAntivirus.GetSheetWidth("Antivirus"), m_hAntivirus.GetSheetHeight("Antivirus")); BaseClass::Paint(x, y, w, h); if (!m_sEmotion.length()) return; CGameRenderingContext c(GameServer()->GetRenderer(), true); c.SetBlend(BLEND_ALPHA); c.SetColor(Color(255, 255, 255, 255)); Rect recEmotion = m_hGeneral.GetArea(m_sEmotion); glgui::CBaseControl::PaintSheet(m_hGeneral.GetSheet(m_sEmotion), x, y, 256, 256, recEmotion.x, recEmotion.y, recEmotion.w, recEmotion.h, m_hGeneral.GetSheetWidth(m_sEmotion), m_hGeneral.GetSheetHeight(m_sEmotion)); if ((m_bHelperSpeaking || m_bProgressBar) && Oscillate((float)GameServer()->GetGameTime(), 0.2f) > 0.5) { Rect recMouth = m_hGeneralMouth.GetArea(m_sEmotion); glgui::CBaseControl::PaintSheet(m_hGeneralMouth.GetSheet(m_sEmotion), x, y, 256, 256, recMouth.x, recMouth.y, recMouth.w, recMouth.h, m_hGeneralMouth.GetSheetWidth(m_sEmotion), m_hGeneralMouth.GetSheetHeight(m_sEmotion)); } if (m_bProgressBar) { double flTime = 3; glgui::CBaseControl::PaintRect(x + m_pText->GetLeft(), y + 160, m_pText->GetWidth(), 10, Color(255, 255, 255, 255)); glgui::CBaseControl::PaintRect(x + m_pText->GetLeft() + 2, y + 160 + 2, ((m_pText->GetWidth() - 4) * (float)RemapValClamped(GameServer()->GetGameTime(), m_flStartTime, m_flStartTime+flTime, 0.0, 1.0)), 10 - 4, Color(42, 65, 122, 255)); static tstring sEstimate; static double flLastEstimateUpdate = 0; if (!sEstimate.length() || GameServer()->GetGameTime() - flLastEstimateUpdate > 1) { int iRandomTime = RandomInt(0, 5); tstring sRandomTime; if (iRandomTime == 0) sRandomTime = "centuries"; else if (iRandomTime == 1) sRandomTime = "minutes"; else if (iRandomTime == 2) sRandomTime = "hours"; else if (iRandomTime == 3) sRandomTime = "days"; else sRandomTime = "seconds"; sEstimate = tsprintf(tstring("Estimated time remaining: %d %s"), RandomInt(2, 100), sRandomTime.c_str()); flLastEstimateUpdate = GameServer()->GetGameTime(); } float flWidth = glgui::RootPanel()->GetTextWidth(sEstimate, sEstimate.length(), "sans-serif", 12); glgui::CLabel::PaintText(sEstimate, sEstimate.length(), "sans-serif", 12, x + m_pText->GetLeft() + m_pText->GetWidth()/2 - flWidth/2, (float)y + 190, Color(0, 0, 0, 255)); } }
//----------------------------------------------------------------------------- // Methods related to actually driving the vehicle //----------------------------------------------------------------------------- void CFourWheelVehiclePhysics::UpdateDriverControls( CUserCmd *cmd, float flFrameTime ) { int nButtons = cmd->buttons; // Get vehicle data. const vehicle_operatingparams_t &carState = m_pVehicle->GetOperatingParams(); const vehicleparams_t &vehicleData = m_pVehicle->GetVehicleParams(); // Get current speed in miles/hour. float flCarSign = carState.speed >= 0.0f ? 1.0f : -1.0f; float carSpeed = fabs(INS2MPH(carState.speed)); #ifdef _XBOX float in = cmd->sidemove; float out; if( cmd->forwardmove >= 0.0f ) { bool negative = (in < 0); in = fabs(in); if( in <= 150 ) { out = RemapVal( in, 0, 150, 0, 100 ); } else { out = RemapVal( in, 150, 400, 100, 400 ); } if( negative ) { out = -out; } cmd->sidemove = out; } // If going forward and turning hard, keep the throttle applied. if( xbox_autothrottle.GetBool() && cmd->forwardmove > 0.0f ) { if( carSpeed > GetMaxSpeed() * 0.75 ) { if( fabs(cmd->sidemove) > cmd->forwardmove ) { cmd->forwardmove = STICK_EXTENTS; } } } #endif//XBOX #if 0 // Set save data. m_nLastSpeed = m_nSpeed; m_nSpeed = (int)carSpeed; m_nRPM = (int)carState.engineRPM; m_nHasBoost = vehicleData.engine.boostDelay; // if we have any boost delay, vehicle has boost ability #endif // If changing direction, use default "return to zero" speed to more quickly transition. if ( ( nButtons & IN_MOVELEFT ) || ( nButtons & IN_MOVERIGHT ) ) { SteeringTurn( carSpeed, vehicleData, ( ( nButtons & IN_MOVELEFT ) != 0 ) ); } else if ( cmd->sidemove != 0.0f ) { SteeringTurnAnalog( carSpeed, vehicleData, cmd->sidemove ); } else { SteeringRest( carSpeed, vehicleData ); } // Set vehicle control inputs. m_controls.boost = 0; m_controls.handbrake = false; m_controls.handbrakeLeft = false; m_controls.handbrakeRight = false; m_controls.brakepedal = false; bool bThrottle; //------------------------------------------------------------------------- // Analog throttle biasing - This code gives the player a bit of control stick // 'slop' in the opposite direction that they are driving. If a player is // driving forward and makes a hard turn in which the stick actually goes // below neutral (toward reverse), this code continues to propel the car // forward unless the player makes a significant motion towards reverse. // (The inverse is true when driving in reverse and the stick is moved slightly forward) //------------------------------------------------------------------------- CBaseEntity *pDriver = m_pOuterServerVehicle->GetDriver(); CBasePlayer *pPlayerDriver; float flBiasThreshold = xbox_throttlebias.GetFloat(); if( pDriver && pDriver->IsPlayer() ) { pPlayerDriver = dynamic_cast<CBasePlayer*>(pDriver); if( cmd->forwardmove == 0.0f && (fabs(cmd->sidemove) < 200.0f) ) { // If the stick goes neutral, clear out the bias. When the bias is neutral, it will begin biasing // in whichever direction the user next presses the analog stick. pPlayerDriver->SetVehicleAnalogControlBias( VEHICLE_ANALOG_BIAS_NONE ); } else if( cmd->forwardmove > 0.0f) { if( pPlayerDriver->GetVehicleAnalogControlBias() == VEHICLE_ANALOG_BIAS_REVERSE ) { // Player is pushing forward, but the controller is currently biased for reverse driving. // Must pass a threshold to be accepted as forward input. Otherwise we just spoof a reduced reverse input // to keep the car moving in the direction the player probably expects. if( cmd->forwardmove < flBiasThreshold ) { cmd->forwardmove = -xbox_throttlespoof.GetFloat(); } else { // Passed the threshold. Allow the direction change to occur. pPlayerDriver->SetVehicleAnalogControlBias( VEHICLE_ANALOG_BIAS_FORWARD ); } } else if( pPlayerDriver->GetVehicleAnalogControlBias() == VEHICLE_ANALOG_BIAS_NONE ) { pPlayerDriver->SetVehicleAnalogControlBias( VEHICLE_ANALOG_BIAS_FORWARD ); } } else if( cmd->forwardmove < 0.0f ) { if( pPlayerDriver->GetVehicleAnalogControlBias() == VEHICLE_ANALOG_BIAS_FORWARD ) { // Inverse of above logic if( cmd->forwardmove > -flBiasThreshold ) { cmd->forwardmove = xbox_throttlespoof.GetFloat(); } else { pPlayerDriver->SetVehicleAnalogControlBias( VEHICLE_ANALOG_BIAS_REVERSE ); } } else if( pPlayerDriver->GetVehicleAnalogControlBias() == VEHICLE_ANALOG_BIAS_NONE ) { pPlayerDriver->SetVehicleAnalogControlBias( VEHICLE_ANALOG_BIAS_REVERSE ); } } } #ifdef _XBOX //========================= //========================= if( cmd->forwardmove > 0.0f ) { float flAnalogThrottle = cmd->forwardmove / STICK_EXTENTS; flAnalogThrottle = clamp( flAnalogThrottle, 0.25f, 1.0f ); bThrottle = true; if ( m_controls.throttle < 0 ) { m_controls.throttle = 0; } float flMaxThrottle = MAX( 0.1, m_maxThrottle - ( m_maxThrottle * m_flThrottleReduction ) ); m_controls.throttle = Approach( flMaxThrottle * flAnalogThrottle, m_controls.throttle, flFrameTime * m_throttleRate ); // Apply the brake. if ( ( flCarSign < 0.0f ) && m_controls.bHasBrakePedal ) { m_controls.brake = Approach( BRAKE_MAX_VALUE, m_controls.brake, flFrameTime * r_vehicleBrakeRate.GetFloat() * BRAKE_BACK_FORWARD_SCALAR ); m_controls.brakepedal = true; m_controls.throttle = 0.0f; bThrottle = false; } else { m_controls.brake = 0.0f; } } else if( cmd->forwardmove < 0.0f ) { float flAnalogBrake = fabs(cmd->forwardmove / STICK_EXTENTS); flAnalogBrake = clamp( flAnalogBrake, 0.25f, 1.0f ); bThrottle = true; if ( m_controls.throttle > 0 ) { m_controls.throttle = 0; } float flMaxThrottle = MIN( -0.1, m_flMaxRevThrottle - ( m_flMaxRevThrottle * m_flThrottleReduction ) ); m_controls.throttle = Approach( flMaxThrottle * flAnalogBrake, m_controls.throttle, flFrameTime * m_throttleRate ); // Apply the brake. if ( ( flCarSign > 0.0f ) && m_controls.bHasBrakePedal ) { m_controls.brake = Approach( BRAKE_MAX_VALUE, m_controls.brake, flFrameTime * r_vehicleBrakeRate.GetFloat() ); m_controls.brakepedal = true; m_controls.throttle = 0.0f; bThrottle = false; } else { m_controls.brake = 0.0f; } } else { bThrottle = false; m_controls.throttle = 0; m_controls.brake = 0.0f; } //========================= //========================= #else if ( nButtons & IN_FORWARD ) { bThrottle = true; if ( m_controls.throttle < 0 ) { m_controls.throttle = 0; } float flMaxThrottle = MAX( 0.1, m_maxThrottle - ( m_maxThrottle * m_flThrottleReduction ) ); m_controls.throttle = Approach( flMaxThrottle, m_controls.throttle, flFrameTime * m_throttleRate ); // Apply the brake. if ( ( flCarSign < 0.0f ) && m_controls.bHasBrakePedal ) { m_controls.brake = Approach( BRAKE_MAX_VALUE, m_controls.brake, flFrameTime * r_vehicleBrakeRate.GetFloat() * BRAKE_BACK_FORWARD_SCALAR ); m_controls.brakepedal = true; m_controls.throttle = 0.0f; bThrottle = false; } else { m_controls.brake = 0.0f; } } else if ( nButtons & IN_BACK ) { bThrottle = true; if ( m_controls.throttle > 0 ) { m_controls.throttle = 0; } float flMaxThrottle = MIN( -0.1, m_flMaxRevThrottle - ( m_flMaxRevThrottle * m_flThrottleReduction ) ); m_controls.throttle = Approach( flMaxThrottle, m_controls.throttle, flFrameTime * m_throttleRate ); // Apply the brake. if ( ( flCarSign > 0.0f ) && m_controls.bHasBrakePedal ) { m_controls.brake = Approach( BRAKE_MAX_VALUE, m_controls.brake, flFrameTime * r_vehicleBrakeRate.GetFloat() ); m_controls.brakepedal = true; m_controls.throttle = 0.0f; bThrottle = false; } else { m_controls.brake = 0.0f; } } else { bThrottle = false; m_controls.throttle = 0; m_controls.brake = 0.0f; } #endif//_XBOX if ( ( nButtons & IN_SPEED ) && !IsEngineDisabled() ) { m_controls.boost = 1.0f; } // Using has brakepedal for handbrake as well. if ( ( nButtons & IN_JUMP ) && m_controls.bHasBrakePedal ) { m_controls.handbrake = true; if ( nButtons & IN_MOVELEFT ) { m_controls.handbrakeLeft = true; } else if ( nButtons & IN_MOVERIGHT ) { m_controls.handbrakeRight = true; } // Prevent playing of the engine revup when we're braking bThrottle = false; } if ( IsEngineDisabled() ) { m_controls.throttle = 0.0f; m_controls.handbrake = true; bThrottle = false; } // throttle sounds // If we dropped a bunch of speed, restart the throttle if ( bThrottle && (m_nLastSpeed > m_nSpeed && (m_nLastSpeed - m_nSpeed > 10)) ) { m_bLastThrottle = false; } // throttle down now but not before??? (or we're braking) if ( !m_controls.handbrake && !m_controls.brakepedal && bThrottle && !m_bLastThrottle ) { m_throttleStartTime = gpGlobals->curtime; // need to track how long throttle is down m_bLastThrottle = true; } // throttle up now but not before?? else if ( !bThrottle && m_bLastThrottle && IsEngineDisabled() == false ) { m_throttleActiveTime = gpGlobals->curtime - m_throttleStartTime; m_bLastThrottle = false; } float flSpeedPercentage = clamp( m_nSpeed / m_flMaxSpeed, 0, 1 ); vbs_sound_update_t params; params.Defaults(); params.bReverse = (m_controls.throttle < 0); params.bThrottleDown = bThrottle; params.bTurbo = IsBoosting(); params.bVehicleInWater = m_pOuterServerVehicle->IsVehicleBodyInWater(); params.flCurrentSpeedFraction = flSpeedPercentage; params.flFrameTime = flFrameTime; params.flWorldSpaceSpeed = carState.speed; m_pOuterServerVehicle->SoundUpdate( params ); }
void CSupplier::UpdateTendrils() { if (IsConstructing()) return; TStubbed("Tendrils"); #if 0 if (!GetPlayerOwner()) { if (m_iTendrilsCallList) glDeleteLists((GLuint)m_iTendrilsCallList, 1); m_iTendrilsCallList = 0; DigitanksGame()->GetTerrain()->DirtyChunkTexturesWithinDistance(GetGlobalOrigin(), GetDataFlowRadius() + GetBoundingRadius()); return; } if (GameServer()->IsLoading()) return; bool bUpdateTerrain = false; size_t iRadius = (size_t)GetDataFlowRadius(); while (m_aTendrils.size() < iRadius) { m_aTendrils.push_back(CTendril()); CTendril* pTendril = &m_aTendrils[m_aTendrils.size()-1]; pTendril->m_flLength = (float)m_aTendrils.size() + GetBoundingRadius(); pTendril->m_vecEndPoint = DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin() + AngleVector(EAngle(0, RandomFloat(0, 360), 0)) * pTendril->m_flLength); pTendril->m_flScale = RandomFloat(3, 7); pTendril->m_flOffset = RandomFloat(0, 1); pTendril->m_flSpeed = RandomFloat(0.5f, 2); bUpdateTerrain = true; } if (bUpdateTerrain) DigitanksGame()->GetTerrain()->DirtyChunkTexturesWithinDistance(GetGlobalOrigin(), GetDataFlowRadius() + GetBoundingRadius()); if (m_iTendrilsCallList) glDeleteLists((GLuint)m_iTendrilsCallList, 1); m_iTendrilsCallList = glGenLists(1); Color clrTeam = GetPlayerOwner()->GetColor(); clrTeam = (Vector(clrTeam) + Vector(1,1,1))/2; glNewList((GLuint)m_iTendrilsCallList, GL_COMPILE); for (size_t i = 0; i < m_aTendrils.size(); i++) { // Only show the longest tendrils, for perf reasons. if (i < iRadius - 15) continue; CTendril* pTendril = &m_aTendrils[i]; Vector vecDestination = pTendril->m_vecEndPoint; Vector vecPath = vecDestination - GetGlobalOrigin(); vecPath.y = 0; float flDistance = vecPath.Length2D(); Vector vecDirection = vecPath.Normalized(); size_t iSegments = (size_t)(flDistance/3); GLuint iScrollingTextureProgram = (GLuint)CShaderLibrary::GetScrollingTextureProgram(); GLuint flSpeed = glGetUniformLocation(iScrollingTextureProgram, "flSpeed"); glUniform1f(flSpeed, pTendril->m_flSpeed); clrTeam.SetAlpha(105); CRopeRenderer oRope(GameServer()->GetRenderer(), s_iTendrilBeam, DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin()) + Vector(0, 0, 1), 1.0f); oRope.SetColor(clrTeam); oRope.SetTextureScale(pTendril->m_flScale); oRope.SetTextureOffset(pTendril->m_flOffset); oRope.SetForward(Vector(0, 0, -1)); for (size_t i = 1; i < iSegments; i++) { clrTeam.SetAlpha((int)RemapVal((float)i, 1, (float)iSegments, 100, 30)); oRope.SetColor(clrTeam); float flCurrentDistance = ((float)i*flDistance)/iSegments; oRope.AddLink(DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin() + vecDirection*flCurrentDistance) + Vector(0, 0, 1)); } oRope.Finish(DigitanksGame()->GetTerrain()->GetPointHeight(vecDestination) + Vector(0, 0, 1)); } glEndList(); #endif }
void BlendEdges( CCoreDispInfo **ppListBase, int listSize ) { for ( int iDisp=0; iDisp < listSize; iDisp++ ) { CCoreDispInfo *pDisp = ppListBase[iDisp]; for ( int iEdge=0; iEdge < 4; iEdge++ ) { CDispNeighbor *pEdge = pDisp->GetEdgeNeighbor( iEdge ); for ( int iSub=0; iSub < 2; iSub++ ) { CDispSubNeighbor *pSub = &pEdge->m_SubNeighbors[iSub]; if ( !pSub->IsValid() ) continue; CCoreDispInfo *pNeighbor = ppListBase[ pSub->GetNeighborIndex() ]; int iEdgeDim = g_EdgeDims[iEdge]; CDispSubEdgeIterator it; it.Start( pDisp, iEdge, iSub, true ); // Get setup on the first corner vert. it.Next(); CVertIndex viPrevPos = it.GetVertIndex(); while ( it.Next() ) { // Blend the two. if ( !it.IsLastVert() ) { Vector vAverage = pDisp->GetNormal( it.GetVertIndex() ) + pNeighbor->GetNormal( it.GetNBVertIndex() ); VectorNormalize( vAverage ); pDisp->SetNormal( it.GetVertIndex(), vAverage ); pNeighbor->SetNormal( it.GetNBVertIndex(), vAverage ); #if defined( USE_SCRATCHPAD ) ScratchPad_DrawArrowSimple( g_pPad, pDisp->GetVert( it.GetVertIndex() ), pDisp->GetNormal( it.GetVertIndex() ), Vector( 1, 0, 0 ), 25 ); #endif } // Now blend the in-between verts (if this edge is high-res). int iPrevPos = viPrevPos[ !iEdgeDim ]; int iCurPos = it.GetVertIndex()[ !iEdgeDim ]; for ( int iTween = iPrevPos+1; iTween < iCurPos; iTween++ ) { float flPercent = RemapVal( iTween, iPrevPos, iCurPos, 0, 1 ); Vector vNormal; VectorLerp( pDisp->GetNormal( viPrevPos ), pDisp->GetNormal( it.GetVertIndex() ), flPercent, vNormal ); VectorNormalize( vNormal ); CVertIndex viTween; viTween[iEdgeDim] = it.GetVertIndex()[ iEdgeDim ]; viTween[!iEdgeDim] = iTween; pDisp->SetNormal( viTween, vNormal ); #if defined( USE_SCRATCHPAD ) ScratchPad_DrawArrowSimple( g_pPad, pDisp->GetVert( viTween ), pDisp->GetNormal( viTween ), Vector( 1, 0.5, 0 ), 25 ); #endif } viPrevPos = it.GetVertIndex(); } } } } }
void CSupplier::PostRender() const { BaseClass::PostRender(); if (!GameServer()->GetRenderer()->IsRenderingTransparent()) return; float flGrowthTime = (float)(GameServer()->GetGameTime() - m_flTendrilGrowthStartTime); if (flGrowthTime < 0) return; if (m_flTendrilGrowthStartTime == 0) { DigitanksGame()->GetDigitanksRenderer()->AddTendrilBatch(this); return; } COverheadCamera* pCamera = DigitanksGame()->GetOverheadCamera(); Vector vecCamera = pCamera->GetGlobalOrigin(); float flDistanceSqr = GetGlobalOrigin().DistanceSqr(vecCamera); float flFadeDistance = tendril_fade_distance.GetFloat(); float flFadeAlpha = RemapValClamped(flDistanceSqr, flFadeDistance*flFadeDistance, (flFadeDistance+20)*(flFadeDistance+20), 1.0f, 0.0f); if (flFadeAlpha <= 0) return; float flTreeAlpha = 1.0f; if (DigitanksGame()->GetTerrain()->GetBit(CTerrain::WorldToArraySpace(GetGlobalOrigin().x), CTerrain::WorldToArraySpace(GetGlobalOrigin().y), TB_TREE)) flTreeAlpha = 0.3f; CRenderingContext r(GameServer()->GetRenderer(), true); if (DigitanksGame()->ShouldRenderFogOfWar()) r.UseFrameBuffer(DigitanksGame()->GetDigitanksRenderer()->GetVisibilityMaskedBuffer()); r.SetDepthMask(false); r.UseMaterial(s_hTendrilBeam); r.SetUniform("flTime", (float)GameServer()->GetGameTime()); r.SetUniform("iTexture", 0); r.SetUniform("flAlpha", flFadeAlpha * flTreeAlpha); Color clrTeam = GetPlayerOwner()?GetPlayerOwner()->GetColor():Color(255,255,255,255); clrTeam = (Vector(clrTeam) + Vector(1,1,1))/2; if (m_flTendrilGrowthStartTime > 0) { float flTotalSize = (float)m_aTendrils.size() + GetBoundingRadius(); for (size_t i = 0; i < m_aTendrils.size(); i++) { if (i < m_aTendrils.size() - 15) continue; const CTendril* pTendril = &m_aTendrils[i]; float flGrowthLength = RemapVal(flGrowthTime, 0, GROWTH_TIME, pTendril->m_flLength-flTotalSize, pTendril->m_flLength); if (flGrowthLength < 0) continue; Vector vecDestination = GetGlobalOrigin() + (pTendril->m_vecEndPoint - GetGlobalOrigin()).Normalized() * flGrowthLength; Vector vecPath = vecDestination - GetGlobalOrigin(); vecPath.y = 0; float flDistance = vecPath.Length2D(); Vector vecDirection = vecPath.Normalized(); size_t iSegments = (size_t)(flDistance/3); r.SetUniform("flSpeed", pTendril->m_flSpeed); clrTeam.SetAlpha(105); CRopeRenderer oRope(GameServer()->GetRenderer(), s_hTendrilBeam, DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin()) + Vector(0, 0, 1), 1.0f); oRope.SetColor(clrTeam); oRope.SetTextureScale(pTendril->m_flScale); oRope.SetTextureOffset(pTendril->m_flOffset); oRope.SetForward(Vector(0, 0, -1)); for (size_t i = 1; i < iSegments; i++) { clrTeam.SetAlpha((int)RemapVal((float)i, 1, (float)iSegments, 100, 30)); oRope.SetColor(clrTeam); float flCurrentDistance = ((float)i*flDistance)/iSegments; oRope.AddLink(DigitanksGame()->GetTerrain()->GetPointHeight(GetGlobalOrigin() + vecDirection*flCurrentDistance) + Vector(0, 0, 1)); } oRope.Finish(DigitanksGame()->GetTerrain()->GetPointHeight(vecDestination) + Vector(0, 0, 1)); } } }
void CObjectTeleporter::DeterminePlaybackRate( void ) { float flPlaybackRate = GetPlaybackRate(); bool bWasBelowFullSpeed = ( flPlaybackRate < 1.0f ); if ( IsBuilding() ) { // Default half rate, author build anim as if one player is building SetPlaybackRate( GetRepairMultiplier() * 0.5 ); } else if ( IsPlacing() ) { SetPlaybackRate( 1.0f ); } else { float flFrameTime = 0.1; // BaseObjectThink delay switch( m_iState ) { case TELEPORTER_STATE_READY: { // spin up to 1.0 from whatever we're at, at some high rate flPlaybackRate = Approach( 1.0f, flPlaybackRate, 0.5f * flFrameTime ); } break; case TELEPORTER_STATE_RECHARGING: { // Recharge - spin down to low and back up to full speed over 10 seconds // 0 -> 4, spin to low // 4 -> 6, stay at low // 6 -> 10, spin to 1.0 float flTimeSinceChange = gpGlobals->curtime - m_flLastStateChangeTime; float flLowSpinSpeed = 0.15f; if ( flTimeSinceChange <= 4.0f ) { flPlaybackRate = RemapVal( gpGlobals->curtime, m_flLastStateChangeTime, m_flLastStateChangeTime + 4.0f, 1.0f, flLowSpinSpeed ); } else if ( flTimeSinceChange > 4.0f && flTimeSinceChange <= 6.0f ) { flPlaybackRate = flLowSpinSpeed; } else { flPlaybackRate = RemapVal( gpGlobals->curtime, m_flLastStateChangeTime + 6.0f, m_flLastStateChangeTime + 10.0f, flLowSpinSpeed, 1.0f ); } } break; default: { if ( m_flLastStateChangeTime <= 0.0f ) { flPlaybackRate = 0.0f; } else { // lost connect - spin down to 0.0 from whatever we're at, slowish rate flPlaybackRate = Approach( 0.0f, flPlaybackRate, 0.25f * flFrameTime ); } } break; } SetPlaybackRate( flPlaybackRate ); } bool bBelowFullSpeed = ( GetPlaybackRate() < 1.0f ); if ( m_iBlurBodygroup >= 0 && bBelowFullSpeed != bWasBelowFullSpeed ) { if ( bBelowFullSpeed ) { SetBodygroup( m_iBlurBodygroup, 0 ); // turn off blur bodygroup } else { SetBodygroup( m_iBlurBodygroup, 1 ); // turn on blur bodygroup } } StudioFrameAdvance(); }