예제 #1
0
파일: view.cpp 프로젝트: janisl/jlquake
static void VQH_CalcRefdef( qwplayer_state_t* qwViewMessage, hwplayer_state_t* hwViewMessage ) {
	static float oldz = 0;

	if ( !( GGameType & GAME_Hexen2 ) || !cl.h2_v.cameramode ) {
		VQH_DriftPitch( qwViewMessage, hwViewMessage );
		if ( GGameType & GAME_Hexen2 ) {
			VH2_DriftRoll( hwViewMessage );
		}
	}

	float bob = VQH_CalcBob();

	// ent is the player model (visible when out of body)
	q1entity_t* q1ent;
	h2entity_t* h2ent;
	if ( GGameType & GAME_QuakeWorld ) {
		// refresh position from simulated origin
		VectorCopy( cl.qh_simorg, cl.refdef.vieworg );
	} else if ( GGameType & GAME_Quake ) {
		q1ent = &clq1_entities[ cl.viewentity ];

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

		// refresh position
		VectorCopy( q1ent->state.origin, cl.refdef.vieworg );

		cl.refdef.vieworg[ 2 ] += cl.qh_viewheight;
	} else if ( GGameType & GAME_HexenWorld ) {
		// refresh position from simulated origin
		VectorCopy( cl.qh_simorg, cl.refdef.vieworg );
	} else {
		h2ent = &h2cl_entities[ cl.viewentity ];

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

		// refresh position
		VectorCopy( h2ent->state.origin, cl.refdef.vieworg );

		cl.refdef.vieworg[ 2 ] += cl.qh_viewheight;
	}

	cl.refdef.vieworg[ 2 ] += 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/8 pixel, so add 1/16 in each axis
	cl.refdef.vieworg[ 0 ] += 1.0 / 16;
	cl.refdef.vieworg[ 1 ] += 1.0 / 16;
	cl.refdef.vieworg[ 2 ] += 1.0 / 16;

	vec3_t viewangles;
	if ( GGameType & ( GAME_QuakeWorld | GAME_HexenWorld ) ) {
		VectorCopy( cl.qh_simangles, viewangles );
	} else {
		VectorCopy( cl.viewangles, viewangles );
	}
	VQH_CalcViewRoll( viewangles );
	VQH_AddIdle( viewangles );

	vec3_t forward, right, up;
	if ( GGameType & GAME_QuakeWorld ) {
		if ( qwViewMessage->flags & QWPF_GIB ) {
			cl.refdef.vieworg[ 2 ] += 8;	// gib view height
		} else if ( qwViewMessage->flags & QWPF_DEAD ) {
			cl.refdef.vieworg[ 2 ] -= 16;	// corpse view height
		} else {
			cl.refdef.vieworg[ 2 ] += 22;	// view height
		}
		if ( qwViewMessage->flags & QWPF_DEAD ) {		// QWPF_GIB will also set QWPF_DEAD
			viewangles[ ROLL ] = 80;	// dead view angle
		}

		// offsets
		AngleVectors( cl.qh_simangles, forward, right, up );
	} else if ( GGameType & GAME_HexenWorld ) {
		if ( cl.qh_spectator ) {
			cl.refdef.vieworg[ 2 ] += 50;	// view height
		} else {
			if ( hwViewMessage->flags & HWPF_CROUCH ) {
				cl.refdef.vieworg[ 2 ] += 24;	// gib view height
			} else if ( hwViewMessage->flags & HWPF_DEAD ) {
				cl.refdef.vieworg[ 2 ] += 8;	// corpse view height
			} else {
				cl.refdef.vieworg[ 2 ] += 50;	// view height

			}
			if ( hwViewMessage->flags & HWPF_DEAD ) {		// PF_GIB will also set HWPF_DEAD
				viewangles[ ROLL ] = 80;	// dead view angle
			}
		}

		// offsets
		AngleVectors( cl.qh_simangles, forward, right, up );
	} else if ( GGameType & GAME_Quake ) {
		// offsets
		vec3_t angles;
		angles[ PITCH ] = -q1ent->state.angles[ PITCH ];	// because entity pitches are actually backward
		angles[ YAW ] = q1ent->state.angles[ YAW ];
		angles[ ROLL ] = q1ent->state.angles[ ROLL ];

		AngleVectors( angles, forward, right, up );

		VQH_BoundOffsets();
	} else {
		// offsets
		vec3_t angles;
		angles[ PITCH ] = -h2ent->state.angles[ PITCH ];	// because entity pitches are actually backward
		angles[ YAW ] = h2ent->state.angles[ YAW ];
		angles[ ROLL ] = h2ent->state.angles[ ROLL ];

		AngleVectors( angles, forward, right, up );

		VQH_BoundOffsets();
	}

	// view is the weapon model (only visible from inside body)
	q1entity_t* q1view;
	h2entity_t* h2view;
	if ( GGameType & GAME_Quake ) {
		q1view = &cl.q1_viewent;

		// set up gun position
		if ( GGameType & GAME_QuakeWorld ) {
			VectorCopy( cl.qh_simangles, q1view->state.angles );
		} else {
			VectorCopy( cl.viewangles, q1view->state.angles );
		}

		VQH_CalcGunAngle( viewangles );

		if ( GGameType & GAME_QuakeWorld ) {
			VectorCopy( cl.qh_simorg, q1view->state.origin );
			q1view->state.origin[ 2 ] += 22;
		} else {
			VectorCopy( q1ent->state.origin, q1view->state.origin );
			q1view->state.origin[ 2 ] += cl.qh_viewheight;
		}

		for ( int i = 0; i < 3; i++ ) {
			q1view->state.origin[ i ] += forward[ i ] * bob * 0.4;
		}
		q1view->state.origin[ 2 ] += bob;

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

		if ( GGameType & GAME_QuakeWorld ) {
			if ( qwViewMessage->flags & ( QWPF_GIB | QWPF_DEAD ) ) {
				q1view->state.modelindex = 0;
			} else {
				q1view->state.modelindex = cl.qh_stats[ Q1STAT_WEAPON ];
			}
			q1view->state.frame = qwViewMessage->weaponframe;
		} else {
			q1view->state.modelindex = cl.qh_stats[ Q1STAT_WEAPON ];
			q1view->state.frame = cl.qh_stats[ Q1STAT_WEAPONFRAME ];
			q1view->state.colormap = 0;
		}
	} else {
		h2view = &cl.h2_viewent;

		// set up gun position
		if ( GGameType & GAME_HexenWorld ) {
			VectorCopy( cl.qh_simangles, h2view->state.angles );
		} else {
			VectorCopy( cl.viewangles, h2view->state.angles );
		}

		VQH_CalcGunAngle( viewangles );

		if ( GGameType & GAME_HexenWorld ) {
			VectorCopy( cl.refdef.vieworg, h2view->state.origin );
		} else {
			VectorCopy( h2ent->state.origin, h2view->state.origin );
			h2view->state.origin[ 2 ] += cl.qh_viewheight;
		}

		for ( int i = 0; i < 3; i++ ) {
			h2view->state.origin[ i ] += forward[ i ] * bob * 0.4;
		}
		if ( !( GGameType & GAME_HexenWorld ) ) {
			h2view->state.origin[ 2 ] += bob;
		}

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

		if ( GGameType & GAME_HexenWorld ) {
			if ( hwViewMessage->flags & ( HWPF_DEAD ) ) {
				h2view->state.modelindex = 0;
			} else {
				h2view->state.modelindex = cl.qh_stats[ Q1STAT_WEAPON ];
			}
			h2view->state.frame = hwViewMessage->weaponframe;

			// Place weapon in powered up mode
			if ( ( cl.hw_frames[ clc.netchan.incomingSequence & UPDATE_MASK_HW ].playerstate[ cl.playernum ].drawflags & H2MLS_MASKIN ) == H2MLS_POWERMODE ) {
				h2view->state.drawflags = ( h2view->state.drawflags & H2MLS_MASKOUT ) | H2MLS_POWERMODE;
			} else {
				h2view->state.drawflags = ( h2view->state.drawflags & H2MLS_MASKOUT ) | 0;
			}
		} else {
			h2view->state.modelindex = cl.qh_stats[ Q1STAT_WEAPON ];
			h2view->state.frame = cl.qh_stats[ Q1STAT_WEAPONFRAME ];

			// Place weapon in powered up mode
			if ( ( h2ent->state.drawflags & H2MLS_MASKIN ) == H2MLS_POWERMODE ) {
				h2view->state.drawflags = ( h2view->state.drawflags & H2MLS_MASKOUT ) | H2MLS_POWERMODE;
			} else {
				h2view->state.drawflags = ( h2view->state.drawflags & H2MLS_MASKOUT ) | 0;
			}
		}
	}

	// set up the refresh position
	if ( GGameType & ( GAME_QuakeWorld | GAME_HexenWorld ) ) {
		viewangles[ PITCH ] += cl.qh_punchangle;
	} else {
		VectorAdd( viewangles, cl.qh_punchangles, viewangles );
	}
	AnglesToAxis( viewangles, cl.refdef.viewaxis );

	bool onGround;
	float currentZ;
	if ( GGameType & GAME_QuakeWorld ) {
		onGround = qwViewMessage->onground != -1;
		currentZ = cl.qh_simorg[ 2 ];
	} else if ( GGameType & GAME_Quake ) {
		onGround = cl.qh_onground;
		currentZ = q1ent->state.origin[ 2 ];
	} else if ( GGameType & GAME_HexenWorld ) {
		onGround = hwViewMessage->onground != -1;
		currentZ = cl.qh_simorg[ 2 ];
	} else {
		onGround = cl.qh_onground;
		currentZ = h2ent->state.origin[ 2 ];
	}

	// smooth out stair step ups
	if ( onGround && currentZ - oldz > 0 ) {
		float steptime = cls.frametime * 0.001;

		oldz += steptime * 80;
		if ( oldz > currentZ ) {
			oldz = currentZ;
		}
		if ( currentZ - oldz > 12 ) {
			oldz = currentZ - 12;
		}
		cl.refdef.vieworg[ 2 ] += oldz - currentZ;
		if ( GGameType & GAME_Hexen2 ) {
			h2view->state.origin[ 2 ] += oldz - currentZ;
		} else {
			q1view->state.origin[ 2 ] += oldz - currentZ;
		}
	} else {
		oldz = currentZ;
	}

	if ( !( GGameType & ( GAME_QuakeWorld | GAME_HexenWorld ) ) && chase_active->value ) {
		Chase_Update();
	}
}
예제 #2
0
파일: view.c 프로젝트: CatalystG/tyrquake
/*
==================
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();
}
예제 #3
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);
}