コード例 #1
0
ファイル: cg_view.c プロジェクト: lepe/trem-gpp-bots
/*
===============
CG_OffsetFirstPersonView

===============
*/
void CG_OffsetFirstPersonView( void )
{
  float         *origin;
  float         *angles;
  float         bob;
  float         ratio;
  float         delta;
  float         speed;
  float         f;
  vec3_t        predictedVelocity;
  int           timeDelta;
  float         bob2;
  vec3_t        normal, baseOrigin;
  playerState_t *ps = &cg.predictedPlayerState;

  BG_GetClientNormal( ps, normal );

  if( cg.snap->ps.pm_type == PM_INTERMISSION )
    return;

  origin = cg.refdef.vieworg;
  angles = cg.refdefViewAngles;

  VectorCopy( origin, baseOrigin );

  // if dead, fix the angle and don't add any kick
  if( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 )
  {
    angles[ ROLL ] = 40;
    angles[ PITCH ] = -15;
    angles[ YAW ] = cg.snap->ps.stats[ STAT_VIEWLOCK ];
    origin[ 2 ] += cg.predictedPlayerState.viewheight;
    return;
  }
  // camera shake effect
  else if( cg.snap->ps.stats[ STAT_SHAKE ] > 0 )
  {
    float fac;

    fac = (float) cg.snap->ps.stats[ STAT_SHAKE ] *
          cg_cameraShakeMagnitude.value * 0.15f;

    angles[ 0 ] += crandom() * fac;
    angles[ 1 ] += crandom() * fac;
    angles[ 2 ] += crandom() * fac;
  }

  // add angles based on damage kick
  if( cg.damageTime )
  {
    ratio = cg.time - cg.damageTime;
    if( ratio < DAMAGE_DEFLECT_TIME )
    {
      ratio /= DAMAGE_DEFLECT_TIME;
      angles[ PITCH ] += ratio * cg.v_dmg_pitch;
      angles[ ROLL ] += ratio * cg.v_dmg_roll;
    }
    else
    {
      ratio = 1.0 - ( ratio - DAMAGE_DEFLECT_TIME ) / DAMAGE_RETURN_TIME;
      if( ratio > 0 )
      {
        angles[ PITCH ] += ratio * cg.v_dmg_pitch;
        angles[ ROLL ] += ratio * cg.v_dmg_roll;
      }
    }
  }

  // add pitch based on fall kick
#if 0
  ratio = ( cg.time - cg.landTime) / FALL_TIME;
  if (ratio < 0)
    ratio = 0;
  angles[PITCH] += ratio * cg.fall_value;
#endif

  // add angles based on velocity
  VectorCopy( cg.predictedPlayerState.velocity, predictedVelocity );

  delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 0 ] );
  angles[ PITCH ] += delta * cg_runpitch.value;

  delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 1 ] );
  angles[ ROLL ] -= delta * cg_runroll.value;

  // add angles based on bob
  // bob amount is class dependant

  if( cg.snap->ps.persistant[ PERS_SPECSTATE ] != SPECTATOR_NOT )
    bob2 = 0.0f;
  else
    bob2 = BG_Class( cg.predictedPlayerState.stats[ STAT_CLASS ] )->bob;


#define LEVEL4_FEEDBACK  10.0f

  //give a charging player some feedback
  if( ps->weapon == WP_ALEVEL4 )
  {
    if( ps->stats[ STAT_MISC ] > 0 )
    {
      float fraction = (float)ps->stats[ STAT_MISC ] /
                       LEVEL4_TRAMPLE_CHARGE_MAX;

      if( fraction > 1.0f )
        fraction = 1.0f;

      bob2 *= ( 1.0f + fraction * LEVEL4_FEEDBACK );
    }
  }

  if( bob2 != 0.0f )
  {
    // make sure the bob is visible even at low speeds
    speed = cg.xyspeed > 200 ? cg.xyspeed : 200;

    delta = cg.bobfracsin * ( bob2 ) * speed;
    if( cg.predictedPlayerState.pm_flags & PMF_DUCKED )
      delta *= 3;   // crouching

    angles[ PITCH ] += delta;
    delta = cg.bobfracsin * ( bob2 ) * speed;
    if( cg.predictedPlayerState.pm_flags & PMF_DUCKED )
      delta *= 3;   // crouching accentuates roll

    if( cg.bobcycle & 1 )
      delta = -delta;

    angles[ ROLL ] += delta;
  }

#define LEVEL3_FEEDBACK  20.0f

  //provide some feedback for pouncing
  if( ( cg.predictedPlayerState.weapon == WP_ALEVEL3 ||
        cg.predictedPlayerState.weapon == WP_ALEVEL3_UPG ) &&
      cg.predictedPlayerState.stats[ STAT_MISC ] > 0 )
  {
    float fraction1, fraction2;
    vec3_t forward;

    AngleVectors( angles, forward, NULL, NULL );
    VectorNormalize( forward );

    fraction1 = (float)cg.predictedPlayerState.stats[ STAT_MISC ] /
                LEVEL3_POUNCE_TIME_UPG;
    if( fraction1 > 1.0f )
      fraction1 = 1.0f;

    fraction2 = -sin( fraction1 * M_PI / 2 );

    VectorMA( origin, LEVEL3_FEEDBACK * fraction2, forward, origin );
  }

