Beispiel #1
0
vec3_t CTriMenu::MakePointOrtho( vec2_t vOrg )
{
	vec3_t vForward, vRight, vUp, vTotalOrg, vFRight, vFUp;

	if(CL_IsThirdPerson())
	{
		extern vec3_t g_vecCamAngles;
		AngleVectors( g_vecCamAngles, vForward, vRight, vUp );
	}
	// Use first person angles
	else
	{
		AngleVectors( g_vPlayerAngles , vForward, vRight, vUp );
	}

	vTotalOrg = g_vViewOrg + vForward*5;
	
	float flTmp[3] = {1, 1, 0};
	flTmp[0] = ( 2* vOrg.x ) - 1;
	flTmp[1] = ( 2 *vOrg.y) - 1;

	/*vFRight = */gEngfuncs.pTriAPI->ScreenToWorld( flTmp, vFRight ); 
	// software mode fallback casue screentoworld doesnt work there
	if( !IEngineStudio.IsHardware( ) )
	{
		vFRight = vRight+(vRight*( 6.5* vOrg.x - 3.75 )/.5 );
		vFUp = vUp+(vUp*( 4.9*vOrg.y - 2.95 )/.5);

		vFRight = vFRight + vTotalOrg + vFUp + ( vForward * 1.5 );
	}

	// add forward so it doesnt clip the view
	return vFRight;//vTotalOrg + vFRight + vFUp + ( vForward * 1.5 );
}
Beispiel #2
0
void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams )
{
	// intermission / finale rendering
	if ( pparams->intermission )
	{
		V_CalcIntermissionRefdef ( pparams );
	}
	else if ( pparams->spectator || g_iUser1 )	// g_iUser true if in spectator mode
	{
		V_CalcSpectatorRefdef ( pparams );
	}
	else if ( CL_IsThirdPerson() )
	{
		V_CalcThirdPersonRefdef ( pparams );
	}
	else
	{
		V_CalcNormalRefdef ( pparams );
	}
}
Beispiel #3
0
/*
==================
V_CalcRefdef

==================
*/
void V_CalcNormalRefdef(struct ref_params_s *pparams)
{
	cl_entity_t *       ent, *view;
	int                 i;
	vec3_t              angles;
	float               bob, waterOffset;
	static viewinterp_t ViewInterp;

	static float oldz = 0;
	static float lasttime;

	static float lastang[3];
	vec3_t       angdelta;

	vec3_t       camAngles, camForward, camRight, camUp;
	cl_entity_t *pwater;

	// don't allow cheats in multiplayer
	if(pparams->maxclients > 1)
	{
		scr_ofsx->value = 0.0;
		scr_ofsy->value = 0.0;
		scr_ofsz->value = 0.0;
	}

	V_DriftPitch(pparams);

	// ent is the player model ( visible when out of body )
	ent = gEngfuncs.GetLocalPlayer();

	// view is the weapon model (only visible from inside body )
	view = gEngfuncs.GetViewModel();

	// transform the view offset by the model's matrix to get the offset from
	// model origin for the view
	bob = V_CalcBob(pparams);

	// Observer angle capturing and smoothing
	if(iHasNewViewOrigin)
	{
		// Get the angles from the physics code
		VectorCopy(vecNewViewOrigin, pparams->vieworg);
		VectorCopy(vecNewViewOrigin, pparams->simorg);
	}

	// refresh position
	VectorCopy(pparams->simorg, pparams->vieworg);
	pparams->vieworg[2] += (bob);
	VectorAdd(pparams->vieworg, pparams->viewheight, pparams->vieworg);

	// Observer angle capturing and smoothing
	if(iHasNewViewAngles)
	{
		// Get the angles from the physics code
		VectorCopy(vecNewViewAngles, pparams->cl_viewangles);
	}
	else if(pparams->health == -5)
	{
		CAM_ToThirdPerson();

		// Lock mouse movement
		iMouseInUse = 1;

		pparams->cl_viewangles[0] = 89;

		// Spin the view
		float flTimeDelta = (pparams->time - g_flStartScaleTime);
		if(flTimeDelta > 0)
		{
			float flROFSpin = 1.0 + (flTimeDelta * 2.0);
			float flSpin    = flTimeDelta * 45;

			pparams->cl_viewangles[1] = flSpin * flROFSpin;
		}
	}
	else
	{
		CAM_ToFirstPerson();

		// Unlock mouse movement
		iMouseInUse = 0;
	}

	VectorSubtract(pparams->cl_viewangles, lastang, angdelta);
	if(Length(angdelta) != 0.0)
	{
		VectorCopy(pparams->cl_viewangles, ViewInterp.Angles[ViewInterp.CurrentAngle & ORIGIN_MASK]);
		ViewInterp.AngleTime[ViewInterp.CurrentAngle & ORIGIN_MASK] = pparams->time;
		ViewInterp.CurrentAngle++;

		VectorCopy(pparams->cl_viewangles, lastang);
	}

	if(cl_vsmoothing && cl_vsmoothing->value && (iIsSpectator & SPEC_SMOOTH_ANGLES))
	{
		int   foundidx;
		int   i;
		float t;

		if(cl_vsmoothing->value < 0.0)
		{
			gEngfuncs.Cvar_SetValue("cl_vsmoothing", 0.0);
		}

		t = pparams->time - cl_vsmoothing->value;

		for(i = 1; i < ORIGIN_MASK; i++)
		{
			foundidx = ViewInterp.CurrentAngle - 1 - i;
			if(ViewInterp.AngleTime[foundidx & ORIGIN_MASK] <= t)
				break;
		}

		if(i < ORIGIN_MASK && ViewInterp.AngleTime[foundidx & ORIGIN_MASK] != 0.0)
		{
			// Interpolate
			double dt;

			dt = ViewInterp.AngleTime[(foundidx + 1) & ORIGIN_MASK] - ViewInterp.AngleTime[foundidx & ORIGIN_MASK];
			if(dt > 0.0)
			{
				double frac;

				frac = (t - ViewInterp.AngleTime[foundidx & ORIGIN_MASK]) / dt;
				frac = min(1.0, frac);

				// interpolate angles
				V_InterpolateAngles(ViewInterp.Angles[foundidx & ORIGIN_MASK], ViewInterp.Angles[(foundidx + 1) & ORIGIN_MASK], pparams->cl_viewangles, frac);

				VectorCopy(pparams->cl_viewangles, vecNewViewAngles);
			}
		}
	}

	VectorCopy(pparams->cl_viewangles, pparams->viewangles);

	gEngfuncs.V_CalcShake();
	gEngfuncs.V_ApplyShake(pparams->vieworg, pparams->viewangles, 1.0);

	// never let view origin sit exactly on a node line, because a water plane can
	// dissapear when viewed with the eye exactly on it.
	// FIXME, we send origin at 1/128 now, change this?
	// the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis

	pparams->vieworg[0] += 1.0 / 32;
	pparams->vieworg[1] += 1.0 / 32;
	pparams->vieworg[2] += 1.0 / 32;

	// Check for problems around water, move the viewer artificially if necessary
	// -- this prevents drawing errors in GL due to waves

	waterOffset = 0;
	if(pparams->waterlevel >= 2)
	{
		int    i, contents, waterDist, waterEntity;
		vec3_t point;
		waterDist = cl_waterdist->value;

		if(pparams->hardware)
		{
			waterEntity = gEngfuncs.PM_WaterEntity(pparams->simorg);
			if(waterEntity >= 0 && waterEntity < pparams->max_entities)
			{
				pwater = gEngfuncs.GetEntityByIndex(waterEntity);
				if(pwater && (pwater->model != NULL))
				{
					waterDist += (pwater->curstate.scale * 16); // Add in wave height
				}
			}
		}
		else
		{
			waterEntity = 0; // Don't need this in software
		}

		VectorCopy(pparams->vieworg, point);

		// Eyes are above water, make sure we're above the waves
		if(pparams->waterlevel == 2)
		{
			point[2] -= waterDist;
			for(i = 0; i < waterDist; i++)
			{
				contents = gEngfuncs.PM_PointContents(point, NULL);
				if(contents > CONTENTS_WATER)
					break;
				point[2] += 1;
			}
			waterOffset = (point[2] + waterDist) - pparams->vieworg[2];
		}
		else
		{
			// eyes are under water.  Make sure we're far enough under
			point[2] += waterDist;

			for(i = 0; i < waterDist; i++)
			{
				contents = gEngfuncs.PM_PointContents(point, NULL);
				if(contents <= CONTENTS_WATER)
					break;
				point[2] -= 1;
			}
			waterOffset = (point[2] - waterDist) - pparams->vieworg[2];
		}
	}

	pparams->vieworg[2] += waterOffset;

	V_CalcViewRoll(pparams);

	V_AddIdle(pparams);

	// offsets
	VectorCopy(pparams->cl_viewangles, angles);

	AngleVectors(angles, pparams->forward, pparams->right, pparams->up);

	for(i = 0; i < 3; i++)
	{
		pparams->vieworg[i] += scr_ofsx->value * pparams->forward[i] + scr_ofsy->value * pparams->right[i] + scr_ofsz->value * pparams->up[i];
	}

	// Treating cam_ofs[2] as the distance
	if(CL_IsThirdPerson())
	{
		vec3_t ofs;
		ofs[0] = ofs[1] = ofs[2] = 0.0;
		CL_CameraOffset((float *)&ofs);

		VectorCopy(ofs, camAngles);
		camAngles[ROLL] = 0;
		AngleVectors(camAngles, camForward, camRight, camUp);

		// Is the player in a falling anim? If so, raise camera above and look down
		if(pparams->health == -5)
		{
			pparams->vieworg[2] += 92;
		}
		else
		{
			for(i = 0; i < 3; i++)
			{
				pparams->vieworg[i] += -ofs[2] * camForward[i];
			}

			pparams->vieworg[2] += 20;
		}
	}

	// Give gun our viewangles
	VectorCopy(pparams->cl_viewangles, view->angles);

	// set up gun position
	V_CalcGunAngle(pparams);

	// Use predicted origin as view origin.
	VectorCopy(pparams->simorg, view->origin);
	view->origin[2] += (waterOffset);
	VectorAdd(view->origin, pparams->viewheight, view->origin);

	// Let the viewmodel shake at about 10% of the amplitude
	gEngfuncs.V_ApplyShake(view->origin, view->angles, 0.9);

	for(i = 0; i < 3; i++)
	{
		view->origin[i] += bob * 0.4 * pparams->forward[i];
	}
	view->origin[2] += bob;

	// throw in a little tilt.
	view->angles[YAW] -= bob * 0.5;
	view->angles[ROLL] -= bob * 1;
	view->angles[PITCH] -= bob * 0.3;

	// pushing the view origin down off of the same X/Z plane as the ent's origin will give the
	// gun a very nice 'shifting' effect when the player looks up/down. If there is a problem
	// with view model distortion, this may be a cause. (SJB).
	view->origin[2] -= 1;

	// fudge position around to keep amount of weapon visible
	// roughly equal with different FOV
	if(pparams->viewsize == 110)
	{
		view->origin[2] += 1;
	}
	else if(pparams->viewsize == 100)
	{
		view->origin[2] += 2;
	}
	else if(pparams->viewsize == 90)
	{
		view->origin[2] += 1;
	}
	else if(pparams->viewsize == 80)
	{
		view->origin[2] += 0.5;
	}

	// Add in the punchangle, if any
	VectorAdd(pparams->viewangles, pparams->punchangle, pparams->viewangles);

	// Include client side punch, too
	VectorAdd(pparams->viewangles, (float *)&ev_punchangle, pparams->viewangles);

	V_DropPunchAngle(pparams->frametime, (float *)&ev_punchangle);

// smooth out stair step ups
#if 1
	if(!pparams->smoothing && pparams->onground && pparams->simorg[2] - oldz > 0)
	{
		float steptime;

		steptime = pparams->time - lasttime;
		if(steptime < 0)
			//FIXME		I_Error ("steptime < 0");
			steptime = 0;

		oldz += steptime * 150;
		if(oldz > pparams->simorg[2])
			oldz = pparams->simorg[2];
		if(pparams->simorg[2] - oldz > 18)
			oldz = pparams->simorg[2] - 18;
		pparams->vieworg[2] += oldz - pparams->simorg[2];
		view->origin[2] += oldz - pparams->simorg[2];
	}
	else
	{
		oldz = pparams->simorg[2];
	}
#endif

	{
		static float lastorg[3];
		vec3_t       delta;

		VectorSubtract(pparams->simorg, lastorg, delta);

		if(Length(delta) != 0.0)
		{
			VectorCopy(pparams->simorg, ViewInterp.Origins[ViewInterp.CurrentOrigin & ORIGIN_MASK]);
			ViewInterp.OriginTime[ViewInterp.CurrentOrigin & ORIGIN_MASK] = pparams->time;
			ViewInterp.CurrentOrigin++;

			VectorCopy(pparams->simorg, lastorg);
		}
	}

	// Smooth out whole view in multiplayer when on trains, lifts
	if(cl_vsmoothing && cl_vsmoothing->value &&
	   ((iIsSpectator & SPEC_SMOOTH_ORIGIN) || (pparams->smoothing && (pparams->maxclients > 1))))
	{
		int   foundidx;
		int   i;
		float t;

		if(cl_vsmoothing->value < 0.0)
		{
			gEngfuncs.Cvar_SetValue("cl_vsmoothing", 0.0);
		}

		t = pparams->time - cl_vsmoothing->value;

		for(i = 1; i < ORIGIN_MASK; i++)
		{
			foundidx = ViewInterp.CurrentOrigin - 1 - i;
			if(ViewInterp.OriginTime[foundidx & ORIGIN_MASK] <= t)
				break;
		}

		if(i < ORIGIN_MASK && ViewInterp.OriginTime[foundidx & ORIGIN_MASK] != 0.0)
		{
			// Interpolate
			vec3_t delta;
			double frac;
			double dt;
			vec3_t neworg;

			dt = ViewInterp.OriginTime[(foundidx + 1) & ORIGIN_MASK] - ViewInterp.OriginTime[foundidx & ORIGIN_MASK];
			if(dt > 0.0)
			{
				frac = (t - ViewInterp.OriginTime[foundidx & ORIGIN_MASK]) / dt;
				frac = min(1.0, frac);
				VectorSubtract(ViewInterp.Origins[(foundidx + 1) & ORIGIN_MASK], ViewInterp.Origins[foundidx & ORIGIN_MASK], delta);
				VectorMA(ViewInterp.Origins[foundidx & ORIGIN_MASK], frac, delta, neworg);

				// Dont interpolate large changes
				if(Length(delta) < 64)
				{
					VectorSubtract(neworg, pparams->simorg, delta);

					VectorAdd(pparams->simorg, delta, pparams->simorg);
					VectorAdd(pparams->vieworg, delta, pparams->vieworg);
					VectorAdd(view->origin, delta, view->origin);

					VectorCopy(pparams->simorg, vecNewViewOrigin);
				}
			}
		}
	}

	// Store off v_angles before munging for third person
	v_angles = pparams->viewangles;

	if(CL_IsThirdPerson())
	{
		VectorCopy(camAngles, pparams->viewangles);
	}

	// override all previous settings if the viewent isn't the client
	if(pparams->viewentity > pparams->maxclients)
	{
		cl_entity_t *viewentity;
		viewentity = gEngfuncs.GetEntityByIndex(pparams->viewentity);
		if(viewentity)
		{
			VectorCopy(viewentity->origin, pparams->vieworg);
			VectorCopy(viewentity->angles, pparams->viewangles);

			// Store off overridden viewangles
			v_angles = pparams->viewangles;
		}
	}

	lasttime = pparams->time;

	v_origin = pparams->vieworg;
}
Beispiel #4
0
/*
==================
V_CalcRefdef

==================
*/
void V_CalcNormalRefdef ( ref_params_t *pparams )
{
	cl_entity_t		*ent, *view;
	int				i;
	Vector			angles;
	float			bob, waterOffset;
	static viewinterp_t		ViewInterp;

	static float oldz = 0;
	static float lasttime;

	Vector camAngles, camForward, camRight, camUp;
	cl_entity_t *pwater;

	V_DriftPitch ( pparams );

	if ( gEngfuncs.IsSpectateOnly() )
	{
		ent = gEngfuncs.GetEntityByIndex( g_iUser2 );
	}
	else
	{
		// ent is the player model ( visible when out of body )
		ent = gEngfuncs.GetLocalPlayer();
	}
	
	// view is the weapon model (only visible from inside body )
	view = gEngfuncs.GetViewModel();

	// transform the view offset by the model's matrix to get the offset from
	// model origin for the view
	bob = V_CalcBob ( pparams );

	// refresh position
	pparams->vieworg = pparams->simorg;
	pparams->vieworg[2] += ( bob );

	pparams->vieworg = pparams->vieworg + pparams->viewheight;

	pparams->viewangles = pparams->cl_viewangles;

	gEngfuncs.V_CalcShake();
	gEngfuncs.V_ApplyShake( pparams->vieworg, pparams->viewangles, 1.0 );

	// never let view origin sit exactly on a node line, because a water plane can
	// dissapear when viewed with the eye exactly on it.
	// FIXME, we send origin at 1/128 now, change this?
	// the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis
	
	pparams->vieworg[0] += 1.0/32;
	pparams->vieworg[1] += 1.0/32;
	pparams->vieworg[2] += 1.0/32;

	// Check for problems around water, move the viewer artificially if necessary 
	// -- this prevents drawing errors in GL due to waves

	waterOffset = 0;
	if ( pparams->waterlevel >= WATERLEVEL_WAIST )
	{
		int		i, contents, waterDist, waterEntity;
		Vector	point;
		waterDist = cl_waterdist->value;

		if ( pparams->hardware )
		{
			waterEntity = gEngfuncs.PM_WaterEntity( pparams->simorg );
			if ( waterEntity >= 0 && waterEntity < pparams->max_entities )
			{
				pwater = gEngfuncs.GetEntityByIndex( waterEntity );
				if ( pwater && ( pwater->model != NULL ) )
				{
					waterDist += ( pwater->curstate.scale * 16 );	// Add in wave height
				}
			}
		}
		else
		{
			waterEntity = 0;	// Don't need this in software
		}
		
		point = pparams->vieworg;

		// Eyes are above water, make sure we're above the waves
		if ( pparams->waterlevel == WATERLEVEL_WAIST )	
		{
			point[2] -= waterDist;
			for ( i = 0; i < waterDist; i++ )
			{
				contents = gEngfuncs.PM_PointContents( point, NULL );
				if ( contents > CONTENTS_WATER )
					break;
				point[2] += 1;
			}
			waterOffset = (point[2] + waterDist) - pparams->vieworg[2];
		}
		else
		{
			// eyes are under water.  Make sure we're far enough under
			point[2] += waterDist;

			for ( i = 0; i < waterDist; i++ )
			{
				contents = gEngfuncs.PM_PointContents( point, NULL );
				if ( contents <= CONTENTS_WATER )
					break;
				point[2] -= 1;
			}
			waterOffset = (point[2] - waterDist) - pparams->vieworg[2];
		}
	}

	pparams->vieworg[2] += waterOffset;
	
	V_CalcViewRoll ( pparams );
	
	V_AddIdle ( pparams );

	// offsets
	angles = pparams->cl_viewangles;

	AngleVectors ( angles, pparams->forward, pparams->right, pparams->up );

	// don't allow cheats in multiplayer
	if ( pparams->maxclients <= 1 )
	{
		for ( i=0 ; i<3 ; i++ )
		{
			pparams->vieworg[i] += scr_ofsx->value*pparams->forward[i] + scr_ofsy->value*pparams->right[i] + scr_ofsz->value*pparams->up[i];
		}
	}
	
	// Treating cam_ofs[2] as the distance
	if( CL_IsThirdPerson() )
	{
		Vector ofs;

		ofs[0] = ofs[1] = ofs[2] = 0.0;

		CL_CameraOffset( ofs );

		camAngles = ofs;
		camAngles[ ROLL ]	= 0;

		AngleVectors( camAngles, camForward, camRight, camUp );

		for ( i = 0; i < 3; i++ )
		{
			pparams->vieworg[ i ] += -ofs[2] * camForward[ i ];
		}
	}
	
	// Give gun our viewangles
	view->angles = pparams->cl_viewangles;
	
	// set up gun position
	V_CalcGunAngle ( pparams );

	// Use predicted origin as view origin.
	view->origin = pparams->simorg;
	view->origin[2] += ( waterOffset );

	view->origin = view->origin + pparams->viewheight;

	// Let the viewmodel shake at about 10% of the amplitude
	gEngfuncs.V_ApplyShake( view->origin, view->angles, 0.9 );

	for ( i = 0; i < 3; i++ )
	{
		view->origin[ i ] += bob * 0.4 * pparams->forward[ i ];
	}
	view->origin[2] += bob;

	// throw in a little tilt.
	view->angles[YAW]   -= bob * 0.5;
	view->angles[ROLL]  -= bob * 1;
	view->angles[PITCH] -= bob * 0.3;

	// pushing the view origin down off of the same X/Z plane as the ent's origin will give the
	// gun a very nice 'shifting' effect when the player looks up/down. If there is a problem
	// with view model distortion, this may be a cause. (SJB). 
	view->origin[2] -= 1;

	// fudge position around to keep amount of weapon visible
	// roughly equal with different FOV
	if (pparams->viewsize == 110)
	{
		view->origin[2] += 1;
	}
	else if (pparams->viewsize == 100)
	{
		view->origin[2] += 2;
	}
	else if (pparams->viewsize == 90)
	{
		view->origin[2] += 1;
	}
	else if (pparams->viewsize == 80)
	{
		view->origin[2] += 0.5;
	}

	// Add in the punchangle, if any
	pparams->viewangles = pparams->viewangles + pparams->punchangle;

	// Include client side punch, too
	pparams->viewangles = pparams->viewangles + ev_punchangle;

	V_DropPunchAngle ( pparams->frametime, ev_punchangle );

	// smooth out stair step ups
#if 1
	if ( !pparams->smoothing && pparams->onground && pparams->simorg[2] - oldz > 0)
	{
		float steptime;
		
		steptime = pparams->time - lasttime;
		if (steptime < 0)
	//FIXME		I_Error ("steptime < 0");
			steptime = 0;

		oldz += steptime * 150;
		if (oldz > pparams->simorg[2])
			oldz = pparams->simorg[2];
		if (pparams->simorg[2] - oldz > 18)
			oldz = pparams->simorg[2]- 18;
		pparams->vieworg[2] += oldz - pparams->simorg[2];
		view->origin[2] += oldz - pparams->simorg[2];
	}
	else
	{
		oldz = pparams->simorg[2];
	}
#endif

	{
		static Vector lastorg;
		const Vector delta = pparams->simorg - lastorg;

		if ( delta.Length() != 0.0 )
		{
			ViewInterp.Origins[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] = pparams->simorg;
			ViewInterp.OriginTime[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] = pparams->time;
			ViewInterp.CurrentOrigin++;

			lastorg = pparams->simorg;
		}
	}

	// Smooth out whole view in multiplayer when on trains, lifts
	if ( cl_vsmoothing && cl_vsmoothing->value &&
		( pparams->smoothing && ( pparams->maxclients > 1 ) ) )
	{
		int foundidx;
		int i;
		float t;

		if ( cl_vsmoothing->value < 0.0 )
		{
			gEngfuncs.Cvar_SetValue( "cl_vsmoothing", 0.0 );
		}

		t = pparams->time - cl_vsmoothing->value;

		for ( i = 1; i < ORIGIN_MASK; i++ )
		{
			foundidx = ViewInterp.CurrentOrigin - 1 - i;
			if ( ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] <= t )
				break;
		}

		if ( i < ORIGIN_MASK &&  ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] != 0.0 )
		{
			// Interpolate
			Vector delta;
			double frac;
			double dt;
			Vector neworg;

			dt = ViewInterp.OriginTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ];
			if ( dt > 0.0 )
			{
				frac = ( t - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK] ) / dt;
				frac = min( 1.0, frac );
				delta = ViewInterp.Origins[ ( foundidx + 1 ) & ORIGIN_MASK ] - ViewInterp.Origins[ foundidx & ORIGIN_MASK ];
				VectorMA( ViewInterp.Origins[ foundidx & ORIGIN_MASK ], frac, delta, neworg );

				// Dont interpolate large changes
				if ( delta.Length() < 64 )
				{
					delta = neworg - pparams->simorg;

					pparams->simorg = pparams->simorg + delta;
					pparams->vieworg = pparams->vieworg + delta;
					view->origin = view->origin + delta;
				}
			}
		}
	}

	// Store off v_angles before munging for third person
	v_angles = pparams->viewangles;
	v_client_aimangles = pparams->cl_viewangles;
	v_lastAngles = pparams->viewangles;
//	v_cl_angles = pparams->cl_viewangles;	// keep old user mouse angles !
	if ( CL_IsThirdPerson() )
	{
		pparams->viewangles = camAngles;
		float pitch = camAngles[ 0 ];

		// Normalize angles
		if ( pitch > 180 ) 
			pitch -= 360.0;
		else if ( pitch < -180 )
			pitch += 360;

		// Player pitch is inverted
		pitch /= -3.0;

		// Slam local player's pitch value
		ent->angles[ 0 ] = pitch;
		ent->curstate.angles[ 0 ] = pitch;
		ent->prevstate.angles[ 0 ] = pitch;
		ent->latched.prevangles[ 0 ] = pitch;
	}

	// override all previous settings if the viewent isn't the client
	if ( pparams->viewentity > pparams->maxclients )
	{
		cl_entity_t *viewentity;
		viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity );
		if ( viewentity )
		{
			pparams->vieworg = viewentity->origin;
			pparams->viewangles = viewentity->angles;

			// Store off overridden viewangles
			v_angles = pparams->viewangles;
		}
	}

	lasttime = pparams->time;

	v_origin = pparams->vieworg;
}