Beispiel #1
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 #2
0
/*
==================
V_CalcRefdef

==================
*/
void
V_CalcRefdef(void)
{
    entity_t *ent, *view;
    int i;
    vec3_t forward, right, up;
    vec3_t angles;
    float bob;
    static float oldz = 0;

    V_DriftPitch();

// ent is the player model (visible when out of body)
    ent = &cl_entities[cl.viewentity];
// view is the weapon model (only visible from inside body)
    view = &cl.viewent;

// transform the view offset by the model's matrix to get the offset from
// model origin for the view
    ent->angles[YAW] = cl.viewangles[YAW];	// the model should face
    // the view dir
    ent->angles[PITCH] = -cl.viewangles[PITCH];	// the model should face
    // the view dir

    bob = V_CalcBob();

// refresh position
    VectorCopy(ent->origin, r_refdef.vieworg);
    r_refdef.vieworg[2] += cl.viewheight + bob;

// never let it sit exactly on a node line, because a water plane can
// dissapear when viewed with the eye exactly on it.
// the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis
    r_refdef.vieworg[0] += 1.0 / 32;
    r_refdef.vieworg[1] += 1.0 / 32;
    r_refdef.vieworg[2] += 1.0 / 32;

    VectorCopy(cl.viewangles, r_refdef.viewangles);
    V_CalcViewRoll();
    V_AddIdle();

// offsets
    angles[PITCH] = -ent->angles[PITCH];	// because entity pitches are
    //  actually backward
    angles[YAW] = ent->angles[YAW];
    angles[ROLL] = ent->angles[ROLL];

    AngleVectors(angles, forward, right, up);

    for (i = 0; i < 3; i++)
	r_refdef.vieworg[i] += scr_ofsx.value * forward[i]
	    + scr_ofsy.value * right[i]
	    + scr_ofsz.value * up[i];

    V_BoundOffsets();

// set up gun position
    VectorCopy(cl.viewangles, view->angles);

    CalcGunAngle();

    VectorCopy(ent->origin, view->origin);
    view->origin[2] += cl.viewheight;

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

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

    view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
    view->frame = cl.stats[STAT_WEAPONFRAME];
    view->colormap = vid.colormap;

// set up the refresh position
    VectorAdd(r_refdef.viewangles, cl.punchangle, r_refdef.viewangles);

// smooth out stair step ups
    if (cl.onground && ent->origin[2] - oldz > 0) {
	float steptime;

	steptime = cl.time - cl.oldtime;
	if (steptime < 0)
//FIXME         I_Error ("steptime < 0");
	    steptime = 0;

	oldz += steptime * 80;
	if (oldz > ent->origin[2])
	    oldz = ent->origin[2];
	if (ent->origin[2] - oldz > 12)
	    oldz = ent->origin[2] - 12;
	r_refdef.vieworg[2] += oldz - ent->origin[2];
	view->origin[2] += oldz - ent->origin[2];
    } else
	oldz = ent->origin[2];

    if (chase_active.value)
	Chase_Update();
}
Beispiel #3
0
//==========================
// V_CalcFirstPersonRefdef
//==========================
void V_CalcFirstPersonRefdef( struct ref_params_s *pparams )
{
	V_DriftPitch( pparams );

	float bob = V_CalcBob( pparams );

	pparams->vieworg = pparams->simorg;
	pparams->vieworg += pparams->viewheight;
	pparams->vieworg.z += bob;

	pparams->viewangles = pparams->cl_viewangles;

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

	V_CalcSendOrigin( pparams );

	float waterOffset = V_CalcWaterLevel( pparams );
	pparams->vieworg[2] += waterOffset;

	V_CalcViewRoll( pparams );
	V_AddIdle( pparams );

	// offsets
	AngleVectors( pparams->cl_viewangles, pparams->forward, pparams->right, pparams->up );

	cl_entity_t *view = GET_VIEWMODEL();
	Vector lastAngles = view->angles = pparams->cl_viewangles;

	V_CalcGunAngle( pparams );

	// use predicted origin as view origin.
	view->origin = pparams->simorg;      
	view->origin += pparams->viewheight;
	view->origin.z += waterOffset;

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

	view->origin += pparams->forward * bob * 0.4f;
	view->origin.z += bob;

	view->angles[PITCH] -= bob * 0.3f;
	view->angles[YAW] -= bob * 0.5f;
	view->angles[ROLL] -= bob * 1.0f;
	view->origin.z -= 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;
	}

	V_CalcViewModelLag( pparams, view->origin, view->angles, lastAngles );
		
	pparams->viewangles += pparams->punchangle;
    pparams->viewangles += ev_punchangle;

    V_DropPunchAngle(pparams->frametime,ev_punchangle);

	static float lasttime, oldz = 0;

	if( !pparams->smoothing && pparams->onground && pparams->simorg[2] - oldz > 0.0f )
	{
		float steptime;
		
		steptime = pparams->time - lasttime;
		if( steptime < 0 ) steptime = 0;

		oldz += steptime * 150.0f;

		if( oldz > pparams->simorg[2] )
			oldz = pparams->simorg[2];
		if( pparams->simorg[2] - oldz > pparams->movevars->stepsize )
			oldz = pparams->simorg[2] - pparams->movevars->stepsize;

		pparams->vieworg[2] += oldz - pparams->simorg[2];
		view->origin.z += oldz - pparams->simorg[2];
	}
	else
	{
		oldz = pparams->simorg[2];
	}

	lasttime = pparams->time;

	// smooth player view in multiplayer
	V_InterpolatePos( pparams );
}
void V_CalcRefdef (void) {
	vec3_t forward;
	float bob;
	float height_adjustment;

	V_DriftPitch ();

	bob = V_CalcBob ();
	
	height_adjustment = v_viewheight.value ? bound (-7, v_viewheight.value, 4) : V_CalcBob ();
	

	// set up the refresh position
	VectorCopy (cl.simorg, r_refdef.vieworg);

	// never let it sit exactly on a node line, because a water plane can
	// dissapear when viewed with the eye exactly on it.
	// the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis
	r_refdef.vieworg[0] += 1.0/16;
	r_refdef.vieworg[1] += 1.0/16;
	r_refdef.vieworg[2] += 1.0/16;

	// add view height
	if (view_message.flags & PF_GIB) {
		r_refdef.vieworg[2] += 8;	// gib view height
	} else if (view_message.flags & PF_DEAD && (cl.stats[STAT_HEALTH] <= 0)) {	
		r_refdef.vieworg[2] -= 16;	// corpse view height
	} else {
		// normal view height
		// Use STAT_VIEWHEIGHT in case of server support it or NQ demoplayback, if not then use default viewheight.
		r_refdef.vieworg[2] += ((cl.z_ext & Z_EXT_VIEWHEIGHT) || cls.nqdemoplayback) ? cl.stats[STAT_VIEWHEIGHT] : DEFAULT_VIEWHEIGHT;

		r_refdef.vieworg[2] += height_adjustment;

		r_refdef.vieworg[2] += bob;
		
		// smooth out stair step ups
		r_refdef.vieworg[2] += cl.crouch;
	}

	// set up refresh view angles
	VectorCopy (cl.simangles, r_refdef.viewangles);
	V_CalcViewRoll ();
	V_AddIdle ();

	if (v_gunkick.value) {
		// add weapon kick offset
		AngleVectors (r_refdef.viewangles, forward, NULL, NULL);
		VectorMA (r_refdef.vieworg, cl.punchangle, forward, r_refdef.vieworg);

		// add weapon kick angle
		r_refdef.viewangles[PITCH] += cl.punchangle * 0.5;
	}
	
	if (view_message.flags & PF_DEAD && (cl.stats[STAT_HEALTH] <= 0))
		r_refdef.viewangles[ROLL] = 80;	// dead view angle

	//VULT CAMERAS
	CameraUpdate(view_message.flags & PF_DEAD);
	V_AddViewWeapon (height_adjustment);
	
}
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;

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

	static struct model_s *savedviewmodel;

	//LRC - if this is the second pass through, then we've just drawn the sky, and now we're setting up the normal view.
	if (pparams->nextView == 1)
	{
		gHUD.m_iSkyMode = SKY_ON; //This means that an env_sky is in the level but we are drawing the normal view this time. 
		view = gEngfuncs.GetViewModel();
		view->model = savedviewmodel;
		pparams->viewangles[0] = v_angles.x;
		pparams->viewangles[1] = v_angles.y;
		pparams->viewangles[2] = v_angles.z;
		pparams->vieworg[0] = v_origin.x;
		pparams->vieworg[1] = v_origin.y;
		pparams->vieworg[2] = v_origin.z;
		pparams->nextView = 0;
	
		if (gHUD.viewFlags & 1 ) // custom view active (trigger_viewset) //AJH (copied function from below)
		{
			cl_entity_t *viewentity;
			viewentity = gEngfuncs.GetEntityByIndex( gHUD.viewEntityIndex );
			if (viewentity)
			{
				pparams->vieworg[0] = viewentity->origin[0];
				pparams->vieworg[1] = viewentity->origin[1];
				pparams->vieworg[2] = viewentity->origin[2];
				pparams->vieworg[2] = viewentity->origin[2];
				pparams->viewangles[0] = viewentity->angles[0];
				pparams->viewangles[1] = viewentity->angles[1];
				pparams->viewangles[2] = viewentity->angles[2];
				pparams->crosshairangle[PITCH] = 100; // test // ugly method to remove crosshair from screen
				
				if(gHUD.viewFlags & 8 )	//AJH Do we draw the player in the camera?
				{
					gHUD.m_iCameraMode=2;
				}
				if(gHUD.viewFlags & 4 )	//AJH Invert the x view angle again if we are using an item camera?
				{
					pparams->viewangles[0] = -viewentity->angles[0];
				}
			}
			else
			{
				gEngfuncs.Con_DPrintf( "Warning : invalid view ent index: %i\n", gHUD.viewEntityIndex );
			}
		}
		else
		{
			pparams->crosshairangle[PITCH] = 0; // test
		}

		return;
	}

	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();

	// trigger_viewset - dont show weapon model when custom view is enabled
	if (gHUD.viewFlags & 1)
		view->model = NULL;

	//LRC - don't show weapon models when we're drawing the sky.
	if (gHUD.m_iSkyMode == SKY_ON)
	{
		savedviewmodel = view->model;
		view->model = NULL;
	}

	// 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
	VectorCopy ( pparams->simorg, pparams->vieworg );
	pparams->vieworg[2] += ( bob );
	VectorAdd( pparams->vieworg, pparams->viewheight, pparams->vieworg );

	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 );

	// 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];
		}
	}	
		
	// 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 &&
		( 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 );

				}
			}
		}
	}

	// Store off v_angles before munging for third person
	v_angles = pparams->viewangles;
	v_lastAngles = pparams->viewangles;