#define STRUGGLE_DIST 5.0f
#define STRUGGLE_TIME 250

  //allow the player to struggle a little whilst grabbed
  if( cg.predictedPlayerState.pm_type == PM_GRABBED )
  {
    vec3_t    forward, right, up;
    usercmd_t cmd;
    int       cmdNum;
    float     fFraction, rFraction, uFraction;
    float     fFraction2, rFraction2, uFraction2;

    cmdNum = trap_GetCurrentCmdNumber();
    trap_GetUserCmd( cmdNum, &cmd );

    AngleVectors( angles, forward, right, up );

    fFraction = (float)( cg.time - cg.forwardMoveTime ) / STRUGGLE_TIME;
    rFraction = (float)( cg.time - cg.rightMoveTime ) / STRUGGLE_TIME;
    uFraction = (float)( cg.time - cg.upMoveTime ) / STRUGGLE_TIME;

    if( fFraction > 1.0f )
      fFraction = 1.0f;
    if( rFraction > 1.0f )
      rFraction = 1.0f;
    if( uFraction > 1.0f )
      uFraction = 1.0f;

    fFraction2 = -sin( fFraction * M_PI / 2 );
    rFraction2 = -sin( rFraction * M_PI / 2 );
    uFraction2 = -sin( uFraction * M_PI / 2 );

    if( cmd.forwardmove > 0 )
      VectorMA( origin, STRUGGLE_DIST * fFraction, forward, origin );
    else if( cmd.forwardmove < 0 )
      VectorMA( origin, -STRUGGLE_DIST * fFraction, forward, origin );
    else
      cg.forwardMoveTime = cg.time;

    if( cmd.rightmove > 0 )
      VectorMA( origin, STRUGGLE_DIST * rFraction, right, origin );
    else if( cmd.rightmove < 0 )
      VectorMA( origin, -STRUGGLE_DIST * rFraction, right, origin );
    else
      cg.rightMoveTime = cg.time;

    if( cmd.upmove > 0 )
      VectorMA( origin, STRUGGLE_DIST * uFraction, up, origin );
    else if( cmd.upmove < 0 )
      VectorMA( origin, -STRUGGLE_DIST * uFraction, up, origin );
    else
      cg.upMoveTime = cg.time;
  }

  if( ( cg.predictedPlayerEntity.currentState.eFlags & EF_POISONCLOUDED ) &&
      ( cg.time - cg.poisonedTime < PCLOUD_DISORIENT_DURATION) &&
      !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
  {
    float scale, fraction, pitchFraction;
    
    scale = 1.0f - (float)( cg.time - cg.poisonedTime ) /
            BG_PlayerPoisonCloudTime( &cg.predictedPlayerState );
    if( scale < 0.0f )
      scale = 0.0f;

    fraction = sin( ( cg.time - cg.poisonedTime ) / 500.0f * M_PI * PCLOUD_ROLL_FREQUENCY ) *
               scale;
    pitchFraction = sin( ( cg.time - cg.poisonedTime ) / 200.0f * M_PI * PCLOUD_ROLL_FREQUENCY ) *
                    scale;

    angles[ ROLL ] += fraction * PCLOUD_ROLL_AMPLITUDE;
    angles[ YAW ] += fraction * PCLOUD_ROLL_AMPLITUDE;
    angles[ PITCH ] += pitchFraction * PCLOUD_ROLL_AMPLITUDE / 2.0f;
  }

  // this *feels* more realisitic for humans
  if( cg.predictedPlayerState.stats[ STAT_TEAM ] == TEAM_HUMANS &&
      ( cg.predictedPlayerState.pm_type == PM_NORMAL ||
        cg.predictedPlayerState.pm_type == PM_JETPACK ) )
  {
    angles[PITCH] += cg.bobfracsin * bob2 * 0.5;

    // heavy breathing effects //FIXME: sound
    if( cg.predictedPlayerState.stats[ STAT_STAMINA ] < STAMINA_BREATHING_LEVEL )
    {
      float deltaBreath = ( cg.predictedPlayerState.stats[ STAT_STAMINA ] -
                            STAMINA_BREATHING_LEVEL ) / -250.0;
      float deltaAngle = cos( (float)cg.time/150.0 ) * deltaBreath;

      deltaAngle += ( deltaAngle < 0 ? -deltaAngle : deltaAngle ) * 0.5;

      angles[ PITCH ] -= deltaAngle;
    }
  }

//===================================

  // add view height
  VectorMA( origin, ps->viewheight, normal, origin );

  // smooth out duck height changes
  timeDelta = cg.time - cg.duckTime;
  if( timeDelta < DUCK_TIME)
  {
    cg.refdef.vieworg[ 2 ] -= cg.duckChange
      * ( DUCK_TIME - timeDelta ) / DUCK_TIME;
  }

  // add bob height
  bob = cg.bobfracsin * cg.xyspeed * bob2;

  if( bob > 6 )
    bob = 6;

  VectorMA( origin, bob, normal, origin );

  // add fall height
  delta = cg.time - cg.landTime;

  if( delta < LAND_DEFLECT_TIME )
  {
    f = delta / LAND_DEFLECT_TIME;
    cg.refdef.vieworg[ 2 ] += cg.landChange * f;
  }
  else if( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME )
  {
    delta -= LAND_DEFLECT_TIME;
    f = 1.0 - ( delta / LAND_RETURN_TIME );
    cg.refdef.vieworg[ 2 ] += cg.landChange * f;
  }

  // add step offset
  CG_StepOffset( );
}
コード例 #2
0
/*
===============
CG_OffsetFirstPersonView

===============
*/
void CG_OffsetFirstPersonView( void )
{
	float         *origin;
	float         *angles;
	float         bob;
	float         ratio;
	float         delta;
	float         speed;
	float         f;
	vec3_t        predictedVelocity;
	int           timeDelta;
	float         bob2;
	vec3_t        normal, baseOrigin;
	playerState_t *ps = &cg.predictedPlayerState;

	BG_GetClientNormal( ps, normal );

	if ( cg.snap->ps.pm_type == PM_INTERMISSION )
	{
		return;
	}

	origin = cg.refdef.vieworg;
	angles = cg.refdefViewAngles;

	VectorCopy( origin, baseOrigin );

	// if dead, fix the angle and don't add any kick
	if ( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 )
	{
		angles[ ROLL ] = 40;
		angles[ PITCH ] = -15;
		angles[ YAW ] = cg.snap->ps.stats[ STAT_VIEWLOCK ];
		origin[ 2 ] += cg.predictedPlayerState.viewheight;
		return;
	}

	// add angles based on damage kick
	if ( cg.damageTime )
	{
		ratio = cg.time - cg.damageTime;

		if ( ratio < DAMAGE_DEFLECT_TIME )
		{
			ratio /= DAMAGE_DEFLECT_TIME;
			angles[ PITCH ] += ratio * cg.v_dmg_pitch;
			angles[ ROLL ] += ratio * cg.v_dmg_roll;
		}
		else
		{
			ratio = 1.0 - ( ratio - DAMAGE_DEFLECT_TIME ) / DAMAGE_RETURN_TIME;

			if ( ratio > 0 )
			{
				angles[ PITCH ] += ratio * cg.v_dmg_pitch;
				angles[ ROLL ] += ratio * cg.v_dmg_roll;
			}
		}
	}

	// add pitch based on fall kick
#if 0
	ratio = ( cg.time - cg.landTime ) / FALL_TIME;

	if ( ratio < 0 )
	{
		ratio = 0;
	}

	angles[ PITCH ] += ratio * cg.fall_value;
#endif

	// add angles based on velocity
	VectorCopy( cg.predictedPlayerState.velocity, predictedVelocity );

	delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 0 ] );
	angles[ PITCH ] += delta * cg_runpitch.value;

	delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 1 ] );
	angles[ ROLL ] -= delta * cg_runroll.value;

	// add angles based on bob
	// bob amount is class-dependent

	if ( cg.snap->ps.persistant[ PERS_SPECSTATE ] != SPECTATOR_NOT )
	{
		bob2 = 0.0f;
	}
	else
	{
		bob2 = BG_Class( cg.predictedPlayerState.stats[ STAT_CLASS ] )->bob;
	}

