Exemple #1
0
static void CG_AddFadeScaleModel( localEntity_t *le ) {
	refEntity_t	*ent = &le->refEntity;

	float frac = (cg.time - le->startTime) / ((float)(le->endTime - le->startTime));

	frac *= frac * frac; // yes, this is completely ridiculous...but it causes the shell to grow slowly then "explode" at the end

	ent->nonNormalizedAxes = qtrue;

	AxisCopy( axisDefault, ent->axis );

	VectorScale( &ent->axis[0], le->radius*frac, &ent->axis[0] );
	VectorScale( &ent->axis[1], le->radius*frac, &ent->axis[1] );
	VectorScale( &ent->axis[2], le->radius*0.5f*frac, &ent->axis[2] );

	frac = 1.0f - frac;

	ent->shaderRGBA[0] = le->color[0] * frac;
	ent->shaderRGBA[1] = le->color[1] * frac;
	ent->shaderRGBA[2] = le->color[2] * frac;
	ent->shaderRGBA[3] = le->color[3] * frac;

	// add the entity
	SE_R_AddRefEntityToScene( ent, MAX_CLIENTS );
}
Exemple #2
0
/*
==================
CG_LaunchGib
==================
*/
void CG_LaunchGib( vector3 *origin, vector3 *velocity, qhandle_t hModel ) {
	localEntity_t	*le;
	refEntity_t		*re;

	le = CG_AllocLocalEntity();
	re = &le->refEntity;

	le->leType = LE_FRAGMENT;
	le->startTime = cg.time;
	le->endTime = le->startTime + 5000 + random() * 3000;

	VectorCopy( origin, &re->origin );
	AxisCopy( axisDefault, re->axis );
	re->hModel = hModel;

	le->pos.trType = TR_GRAVITY;
	VectorCopy( origin, &le->pos.trBase );
	VectorCopy( velocity, &le->pos.trDelta );
	le->pos.trTime = cg.time;

	le->bounceFactor = 0.6f;

	le->leBounceSoundType = LEBS_BLOOD;
	le->leMarkType = LEMT_BLOOD;
}
Exemple #3
0
/*
==================
CG_LaunchGib
==================
*/
void CG_LaunchGib( bvec3_t origin, bvec3_t velocity, qhandle_t hModel ) {
	localEntity_t	*le;
	refEntity_t		*re;

	le = CG_AllocLocalEntity();
	re = &le->refEntity;

	le->leType = LE_FRAGMENT;
	le->startTime = cg.time;
	le->endTime = le->startTime + 5000 + FIXED_TO_INT(random() * GFIXED(3000,0));

	VectorCopy( origin, re->origin );
	AxisCopy( aaxisDefault, re->axis );
	re->hModel = hModel;

	le->pos.trType = TR_GRAVITY;
	VectorCopy( origin, le->pos.trBase );
	VectorCopy( velocity, le->pos.trDelta );
	le->pos.trTime = cg.time;

	le->bounceFactor = BFIXED(0,6);

	le->leBounceSoundType = LEBS_BLOOD;
	le->leMarkType = LEMT_BLOOD;
}
/*
==================
CG_LaunchGib
==================
*/
void CG_LaunchExplode( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
	localEntity_t	*le;
	refEntity_t		*re;

	le = CG_AllocLocalEntity();
	re = &le->refEntity;

	le->leType = LE_FRAGMENT;
	le->startTime = cg.time;
	le->endTime = le->startTime + 10000 + random() * 6000;

	VectorCopy( origin, re->origin );
	AxisCopy( axisDefault, re->axis );
	re->hModel = hModel;

	le->pos.trType = TR_GRAVITY;
	VectorCopy( origin, le->pos.trBase );
	VectorCopy( velocity, le->pos.trDelta );
	le->pos.trTime = cg.time;

	le->bounceFactor = 0.1f;

	le->leBounceSoundType = LEBS_BRASS;
	le->leMarkType = LEMT_NONE;
}
Exemple #5
0
/*
==================
CG_ThrowChunk
==================
*/
void CG_ThrowChunk( vec3_t origin, vec3_t velocity, qhandle_t hModel, int optionalSound, int startalpha ) {
	localEntity_t	*le;
	refEntity_t		*re;

	le = CG_AllocLocalEntity();
	re = &le->refEntity;

	le->leType = LE_FRAGMENT;
	le->startTime = cg.time;
	le->endTime = le->startTime + 5000 + random() * 3000;

	VectorCopy( origin, re->origin );
	AxisCopy( axisDefault, re->axis );
	re->hModel = hModel;

	le->pos.trType = TR_GRAVITY;
	le->angles.trType = TR_GRAVITY;
	VectorCopy( origin, le->pos.trBase );
	VectorCopy( velocity, le->pos.trDelta );
	VectorSet(le->angles.trBase, 20, 20, 20);
	VectorCopy( velocity, le->angles.trDelta );
	le->pos.trTime = cg.time;
	le->angles.trTime = cg.time;

	le->leFlags = LEF_TUMBLE;

	le->angles.trBase[YAW] = 180;

	le->bounceFactor = 0.3f;
	le->bounceSound = optionalSound;

	le->forceAlpha = startalpha;
}
Exemple #6
0
/*
==================
CG_LaunchGib
==================
*/
void CG_LaunchGib( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
	localEntity_t	*le;
	refEntity_t		*re;

	le = CG_AllocLocalEntity();
	re = &le->refEntity;

	le->leType = LE_FRAGMENT;
	le->startTime = cg.time;
	le->endTime = le->startTime + 5000 + random() * 3000;

	VectorCopy( origin, re->origin );
	AxisCopy( axisDefault, re->axis );
	re->hModel = hModel;

	le->pos.trType = TR_GRAVITY;
	VectorCopy( origin, le->pos.trBase );
	VectorCopy( velocity, le->pos.trDelta );
	le->pos.trTime = cg.time;

	le->bounceFactor = 0.6f;

	le->leBounceSoundType = LEBS_BLOOD;
	le->leMarkType = LEMT_BLOOD;
		if ( cg_leiSuperGoreyAwesome.integer ) {
			CG_SpurtBlood( origin, velocity, 7); // LEILEI toss some extra juice
			CG_SpurtBlood( origin, velocity, 22); 
			CG_SpurtBlood( origin, velocity, 11); 
			}
	
}
/*
===============
CG_smoothWJTransitions
===============
*/
static void CG_smoothWJTransitions( playerState_t *ps, const vec3_t in, vec3_t out )
{
	int      i;
	float    stLocal, sFraction;
	qboolean performed = qfalse;
	vec3_t   inAxis[ 3 ], outAxis[ 3 ];

	Q_UNUSED(ps);

	if ( cg.snap->ps.pm_flags & PMF_FOLLOW )
	{
		VectorCopy( in, out );
		return;
	}

	AnglesToAxis( in, inAxis );

	//iterate through ops
	for ( i = MAXSMOOTHS - 1; i >= 0; i-- )
	{
		//if this op has time remaining, perform it
		if ( cg.time < cg.sList[ i ].time + cg_wwSmoothTime.integer )
		{
			stLocal = ( ( cg.sList[ i ].time + cg_wwSmoothTime.integer ) - cg.time ) / cg_wwSmoothTime.integer;
			sFraction = 1.0f - ( ( cos( stLocal * M_PI * 2.0f ) + 1.0f ) / 2.0f );

			RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis,
			                         inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle );
			RotatePointAroundVector( outAxis[ 1 ], cg.sList[ i ].rotAxis,
			                         inAxis[ 1 ], sFraction * cg.sList[ i ].rotAngle );
			RotatePointAroundVector( outAxis[ 2 ], cg.sList[ i ].rotAxis,
			                         inAxis[ 2 ], sFraction * cg.sList[ i ].rotAngle );

			AxisCopy( outAxis, inAxis );
			performed = qtrue;
		}
	}

	//if we performed any ops then return the smoothed angles
	//otherwise simply return the in angles
	if ( performed )
	{
		AxisToAngles( outAxis, out );
	}
	else
	{
		VectorCopy( in, out );
	}
}
Exemple #8
0
/*
===============
CG_AttachmentAxis

Return the attachment axis
===============
*/
qboolean CG_AttachmentAxis( attachment_t *a, vec3_t axis[ 3 ] )
{
    centity_t *cent;

    if ( !a )
    {
        return qfalse;
    }

    switch ( a->type )
    {
    case AT_STATIC:
        return qfalse;
        break;

    case AT_TAG:
        if ( !a->tagValid )
        {
            return qfalse;
        }

        AxisCopy( a->re.axis, axis );
        break;

    case AT_CENT:
        if ( !a->centValid )
        {
            return qfalse;
        }

        cent = &cg_entities[ a->centNum ];
        AnglesToAxis( cent->lerpAngles, axis );
        break;

    case AT_PARTICLE:
        return qfalse;
        break;

    default:
        CG_Printf( S_COLOR_RED "ERROR: Invalid attachmentType_t in attachment\n" );
        break;
    }

    return qtrue;
}
Exemple #9
0
/*
==================
CG_LaunchGib
==================
*/
void CG_LaunchGib( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
	localEntity_t	*le;
	refEntity_t		*re;
//freeze
	int	num;
	centity_t	*cent;
//freeze

	le = CG_AllocLocalEntity();
	re = &le->refEntity;

	le->leType = LE_FRAGMENT;
	le->startTime = cg.time;
	le->endTime = le->startTime + 5000 + random() * 3000;

	VectorCopy( origin, re->origin );
	AxisCopy( axisDefault, re->axis );
	re->hModel = hModel;

	le->pos.trType = TR_GRAVITY;
	VectorCopy( origin, le->pos.trBase );
	VectorCopy( velocity, le->pos.trDelta );
	le->pos.trTime = cg.time;

	le->bounceFactor = 0.6f;

	le->leBounceSoundType = LEBS_BLOOD;
	le->leMarkType = LEMT_BLOOD;
//freeze
	for ( num = 0; num < cg.snap->numEntities; num++ ) {
		cent = &cg_entities[ cg.snap->entities[ num ].number ];
		if ( cent->currentState.eventParm != 255 ) continue;
		if ( VectorCompare( cent->lerpOrigin, origin ) ) {
			re->customShader = cgs.media.freezeShader;
			break;
		}
	}
//freeze
}
Exemple #10
0
/*
===============
CG_AttachmentPoint

Return the attachment point
===============
*/
qboolean CG_AttachmentPoint( attachment_t *a, vec3_t v )
{
    centity_t *cent;

    if ( !a )
    {
        return qfalse;
    }

    // if it all breaks, then use the last point we know was correct
    VectorCopy( a->lastValidAttachmentPoint, v );

    switch ( a->type )
    {
    case AT_STATIC:
        if ( !a->staticValid )
        {
            return qfalse;
        }

        VectorCopy( a->origin, v );
        break;

    case AT_TAG:
        if ( !a->tagValid )
        {
            return qfalse;
        }

        AxisCopy( axisDefault, a->re.axis );
        CG_PositionRotatedEntityOnTag( &a->re, &a->parent,
                                       a->model, a->tagName );
        VectorCopy( a->re.origin, v );
        break;

    case AT_CENT:
        if ( !a->centValid )
        {
            return qfalse;
        }

        if ( a->centNum == cg.predictedPlayerState.clientNum )
        {
            // this is smoother if it's the local client
            VectorCopy( cg.predictedPlayerState.origin, v );
        }
        else
        {
            cent = &cg_entities[ a->centNum ];
            VectorCopy( cent->lerpOrigin, v );
        }

        break;

    case AT_PARTICLE:
        if ( !a->particleValid )
        {
            return qfalse;
        }

        if ( !a->particle->valid )
        {
            a->particleValid = qfalse;
            return qfalse;
        }
        else
        {
            VectorCopy( a->particle->origin, v );
        }

        break;

    default:
        CG_Printf( S_COLOR_RED "ERROR: Invalid attachmentType_t in attachment\n" );
        break;
    }

    if ( a->hasOffset )
    {
        VectorAdd( v, a->offset, v );
    }

    VectorCopy( v, a->lastValidAttachmentPoint );

    return qtrue;
}
Exemple #11
0
/*
==========================
CG_MachineGunEjectBrass
==========================
*/
static void CG_MachineGunEjectBrass( centity_t *cent ) {
	localEntity_t	*le;
	refEntity_t		*re;
	vec3_t			velocity, xvelocity;
	vec3_t			offset, xoffset;
	float			waterScale = 1.0f;
	vec3_t			v[3];

	if ( cg_brassTime.integer <= 0 ) {
		return;
	}

	le = CG_AllocLocalEntity();
	re = &le->refEntity;

	velocity[0] = 0;
	velocity[1] = -50 + 40 * crandom();
	velocity[2] = 100 + 50 * crandom();

	le->leType = LE_FRAGMENT;
	le->startTime = cg.time;
	le->endTime = le->startTime + cg_brassTime.integer + ( cg_brassTime.integer / 4 ) * random();

	le->pos.trType = TR_GRAVITY;
	le->pos.trTime = cg.time - (rand()&15);

	AnglesToAxis( cent->lerpAngles, v );

	offset[0] = 8;
	offset[1] = -4;
	offset[2] = 24;

	xoffset[0] = offset[0] * v[0][0] + offset[1] * v[1][0] + offset[2] * v[2][0];
	xoffset[1] = offset[0] * v[0][1] + offset[1] * v[1][1] + offset[2] * v[2][1];
	xoffset[2] = offset[0] * v[0][2] + offset[1] * v[1][2] + offset[2] * v[2][2];
	VectorAdd( cent->lerpOrigin, xoffset, re->origin );

	VectorCopy( re->origin, le->pos.trBase );

	if ( CG_PointContents( re->origin, -1 ) & CONTENTS_WATER ) {
		waterScale = 0.10f;
	}

	xvelocity[0] = velocity[0] * v[0][0] + velocity[1] * v[1][0] + velocity[2] * v[2][0];
	xvelocity[1] = velocity[0] * v[0][1] + velocity[1] * v[1][1] + velocity[2] * v[2][1];
	xvelocity[2] = velocity[0] * v[0][2] + velocity[1] * v[1][2] + velocity[2] * v[2][2];
	VectorScale( xvelocity, waterScale, le->pos.trDelta );

	AxisCopy( axisDefault, re->axis );
	re->hModel = cgs.media.machinegunBrassModel;

	le->bounceFactor = 0.4 * waterScale;

	le->angles.trType = TR_LINEAR;
	le->angles.trTime = cg.time;
	le->angles.trBase[0] = rand()&31;
	le->angles.trBase[1] = rand()&31;
	le->angles.trBase[2] = rand()&31;
	le->angles.trDelta[0] = 2;
	le->angles.trDelta[1] = 1;
	le->angles.trDelta[2] = 0;

	le->leFlags = LEF_TUMBLE;
	le->leBounceSoundType = LEBS_BRASS;
	le->leMarkType = LEMT_NONE;
}
Exemple #12
0
/*
===============
CG_OffsetThirdPersonView

===============
*/
void CG_OffsetThirdPersonView( void )
{
  int i;
  vec3_t        forward, right, up;
  vec3_t        view;
  trace_t       trace;
  static vec3_t mins = { -8, -8, -8 };
  static vec3_t maxs = { 8, 8, 8 };
  vec3_t        focusPoint;
  vec3_t        surfNormal;
  int           cmdNum;
  usercmd_t     cmd, oldCmd;
  float         range;
  vec3_t        mouseInputAngles;
  vec3_t        rotationAngles;
  vec3_t        axis[ 3 ], rotaxis[ 3 ];
  float         deltaPitch;
  static float  pitch;
  static vec3_t killerPos = { 0, 0, 0 };

  // If cg_thirdpersonShoulderViewMode == 2, do shoulder view instead
  // If cg_thirdpersonShoulderViewMode == 1, do shoulder view when chasing
  //   a wallwalker because it's really erratic to watch
  if( ( cg_thirdPersonShoulderViewMode.integer == 2 ) ||
      ( ( cg_thirdPersonShoulderViewMode.integer == 1 ) &&
        ( cg.snap->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) &&
        ( cg.snap->ps.stats[ STAT_HEALTH ] > 0 ) ) )
  {
    CG_OffsetShoulderView( );
    return;
  }

  BG_GetClientNormal( &cg.predictedPlayerState, surfNormal );
  // Set the view origin to the class's view height
  VectorMA( cg.refdef.vieworg, cg.predictedPlayerState.viewheight, surfNormal, cg.refdef.vieworg );

  // Set the focus point where the camera will look (at the player's vieworg)
  VectorCopy( cg.refdef.vieworg, focusPoint );

  // If player is dead, we want the player to be between us and the killer
  // so pretend that the player was looking at the killer, then place cam behind them.
  if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
  {
    int killerEntNum = cg.predictedPlayerState.stats[ STAT_VIEWLOCK ];

    // already looking at ourself
    if( killerEntNum != cg.snap->ps.clientNum )
    {
      vec3_t lookDirection;
      if( cg.wasDeadLastFrame == qfalse || !cg_staticDeathCam.integer )
      {
        VectorCopy( cg_entities[ killerEntNum ].lerpOrigin, killerPos );
        cg.wasDeadLastFrame = qtrue;
      }
      VectorSubtract( killerPos, cg.refdef.vieworg, lookDirection );
      vectoangles( lookDirection, cg.refdefViewAngles );
    }
  }

  // get and rangecheck cg_thirdPersonRange
  range = cg_thirdPersonRange.value;
  if( range > 150.0f ) range = 150.0f;
  if( range < 30.0f ) range = 30.0f;

  // Calculate the angle of the camera's position around the player.
  // Unless in demo, PLAYING in third person, or in dead-third-person cam, allow the player 
  // to control camera position offsets using the mouse position.
  if( cg.demoPlayback || 
    ( ( cg.snap->ps.pm_flags & PMF_FOLLOW ) && 
      ( cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 ) ) )
  {
    // Collect our input values from the mouse.
    cmdNum = trap_GetCurrentCmdNumber();
    trap_GetUserCmd( cmdNum, &cmd );
    trap_GetUserCmd( cmdNum - 1, &oldCmd );

    // Prevent pitch from wrapping and clamp it within a [-75, 90] range.
    // Cgame has no access to ps.delta_angles[] here, so we need to reproduce
    // it ourselves.
    deltaPitch = SHORT2ANGLE( cmd.angles[ PITCH ] - oldCmd.angles[ PITCH ] );
    if( fabs(deltaPitch) < 200.0f )
    {
      pitch += deltaPitch;
    }

    mouseInputAngles[ PITCH ] = pitch;
    mouseInputAngles[ YAW ] = -1.0f * SHORT2ANGLE( cmd.angles[ YAW ] ); // yaw is inverted
    mouseInputAngles[ ROLL ] = 0.0f;

    for( i = 0; i < 3; i++ )
      mouseInputAngles[ i ] = AngleNormalize180( mouseInputAngles[ i ] );

    // Set the rotation angles to be the view angles offset by the mouse input
    // Ignore the original pitch though; it's too jerky otherwise
    if( !cg_thirdPersonPitchFollow.integer ) 
      cg.refdefViewAngles[ PITCH ] = 0.0f;

    for( i = 0; i < 3; i++ )
    {
      rotationAngles[ i ] = AngleNormalize180(cg.refdefViewAngles[ i ]) + mouseInputAngles[ i ];
      AngleNormalize180( rotationAngles[ i ] );
    }

    // Don't let pitch go too high/too low or the camera flips around and
    // that's really annoying.
    // However, when we're not on the floor or ceiling (wallwalk) pitch 
    // may not be pitch, so just let it go.
    if( surfNormal[ 2 ] > 0.5f || surfNormal[ 2 ] < -0.5f ) 
    {
      if( rotationAngles[ PITCH ] > 85.0f )
        rotationAngles[ PITCH ] = 85.0f;
      else if( rotationAngles[ PITCH ] < -85.0f )
        rotationAngles[ PITCH ] = -85.0f;
    }

    // Perform the rotations specified by rotationAngles.
    AnglesToAxis( rotationAngles, axis );
    if( !( cg.snap->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) ||
        !BG_RotateAxis( cg.snap->ps.grapplePoint, axis, rotaxis, qfalse,
                        cg.snap->ps.eFlags & EF_WALLCLIMBCEILING ) )
      AxisCopy( axis, rotaxis );

    // Convert the new axis back to angles.
    AxisToAngles( rotaxis, rotationAngles );
  }
  else 
  {
    if( cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 )
    {
      // If we're playing the game in third person, the viewangles already
      // take care of our mouselook, so just use them.
      for( i = 0; i < 3; i++ )
        rotationAngles[ i ] = cg.refdefViewAngles[ i ];
    }
    else // dead
    {
      rotationAngles[ PITCH ] = 20.0f;
      rotationAngles[ YAW ] = cg.refdefViewAngles[ YAW ];
    }
  }

  rotationAngles[ YAW ] -= cg_thirdPersonAngle.value;

  // Move the camera range distance back.
  AngleVectors( rotationAngles, forward, right, up );
  VectorCopy( cg.refdef.vieworg, view );
  VectorMA( view, -range, forward, view );

  // Ensure that the current camera position isn't out of bounds and that there
  // is nothing between the camera and the player.
  if( !cg_cameraMode.integer )
  {
    // Trace a ray from the origin to the viewpoint to make sure the view isn't
    // in a solid block.  Use an 8 by 8 block to prevent the view from near clipping anything
    CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID );

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

      CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID );
      VectorCopy( trace.endpos, view );
    }
  }

  // Set the camera position to what we calculated.
  VectorCopy( view, cg.refdef.vieworg );

  // The above checks may have moved the camera such that the existing viewangles
  // may not still face the player. Recalculate them to do so.
  // but if we're dead, don't bother because we'd rather see what killed us
  if( cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 )
  {
    VectorSubtract( focusPoint, cg.refdef.vieworg, focusPoint );
    vectoangles( focusPoint, cg.refdefViewAngles );
  }
}
Exemple #13
0
/*
=================
R_GetPortalOrientation

entityNum is the entity that the portal surface is a part of, which may
be moving and rotating.

Returns qtrue if it should be mirrored
=================
*/
qboolean R_GetPortalOrientations( drawSurf_t *drawSurf, int entityNum,
							 orientation_t *surface, orientation_t *camera,
							 vec3_t pvsOrigin, qboolean *mirror ) {
	int			i;
	cplane_t	originalPlane, plane;
	trRefEntity_t	*e;
	float		d;
	vec3_t		transformed;

	// create plane axis for the portal we are seeing
	R_PlaneForSurface( drawSurf->surface, &originalPlane );

	// rotate the plane if necessary
	if ( entityNum != REFENTITYNUM_WORLD ) {
		tr.currentEntityNum = entityNum;
		tr.currentEntity = &tr.refdef.entities[entityNum];

		// get the orientation of the entity
		R_RotateForEntity( tr.currentEntity, &tr.viewParms, &tr.ori );

		// rotate the plane, but keep the non-rotated version for matching
		// against the portalSurface entities
		R_LocalNormalToWorld( originalPlane.normal, plane.normal );
		plane.dist = originalPlane.dist + DotProduct( plane.normal, tr.ori.origin );

		// translate the original plane
		originalPlane.dist = originalPlane.dist + DotProduct( originalPlane.normal, tr.ori.origin );
	} else {
		plane = originalPlane;
	}

	VectorCopy( plane.normal, surface->axis[0] );
	PerpendicularVector( surface->axis[1], surface->axis[0] );
	CrossProduct( surface->axis[0], surface->axis[1], surface->axis[2] );

	// locate the portal entity closest to this plane.
	// origin will be the origin of the portal, origin2 will be
	// the origin of the camera
	for ( i = 0 ; i < tr.refdef.num_entities ; i++ ) {
		e = &tr.refdef.entities[i];
		if ( e->e.reType != RT_PORTALSURFACE ) {
			continue;
		}

		d = DotProduct( e->e.origin, originalPlane.normal ) - originalPlane.dist;
		if ( d > 64 || d < -64) {
			continue;
		}

		// get the pvsOrigin from the entity
		VectorCopy( e->e.oldorigin, pvsOrigin );

		// if the entity is just a mirror, don't use as a camera point
		if ( e->e.oldorigin[0] == e->e.origin[0] &&
			e->e.oldorigin[1] == e->e.origin[1] &&
			e->e.oldorigin[2] == e->e.origin[2] ) {
			VectorScale( plane.normal, plane.dist, surface->origin );
			VectorCopy( surface->origin, camera->origin );
			VectorSubtract( vec3_origin, surface->axis[0], camera->axis[0] );
			VectorCopy( surface->axis[1], camera->axis[1] );
			VectorCopy( surface->axis[2], camera->axis[2] );

			*mirror = qtrue;
			return qtrue;
		}

		// project the origin onto the surface plane to get
		// an origin point we can rotate around
		d = DotProduct( e->e.origin, plane.normal ) - plane.dist;
		VectorMA( e->e.origin, -d, surface->axis[0], surface->origin );

		// now get the camera origin and orientation
		VectorCopy( e->e.oldorigin, camera->origin );
		AxisCopy( e->e.axis, camera->axis );
		VectorSubtract( vec3_origin, camera->axis[0], camera->axis[0] );
		VectorSubtract( vec3_origin, camera->axis[1], camera->axis[1] );

		// optionally rotate
		if ( e->e.oldframe ) {
			// if a speed is specified
			if ( e->e.frame ) {
				// continuous rotate
				d = (tr.refdef.time/1000.0f) * e->e.frame;
				VectorCopy( camera->axis[1], transformed );
				RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
				CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
			} else {
				// bobbing rotate, with skinNum being the rotation offset
				d = sin( tr.refdef.time * 0.003f );
				d = e->e.skinNum + d * 4;
				VectorCopy( camera->axis[1], transformed );
				RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
				CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
			}
		}
		else if ( e->e.skinNum ) {
			d = e->e.skinNum;
			VectorCopy( camera->axis[1], transformed );
			RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
			CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
		}
		*mirror = qfalse;
		return qtrue;
	}

	// if we didn't locate a portal entity, don't render anything.
	// We don't want to just treat it as a mirror, because without a
	// portal entity the server won't have communicated a proper entity set
	// in the snapshot

	// unfortunately, with local movement prediction it is easily possible
	// to see a surface before the server has communicated the matching
	// portal surface entity, so we don't want to print anything here...

	//ri->Printf( PRINT_ALL, "Portal surface without a portal entity\n" );

	return qfalse;
}
void ME_DrawVehicle( IGME_vehicle_t* veh ) 
{
	if( !veh ) return;

	if( veh->groundInstallation ) {
		DrawInfo_GI_t drawInfo;
		memset( &drawInfo, 0, sizeof(drawInfo) );
		VectorCopy( veh->angles, drawInfo.basicInfo.angles );
		VectorCopy( veh->origin, drawInfo.basicInfo.origin );
		AnglesToAxis( veh->angles, drawInfo.basicInfo.axis );
		drawInfo.basicInfo.vehicleIndex = veh->vehidx;
		drawInfo.basicInfo.entityNum = -1;
		drawInfo.turretAngle = 0;
		drawInfo.gunAngle = 10;
		drawInfo.upgrades = availableGroundInstallations[veh->vehidx].upgrades;
		CG_DrawGI(&drawInfo);
	} else {
		switch( availableVehicles[veh->vehidx].cat ) {
		case CAT_PLANE:
			{
				DrawInfo_Plane_t drawInfo;
				memset( &drawInfo, 0, sizeof(drawInfo) );
				VectorCopy( veh->angles, drawInfo.basicInfo.angles );
				VectorCopy( veh->origin, drawInfo.basicInfo.origin );
				AnglesToAxis( veh->angles, drawInfo.basicInfo.axis );
				drawInfo.basicInfo.vehicleIndex = veh->vehidx;
				drawInfo.basicInfo.entityNum = -1;
				drawInfo.basicInfo.usedLoadout = &availableLoadouts[veh->vehidx];
				CG_DrawPlane(&drawInfo);	
			}
			break;
		case CAT_GROUND:
			{
				DrawInfo_GV_t drawInfo;
				memset( &drawInfo, 0, sizeof(drawInfo) );
				VectorCopy( veh->angles, drawInfo.basicInfo.angles );
				VectorCopy( veh->origin, drawInfo.basicInfo.origin );
				AnglesToAxis( veh->angles, drawInfo.basicInfo.axis );
				drawInfo.basicInfo.vehicleIndex = veh->vehidx;
				drawInfo.basicInfo.entityNum = -1;
				drawInfo.basicInfo.usedLoadout = &availableLoadouts[veh->vehidx];
				CG_DrawGV(&drawInfo);	
			}
			break;
		case CAT_BOAT:
			{
				DrawInfo_Boat_t drawInfo;
				memset( &drawInfo, 0, sizeof(drawInfo) );
				VectorCopy( veh->angles, drawInfo.basicInfo.angles );
				VectorCopy( veh->origin, drawInfo.basicInfo.origin );
				AnglesToAxis( veh->angles, drawInfo.basicInfo.axis );
				drawInfo.basicInfo.vehicleIndex = veh->vehidx;
				drawInfo.basicInfo.entityNum = -1;
				drawInfo.basicInfo.usedLoadout = &availableLoadouts[veh->vehidx];
				CG_DrawBoat(&drawInfo);
			}
			break;
		case CAT_HELO:
			break;
		case CAT_LQM:
			break;
		}
	}

	// draw selectors
	if( veh->selected ) {
		refEntity_t	sel;
		int j;
		memset( &sel, 0, sizeof(sel) );
		sel.hModel = cgs.media.IGME_selector;
		VectorCopy( veh->origin, sel.origin );
		VectorCopy( veh->origin, sel.lightingOrigin );
		VectorCopy( veh->origin, sel.oldorigin );
		AnglesToAxis( veh->angles, sel.axis );
		for( j = 0; j < 3; ++j ) {
			VectorScale( sel.axis[j], veh->selectorScale[j], sel.axis[j] );
		}
		sel.nonNormalizedAxes = true;
		refExport.AddRefEntityToScene( &sel );
	}
	// draw waypoints
	if( cgs.IGME.waypointmode && (veh->selected || cgs.IGME.showAllWaypoints) ) {
		int k;
		vec3_t lastpos, dir, ang;
		VectorCopy( veh->origin, lastpos );
		for( k = 0; k < IGME_MAX_WAYPOINTS; ++k ) {
			refEntity_t	wpt, lnk;
			int l;
			float dist;
			if( !veh->waypoints[k].active ) break;//as they are in a row
			memset( &wpt, 0, sizeof(wpt) );
			wpt.hModel = cgs.media.IGME_selector;
			VectorCopy( veh->waypoints[k].origin, wpt.origin );
			VectorCopy( wpt.origin, wpt.lightingOrigin );
			VectorCopy( wpt.origin, wpt.oldorigin );
			AxisCopy( axisDefault, wpt.axis );
			for( l = 0; l < 3; ++l ) {
				VectorScale( wpt.axis[l], 0.25f, wpt.axis[l] );
			}
			wpt.nonNormalizedAxes = true;
			if( veh->waypoints[k].selected ) {
				wpt.customShader = cgs.media.IGME_waypoint;
			} else {
				wpt.customShader = cgs.media.IGME_waypoint2;
			}
			refExport.AddRefEntityToScene( &wpt );
			// draw link
			VectorSubtract( wpt.origin, lastpos, dir );
			dist = VectorNormalize( dir );
			dist *= 0.97f;
			vectoangles( dir, ang );
			memset( &lnk, 0, sizeof(lnk) );
			lnk.hModel = cgs.media.IGME_selector;
			VectorMA( lastpos, dist/2, dir, lnk.origin );
			VectorCopy( lnk.origin, lnk.lightingOrigin );
			VectorCopy( lnk.origin, lnk.oldorigin );
			AnglesToAxis( ang, lnk.axis );
			VectorScale( lnk.axis[0], dist/200.0f, lnk.axis[0] );
			VectorScale( lnk.axis[1], 0.01f, lnk.axis[1] );
			VectorScale( lnk.axis[2], 0.01f, lnk.axis[2] );
			lnk.nonNormalizedAxes = true;
			lnk.customShader = cgs.media.IGME_waypoint2;
			refExport.AddRefEntityToScene( &lnk );
			VectorCopy( veh->waypoints[k].origin, lastpos );
		}
	}
}
Exemple #15
0
void CG_Chunks( int owner, vec3_t origin, const vec3_t normal, const vec3_t mins, const vec3_t maxs,
						float speed, int numChunks, material_t chunkType, int customChunk, float baseScale, int customSound = 0 )
{
	localEntity_t	*le;
	refEntity_t		*re;
	vec3_t			dir;
	int				i, j, k;
	int				chunkModel = 0;
	leBounceSound_t	bounce = LEBS_NONE;
	float			r, speedMod = 1.0f;
	qboolean		chunk = qfalse;

	if ( chunkType == MAT_NONE )
	{
		// Well, we should do nothing
		return;
	}

	if ( customSound )
	{
		if ( cgs.sound_precache[customSound] )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgs.sound_precache[customSound] );
		}
	}
	// Set up our chunk sound info...breaking sounds are done here so they are done once on breaking..some return instantly because the chunks are done with effects instead of models
	switch( chunkType )
	{
	case MAT_GLASS:
		if ( !customSound )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgs.media.glassChunkSound );
		}
		return;
		break;
	case MAT_GRATE1:
		if ( !customSound )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgs.media.grateSound );
		}
		return;
		break;
	case MAT_ELECTRICAL:// (sparks)
		if ( !customSound )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgi_S_RegisterSound (va("sound/ambience/spark%d.wav", Q_irand(1, 6))) );
		}
		return;
		break;
	case MAT_DRK_STONE:
	case MAT_LT_STONE:
	case MAT_GREY_STONE:
	case MAT_WHITE_METAL:  // not quite sure what this stuff is supposed to be...it's for Stu
		if ( !customSound )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgs.media.rockBreakSound );
			bounce = LEBS_ROCK;
		}
		speedMod = 0.5f; // rock blows up less
		break;
	case MAT_GLASS_METAL:
		if ( !customSound )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgs.media.glassChunkSound ); // FIXME: should probably have a custom sound
			bounce = LEBS_METAL;
		}
		break;
	case MAT_CRATE1:
	case MAT_CRATE2:
		if ( !customSound )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgs.media.crateBreakSound[Q_irand(0,1)] );
		}
		break;
	case MAT_METAL:
	case MAT_METAL2:
	case MAT_METAL3:
	case MAT_ELEC_METAL:// FIXME: maybe have its own sound?
		if ( !customSound )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgs.media.chunkSound );
			bounce = LEBS_METAL;
		}
		speedMod = 0.8f; // metal blows up a bit more
		break;
	case MAT_ROPE:
		/*
		if ( !customSound )
		{
			cgi_S_StartSound( NULL, owner, CHAN_BODY, cgi_S_RegisterSound( "" ));  FIXME:  needs a sound
		}
		*/
		return;
	default:
		break;
	}

	if ( baseScale <= 0.0f )
	{
		baseScale = 1.0f;
	}

	// Chunks
	for( i = 0; i < numChunks; i++ )
	{
		if ( customChunk > 0 )
		{
			// Try to use a custom chunk.
			if ( cgs.model_draw[customChunk] )
			{
				chunk = qtrue;
				chunkModel = cgs.model_draw[customChunk];
			}
		}

		if ( !chunk )
		{
			// No custom chunk.  Pick a random chunk type at run-time so we don't get the same chunks
			switch( chunkType )
			{
			case MAT_METAL2: //bluegrey
				chunkModel = cgs.media.chunkModels[CHUNK_METAL2][Q_irand(0, 3)];
				break;
			case MAT_GREY_STONE://gray
				chunkModel = cgs.media.chunkModels[CHUNK_ROCK1][Q_irand(0, 3)];
				break;
			case MAT_LT_STONE: //tan
				chunkModel = cgs.media.chunkModels[CHUNK_ROCK2][Q_irand(0, 3)];
				break;
			case MAT_DRK_STONE://brown
				chunkModel = cgs.media.chunkModels[CHUNK_ROCK3][Q_irand(0, 3)];
				break;
			case MAT_WHITE_METAL:
				chunkModel = cgs.media.chunkModels[CHUNK_WHITE_METAL][Q_irand(0, 3)];
				break;
			case MAT_CRATE1://yellow multi-colored crate chunks
				chunkModel = cgs.media.chunkModels[CHUNK_CRATE1][Q_irand(0, 3)];
				break;
			case MAT_CRATE2://red multi-colored crate chunks
				chunkModel = cgs.media.chunkModels[CHUNK_CRATE2][Q_irand(0, 3)];
				break;
			case MAT_ELEC_METAL:
			case MAT_GLASS_METAL:
			case MAT_METAL://grey
				chunkModel = cgs.media.chunkModels[CHUNK_METAL1][Q_irand(0, 3)];
				break;
			case MAT_METAL3:
				if ( rand() & 1 )
				{
					chunkModel = cgs.media.chunkModels[CHUNK_METAL1][Q_irand(0, 3)];
				}
				else
				{
					chunkModel = cgs.media.chunkModels[CHUNK_METAL2][Q_irand(0, 3)];
				}
				break;
			default:
				break;
			}
		}

		// It wouldn't look good to throw a bunch of RGB axis models...so make sure we have something to work with.
		if ( chunkModel )
		{
			le = CG_AllocLocalEntity();
			re = &le->refEntity;

			re->hModel = chunkModel;
			le->leType = LE_FRAGMENT;
			le->endTime = cg.time + 1300 + Q_flrand(0.0f, 1.0f) * 900;

			// spawn chunk roughly in the bbox of the thing...bias towards center in case thing blowing up doesn't complete fill its bbox.
			for( j = 0; j < 3; j++ )
			{
				r = Q_flrand(0.0f, 1.0f) * 0.8f + 0.1f;
				re->origin[j] = ( r * mins[j] + ( 1 - r ) * maxs[j] );
			}
			VectorCopy( re->origin, le->pos.trBase );

			// Move out from center of thing, otherwise you can end up things moving across the brush in an undesirable direction.  Visually looks wrong
			VectorSubtract( re->origin, origin, dir );
			VectorNormalize( dir );
			VectorScale( dir, Q_flrand( speed * 0.5f, speed * 1.25f ) * speedMod, le->pos.trDelta );

			// Angular Velocity
			VectorSet( le->angles.trBase, Q_flrand(0.0f, 1.0f) * 360, Q_flrand(0.0f, 1.0f) * 360, Q_flrand(0.0f, 1.0f) * 360 );

			le->angles.trDelta[0] = Q_flrand(-1.0f, 1.0f);
			le->angles.trDelta[1] = Q_flrand(-1.0f, 1.0f);
			le->angles.trDelta[2] = 0; // don't do roll

			VectorScale( le->angles.trDelta, Q_flrand(0.0f, 1.0f) * 600.0f + 200.0f, le->angles.trDelta );

			le->pos.trType = TR_GRAVITY;
			le->angles.trType = TR_LINEAR;
			le->pos.trTime = le->angles.trTime = cg.time;
			le->bounceFactor = 0.2f + Q_flrand(0.0f, 1.0f) * 0.2f;
			le->leFlags |= LEF_TUMBLE;
			le->ownerGentNum = owner;
			le->leBounceSoundType = bounce;

			// Make sure that we have the desired start size set
			le->radius = Q_flrand( baseScale * 0.75f, baseScale * 1.25f );
			re->nonNormalizedAxes = qtrue;
			AxisCopy( axisDefault, re->axis ); // could do an angles to axis, but this is cheaper and works ok
			for( k = 0; k < 3; k++ )
			{
				VectorScale( re->axis[k], le->radius, re->axis[k] );
			}
		}
	}
}
Exemple #16
0
/*
==============
CG_LoseHat
==============
*/
void CG_LoseHat(centity_t *cent, vec3_t dir)
{
	clientInfo_t *ci;
	int          clientNum;
//	int				i, count, tagIndex, gibIndex;
	int            tagIndex;
	vec3_t         origin, velocity;
	bg_character_t *character;

	clientNum = cent->currentState.clientNum;
	if (clientNum < 0 || clientNum >= MAX_CLIENTS)
	{
		CG_Error("Bad clientNum on player entity");
	}
	ci        = &cgs.clientinfo[clientNum];
	character = CG_CharacterForClientinfo(ci, cent);

	// don't launch anything if they don't have one
	if (!character->accModels[ACC_HAT])
	{
		return;
	}

	tagIndex = CG_GetOriginForTag(cent, &cent->pe.headRefEnt, "tag_mouth", 0, origin, NULL);

	velocity[0] = dir[0] * (0.75 + random()) * GIB_VELOCITY;
	velocity[1] = dir[1] * (0.75 + random()) * GIB_VELOCITY;
	velocity[2] = GIB_JUMP - 50 + dir[2] * (0.5 + random()) * GIB_VELOCITY;

	{
		localEntity_t *le;
		refEntity_t   *re;

		le = CG_AllocLocalEntity();
		re = &le->refEntity;

		le->leType    = LE_FRAGMENT;
		le->startTime = cg.time;
		le->endTime   = le->startTime + 20000 + (crandom() * 5000);

		VectorCopy(origin, re->origin);
		AxisCopy(axisDefault, re->axis);
		re->hModel     = character->accModels[ACC_HAT];
		re->customSkin = character->accSkins[ACC_HAT];

		re->fadeStartTime = le->endTime - 1000;
		re->fadeEndTime   = le->endTime;

		// (SA) FIXME: origin of hat md3 is offset from center.  need to center the origin when you toss it
		le->pos.trType = TR_GRAVITY;
		VectorCopy(origin, le->pos.trBase);
		VectorCopy(velocity, le->pos.trDelta);
		le->pos.trTime = cg.time;

		// spin it a bit
		le->angles.trType = TR_LINEAR;
		VectorCopy(tv(0, 0, 0), le->angles.trBase);
		le->angles.trDelta[0] = 0;
		le->angles.trDelta[1] = (100 + (rand() & 500)) - 300;
//		le->angles.trDelta[2]	= 0;
		le->angles.trDelta[2] = 400;    // (SA) this is set with a very particular value to try to get it
		                                // to flip exactly once before landing (based on player alive
		                                // (standing) and on level ground) and will be unnecessary when
		                                // I have things landing properly on their own

		le->angles.trTime = cg.time;

		le->bounceFactor = 0.2;

		// Ridah, if the player is on fire, then make the hat on fire
		if (cent && CG_EntOnFire(cent))
		{
			le->onFireStart = cent->currentState.onFireStart;
			le->onFireEnd   = cent->currentState.onFireEnd + 4000;
		}
	}
}
Exemple #17
0
void
CBulletVolume::render( centity_t& ent )
{
    entityState_t& es = ent.currentState;

    if (!(es.groundEntityNum & BVF_ENABLED))
        return;

    // Setup refent.
    refEntity_t re;
    memset( &re, 0, sizeof(re) );

    re.reType            = RT_MODEL;
    re.renderfx          = RF_NOSHADOW;
    re.hModel            = cgs.media.polygonCubeFO;
    re.nonNormalizedAxes = qtrue;
    re.customShader      = cgs.media.bulletVolumeShader;

    re.shaderRGBA[3] = byte(es.angles2[2] * 255.0f);
    switch (es.modelindex) {
        default: // UNKNWON -> GRAY
        case 0:
            re.shaderRGBA[0] = byte(0.5f * 255.0f);
            re.shaderRGBA[1] = byte(0.5f * 255.0f);
            re.shaderRGBA[2] = byte(0.5f * 255.0f);
            break;

        case 1: // NOHIT -> BLUE
            re.shaderRGBA[0] = byte(0.0f * 255.0f);
            re.shaderRGBA[1] = byte(0.0f * 255.0f);
            re.shaderRGBA[2] = byte(1.0f * 255.0f);
            break;

        case 2: // HIT -> RED
            re.shaderRGBA[0] = byte(1.0f * 255.0f);
            re.shaderRGBA[1] = byte(0.0f * 255.0f);
            re.shaderRGBA[2] = byte(0.0f * 255.0f);
            break;

        case 3: // REFERENCE NOHIT -> GREEN
            re.shaderRGBA[0] = byte(0.0f * 255.0f);
            re.shaderRGBA[1] = byte(1.0f * 255.0f);
            re.shaderRGBA[2] = byte(0.0f * 255.0f);
            break;

        case 4: // REFERENCE HIT -> YELLOW
            re.shaderRGBA[0] = byte(1.0f * 255.0f);
            re.shaderRGBA[1] = byte(1.0f * 255.0f);
            re.shaderRGBA[2] = byte(0.0f * 255.0f);
            break;
    }

    // Apply entity rotation.
    AxisClear( re.axis );
    AnglesToAxis( es.angles, re.axis );

    // Apply scaling matrix.
    vec3_t smatrix[3];
    AxisClear( smatrix );

    smatrix[0][0] *= es.origin2[0];
    smatrix[1][1] *= es.origin2[1];
    smatrix[2][2] *= es.origin2[2];

    vec3_t tmp[3];
    MatrixMultiply( smatrix, re.axis, tmp );
    AxisCopy( tmp, re.axis );

    // Set origins.
    VectorCopy( es.origin, re.origin );
    VectorCopy( es.origin, re.oldorigin );
    VectorCopy( es.origin, re.lightingOrigin );

    trap_R_AddRefEntityToScene( &re );
}
Exemple #18
0
/*
===============
CG_smoothWWTransitions
===============
*/
static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t out )
{
  vec3_t    surfNormal, rotAxis, temp;
  vec3_t    refNormal     = { 0.0f, 0.0f,  1.0f };
  vec3_t    ceilingNormal = { 0.0f, 0.0f, -1.0f };
  int       i;
  float     stLocal, sFraction, rotAngle;
  float     smoothTime, timeMod;
  qboolean  performed = qfalse;
  vec3_t    inAxis[ 3 ], lastAxis[ 3 ], outAxis[ 3 ];

  if( cg.snap->ps.pm_flags & PMF_FOLLOW )
  {
    VectorCopy( in, out );
    return;
  }

  //set surfNormal
  BG_GetClientNormal( ps, surfNormal );

  AnglesToAxis( in, inAxis );

  //if we are moving from one surface to another smooth the transition
  if( !VectorCompare( surfNormal, cg.lastNormal ) )
  {
    //if we moving from the ceiling to the floor special case
    //( x product of colinear vectors is undefined)
    if( VectorCompare( ceilingNormal, cg.lastNormal ) &&
        VectorCompare( refNormal,     surfNormal ) )
    {
      AngleVectors( in, temp, NULL, NULL );
      ProjectPointOnPlane( rotAxis, temp, refNormal );
      VectorNormalize( rotAxis );
      rotAngle = 180.0f;
      timeMod = 1.5f;
    }
    else
    {
      AnglesToAxis( cg.lastVangles, lastAxis );
      rotAngle = DotProduct( inAxis[ 0 ], lastAxis[ 0 ] ) +
                 DotProduct( inAxis[ 1 ], lastAxis[ 1 ] ) +
                 DotProduct( inAxis[ 2 ], lastAxis[ 2 ] );

      rotAngle = RAD2DEG( acos( ( rotAngle - 1.0f ) / 2.0f ) );

      CrossProduct( lastAxis[ 0 ], inAxis[ 0 ], temp );
      VectorCopy( temp, rotAxis );
      CrossProduct( lastAxis[ 1 ], inAxis[ 1 ], temp );
      VectorAdd( rotAxis, temp, rotAxis );
      CrossProduct( lastAxis[ 2 ], inAxis[ 2 ], temp );
      VectorAdd( rotAxis, temp, rotAxis );

      VectorNormalize( rotAxis );

      timeMod = 1.0f;
    }

    //add the op
    CG_addSmoothOp( rotAxis, rotAngle, timeMod );
  }

  //iterate through ops
  for( i = MAXSMOOTHS - 1; i >= 0; i-- )
  {
    smoothTime = (int)( cg_wwSmoothTime.integer * cg.sList[ i ].timeMod );

    //if this op has time remaining, perform it
    if( cg.time < cg.sList[ i ].time + smoothTime )
    {
      stLocal = 1.0f - ( ( ( cg.sList[ i ].time + smoothTime ) - cg.time ) / smoothTime );
      sFraction = -( cos( stLocal * M_PI ) + 1.0f ) / 2.0f;

      RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis,
        inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle );
      RotatePointAroundVector( outAxis[ 1 ], cg.sList[ i ].rotAxis,
        inAxis[ 1 ], sFraction * cg.sList[ i ].rotAngle );
      RotatePointAroundVector( outAxis[ 2 ], cg.sList[ i ].rotAxis,
        inAxis[ 2 ], sFraction * cg.sList[ i ].rotAngle );

      AxisCopy( outAxis, inAxis );
      performed = qtrue;
    }
  }

  //if we performed any ops then return the smoothed angles
  //otherwise simply return the in angles
  if( performed )
    AxisToAngles( outAxis, out );
  else
    VectorCopy( in, out );

  //copy the current normal to the lastNormal
  VectorCopy( in, cg.lastVangles );
  VectorCopy( surfNormal, cg.lastNormal );
}
Exemple #19
0
void FX_EnergyGibs(vec3_t origin )
{
	localEntity_t	*le;
	refEntity_t		*re;
	vec3_t			dir;
	int				i, j, k;
	int				chunkModel=0;
	float			baseScale = 0.7f, dist;
	int				numChunks;

	numChunks = irandom( 10, 15 );

	VectorSubtract(cg.snap->ps.origin, origin, dir);
	dist = VectorLength(dir);
	if (dist > 512)
	{
		numChunks *= 512.0/dist;		// 1/2 at 1024, 1/4 at 2048, etc.
	}

	for ( i = 0; i < numChunks; i++ )
	{
		chunkModel = cgs.media.chunkModels[MT_METAL][irandom(0,5)];

		le = CG_AllocLocalEntity();
		re = &le->refEntity;

		le->leType = LE_FRAGMENT;
		le->endTime = cg.time + 2000;

		VectorCopy( origin, re->origin );

		for ( j = 0; j < 3; j++ )
		{
			re->origin[j] += crandom() * 12;
		}
		VectorCopy( re->origin, le->pos.trBase );

		//Velocity
		VectorSet( dir, crandom(), crandom(), crandom() );
		VectorScale( dir, flrandom( 300, 500 ), le->pos.trDelta );

		//Angular Velocity
		VectorSet( le->angles.trBase, crandom() * 360, crandom() * 360, crandom() * 360 );
		VectorSet( le->angles.trDelta, crandom() * 90, crandom() * 90, crandom() * 90 );

		AxisCopy( axisDefault, re->axis );

		le->data.fragment.radius = flrandom(baseScale * 0.4f, baseScale * 0.8f );

		re->nonNormalizedAxes = qtrue;
		re->hModel = chunkModel;
		re->renderfx |= RF_CAP_FRAMES;
		re->customShader = cgs.media.quantumDisruptorShader;
		re->shaderTime = cg.time/1000.0f;
		
		le->pos.trType = TR_GRAVITY;
		le->pos.trTime = cg.time;
		le->angles.trType = TR_INTERPOLATE;
		le->angles.trTime = cg.time;
		le->bounceFactor = 0.2f + random() * 0.2f;
		le->leFlags |= LEF_TUMBLE;

		re->shaderRGBA[0] = re->shaderRGBA[1] = re->shaderRGBA[2] = re->shaderRGBA[3] = 255;

		// Make sure that we have the desired start size set
		for( k = 0; k < 3; k++)
		{
			VectorScale(le->refEntity.axis[k], le->data.fragment.radius, le->refEntity.axis[k]);
		}
	}
}
Exemple #20
0
/*
===============
CG_OffsetShoulderView

===============
*/
void CG_OffsetShoulderView( void )
{
  int            i;
  int            cmdNum;
  usercmd_t      cmd, oldCmd;
  vec3_t         rotationAngles;
  vec3_t         axis[ 3 ], rotaxis[ 3 ];
  float          deltaMousePitch;
  static float   mousePitch;
  vec3_t         forward, right, up;
  classConfig_t* classConfig;

  // Ignore following pitch; it's too jerky otherwise.
  if( !cg_thirdPersonPitchFollow.integer ) 
    cg.refdefViewAngles[ PITCH ] = 0.0f;
    
  AngleVectors( cg.refdefViewAngles, forward, right, up );

  classConfig = BG_ClassConfig( cg.snap->ps.stats[ STAT_CLASS ] );
  VectorMA( cg.refdef.vieworg, classConfig->shoulderOffsets[ 0 ], forward, cg.refdef.vieworg );
  VectorMA( cg.refdef.vieworg, classConfig->shoulderOffsets[ 1 ], right, cg.refdef.vieworg );
  VectorMA( cg.refdef.vieworg, classConfig->shoulderOffsets[ 2 ], up, cg.refdef.vieworg );

  // If someone is playing like this, the rest is already taken care of
  // so just get the firstperson effects and leave.
  if( !cg.demoPlayback && !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
  {
    CG_OffsetFirstPersonView();
    return;
  }

  // Get mouse input for camera rotation. 
  cmdNum = trap_GetCurrentCmdNumber();
  trap_GetUserCmd( cmdNum, &cmd );
  trap_GetUserCmd( cmdNum - 1, &oldCmd );

  // Prevent pitch from wrapping and clamp it within a [30, -50] range.
  // Cgame has no access to ps.delta_angles[] here, so we need to reproduce
  // it ourselves here.
  deltaMousePitch = SHORT2ANGLE( cmd.angles[ PITCH ] - oldCmd.angles[ PITCH ] );
  if( fabs(deltaMousePitch) < 200.0f )
    mousePitch += deltaMousePitch;

  // Handle pitch.
  rotationAngles[ PITCH ] = mousePitch;

  rotationAngles[ PITCH ] = AngleNormalize180( rotationAngles[ PITCH ] + AngleNormalize180( cg.refdefViewAngles[ PITCH ] ) );
  if( rotationAngles [ PITCH ] < -90.0f ) rotationAngles [ PITCH ] = -90.0f;
  if( rotationAngles [ PITCH ] > 90.0f ) rotationAngles [ PITCH ] = 90.0f;

  // Yaw and Roll are much easier.
  rotationAngles[ YAW ] = SHORT2ANGLE( cmd.angles[ YAW ] ) + cg.refdefViewAngles[ YAW ];
  rotationAngles[ ROLL ] = 0.0f;

  // Perform the rotations.
  AnglesToAxis( rotationAngles, axis );
  if( !( cg.snap->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) ||
      !BG_RotateAxis( cg.snap->ps.grapplePoint, axis, rotaxis, qfalse,
                      cg.snap->ps.eFlags & EF_WALLCLIMBCEILING ) )
    AxisCopy( axis, rotaxis );

  AxisToAngles( rotaxis, rotationAngles );

  // Actually set the viewangles.
  for( i = 0; i < 3; i++ )
    cg.refdefViewAngles[ i ] = rotationAngles[ i ];

  // Now run the first person stuff so we get various effects added.
  CG_OffsetFirstPersonView( );
}
Exemple #21
0
static void CG_PlasmaTrail( centity_t *cent, const weaponInfo_t *wi ) {
	localEntity_t	*le;
	refEntity_t		*re;
	entityState_t	*es;
	vec3_t			velocity, xvelocity, origin;
	vec3_t			offset, xoffset;
	vec3_t			v[3];
	int				t, startTime, step;

	float	waterScale = 1.0f;

	if ( cg_noProjectileTrail.integer || cg_oldPlasma.integer ) {
		return;
	}

	step = 50;

	es = &cent->currentState;
	startTime = cent->trailTime;
	t = step * ( (startTime + step) / step );

	BG_EvaluateTrajectory( &es->pos, cg.time, origin );

	le = CG_AllocLocalEntity();
	re = &le->refEntity;

	velocity[0] = 60 - 120 * crandom();
	velocity[1] = 40 - 80 * crandom();
	velocity[2] = 100 - 200 * crandom();

	le->leType = LE_MOVE_SCALE_FADE;
	le->leFlags = LEF_TUMBLE;
	le->leBounceSoundType = LEBS_NONE;
	le->leMarkType = LEMT_NONE;

	le->startTime = cg.time;
	le->endTime = le->startTime + 600;

	le->pos.trType = TR_GRAVITY;
	le->pos.trTime = cg.time;

	AnglesToAxis( cent->lerpAngles, v );

	offset[0] = 2;
	offset[1] = 2;
	offset[2] = 2;

	xoffset[0] = offset[0] * v[0][0] + offset[1] * v[1][0] + offset[2] * v[2][0];
	xoffset[1] = offset[0] * v[0][1] + offset[1] * v[1][1] + offset[2] * v[2][1];
	xoffset[2] = offset[0] * v[0][2] + offset[1] * v[1][2] + offset[2] * v[2][2];

	VectorAdd( origin, xoffset, re->origin );
	VectorCopy( re->origin, le->pos.trBase );

	if ( CG_PointContents( re->origin, -1 ) & CONTENTS_WATER ) {
		waterScale = 0.10f;
	}

	xvelocity[0] = velocity[0] * v[0][0] + velocity[1] * v[1][0] + velocity[2] * v[2][0];
	xvelocity[1] = velocity[0] * v[0][1] + velocity[1] * v[1][1] + velocity[2] * v[2][1];
	xvelocity[2] = velocity[0] * v[0][2] + velocity[1] * v[1][2] + velocity[2] * v[2][2];
	VectorScale( xvelocity, waterScale, le->pos.trDelta );

	AxisCopy( axisDefault, re->axis );
    re->shaderTime = cg.time / 1000.0f;
    re->reType = RT_SPRITE;
    re->radius = 0.25f;
	re->customShader = cgs.media.railRingsShader;
	le->bounceFactor = 0.3f;

    re->shaderRGBA[0] = wi->flashDlightColor[0] * 63;
    re->shaderRGBA[1] = wi->flashDlightColor[1] * 63;
    re->shaderRGBA[2] = wi->flashDlightColor[2] * 63;
    re->shaderRGBA[3] = 63;

    le->color[0] = wi->flashDlightColor[0] * 0.2;
    le->color[1] = wi->flashDlightColor[1] * 0.2;
    le->color[2] = wi->flashDlightColor[2] * 0.2;
    le->color[3] = 0.25f;

	le->angles.trType = TR_LINEAR;
	le->angles.trTime = cg.time;
	le->angles.trBase[0] = rand()&31;
	le->angles.trBase[1] = rand()&31;
	le->angles.trBase[2] = rand()&31;
	le->angles.trDelta[0] = 1;
	le->angles.trDelta[1] = 0.5;
	le->angles.trDelta[2] = 0;

}