Esempio n. 1
0
static void NQD_LerpPlayerinfo (float f)
{
	if (cl.intermission) {
		// just stay there
		return;
	}

	if (nq_player_teleported) {
		VectorCopy (nq_mvelocity[0], cl.simvel);
		VectorCopy (nq_mviewangles[0], cl.viewangles);
		if (cls.demoplayback)
			VectorCopy (nq_mviewangles[0], cl.simangles);
		return;
	}

	LerpVector (nq_mvelocity[1], nq_mvelocity[0], f, cl.simvel);
	if (cls.demoplayback) {
		LerpAngles (nq_mviewangles[1], nq_mviewangles[0], f, cl.simangles);
		VectorCopy (cl.simangles, cl.viewangles);
	}
}
Esempio n. 2
0
// for .qwd demo playback
static void CL_LerpMove (float msgtime)
{
	static int		lastsequence = 0;
	static vec3_t	lerp_angles[3];
	static vec3_t	lerp_origin[3];
	static float	lerp_times[3];
	static qbool	nolerp[2];
	static float	demo_latency = 0.01;
	float	frac;
	float	simtime;
	int		i;
	int		from, to;

	if (cl_nolerp.value)
		return;

	if (cls.netchan.outgoing_sequence < lastsequence) {
		// reset
		lastsequence = -1;
		lerp_times[0] = -1;
		demo_latency = 0.01;
	}

	if (cls.netchan.outgoing_sequence > lastsequence) {
		lastsequence = cls.netchan.outgoing_sequence;
		// move along
		lerp_times[2] = lerp_times[1];
		lerp_times[1] = lerp_times[0];
		lerp_times[0] = msgtime;

		VectorCopy (lerp_origin[1], lerp_origin[2]);
		VectorCopy (lerp_origin[0], lerp_origin[1]);
		VectorCopy (cl.simorg, lerp_origin[0]);

		VectorCopy (lerp_angles[1], lerp_angles[2]);
		VectorCopy (lerp_angles[0], lerp_angles[1]);
		VectorCopy (cl.simangles, lerp_angles[0]);

		nolerp[1] = nolerp[0];
		nolerp[0] = false;
		for (i = 0; i < 3; i++)
			if (fabs(lerp_origin[0][i] - lerp_origin[1][i]) > 40)
				break;
		if (i < 3)
			nolerp[0] = true;	// a teleport or something
	}

	simtime = cls.realtime - demo_latency;

	// adjust latency
	if (simtime > lerp_times[0]) {
		// Com_DPrintf ("HIGH clamp\n");
		demo_latency = cls.realtime - lerp_times[0];
	}
	else if (simtime < lerp_times[2]) {
		// Com_DPrintf ("   low clamp\n");
		demo_latency = cls.realtime - lerp_times[2];
	} else {
		// drift towards ideal latency
		float ideal_latency = (lerp_times[0] - lerp_times[2]) * 0.6;
		if (demo_latency > ideal_latency)
			demo_latency = max(demo_latency - cls.frametime * 0.1, ideal_latency);
	}

	// decide where to lerp from
	if (simtime > lerp_times[1]) {
		from = 1;
		to = 0;
	} else {
		from = 2;
		to = 1;
	}

	if (nolerp[to])
		return;

	frac = (simtime - lerp_times[from]) / (lerp_times[to] - lerp_times[from]);
	frac = bound (0, frac, 1);

	LerpVector (lerp_origin[from], lerp_origin[to], frac, cl.simorg);
	LerpAngles (lerp_angles[from], lerp_angles[to], frac, cl.simangles);
}
Esempio n. 3
0
void NQD_LinkEntities (void)
{
	entity_t			ent;
	centity_t			*cent;
	entity_state_t		*state;
	float				f;
	struct model_s		*model;
	int					modelflags;
	vec3_t				cur_origin;
	vec3_t				old_origin;
	float				autorotate;
	int					i;
	int					num;

	f = NQD_LerpPoint ();

	NQD_LerpPlayerinfo (f);

	autorotate = anglemod (100*cl.time);

	memset (&ent, 0, sizeof(ent));

	for (num = 1; num < nq_num_entities; num++)
	{
		cent = &cl_entities[num];
		state = &cent->current;

		if (cent->lastframe != cl_entframecount)
			continue;		// not present in this frame

		MSG_UnpackOrigin (state->s_origin, cur_origin);

		if (state->effects & EF_BRIGHTFIELD)
			CL_EntityParticles (cur_origin);

		// spawn light flashes, even ones coming from invisible objects
		if (state->effects & EF_MUZZLEFLASH) {
			vec3_t		angles, forward;
			cdlight_t	*dl;

			dl = CL_AllocDlight (-num);
			MSG_UnpackAngles (state->s_angles, angles);
			AngleVectors (angles, forward, NULL, NULL);
			VectorMA (cur_origin, 18, forward, dl->origin);
			dl->origin[2] += 16;
			dl->radius = 200 + (rand()&31);
			dl->minlight = 32;
			dl->die = cl.time + 0.1;
			dl->type = lt_muzzleflash;
		}
		if (state->effects & EF_BRIGHTLIGHT) {
			if (state->modelindex != cl_playerindex || r_powerupglow.value) {
				vec3_t	tmp;
				VectorCopy (cur_origin, tmp);
				tmp[2] += 16;
				V_AddDlight (state->number, tmp, 400 + (rand()&31), 0, lt_default);
			}
		}
		if (state->effects & EF_DIMLIGHT)
			if (state->modelindex != cl_playerindex || r_powerupglow.value)
				V_AddDlight (state->number, cur_origin, 200 + (rand()&31), 0, lt_default);

		// if set to invisible, skip
		if (!state->modelindex)
			continue;

		cent->current = *state;

		ent.model = model = cl.model_precache[state->modelindex];
		if (!model)
			Host_Error ("CL_LinkPacketEntities: bad modelindex");

		if (cl_r2g.value && cl_grenadeindex != -1)
			if (state->modelindex == cl_rocketindex)
				ent.model = cl.model_precache[cl_grenadeindex];

		modelflags = R_ModelFlags (model);

		// rotate binary objects locally
		if (modelflags & MF_ROTATE)
		{
			ent.angles[0] = 0;
			ent.angles[1] = autorotate;
			ent.angles[2] = 0;
		}
		else
		{
			vec3_t	old, cur;

			MSG_UnpackAngles (cent->current.s_angles, old);
			MSG_UnpackAngles (cent->previous.s_angles, cur);
			LerpAngles (old, cur, f, ent.angles);
		}

if (num == nq_viewentity) {
extern float nq_speed;
float f;
nq_speed = 0;
	for (i = 0; i < 3; i++) {
		f = (cent->current.s_origin[i] - cent->previous.s_origin[i]) * 0.125;
		nq_speed += f * f;
	}
if (nq_speed) nq_speed = sqrt(nq_speed);
nq_speed /= nq_mtime[0] - nq_mtime[1];

}

		// calculate origin
		for (i = 0; i < 3; i++)
		{
			if (abs(cent->current.s_origin[i] - cent->previous.s_origin[i]) > 128 * 8) {
				// teleport or something, don't lerp
				VectorCopy (cur_origin, ent.origin);
				if (num == nq_viewentity)
					nq_player_teleported = true;
				break;
			}
			ent.origin[i] = cent->previous.s_origin[i] * 0.125 + 
				f * (cur_origin[i] - cent->previous.s_origin[i] * 0.125);
		}

		if (num == nq_viewentity) {
			VectorCopy (ent.origin, cent->trail_origin);	// FIXME?
			continue;			// player entity
		}

		if (cl_deadbodyfilter.value && state->modelindex == cl_playerindex
			&& ( (i=state->frame)==49 || i==60 || i==69 || i==84 || i==93 || i==102) )
			continue;

		if (cl_gibfilter.value && cl.modelinfos[state->modelindex] == mi_gib)
			continue;

		// set colormap
		if (state->colormap && state->colormap <= MAX_CLIENTS
			&& state->modelindex == cl_playerindex
		)
			ent.colormap = state->colormap;
		else
			ent.colormap = 0;

		// set skin
		ent.skinnum = state->skinnum;
		
		// set frame
		ent.frame = state->frame;

		// add automatic particle trails
		if ((modelflags & ~MF_ROTATE))
		{
			if (false /*cl_entframecount == 1 || cent->lastframe != cl_entframecount-1*/)
			{	// not in last message
				VectorCopy (ent.origin, old_origin);
			}
			else
			{
				VectorCopy (cent->trail_origin, old_origin);

				for (i=0 ; i<3 ; i++)
					if ( abs(old_origin[i] - ent.origin[i]) > 128)
					{	// no trail if too far
						VectorCopy (ent.origin, old_origin);
						break;
					}
			}

			if (modelflags & MF_ROCKET)
			{
				if (r_rockettrail.value) {
					if (r_rockettrail.value == 2)
						CL_GrenadeTrail (old_origin, ent.origin, cent->trail_origin);
					else
						CL_RocketTrail (old_origin, ent.origin, cent->trail_origin);
				} else
					VectorCopy (ent.origin, cent->trail_origin);

				if (r_rocketlight.value)
					CL_NewDlight (state->number, ent.origin, 200, 0.1, lt_rocket);
			}
			else if (modelflags & MF_GRENADE && r_grenadetrail.value)
				CL_GrenadeTrail (old_origin, ent.origin, cent->trail_origin);
			else if (modelflags & MF_GIB)
				CL_BloodTrail (old_origin, ent.origin, cent->trail_origin);
			else if (modelflags & MF_ZOMGIB)
				CL_SlightBloodTrail (old_origin, ent.origin, cent->trail_origin);
			else if (modelflags & MF_TRACER)
				CL_TracerTrail (old_origin, ent.origin, cent->trail_origin, 52);
			else if (modelflags & MF_TRACER2)
				CL_TracerTrail (old_origin, ent.origin, cent->trail_origin, 230);
			else if (modelflags & MF_TRACER3)
				CL_VoorTrail (old_origin, ent.origin, cent->trail_origin);
		}

		cent->lastframe = cl_entframecount;
		V_AddEntity (&ent);
	}

	if (nq_viewentity == 0)
		Host_Error ("viewentity == 0");
	VectorCopy (cl_entities[nq_viewentity].trail_origin, cl.simorg);
}
Esempio n. 4
0
static void demoFrameInterpolate( demoFrame_t frames[], int frameCount, int index ) {
	int i;
	demoFrame_t *workFrame;

	workFrame = &frames[index % frameCount];
//	return;

	for (i=0; i<MAX_CLIENTS; i++) {
		entityState_t *workEntity;
		workEntity = &workFrame->entities[i];
		if (workEntity->number != ENTITYNUM_NONE && !workFrame->entityData[i]) {
			int m;
			demoFrame_t *prevFrame, *nextFrame;
			prevFrame = nextFrame = 0;
			for (m = index - 1; (m > (index - frameCount)) && m >0 ; m--) {
				demoFrame_t *testFrame = &frames[ m % frameCount];
				if ( !testFrame->entityData[i])
					continue;
				if (!testFrame->serverTime || testFrame->serverTime >= workFrame->serverTime)
					break;
				if ( testFrame->entities[i].number != i)
					break;
				if ( (testFrame->entities[i].eFlags ^ workEntity->eFlags) & EF_TELEPORT_BIT )
					break;
				prevFrame = testFrame;
				break;
			}
			for (m = index + 1; (m < (index + frameCount)); m++) {
				demoFrame_t *testFrame = &frames[ m % frameCount];
				if ( !testFrame->entityData[i])
					continue;
				if (!testFrame->serverTime || testFrame->serverTime <= workFrame->serverTime)
					break;
				if ( testFrame->entities[i].number != i)
					break;
				if ( (testFrame->entities[i].eFlags ^ workEntity->eFlags) & EF_TELEPORT_BIT )
					break;
				nextFrame = testFrame;
				break;
			}
			if (prevFrame && nextFrame) {
				const entityState_t *prevEntity = &prevFrame->entities[i];
				const entityState_t *nextEntity = &nextFrame->entities[i];
				float lerp;
				int posDelta;
				float posLerp;
				int	 prevTime, nextTime;
                  
				prevTime = prevFrame->serverTime;
				nextTime = nextFrame->serverTime;
				lerp = (workFrame->serverTime - prevTime) / (float)( nextTime - prevTime );
				posDelta = nextEntity->pos.trTime - prevEntity->pos.trTime;
				if ( posDelta ) {
					workEntity->pos.trTime = prevEntity->pos.trTime + posDelta * lerp;
					posLerp = (workEntity->pos.trTime - prevEntity->pos.trTime) / (float) posDelta;
				} else {
					posLerp = lerp;
				}
				LerpOrigin( prevEntity->pos.trBase, nextEntity->pos.trBase, workEntity->pos.trBase, posLerp );
				LerpOrigin( prevEntity->pos.trDelta, nextEntity->pos.trDelta, workEntity->pos.trDelta, posLerp );

				LerpAngles( prevEntity->apos.trBase, nextEntity->apos.trBase, workEntity->apos.trBase, lerp );
			}
		}
	}
}