#define LEVEL4_FEEDBACK 10.0f

	//give a charging player some feedback
	if ( ps->weapon == WP_ALEVEL4 )
	{
		if ( ps->stats[ STAT_MISC ] > 0 )
		{
			float fraction = ( float ) ps->stats[ STAT_MISC ] /
			                 LEVEL4_TRAMPLE_CHARGE_MAX;

			if ( fraction > 1.0f )
			{
				fraction = 1.0f;
			}

			bob2 *= ( 1.0f + fraction * LEVEL4_FEEDBACK );
		}
	}

	if ( bob2 != 0.0f )
	{
		// make sure the bob is visible even at low speeds
		speed = cg.xyspeed > 200 ? cg.xyspeed : 200;

		delta = cg.bobfracsin * ( bob2 ) * speed;

		if ( cg.predictedPlayerState.pm_flags & PMF_DUCKED )
		{
			delta *= 3; // crouching
		}

		angles[ PITCH ] += delta;
		delta = cg.bobfracsin * ( bob2 ) * speed;

		if ( cg.predictedPlayerState.pm_flags & PMF_DUCKED )
		{
			delta *= 3; // crouching accentuates roll
		}

		if ( cg.bobcycle & 1 )
		{
			delta = -delta;
		}

		angles[ ROLL ] += delta;
	}

#define LEVEL3_FEEDBACK 20.0f

	//provide some feedback for pouncing
	if ( ( cg.predictedPlayerState.weapon == WP_ALEVEL3 ||
	       cg.predictedPlayerState.weapon == WP_ALEVEL3_UPG ) &&
	     cg.predictedPlayerState.stats[ STAT_MISC ] > 0 )
	{
		float  fraction1, fraction2;
		vec3_t forward;

		AngleVectors( angles, forward, NULL, NULL );
		VectorNormalize( forward );

		fraction1 = ( float ) cg.predictedPlayerState.stats[ STAT_MISC ] /
		            LEVEL3_POUNCE_TIME_UPG;

		if ( fraction1 > 1.0f )
		{
			fraction1 = 1.0f;
		}

		fraction2 = -sin( fraction1 * M_PI / 2 );

		VectorMA( origin, LEVEL3_FEEDBACK * fraction2, forward, origin );
	}

