void  C_NPC_Hydra::CalcBoneChain( Vector pos[], const Vector chain[] )
{
	int i, j;

	// Find the dist chain link that's not zero length
	i = CHAIN_LINKS-1;
	while (i > 0)
	{
		if ((chain[i] - chain[i-1]).LengthSqr() > 0.0)
		{
			break;
		}
		i--;
	}

	// initialize the last bone to the last bone
	j = m_numHydraBones - 1;

	// clamp length
	float totalLength = 0;
	for (int k = i; k > 0; k--)
	{
		// debugoverlay->AddLineOverlay( chain[k], chain[k-1], 255, 255, 255, false, 0 );
		totalLength += (chain[k] - chain[k-1]).Length();
	}
	totalLength = clamp( totalLength, 1.0, m_maxPossibleLength );
	float scale = m_flRelaxedLength / totalLength;

	// starting from the head, fit the hydra skeleton onto the chain spline
	float dist = -16;
	while (j >= 0 && i > 0)
	{
		// debugoverlay->AddLineOverlay( chain[i], chain[i-1], 255, 255, 255, false, 0 );
		float dt = (chain[i] - chain[i-1]).Length() * scale;
		float dx = dt;
		while (j >= 0 && dist + dt >= m_boneLength[j])
		{
			float s = (dx - (dt - (m_boneLength[j] - dist))) / dx;

			if (s < 0 || s > 1.)
				s = 0;
			// pos[j] = chain[i] * (1 - s) + chain[i-1] * s;
			Catmull_Rom_Spline( chain[(i<CHAIN_LINKS-1)?i+1:CHAIN_LINKS-1], chain[i], chain[(i>0)?i-1:0], chain[(i>1)?i-2:0], s, pos[j] );
			// debugoverlay->AddLineOverlay( pos[j], chain[i], 0, 255, 0, false, 0 );
			// debugoverlay->AddLineOverlay( pos[j], chain[i-1], 0, 255, 0, false, 0 );

			dt = dt - (m_boneLength[j] - dist);
			j--;
			dist = 0;
		}
		dist += dt;
		i--;
	}

	while (j >= 0)
	{
		pos[j] = chain[0];
		j--;
	}
}
void CPositionInterpolator_CatmullRom::InterpolatePosition( float time, Vector &vOut )
{
	Catmull_Rom_Spline( 
		g_KeyFramePtr[-1].vPos,
		g_KeyFramePtr[0].vPos,
		g_KeyFramePtr[1].vPos,
		g_KeyFramePtr[2].vPos,
		time,
		vOut );
}
Exemple #3
0
void Interpolator_CurveInterpolate_NonNormalized( int interpolationType,
	const Vector &vPre,
	const Vector &vStart,
	const Vector &vEnd,
	const Vector &vNext,
	float f,
	Vector &vOut )
{
	vOut.Init();

	switch ( interpolationType )
	{
	default:
		Warning( "Unknown interpolation type %d\n",
			(int)interpolationType );
		// break; // Fall through and use catmull_rom as default
	case INTERPOLATE_CATMULL_ROM_NORMALIZEX:
	case INTERPOLATE_DEFAULT:
	case INTERPOLATE_CATMULL_ROM:
	case INTERPOLATE_CATMULL_ROM_NORMALIZE:
	case INTERPOLATE_CATMULL_ROM_TANGENT:
		Catmull_Rom_Spline( 
			vPre,
			vStart,
			vEnd,
			vNext,
			f, 
			vOut );
		break;
	case INTERPOLATE_EASE_IN:
		{
			f = sin( M_PI * f * 0.5f );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			VectorLerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_EASE_OUT:
		{
			f = 1.0f - sin( M_PI * f * 0.5f + 0.5f * M_PI );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			VectorLerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_EASE_INOUT:
		{
			f = SimpleSpline( f );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			VectorLerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_LINEAR_INTERP:
		// Fixme, since this ignores vPre and vNext we could omit computing them aove
		VectorLerp( vStart, vEnd, f, vOut );
		break;
	case INTERPOLATE_KOCHANEK_BARTELS:
	case INTERPOLATE_KOCHANEK_BARTELS_EARLY:
	case INTERPOLATE_KOCHANEK_BARTELS_LATE:
		{
			float t, b, c;
			Interpolator_GetKochanekBartelsParams( interpolationType, t, b, c );
			Kochanek_Bartels_Spline
			( 
				t, b, c, 
				vPre,
				vStart,
				vEnd,
				vNext,
				f, 
				vOut 
			);
		}
		break;
	case INTERPOLATE_SIMPLE_CUBIC:
		Cubic_Spline( 
			vPre,
			vStart,
			vEnd,
			vNext,
			f, 
			vOut );
		break;
	case INTERPOLATE_BSPLINE:
		BSpline( 
			vPre,
			vStart,
			vEnd,
			vNext,
			f, 
			vOut );
		break;
	case INTERPOLATE_EXPONENTIAL_DECAY:
		{
			float dt = vEnd.x - vStart.x;
			if ( dt > 0.0f )
			{
				float val = 1.0f - ExponentialDecay( 0.001, dt, f * dt ); 
				vOut.y = vStart.y + val * ( vEnd.y - vStart.y );
			}
			else
			{
				vOut.y = vStart.y;
			}
		}
		break;
	case INTERPOLATE_HOLD:
		{
			vOut.y = vStart.y;
		}
		break;
	}
}
Exemple #4
0
void CViewAngleAnimation::ClientThink()
{
	if ( IsFinished() )
		return;

	float flCurrentTime = gpGlobals->curtime - m_flAnimStartTime;

	if ( flCurrentTime < 0 )
		flCurrentTime = 0.001;

	// find two nearest points
	int i, c;
	c = m_KeyFrames.Count();
	float flTime = 0;
	for ( i=0;i<c;i++ )
	{
		if ( flTime + m_KeyFrames[i]->m_flTime > flCurrentTime )
		{
			break;
		}

		flTime += m_KeyFrames[i]->m_flTime;
	}

	Assert( i > 0 );

	if ( i >= c )
	{
		if ( i > 0 )
		{
			// animation complete, set to end point
			SetAngles( m_KeyFrames[i-1]->m_vecAngles );
		}

		if ( m_pAnimCompleteCallback )
		{
			m_pAnimCompleteCallback();
		}

		m_bFinished = true;
		return;
	}

	if ( m_KeyFrames[i]->m_iFlags != m_iFlags )
	{
		if ( ( m_KeyFrames[i]->m_iFlags & VIEWANIM_RELATIVE ) && !( m_iFlags & VIEWANIM_RELATIVE ) )
		{
            // new relative position is current angles
			engine->GetViewAngles( m_vecBaseAngles );
		}

		// copy the rest over
		m_iFlags = m_KeyFrames[i]->m_iFlags;
	}

	// previous frame is m_KeyFrames[i-1];
	// next frame is m_KeyFrames[i];
	float flFraction = ( flCurrentTime - flTime ) / ( m_KeyFrames[i]->m_flTime );

	Vector v0, v1, v2, v3;

	if ( i-2 <= 0 )
	{
		QAngleToVector( m_KeyFrames[i-1]->m_vecAngles, v0 );
	}
	else
	{
		QAngleToVector( m_KeyFrames[i-2]->m_vecAngles, v0 );
	}

	QAngleToVector( m_KeyFrames[i-1]->m_vecAngles, v1 );
	QAngleToVector( m_KeyFrames[i]->m_vecAngles, v2 );

	if ( i+1 >= c )
	{
		QAngleToVector( m_KeyFrames[i]->m_vecAngles, v3 );
	}
	else
	{
		QAngleToVector( m_KeyFrames[i+1]->m_vecAngles, v3 );
	}

	Vector out;
	Catmull_Rom_Spline( v0,	v1, v2,	v3,	flFraction,	out );

	QAngle vecCalculatedAngles;
	QAngleToVector( out, vecCalculatedAngles );
	SetAngles( vecCalculatedAngles );
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : time - 
//			type - 
// Output : float
//-----------------------------------------------------------------------------
float CSentence::GetIntensity( float time, float endtime )
{
	float zeroValue = 0.5f;
	
	int c = GetNumSamples();
	
	if ( c <= 0 )
	{
		return zeroValue;
	}
	
	int i;
	for ( i = -1 ; i < c; i++ )
	{
		CEmphasisSample *s = GetBoundedSample( i, endtime );
		CEmphasisSample *n = GetBoundedSample( i + 1, endtime );
		if ( !s || !n )
			continue;

		if ( time >= s->time && time <= n->time )
		{
			break;
		}
	}

	int prev = i - 1;
	int start = i;
	int end = i + 1;
	int next = i + 2;

	prev = max( -1, prev );
	start = max( -1, start );
	end = min( end, GetNumSamples() );
	next = min( next, GetNumSamples() );

	CEmphasisSample *esPre = GetBoundedSample( prev, endtime );
	CEmphasisSample *esStart = GetBoundedSample( start, endtime );
	CEmphasisSample *esEnd = GetBoundedSample( end, endtime );
	CEmphasisSample *esNext = GetBoundedSample( next, endtime );

	float dt = esEnd->time - esStart->time;
	dt = clamp( dt, 0.01f, 1.0f );

	Vector vPre( esPre->time, esPre->value, 0 );
	Vector vStart( esStart->time, esStart->value, 0 );
	Vector vEnd( esEnd->time, esEnd->value, 0 );
	Vector vNext( esNext->time, esNext->value, 0 );

	float f2 = ( time - esStart->time ) / ( dt );
	f2 = clamp( f2, 0.0f, 1.0f );

	Vector vOut;
	Catmull_Rom_Spline( 
		vPre,
		vStart,
		vEnd,
		vNext,
		f2, 
		vOut );

	float retval = clamp( vOut.y, 0.0f, 1.0f );
	return retval;
}
Exemple #6
0
void C_Camera::CalcTVCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov)
{
	if (!GetMatchBall())
		return;

	C_BaseEntity *pTarget;
	bool atMinGoalPos;
	Vector targetPos;
	int tvcamMode = GetTVCamMode();

	if (GetReplayManager() && GetReplayManager()->IsReplaying())
	{
		pTarget = GetReplayBall();

		if (!pTarget)
			return;

		atMinGoalPos = GetReplayManager()->m_bAtMinGoalPos;
		targetPos = pTarget->GetLocalOrigin();
	}
	else
	{
		if (GetMatchBall() && GetMatchBall()->m_eBallState == BALL_STATE_GOAL)
		{
			pTarget = GetMatchBall()->m_pLastActivePlayer;

			if (!pTarget)
				pTarget = GetMatchBall();

			atMinGoalPos = pTarget->GetLocalOrigin().y < SDKGameRules()->m_vKickOff.GetY();
			targetPos = pTarget->GetLocalOrigin();
		}
		else
		{
			pTarget = CBasePlayer::GetLocalPlayer()->GetObserverTarget();
			if (!pTarget)
				pTarget = GetMatchBall();

			atMinGoalPos = pTarget->GetLocalOrigin().y < SDKGameRules()->m_vKickOff.GetY();
			targetPos = pTarget->GetLocalOrigin();

			// Move the camera towards the defending team's goal
			if (GetMatchBall()->m_nLastActiveTeam != TEAM_NONE)
			{
				if (m_nLastPossessingTeam == TEAM_NONE)
				{
					m_nLastPossessingTeam = GetMatchBall()->m_nLastActiveTeam;
					m_flLastPossessionChange = gpGlobals->curtime;
					m_flPossCoeff = 0;
					m_flOldPossCoeff = 0;
				}
				else
				{
					if (GetMatchBall()->m_nLastActiveTeam != m_nLastPossessingTeam)
					{
						m_nLastPossessingTeam = GetMatchBall()->m_nLastActiveTeam;
						m_flLastPossessionChange = gpGlobals->curtime;
						m_flOldPossCoeff = m_flPossCoeff;
					}

					float timeFrac = min(1.0f, (gpGlobals->curtime - m_flLastPossessionChange) / mp_tvcam_offset_forward_time.GetFloat());
					float frac = pow(timeFrac, 2) * (3 - 2 * timeFrac); 
					m_flPossCoeff = Lerp(frac, m_flOldPossCoeff, (float)GetGlobalTeam(GetMatchBall()->m_nLastActiveTeam)->m_nForward);
				}

				if (tvcamMode == TVCAM_MODE_SIDELINE)
				{
					targetPos.y += m_flPossCoeff * mp_tvcam_offset_forward.GetInt();
				}
			}
		}
	}

	if (tvcamMode != TVCAM_MODE_CELEBRATION)
	{
		// Make sure the camera doesn't move too far away from the field borders
		targetPos.x = clamp(targetPos.x, SDKGameRules()->m_vFieldMin.GetX() + mp_tvcam_border_south.GetInt(), SDKGameRules()->m_vFieldMax.GetX() - mp_tvcam_border_north.GetInt());
		targetPos.y = clamp(targetPos.y, SDKGameRules()->m_vFieldMin.GetY() + mp_tvcam_border_west.GetInt(), SDKGameRules()->m_vFieldMax.GetY() - mp_tvcam_border_east.GetInt());
		targetPos.z = SDKGameRules()->m_vKickOff.GetZ();
	}

	if (m_vOldTargetPos == vec3_invalid)
		m_vOldTargetPos = targetPos;
	else
	{
		float speedCoeff = tvcamMode == TVCAM_MODE_CELEBRATION ? mp_tvcam_speed_coeff_fast.GetFloat() : mp_tvcam_speed_coeff.GetFloat();
		float speedExp = tvcamMode == TVCAM_MODE_CELEBRATION ? mp_tvcam_speed_exponent_fast.GetFloat() : mp_tvcam_speed_exponent.GetFloat();
		Vector changeDir = targetPos - m_vOldTargetPos;
		float changeDist = changeDir.Length();
		changeDir.NormalizeInPlace();
		targetPos = m_vOldTargetPos + changeDir * min(changeDist, pow(changeDist * speedCoeff, speedExp) * gpGlobals->frametime);
	}

	switch (GetTVCamMode())
	{
	case TVCAM_MODE_SIDELINE:
		{
			if (SDKGameRules() && SDKGameRules()->IsIntermissionState() && GetReplayManager() && !GetReplayManager()->IsReplaying())
			{
				//float xLength = SDKGameRules()->m_vFieldMax.GetX() - SDKGameRules()->m_vFieldMin.GetX();
				//float yLength = SDKGameRules()->m_vFieldMax.GetY() - SDKGameRules()->m_vFieldMin.GetY();

				float zPos = 450;
				Vector points[4];
				points[0] = Vector(SDKGameRules()->m_vFieldMin.GetX(), SDKGameRules()->m_vFieldMin.GetY(), SDKGameRules()->m_vKickOff.GetZ() + zPos);
				points[1] = Vector(SDKGameRules()->m_vFieldMin.GetX(), SDKGameRules()->m_vFieldMax.GetY(), SDKGameRules()->m_vKickOff.GetZ() + zPos);
				points[2] = Vector(SDKGameRules()->m_vFieldMax.GetX(), SDKGameRules()->m_vFieldMax.GetY(), SDKGameRules()->m_vKickOff.GetZ() + zPos);
				points[3] = Vector(SDKGameRules()->m_vFieldMax.GetX(), SDKGameRules()->m_vFieldMin.GetY(), SDKGameRules()->m_vKickOff.GetZ() + zPos);
				float totalLength = (points[1] - points[0]).Length() + (points[2] - points[1]).Length() + (points[3] - points[2]).Length() + (points[0] - points[3]).Length();

				Vector newPoints[4];

				const float maxDuration = 180.0f;
				float timePassed = fmodf(gpGlobals->curtime, maxDuration);
				
				float lengthSum = 0;
				int offset = 0;
				float length = 0;

				do
				{
					for (int i = 0; i < 4; i++)
						newPoints[i] = points[(i + offset) % 4];

					length = (newPoints[2] - newPoints[1]).Length();
					lengthSum += length;
					offset += 1;
				} while (timePassed > (lengthSum / totalLength * maxDuration));

				float maxStepTime = length / totalLength * maxDuration;

				float frac = 1 - ((lengthSum / totalLength * maxDuration) - timePassed) / maxStepTime;

				Vector output;
				Catmull_Rom_Spline(newPoints[0], newPoints[1], newPoints[2], newPoints[3], frac, output);

/*				float targetDist = (newPoints[2] - newPoints[1]).Length() * frac;
				float epsilon = 10.0f;
				float oldDiff = 0;
				float diff = 0;
				float change = 0.001f;
				bool add = true;

				do
				{
					frac = clamp(frac += (add ? change : -change), 0.0f, 1.0f);

					Catmull_Rom_Spline(newPoints[0], newPoints[1], newPoints[2], newPoints[3], frac, output);
					oldDiff = diff;
					diff = abs((output - newPoints[1]).Length() - targetDist);
					if (diff >= oldDiff)
						add = !add;
				} while (diff > epsilon);*/ 

				eyeOrigin = output;
				VectorAngles(SDKGameRules()->m_vKickOff - output, eyeAngles);
			}
			/*else if (SDKGameRules() && !SDKGameRules()->IsIntermissionState() && gpGlobals->curtime <= SDKGameRules()->m_flStateEnterTime + 4)
			{
				Vector points[4];
				float zPosStart = 450;
				float zPosEnd = 50;
				points[0] = Vector(SDKGameRules()->m_vFieldMin.GetX(), SDKGameRules()->m_vKickOff.GetY() + 10000, SDKGameRules()->m_vKickOff.GetZ() + zPosStart);
				points[1] = Vector(SDKGameRules()->m_vFieldMin.GetX(), SDKGameRules()->m_vKickOff.GetY(), SDKGameRules()->m_vKickOff.GetZ() + zPosStart);
				points[2] = Vector(SDKGameRules()->m_vKickOff.GetX(), SDKGameRules()->m_vKickOff.GetY() - 300, SDKGameRules()->m_vKickOff.GetZ() + zPosEnd);
				points[3] = Vector(SDKGameRules()->m_vKickOff.GetX(), SDKGameRules()->m_vKickOff.GetY() + 10000, SDKGameRules()->m_vKickOff.GetZ() + zPosEnd);
				float frac = min(1.0f, (gpGlobals->curtime - SDKGameRules()->m_flStateEnterTime) / 3.0f);
				Vector output;
				Catmull_Rom_Spline(points[0], points[1], points[2], points[3], frac, output);
				eyeOrigin = output;
				VectorAngles(Vector(SDKGameRules()->m_vKickOff.GetX(), SDKGameRules()->m_vKickOff.GetY(), SDKGameRules()->m_vKickOff.GetZ() + 100) - output, eyeAngles);
			}*/
			else
			{		
				Vector newPos = Vector(targetPos.x - mp_tvcam_sideline_offset_north.GetInt(), targetPos.y, targetPos.z + mp_tvcam_sideline_offset_height.GetInt());
				Vector offsetTargetPos = Vector(targetPos.x - mp_tvcam_offset_north.GetInt(), targetPos.y, targetPos.z);
				Vector newDir = offsetTargetPos - newPos;
				newDir.NormalizeInPlace();
				eyeOrigin = newPos;
				VectorAngles(newDir, eyeAngles);
			}
		}
		break;
	case TVCAM_MODE_FIXED_SIDELINE:
		{
			Vector newPos = Vector(SDKGameRules()->m_vFieldMin.GetX() - 500, SDKGameRules()->m_vKickOff.GetY(), SDKGameRules()->m_vKickOff.GetZ() + 1000);
			Vector offsetTargetPos = Vector(targetPos.x - 500, targetPos.y, targetPos.z);
			Vector newDir = offsetTargetPos - newPos;
			float dist = newDir.Length();
			newDir.NormalizeInPlace();
			newPos = offsetTargetPos - min(750, dist) * newDir;
			eyeOrigin = newPos;
			VectorAngles(newDir, eyeAngles);
		}
		break;
	case TVCAM_MODE_BEHIND_GOAL:
		{
			float yPos = atMinGoalPos ? SDKGameRules()->m_vFieldMin.GetY() : SDKGameRules()->m_vFieldMax.GetY();
			Vector goalCenter = Vector((SDKGameRules()->m_vFieldMin.GetX() + SDKGameRules()->m_vFieldMax.GetX()) / 2.0f, yPos, SDKGameRules()->m_vKickOff.GetZ());
			Vector newPos = goalCenter + Vector(0, 300 * (atMinGoalPos ? -1 : 1), 300);
			Vector newDir = targetPos - newPos;
			newDir.NormalizeInPlace();
			eyeOrigin = newPos;
			VectorAngles(newDir, eyeAngles);
		}
		break;
	case TVCAM_MODE_TOPDOWN:
		{
			eyeOrigin = Vector(targetPos.x, targetPos.y, SDKGameRules()->m_vKickOff.GetZ() + 1000);
			eyeAngles = QAngle(89, 0, 0);
		}
		break;
	case TVCAM_MODE_FLY_FOLLOW:
		{
			Vector newPos = Vector(targetPos.x, targetPos.y + (atMinGoalPos ? 1 : -1) * 500, SDKGameRules()->m_vKickOff.GetZ() + 225);
			Vector newDir = targetPos - newPos;
			newDir.NormalizeInPlace();
			eyeOrigin = newPos;
			VectorAngles(newDir, eyeAngles);
		}
		break;
	case TVCAM_MODE_GOAL_LINE:
		{
			Vector center = Vector(SDKGameRules()->m_vKickOff.GetX(), (atMinGoalPos ? SDKGameRules()->m_vFieldMin.GetY() + 5 : SDKGameRules()->m_vFieldMax.GetY() - 5), SDKGameRules()->m_vKickOff.GetZ());
			Vector newPos = center;
			newPos.x -= 350;
			newPos.z += 200;
			QAngle newAng;
			VectorAngles(center - newPos, newAng);
			eyeOrigin = newPos;
			eyeAngles = newAng;
		}
		break;
	case TVCAM_MODE_CELEBRATION:
		{
			Vector newPos = Vector(
				targetPos.x < SDKGameRules()->m_vKickOff.GetX() ? SDKGameRules()->m_vFieldMin.GetX() - 500 : SDKGameRules()->m_vFieldMax.GetX() + 500,
				targetPos.y < SDKGameRules()->m_vKickOff.GetY() ? SDKGameRules()->m_vFieldMin.GetY() - 500 : SDKGameRules()->m_vFieldMax.GetY() + 500,
				SDKGameRules()->m_vKickOff.GetZ() + 1000);
			Vector newDir = targetPos - newPos;
			float dist = newDir.Length();
			newDir.NormalizeInPlace();
			newPos = targetPos - min(300, dist) * newDir;
			eyeOrigin = newPos;
			VectorAngles(newDir, eyeAngles);
		}
		break;
	}

	m_vOldTargetPos = targetPos;

	fov = C_SDKPlayer::GetLocalSDKPlayer()->GetFOV();
}