//-----------------------------------------------------------------------------
// 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;
}
Exemple #2
0
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);
    }
}
Exemple #4
0
//-----------------------------------------------------------------------------
// 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;
}
Exemple #7
0
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;
}
Exemple #9
0
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.
}
Exemple #10
0
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();
}
Exemple #12
0
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 );
}
Exemple #14
0
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
}
Exemple #15
0
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();
				}
			}
		}
	}
}
Exemple #16
0
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();
}