#define STRUGGLE_DIST 5.0f
#define STRUGGLE_TIME 250

	//allow the player to struggle a little whilst grabbed
	if ( cg.predictedPlayerState.pm_type == PM_GRABBED )
	{
		vec3_t    forward, right, up;
		usercmd_t cmd;
		int       cmdNum;
		float     fFraction, rFraction, uFraction;

		cmdNum = trap_GetCurrentCmdNumber();
		trap_GetUserCmd( cmdNum, &cmd );

		AngleVectors( angles, forward, right, up );

		fFraction = ( float )( cg.time - cg.forwardMoveTime ) / STRUGGLE_TIME;
		rFraction = ( float )( cg.time - cg.rightMoveTime ) / STRUGGLE_TIME;
		uFraction = ( float )( cg.time - cg.upMoveTime ) / STRUGGLE_TIME;

		if ( fFraction > 1.0f )
		{
			fFraction = 1.0f;
		}

		if ( rFraction > 1.0f )
		{
			rFraction = 1.0f;
		}

		if ( uFraction > 1.0f )
		{
			uFraction = 1.0f;
		}

		if ( cmd.forwardmove > 0 )
		{
			VectorMA( origin, STRUGGLE_DIST * fFraction, forward, origin );
		}
		else if ( cmd.forwardmove < 0 )
		{
			VectorMA( origin, -STRUGGLE_DIST * fFraction, forward, origin );
		}
		else
		{
			cg.forwardMoveTime = cg.time;
		}

		if ( cmd.rightmove > 0 )
		{
			VectorMA( origin, STRUGGLE_DIST * rFraction, right, origin );
		}
		else if ( cmd.rightmove < 0 )
		{
			VectorMA( origin, -STRUGGLE_DIST * rFraction, right, origin );
		}
		else
		{
			cg.rightMoveTime = cg.time;
		}

		if ( cmd.upmove > 0 )
		{
			VectorMA( origin, STRUGGLE_DIST * uFraction, up, origin );
		}
		else if ( cmd.upmove < 0 )
		{
			VectorMA( origin, -STRUGGLE_DIST * uFraction, up, origin );
		}
		else
		{
			cg.upMoveTime = cg.time;
		}
	}

	// this *feels* more realisitic for humans <- this comment feels very descriptive
	if ( cg.predictedPlayerState.persistant[ PERS_TEAM ] == TEAM_HUMANS &&
	     cg.predictedPlayerState.pm_type == PM_NORMAL )
	{
		angles[ PITCH ] += cg.bobfracsin * bob2 * 0.5;
	}

	// add view height
	VectorMA( origin, ps->viewheight, normal, origin );

	// smooth out duck height changes
	timeDelta = cg.time - cg.duckTime;

	if ( timeDelta < DUCK_TIME )
	{
		cg.refdef.vieworg[ 2 ] -= cg.duckChange
		                          * ( DUCK_TIME - timeDelta ) / DUCK_TIME;
	}

	// add bob height
	bob = cg.bobfracsin * cg.xyspeed * bob2;

	if ( bob > 6 )
	{
		bob = 6;
	}

	VectorMA( origin, bob, normal, origin );

	// add fall height
	delta = cg.time - cg.landTime;

	if ( delta < LAND_DEFLECT_TIME )
	{
		f = delta / LAND_DEFLECT_TIME;
		cg.refdef.vieworg[ 2 ] += cg.landChange * f;
	}
	else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME )
	{
		delta -= LAND_DEFLECT_TIME;
		f = 1.0 - ( delta / LAND_RETURN_TIME );
		cg.refdef.vieworg[ 2 ] += cg.landChange * f;
	}

	// add step offset
	CG_StepOffset();
}
コード例 #3
0
/*
===============
CG_OffsetFirstPersonView

===============
*/
static void CG_OffsetFirstPersonView( void ) {
	float			*origin;
	float			*angles;
	float			bob;
	float			ratio;
	float			delta;
	float			speed;
	float			f;
	vec3_t			predictedVelocity;
	int				timeDelta;
	
	if ( cg.snap->ps.pm_type == PM_INTERMISSION ) {
		return;
	}

	origin = cg.refdef.vieworg;
	angles = cg.refdefViewAngles;

	// if dead, fix the angle and don't add any kick
	if ( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) {
		angles[ROLL] = 40;
		angles[PITCH] = -15;
		angles[YAW] = cg.snap->ps.stats[STAT_DEAD_YAW];
		origin[2] += cg.predictedPlayerState.viewheight;
		return;
	}

	// add angles based on weapon kick
	VectorAdd (angles, cg.kick_angles, angles);

	// add angles based on damage kick
	if ( cg.damageTime ) {
		ratio = cg.time - cg.damageTime;
		if ( ratio < DAMAGE_DEFLECT_TIME ) {
			ratio /= DAMAGE_DEFLECT_TIME;
			angles[PITCH] += ratio * cg.v_dmg_pitch;
			angles[ROLL] += ratio * cg.v_dmg_roll;
		} else {
			ratio = 1.0 - ( ratio - DAMAGE_DEFLECT_TIME ) / DAMAGE_RETURN_TIME;
			if ( ratio > 0 ) {
				angles[PITCH] += ratio * cg.v_dmg_pitch;
				angles[ROLL] += ratio * cg.v_dmg_roll;
			}
		}
	}

	// add pitch based on fall kick
#if 0
	ratio = ( cg.time - cg.landTime) / FALL_TIME;
	if (ratio < 0)
		ratio = 0;
	angles[PITCH] += ratio * cg.fall_value;
#endif

	// add angles based on velocity
	VectorCopy( cg.predictedPlayerState.velocity, predictedVelocity );

	delta = DotProduct ( predictedVelocity, cg.refdef.viewaxis[0]);
	angles[PITCH] += delta * cg_runpitch.value;
	
	delta = DotProduct ( predictedVelocity, cg.refdef.viewaxis[1]);
	angles[ROLL] -= delta * cg_runroll.value;

	// add angles based on bob

	// make sure the bob is visible even at low speeds
	speed = cg.xyspeed > 200 ? cg.xyspeed : 200;

	delta = cg.bobfracsin * cg_bobpitch.value * speed;
	if (cg.predictedPlayerState.pm_flags & PMF_DUCKED)
		delta *= 3;		// crouching
	angles[PITCH] += delta;
	delta = cg.bobfracsin * cg_bobroll.value * speed;
	if (cg.predictedPlayerState.pm_flags & PMF_DUCKED)
		delta *= 3;		// crouching accentuates roll
	if (cg.bobcycle & 1)
		delta = -delta;
	angles[ROLL] += delta;

//===================================

	// add view height
	origin[2] += cg.predictedPlayerState.viewheight;

	// smooth out duck height changes
	timeDelta = cg.time - cg.duckTime;
	if ( timeDelta < DUCK_TIME) {
		cg.refdef.vieworg[2] -= cg.duckChange 
			* (DUCK_TIME - timeDelta) / DUCK_TIME;
	}

	// add bob height
	bob = cg.bobfracsin * cg.xyspeed * cg_bobup.value;
	if (bob > 6) {
		bob = 6;
	}

	origin[2] += bob;


	// add fall height
	delta = cg.time - cg.landTime;
	if ( delta < LAND_DEFLECT_TIME ) {
		f = delta / LAND_DEFLECT_TIME;
		cg.refdef.vieworg[2] += cg.landChange * f;
	} else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME ) {
		delta -= LAND_DEFLECT_TIME;
		f = 1.0 - ( delta / LAND_RETURN_TIME );
		cg.refdef.vieworg[2] += cg.landChange * f;
	}

	// add step offset
	CG_StepOffset();

	// add kick offset

	VectorAdd (origin, cg.kick_origin, origin);

	// pivot the eye based on a neck length
#if 0
	{
#define	NECK_LENGTH		8
	vec3_t			forward, up;
 
	cg.refdef.vieworg[2] -= NECK_LENGTH;
	AngleVectors( cg.refdefViewAngles, forward, NULL, up );
	VectorMA( cg.refdef.vieworg, 3, forward, cg.refdef.vieworg );
	VectorMA( cg.refdef.vieworg, NECK_LENGTH, up, cg.refdef.vieworg );
	}