//	v_cl_angles = pparams->cl_viewangles;	// keep old user mouse angles !
	
	// 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;

	//LRC 1.8 - clear to the fog color (if any) on the first pass
	if ( pparams->nextView == 0 )
	{
		ClearToFogColor();
	}

	//LRC 1.8 - no fog in the env_sky
	if ( gHUD.m_iSkyMode != SKY_ON_DRAWING )
	{
		RenderFog();
	}

	if (gHUD.viewFlags & 1 && gHUD.m_iSkyMode == SKY_OFF) // custom view active (trigger_viewset) //AJH (added skymode check and copied function to above)
	{
		cl_entity_t *viewentity;
		viewentity = gEngfuncs.GetEntityByIndex( gHUD.viewEntityIndex );
		if (viewentity)
		{
			pparams->vieworg[0] = viewentity->origin[0];
			pparams->vieworg[1] = viewentity->origin[1];
			pparams->vieworg[2] = viewentity->origin[2];
			pparams->vieworg[2] = viewentity->origin[2];
			pparams->viewangles[0] = viewentity->angles[0];
			pparams->viewangles[1] = viewentity->angles[1];
			pparams->viewangles[2] = viewentity->angles[2];
			pparams->crosshairangle[PITCH] = 100; // test // ugly method to remove crosshair from screen
			
			if(gHUD.viewFlags & 8 )	//AJH Do we draw the player in the camera?
			{
				gHUD.m_iCameraMode=2;
			}
			if(gHUD.viewFlags & 4 )	//AJH Invert the x view angle again if we are using an item camera?
			{
				pparams->viewangles[0] = -viewentity->angles[0];
			}
		}
		else
			gEngfuncs.Con_Printf( "Warning : invalid view ent index: %i\n", gHUD.viewEntityIndex );
	}
	else
		pparams->crosshairangle[PITCH] = 0; // test

	// LRC - override the view position if we're drawing a sky, rather than the player's view
	if (gHUD.m_iSkyMode >= SKY_ON && pparams->nextView == 0) 
	{
		gHUD.m_iSkyMode = SKY_ON_DRAWING;
		if (gHUD.m_iSkyScale == 0) //AJH No parallax (old behaviour)
	{
		pparams->vieworg[0] = gHUD.m_vecSkyPos.x;
		pparams->vieworg[1] = gHUD.m_vecSkyPos.y;
		pparams->vieworg[2] = gHUD.m_vecSkyPos.z;		
		}
		else
		{
			VectorCopy(gHUD.m_vecSkyPos + v_origin/gHUD.m_iSkyScale,pparams->vieworg);
		}
		
		if (gHUD.viewFlags & 1)//AJH (to allow skys and cameras to coexist)
		{
			cl_entity_t *viewentity;
			viewentity = gEngfuncs.GetEntityByIndex( gHUD.viewEntityIndex );
			if (viewentity)
			{
				pparams->viewangles[0] = viewentity->angles[0];
				pparams->viewangles[1] = viewentity->angles[1];
				pparams->viewangles[2] = viewentity->angles[2];
			}
			else
				gEngfuncs.Con_Printf( "Warning : invalid view ent index: %i\n", gHUD.viewEntityIndex );
		}
		
		pparams->nextView = 1;
	}
}
Beispiel #6
0
/*
==================
V_CalcRefdef
==================
*/
void V_CalcRefdef (void)
{
	vec3_t		forward;
	float		height_adjustment;
	
	height_adjustment = v_viewheight.value ? bound (-7, v_viewheight.value, 4) : V_CalcBob ();

	// set up the refresh position
	VectorCopy (cl.simorg, r_refdef2.vieworg);

	// never let it sit exactly on a node line, because a water plane can
	// dissapear when viewed with the eye exactly on it.
	// the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis
	r_refdef2.vieworg[0] += 1.0/16;
	r_refdef2.vieworg[1] += 1.0/16;
	r_refdef2.vieworg[2] += 1.0/16;

	// add view height
	if (view_message.flags & PF_GIB)
		r_refdef2.vieworg[2] += 8;	// gib view height
	else if (view_message.flags & PF_DEAD)
		r_refdef2.vieworg[2] -= 16;	// corpse view height
	else
	{
		r_refdef2.vieworg[2] += cl.viewheight;	// normal view height

		r_refdef2.vieworg[2] += height_adjustment;

		// smooth out stair step ups
		r_refdef2.vieworg[2] += cl.crouch;
	}

	if (cl.landtime) {
		const float tt = 350;
		const float lt = 90;
		const float lh = 6;
		float _landtime = 350 - (cl.time - cl.landtime) * 1000;

		if (_landtime <= 0)
			cl.landtime = 0;
		else {
			if (_landtime >= (tt - lt))
				r_refdef2.vieworg[2] -= ((tt - _landtime) / lt) * lh;
			else
				r_refdef2.vieworg[2] -= _landtime / (tt - lt) * lh;
		}
	}

	// set up refresh view angles
	VectorCopy (cl.simangles, r_refdef2.viewangles);
	V_CalcViewRoll ();
	V_AddIdle ();

	if (v_kickback.value)
	{
		if (cls.nqprotocol)
			r_refdef2.viewangles[PITCH] += cl.punchangle;
		else
		{
			// add weapon kick offset
			AngleVectors (r_refdef2.viewangles, forward, NULL, NULL);
			VectorMA (r_refdef2.vieworg, cl.punchangle, forward, r_refdef2.vieworg);

			// add weapon kick angle
			r_refdef2.viewangles[PITCH] += cl.punchangle * 0.5;
		}
	}

	if (view_message.flags & PF_DEAD)		// PF_GIB will also set PF_DEAD
		r_refdef2.viewangles[ROLL] = 80;	// dead view angle

	V_AddViewWeapon (height_adjustment);
}
Beispiel #7
0
static void
V_CalcRefdef (void)
{
	// view is the weapon model (visible only from inside body)
	entity_t   *view = &cl.viewent;
	float       bob;
	static float oldz = 0;
	int         i;
	vec3_t      forward, right, up;
	vec_t      *origin = cl.simorg;
	vec_t      *viewangles = cl.simangles;

	V_DriftPitch ();

	bob = V_CalcBob ();

	// refresh position
	VectorCopy (origin, r_data->refdef->vieworg);
	r_data->refdef->vieworg[2] += cl.viewheight + bob;

	// never let it sit exactly on a node line, because a water plane can
	// disappear when viewed with the eye exactly on it.
	// server protocol specifies to only 1/8 pixel, so add 1/16 in each axis
	r_data->refdef->vieworg[0] += 1.0 / 16;
	r_data->refdef->vieworg[1] += 1.0 / 16;
	r_data->refdef->vieworg[2] += 1.0 / 16;

	VectorCopy (viewangles, r_data->refdef->viewangles);
	V_CalcViewRoll ();
	V_AddIdle ();

	// offsets
	AngleVectors (viewangles, forward, right, up);

	// don't allow cheats in multiplayer
	// FIXME check for dead
	if (cl.maxclients == 1) {
		for (i = 0; i < 3; i++) {
			r_data->refdef->vieworg[i] += scr_ofsx->value * forward[i] +
				scr_ofsy->value * right[i] +
				scr_ofsz->value * up[i];
		}
	}

	V_BoundOffsets ();

	// set up gun position
	VectorCopy (viewangles, view->angles);

	CalcGunAngle ();

	VectorCopy (origin, view->origin);
	view->origin[2] += cl.viewheight;

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

	// fudge position around to keep amount of weapon visible
	// roughly equal with different FOV
	if (hud_sbar->int_val == 0 && r_data->scr_viewsize->int_val >= 100)
		;
	else if (r_data->scr_viewsize->int_val == 110)
		view->origin[2] += 1;
	else if (r_data->scr_viewsize->int_val == 100)
		view->origin[2] += 2;
	else if (r_data->scr_viewsize->int_val == 90)
		view->origin[2] += 1;
	else if (r_data->scr_viewsize->int_val == 80)
		view->origin[2] += 0.5;

	if (view_message->pls.flags & (PF_GIB | PF_DEAD))
		view->model = NULL;
	else
		view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
	view->frame = view_message->pls.weaponframe;
	view->skin = 0;

	// set up the refresh position
	VectorAdd (r_data->refdef->viewangles, cl.punchangle,
			   r_data->refdef->viewangles);

	// smooth out stair step ups
	if ((cl.onground != -1) && (origin[2] - oldz > 0)) {
		float       steptime;

		steptime = host_frametime;

		oldz += steptime * 80;
		if (oldz > origin[2])
			oldz = origin[2];
		if (origin[2] - oldz > 12)
			oldz = origin[2] - 12;
		r_data->refdef->vieworg[2] += oldz - origin[2];
		view->origin[2] += oldz - origin[2];
	} else
		oldz = origin[2];

	if (cl.chase && chase_active->int_val)
		Chase_Update ();

	CL_TransformEntity (view, view->angles, true);
}
Beispiel #8
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;
}
Beispiel #9
0
/*
==================
V_CalcRefdef
==================
*/
void V_CalcRefdef (void)
{
	entity_t	*ent, *view;
	int			i;
	vec3_t		forward, right, up;
	vec3_t		angles;
	float		bob;
	static float oldz = 0;
	static vec3_t punch = {0,0,0}; //johnfitz -- v_gunkick
	float delta; //johnfitz -- v_gunkick

	V_DriftPitch ();

// ent is the player model (visible when out of body)
	ent = &cl_entities[cl.viewentity];
// view is the weapon model (only visible from inside body)
	view = &cl.viewent;


// transform the view offset by the model's matrix to get the offset from
// model origin for the view
	ent->angles[YAW] = cl.viewangles[YAW];	// the model should face the view dir
	ent->angles[PITCH] = -cl.viewangles[PITCH];	// the model should face the view dir

	bob = V_CalcBob ();

// refresh position
	VectorCopy (ent->origin, r_refdef.vieworg);
	r_refdef.vieworg[2] += cl.viewheight + bob;

// never let it sit exactly on a node line, because a water plane can
// dissapear when viewed with the eye exactly on it.
// the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis
	r_refdef.vieworg[0] += 1.0/32;
	r_refdef.vieworg[1] += 1.0/32;
	r_refdef.vieworg[2] += 1.0/32;

	VectorCopy (cl.viewangles, r_refdef.viewangles);
	V_CalcViewRoll ();
	V_AddIdle ();

// offsets
	angles[PITCH] = -ent->angles[PITCH]; // because entity pitches are actually backward
	angles[YAW] = ent->angles[YAW];
	angles[ROLL] = ent->angles[ROLL];

	AngleVectors (angles, forward, right, up);

	if (cl.maxclients <= 1) //johnfitz -- moved cheat-protection here from V_RenderView
		for (i=0 ; i<3 ; i++)
			r_refdef.vieworg[i] += scr_ofsx.value*forward[i] + scr_ofsy.value*right[i] + scr_ofsz.value*up[i];

	V_BoundOffsets ();

// set up gun position
	VectorCopy (cl.viewangles, view->angles);

	CalcGunAngle ();

	VectorCopy (ent->origin, view->origin);
	view->origin[2] += cl.viewheight;

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

	//johnfitz -- removed all gun position fudging code (was used to keep gun from getting covered by sbar)
	//MarkV -- restored this with r_viewmodel_quake cvar
	if (r_viewmodel_quake.value)
	{
		if (scr_viewsize.value == 110)
			view->origin[2] += 1;
		else if (scr_viewsize.value == 100)
			view->origin[2] += 2;
		else if (scr_viewsize.value == 90)
			view->origin[2] += 1;
		else if (scr_viewsize.value == 80)
			view->origin[2] += 0.5;
	}

	view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
	view->frame = cl.stats[STAT_WEAPONFRAME];
	view->colormap = vid.colormap;

//johnfitz -- v_gunkick
	if (v_gunkick.value == 1) //original quake kick
		VectorAdd (r_refdef.viewangles, cl.punchangle, r_refdef.viewangles);
	if (v_gunkick.value == 2) //lerped kick
	{
		for (i=0; i<3; i++)
			if (punch[i] != v_punchangles[0][i])
			{
				//speed determined by how far we need to lerp in 1/10th of a second
				delta = (v_punchangles[0][i]-v_punchangles[1][i]) * host_frametime * 10;

				if (delta > 0)
					punch[i] = q_min(punch[i]+delta, v_punchangles[0][i]);
				else if (delta < 0)
					punch[i] = q_max(punch[i]+delta, v_punchangles[0][i]);
			}

		VectorAdd (r_refdef.viewangles, punch, r_refdef.viewangles);
	}
//johnfitz

// smooth out stair step ups
	if (!noclip_anglehack && cl.onground && ent->origin[2] - oldz > 0) //johnfitz -- added exception for noclip
	//FIXME: noclip_anglehack is set on the server, so in a nonlocal game this won't work.
	{
		float steptime;

		steptime = cl.time - cl.oldtime;
		if (steptime < 0)
			//FIXME	I_Error ("steptime < 0");
			steptime = 0;

		oldz += steptime * 80;
		if (oldz > ent->origin[2])
			oldz = ent->origin[2];
		if (ent->origin[2] - oldz > 12)
			oldz = ent->origin[2] - 12;
		r_refdef.vieworg[2] += oldz - ent->origin[2];
		view->origin[2] += oldz - ent->origin[2];
	}
	else
		oldz = ent->origin[2];

	if (chase_active.value)
		Chase_UpdateForDrawing (); //johnfitz
}