#endif
}
コード例 #4
0
ファイル: cg_view.c プロジェクト: zturtleman/mint-arena
static void CG_OffsetThirdPersonView( void ) {
	vec3_t		forward, right, up;
	vec3_t		view;
	vec3_t		focusAngles;
	trace_t		trace;
	static vec3_t	mins = { -5, -5, -5 };
	static vec3_t	maxs = { 5, 5, 5 };
	vec3_t		focusPoint;
	float		focusDist;
	float		forwardScale, sideScale;
	float		thirdPersonAngle, thirdPersonRange;

	cg.refdef.vieworg[2] += cg.cur_lc->predictedPlayerState.viewheight;

	VectorCopy( cg.refdefViewAngles, focusAngles );

	if ( cg.cur_lc->cameraOrbit ) {
		thirdPersonAngle = cg.cur_lc->cameraOrbitAngle;
		thirdPersonRange = cg.cur_lc->cameraOrbitRange;

		// make camera orbit horizontal
		focusAngles[PITCH] = 0;
		cg.refdefViewAngles[PITCH] = 0;
	} else {
		thirdPersonAngle = cg_thirdPersonAngle[cg.cur_localPlayerNum].value;
		thirdPersonRange = cg_thirdPersonRange[cg.cur_localPlayerNum].value;

		// if dead, look at killer
		if ( cg.cur_lc->predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
			focusAngles[YAW] = cg.cur_lc->predictedPlayerState.stats[STAT_DEAD_YAW];
			cg.refdefViewAngles[YAW] = cg.cur_lc->predictedPlayerState.stats[STAT_DEAD_YAW];
		}
	}

	if ( focusAngles[PITCH] > 45 ) {
		focusAngles[PITCH] = 45;		// don't go too far overhead
	}
	AngleVectors( focusAngles, forward, NULL, NULL );

	if ( cg_thirdPersonSmooth[cg.cur_localPlayerNum].integer ) {
		CG_StepOffset( cg.refdef.vieworg );
	}

	VectorMA( cg.refdef.vieworg, FOCUS_DISTANCE, forward, focusPoint );

	VectorCopy( cg.refdef.vieworg, view );

	view[2] += cg_thirdPersonHeight[cg.cur_localPlayerNum].value;

	cg.refdefViewAngles[PITCH] *= 0.5;

	AngleVectors( cg.refdefViewAngles, forward, right, up );

	forwardScale = cos( thirdPersonAngle / 180 * M_PI );
	sideScale = sin( thirdPersonAngle / 180 * M_PI );
	VectorMA( view, -thirdPersonRange * forwardScale, forward, view );
	VectorMA( view, -thirdPersonRange * sideScale, right, view );

	// trace a ray from the origin to the viewpoint to make sure the view isn't
	// in a solid block.  Use a 10 by 10 block to prevent the view from near clipping anything

	if (!cg_cameraMode.integer) {
		CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.cur_lc->predictedPlayerState.playerNum, MASK_SOLID );

		if ( trace.fraction != 1.0 ) {
			VectorCopy( trace.endpos, view );
			view[2] += (1.0 - trace.fraction) * 32;
			// try another trace to this position, because a tunnel may have the ceiling
			// close enough that this is poking out

			CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.cur_lc->predictedPlayerState.playerNum, MASK_SOLID );
			VectorCopy( trace.endpos, view );
		}
	}


	VectorCopy( view, cg.refdef.vieworg );

	// select pitch to look at focus point from vieword
	VectorSubtract( focusPoint, cg.refdef.vieworg, focusPoint );
	focusDist = sqrt( focusPoint[0] * focusPoint[0] + focusPoint[1] * focusPoint[1] );
	if ( focusDist < 1 ) {
		focusDist = 1;	// should never happen
	}
	cg.refdefViewAngles[PITCH] = -180 / M_PI * atan2( focusPoint[2], focusDist );
	cg.refdefViewAngles[YAW] -= thirdPersonAngle;
}
コード例 #5
0
ファイル: cg_view.c プロジェクト: ztdretcher/zt-tremulous
/*
===============
CG_OffsetFirstPersonView

===============
*/
static void CG_OffsetFirstPersonView( void )
{
  float         *origin;
  float         *angles;
  float         bob;
  float         ratio;
  float         delta;
  float         speed;
  float         f;
  vec3_t        predictedVelocity;
  char temp[1024];
    vec3_t org;
    vec3_t axis[3];
  vec3_t	ang;
  int           timeDelta;
  float         bob2;
  vec3_t        normal, baseOrigin;

  playerState_t *ps = &cg.predictedPlayerState;

  if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBING )
  {
    if( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING )
      VectorSet( normal, 0.0f, 0.0f, -1.0f );
    else
      VectorCopy( ps->grapplePoint, normal );
  }
  else
    VectorSet( normal, 0.0f, 0.0f, 1.0f );


  if( cg.snap->ps.pm_type == PM_INTERMISSION )
    return;

  origin = cg.refdef.vieworg;
  angles = cg.refdefViewAngles;

  VectorCopy( origin, baseOrigin );

 
  // if dead, fix the angle and don't add any kick
  if( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 )
  {
    angles[ ROLL ] = 40;
    angles[ PITCH ] = -15;
    angles[ YAW ] = cg.snap->ps.stats[ STAT_VIEWLOCK ];
    origin[ 2 ] += cg.predictedPlayerState.viewheight;
    return;
  }

    // add angles based on weapon kick
    VectorAdd( angles, cg.kick_angles, angles );
  

  // add angles based on damage kick
  if( cg.damageTime )
  {
    ratio = cg.time - cg.damageTime;
    if( ratio < DAMAGE_DEFLECT_TIME )
    {
      ratio /= DAMAGE_DEFLECT_TIME;
      angles[ PITCH ] += ratio * cg.v_dmg_pitch;
      angles[ ROLL ] += ratio * cg.v_dmg_roll;
    }
    else
    {
      ratio = 1.0 - ( ratio - DAMAGE_DEFLECT_TIME ) / DAMAGE_RETURN_TIME;
      if( ratio > 0 )
      {
        angles[ PITCH ] += ratio * cg.v_dmg_pitch;
        angles[ ROLL ] += ratio * cg.v_dmg_roll;
      }
    }
  }

  // add pitch based on fall kick
#if 0
  ratio = ( cg.time - cg.landTime) / FALL_TIME;
  if (ratio < 0)
    ratio = 0;
  angles[PITCH] += ratio * cg.fall_value;
#endif

  // add angles based on velocity
  VectorCopy( cg.predictedPlayerState.velocity, predictedVelocity );

  delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 0 ] );
  angles[ PITCH ] += delta * cg_runpitch.value;

  delta = DotProduct( predictedVelocity, cg.refdef.viewaxis[ 1 ] );
  angles[ ROLL ] -= delta * cg_runroll.value;

  // add angles based on bob
  //TA: bob amount is class dependant
  if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
    bob2 = 0.0f;
  else
    bob2 = BG_FindBobForClass( cg.predictedPlayerState.stats[ STAT_PCLASS ] );

#define LEVEL4_FEEDBACK  10.0f

  //give a charging player some feedback
  if( ps->weapon == WP_ALEVEL4 )
  {
    if( ps->stats[ STAT_MISC ] > 0 )
    {
      float fraction = (float)ps->stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME;

      if( fraction > 1.0f )
        fraction = 1.0f;

      bob2 *= ( 1.0f + fraction * LEVEL4_FEEDBACK );
    }
  }

  if( bob2 != 0.0f )
  {
    // make sure the bob is visible even at low speeds
    speed = cg.xyspeed > 200 ? cg.xyspeed : 200;

    delta = cg.bobfracsin * ( bob2 ) * speed;
    if( cg.predictedPlayerState.pm_flags & PMF_DUCKED )
      delta *= 3;   // crouching

    angles[ PITCH ] += delta;
    delta = cg.bobfracsin * ( bob2 ) * speed;
    if( cg.predictedPlayerState.pm_flags & PMF_DUCKED )
      delta *= 3;   // crouching accentuates roll

    if( cg.bobcycle & 1 )
      delta = -delta;

    angles[ ROLL ] += delta;
  }

#define LEVEL3_FEEDBACK  20.0f

  //provide some feedback for pouncing
  if( cg.predictedPlayerState.weapon == WP_ALEVEL3 ||
      cg.predictedPlayerState.weapon == WP_ALEVEL3_UPG )
  {
    if( cg.predictedPlayerState.stats[ STAT_MISC ] > 0 )
    {
      float   fraction1, fraction2;
      vec3_t  forward;

      AngleVectors( angles, forward, NULL, NULL );
      VectorNormalize( forward );

      fraction1 = (float)( cg.time - cg.weapon2Time ) / (float)LEVEL3_POUNCE_CHARGE_TIME;

      if( fraction1 > 1.0f )
        fraction1 = 1.0f;

      fraction2 = -sin( fraction1 * M_PI / 2 );

      VectorMA( origin, LEVEL3_FEEDBACK * fraction2, forward, origin );
    }
  }

#define STRUGGLE_DIST 5.0f
#define STRUGGLE_TIME 250

  //allow the player to struggle a little whilst grabbed
  if( cg.predictedPlayerState.pm_type == PM_GRABBED )
  {
    vec3_t    forward, right, up;
    usercmd_t cmd;
    int       cmdNum;
    float     fFraction, rFraction, uFraction;
    float     fFraction2, rFraction2, uFraction2;

    cmdNum = trap_GetCurrentCmdNumber();
    trap_GetUserCmd( cmdNum, &cmd );

    AngleVectors( angles, forward, right, up );

    fFraction = (float)( cg.time - cg.forwardMoveTime ) / STRUGGLE_TIME;
    rFraction = (float)( cg.time - cg.rightMoveTime ) / STRUGGLE_TIME;
    uFraction = (float)( cg.time - cg.upMoveTime ) / STRUGGLE_TIME;

    if( fFraction > 1.0f )
      fFraction = 1.0f;
    if( rFraction > 1.0f )
      rFraction = 1.0f;
    if( uFraction > 1.0f )
      uFraction = 1.0f;

    fFraction2 = -sin( fFraction * M_PI / 2 );
    rFraction2 = -sin( rFraction * M_PI / 2 );
    uFraction2 = -sin( uFraction * M_PI / 2 );

    if( cmd.forwardmove > 0 )
      VectorMA( origin, STRUGGLE_DIST * fFraction, forward, origin );
    else if( cmd.forwardmove < 0 )
      VectorMA( origin, -STRUGGLE_DIST * fFraction, forward, origin );
    else
      cg.forwardMoveTime = cg.time;

    if( cmd.rightmove > 0 )
      VectorMA( origin, STRUGGLE_DIST * rFraction, right, origin );
    else if( cmd.rightmove < 0 )
      VectorMA( origin, -STRUGGLE_DIST * rFraction, right, origin );
    else
      cg.rightMoveTime = cg.time;

    if( cmd.upmove > 0 )
      VectorMA( origin, STRUGGLE_DIST * uFraction, up, origin );
    else if( cmd.upmove < 0 )
      VectorMA( origin, -STRUGGLE_DIST * uFraction, up, origin );
    else
      cg.upMoveTime = cg.time;
  }

  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED &&
      !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
  {
    float fraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 2 * PCLOUD_ROLL_FREQUENCY );
    float pitchFraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 5 * PCLOUD_ROLL_FREQUENCY );

    fraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME );
    pitchFraction *= 1.0f - ( ( cg.time - cg.poisonedTime ) / (float)LEVEL1_PCLOUD_TIME );

    angles[ ROLL ] += fraction * PCLOUD_ROLL_AMPLITUDE;
    angles[ YAW ] += fraction * PCLOUD_ROLL_AMPLITUDE;
    angles[ PITCH ] += pitchFraction * PCLOUD_ROLL_AMPLITUDE / 2.0f;
  }

  //TA: this *feels* more realisitic for humans
  if( cg.predictedPlayerState.stats[ STAT_PTEAM ] == PTE_HUMANS )
  {
    angles[PITCH] += cg.bobfracsin * bob2 * 0.5;

    //TA: heavy breathing effects //FIXME: sound
    if( cg.predictedPlayerState.stats[ STAT_STAMINA ] < 0 )
    {
      float deltaBreath = (float)(
        cg.predictedPlayerState.stats[ STAT_STAMINA ] < 0 ?
        -cg.predictedPlayerState.stats[ STAT_STAMINA ] :
        cg.predictedPlayerState.stats[ STAT_STAMINA ] ) / 200.0;
      float deltaAngle = cos( (float)cg.time/150.0 ) * deltaBreath;

      deltaAngle += ( deltaAngle < 0 ? -deltaAngle : deltaAngle ) * 0.5;

      angles[ PITCH ] -= deltaAngle;
    }
  }

//===================================

  // add view height
  //TA: when wall climbing the viewheight is not straight up
  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING )
    VectorMA( origin, ps->viewheight, normal, origin );
  else
    origin[ 2 ] += cg.predictedPlayerState.viewheight;

  // smooth out duck height changes
  timeDelta = cg.time - cg.duckTime;
  if( timeDelta < DUCK_TIME)
  {
    cg.refdef.vieworg[ 2 ] -= cg.duckChange
      * ( DUCK_TIME - timeDelta ) / DUCK_TIME;
  }

  // add bob height
  bob = cg.bobfracsin * cg.xyspeed * bob2;

  if( bob > 6 )
    bob = 6;

  //TA: likewise for bob
  if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_WALLCLIMBING )
    VectorMA( origin, bob, normal, origin );
  else
    origin[ 2 ] += bob;


  // add fall height
  delta = cg.time - cg.landTime;

  if( delta < LAND_DEFLECT_TIME )
  {
    f = delta / LAND_DEFLECT_TIME;
    cg.refdef.vieworg[ 2 ] += cg.landChange * f;
  }
  else if( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME )
  {
    delta -= LAND_DEFLECT_TIME;
    f = 1.0 - ( delta / LAND_RETURN_TIME );
    cg.refdef.vieworg[ 2 ] += cg.landChange * f;
  }

  // add step offset
  CG_StepOffset( );

  // add kick offset

  VectorAdd (origin, cg.kick_origin, origin);
}
コード例 #6
0
ファイル: cg_view.c プロジェクト: LuckyBro/sgfork
/*
===============
CG_OffsetFirstPersonView

===============
*/
static void CG_OffsetFirstPersonView( void ) {
    float			*origin;
    float			*angles;
    float			bob;
    float			ratio;
    float			delta;
    float			speed;
    float			f;
    vec3_t			predictedVelocity;
    int				timeDelta;
    int	land_deflect_time = LAND_DEFLECT_TIME;
    int land_return_time = LAND_RETURN_TIME;
    int	shoot_deflect_time = LAND_DEFLECT_TIME - 50;

    if ( cg.snap->ps.pm_type == PM_INTERMISSION ) {
        return;
    }

    origin = cg.refdef.vieworg;
    angles = cg.refdefViewAngles;

    // add view height
    origin[2] += cg.predictedPlayerState.viewheight;

    // pivot the eye based on a neck length, new system by spoon
    if(cg.snap->ps.persistant[PERS_TEAM] < TEAM_SPECTATOR) {
        BG_ModifyEyeAngles( origin, angles, CG_Trace, cg.legOffset,
                            qfalse);
    }

    // add angles based on weapon kick
    VectorAdd (angles, cg.kick_angles, angles);

    // add angles based on damage kick
    if ( cg.damageTime ) {
        ratio = cg.time - cg.damageTime;
        if ( ratio < DAMAGE_DEFLECT_TIME ) {
            ratio /= DAMAGE_DEFLECT_TIME;
            angles[PITCH] += ratio * cg.v_dmg_pitch;
            angles[ROLL] += ratio * cg.v_dmg_roll;
        } else {
            ratio = 1.0 - ( ratio - DAMAGE_DEFLECT_TIME ) / DAMAGE_RETURN_TIME;
            if ( ratio > 0 ) {
                angles[PITCH] += ratio * cg.v_dmg_pitch;
                angles[ROLL] += ratio * cg.v_dmg_roll;
            }
        }
    }

    // add pitch based on fall kick
#if 0
    ratio = ( cg.time - cg.landTime) / FALL_TIME;
    if (ratio < 0)
        ratio = 0;
    angles[PITCH] += ratio * cg.fall_value;
#endif

    // add angles based on velocity
    VectorCopy( cg.predictedPlayerState.velocity, predictedVelocity );

    delta = DotProduct ( predictedVelocity, cg.refdef.viewaxis[0]);
    angles[PITCH] += delta * cg_runpitch.value;

    delta = DotProduct ( predictedVelocity, cg.refdef.viewaxis[1]);
    angles[ROLL] -= delta * cg_runroll.value;

    // add angles based on bob

    // make sure the bob is visible even at low speeds
    speed = cg.xyspeed > 200 ? cg.xyspeed : 200;

    delta = cg.bobfracsin * cg_bobpitch.value * speed;
    if (cg.predictedPlayerState.pm_flags & PMF_DUCKED)
        delta *= 3;		// crouching
    angles[PITCH] += delta;
    delta = cg.bobfracsin * cg_bobroll.value * speed;
    if (cg.predictedPlayerState.pm_flags & PMF_DUCKED)
        delta *= 3;		// crouching accentuates roll
    if (cg.bobcycle & 1)
        delta = -delta;
    angles[ROLL] += delta;

//===================================

    // smooth out duck height changes
    timeDelta = cg.time - cg.duckTime;
    if ( timeDelta < DUCK_TIME) {
        cg.refdef.vieworg[2] -= cg.duckChange
                                * (DUCK_TIME - timeDelta) / DUCK_TIME;
    }

    // add bob height
    bob = cg.bobfracsin * cg.xyspeed * cg_bobup.value;
    if (bob > 6) {
        bob = 6;
    }

    origin[2] += bob;
    cg.legOffset[2] += bob;

    //check for bullethit
    if(!cg.landChange && cg.landAngleChange) {
        land_deflect_time /= 2;
        land_return_time /= 2;
    }

    // add fall height
    delta = cg.time - cg.landTime;
    if ( delta < land_deflect_time ) {
        f = delta / land_deflect_time;
        cg.refdef.vieworg[2] += cg.landChange * f;
        //anglechange
        cg.refdefViewAngles[ROLL] += cg.landAngleChange *f;
    } else if ( delta < land_deflect_time + land_return_time ) {
        delta -= land_deflect_time;
        f = 1.0 - ( delta / land_return_time );
        cg.refdef.vieworg[2] += cg.landChange * f;
        //anglechange
        cg.refdefViewAngles[ROLL] += cg.landAngleChange *f;
    }

    // add shoot height
    delta = cg.time - cg.shootTime;
    if ( delta < shoot_deflect_time   ) {
        f = delta / shoot_deflect_time;
        cg.refdef.vieworg[2] += cg.shootChange * f;
        //anglechange
        cg.refdefViewAngles[PITCH] -= cg.shootAngleChange *f;
    } else if ( delta < shoot_deflect_time + land_return_time ) {
        delta -= shoot_deflect_time;
        f = 1.0 - ( delta / land_return_time );
        cg.refdef.vieworg[2] += cg.shootChange * f;
        //anglechange
        cg.refdefViewAngles[PITCH] -= cg.shootAngleChange *f;
    }

    // add step offset
    CG_StepOffset();

    // add kick offset

    VectorAdd (origin, cg.kick_origin, origin);

    // pivot the eye based on a neck length
#if 0
    {
#define	NECK_LENGTH		8
        vec3_t			forward, up;

        cg.refdef.vieworg[2] -= NECK_LENGTH;
        AngleVectors( cg.refdefViewAngles, forward, NULL, up );
        VectorMA( cg.refdef.vieworg, 3, forward, cg.refdef.vieworg );
        VectorMA( cg.refdef.vieworg, NECK_LENGTH, up, cg.refdef.vieworg );
    }
#endif
}
コード例 #7
0
ファイル: cg_view.cpp プロジェクト: OnlyTheGhosts/OWEngine
/*
===============
CG_OffsetFirstPersonView

===============
*/
static void CG_OffsetFirstPersonView( void )
{
    float*          origin;
    float*          angles;
    float           delta;
    float           speed;
    float           f;
    vec3_c          predictedVelocity;
    int             timeDelta;

    origin = cg.refdefViewOrigin;
    angles = cg.refdefViewAngles;

    // add angles based on velocity
    predictedVelocity = cg.predictedPlayerState.velocity;;

    //delta = DotProduct ( predictedVelocity, cg.refdef.viewaxis[0]);
    //angles[PITCH] += delta * cg_runpitch.value;
    //
    //delta = DotProduct ( predictedVelocity, cg.refdef.viewaxis[1]);
    //angles[ROLL] -= delta * cg_runroll.value;

    // add angles based on bob

    // make sure the bob is visible even at low speeds
    speed = 200;


    //===================================

    // add view height
    origin[2] += cg.predictedPlayerState.viewheight;

    // smooth out duck height changes
    timeDelta = cg.time - cg.duckTime;
    if ( timeDelta < DUCK_TIME )
    {
        cg.refdefViewOrigin[2] -= cg.duckChange
                                  * ( DUCK_TIME - timeDelta ) / DUCK_TIME;
    }




    // add fall height
    delta = cg.time - cg.landTime;
    if ( delta < LAND_DEFLECT_TIME )
    {
        f = delta / LAND_DEFLECT_TIME;
        cg.refdefViewOrigin[2] += cg.landChange * f;
    }
    else if ( delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME )
    {
        delta -= LAND_DEFLECT_TIME;
        f = 1.0 - ( delta / LAND_RETURN_TIME );
        cg.refdefViewOrigin[2] += cg.landChange * f;
    }

    // add step offset
    CG_StepOffset();
}
コード例 #8
0
ファイル: cg_view.c プロジェクト: baseas/aftershock
static void CG_OffsetFirstPersonView(void)
{
	float			*origin;
	float			*angles;
	float			delta;
	float			f;
	int				timeDelta;
	
	if (cg.snap->ps.pm_type == PM_INTERMISSION) {
		return;
	}

	origin = cg.refdef.vieworg;
	angles = cg.refdefViewAngles;

	// if dead, fix the angle and don't add any kick
	if (cg.snap->ps.stats[STAT_HEALTH] <= 0) {
		angles[ROLL] = 40;
		angles[PITCH] = -15;
		angles[YAW] = cg.snap->ps.stats[STAT_DEAD_YAW];
		origin[2] += cg.predictedPlayerState.viewheight;
		return;
	}

	// add view height
	origin[2] += cg.predictedPlayerState.viewheight;

	// smooth out duck height changes
	timeDelta = cg.time - cg.duckTime;
	if (timeDelta < DUCK_TIME) {
		cg.refdef.vieworg[2] -= cg.duckChange 
			* (DUCK_TIME - timeDelta) / DUCK_TIME;
	}

	// add fall height
	delta = cg.time - cg.landTime;
	if (delta < LAND_DEFLECT_TIME) {
		f = delta / LAND_DEFLECT_TIME;
		cg.refdef.vieworg[2] += cg.landChange * f;
	} else if (delta < LAND_DEFLECT_TIME + LAND_RETURN_TIME) {
		delta -= LAND_DEFLECT_TIME;
		f = 1.0 - (delta / LAND_RETURN_TIME);
		cg.refdef.vieworg[2] += cg.landChange * f;
	}

	// add step offset
	CG_StepOffset();

	// pivot the eye based on a neck length
#if 0
	{
#define	NECK_LENGTH		8
	vec3_t			forward, up;
 
	cg.refdef.vieworg[2] -= NECK_LENGTH;
	AngleVectors(cg.refdefViewAngles, forward, NULL, up);
	VectorMA(cg.refdef.vieworg, 3, forward, cg.refdef.vieworg);
	VectorMA(cg.refdef.vieworg, NECK_LENGTH, up, cg.refdef.vieworg);
	}
#endif
}