07 Mar 2017
This commit is contained in:
parent
17d224208a
commit
14b954bb63
|
@ -221,7 +221,7 @@ public:
|
|||
void Spawn( void );
|
||||
void Think( void );
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() | FCAP_DONT_SAVE | FCAP_IMPULSE_USE); }
|
||||
virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() | FCAP_IMPULSE_USE); }
|
||||
virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
|
||||
void Animate( float frames );
|
||||
|
||||
|
|
|
@ -1059,6 +1059,7 @@ void CL_LinkPacketEntities( frame_t *frame )
|
|||
#ifdef STUDIO_INTERPOLATION_FIX
|
||||
if( ent->lastmove >= cl.time )
|
||||
VectorCopy( ent->curstate.origin, ent->latched.prevorigin );
|
||||
ent->curstate.movetype = MOVETYPE_STEP;
|
||||
#else
|
||||
if( ent->lastmove >= cl.time )
|
||||
{
|
||||
|
@ -1108,6 +1109,12 @@ void CL_LinkPacketEntities( frame_t *frame )
|
|||
VectorCopy( ent->curstate.origin, ent->origin );
|
||||
VectorCopy( ent->curstate.angles, ent->angles );
|
||||
}
|
||||
|
||||
if( ent->model->type == mod_studio )
|
||||
{
|
||||
if( ent->curstate.movetype == MOVETYPE_STEP && FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
|
||||
R_StudioLerpStepMovement( ent, cl.time, ent->origin, ent->angles );
|
||||
}
|
||||
}
|
||||
|
||||
if( !FBitSet( state->entityType, ENTITY_NORMAL ))
|
||||
|
|
|
@ -633,7 +633,7 @@ void CL_DrawScreenFade( void )
|
|||
if( sf->fadeFlags & FFADE_MODULATE )
|
||||
GL_SetRenderMode( kRenderTransAdd );
|
||||
else GL_SetRenderMode( kRenderTransTexture );
|
||||
R_DrawStretchPic( 0, 0, glState.width, glState.height, 0, 0, 1, 1, cls.fillImage );
|
||||
R_DrawStretchPic( 0, 0, glState.width, glState.height, 0, 0, 1, 1, tr.whiteTexture );
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
|
||||
|
@ -1189,7 +1189,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
|
|||
}
|
||||
|
||||
// load new map sprite
|
||||
if( CL_LoadHudSprite( name, &clgame.sprites[i], true, 0 ))
|
||||
if( CL_LoadHudSprite( name, &clgame.sprites[i], type, 0 ))
|
||||
{
|
||||
if( i < ( MAX_IMAGES - 1 ))
|
||||
clgame.sprites[i].needload = clgame.load_sequence;
|
||||
|
@ -1451,7 +1451,7 @@ void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int
|
|||
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&width, (float *)&height );
|
||||
|
||||
GL_SetRenderMode( kRenderTransAdd );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.fillImage );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, tr.whiteTexture );
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
|
||||
|
@ -2835,7 +2835,7 @@ void CL_FillRGBABlend( int x, int y, int width, int height, int r, int g, int b,
|
|||
pglBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_ONE );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.fillImage );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, tr.whiteTexture );
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
|
||||
|
@ -4048,5 +4048,8 @@ qboolean CL_LoadProgs( const char *name )
|
|||
|
||||
CL_InitStudioAPI( );
|
||||
|
||||
// grab them from client.dll
|
||||
cl_righthand = Cvar_Get( "cl_righthand", "0", FCVAR_ARCHIVE, "flip viewmodel (left to right)" );
|
||||
|
||||
return true;
|
||||
}
|
|
@ -522,7 +522,7 @@ static void pfnFillRGBA( int x, int y, int width, int height, int r, int g, int
|
|||
a = bound( 0, a, 255 );
|
||||
pglColor4ub( r, g, b, a );
|
||||
GL_SetRenderMode( kRenderTransTexture );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, cls.fillImage );
|
||||
R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, tr.whiteTexture );
|
||||
pglColor4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
|
||||
|
|
|
@ -600,12 +600,12 @@ void CL_WeaponAnim( int iAnim, int body )
|
|||
view->curstate.rendermode = kRenderNormal;
|
||||
view->curstate.renderamt = 255;
|
||||
|
||||
#if 1 // g-cont. for GlowShell testing
|
||||
#if 0 // g-cont. for GlowShell testing
|
||||
view->curstate.renderfx = kRenderFxGlowShell;
|
||||
view->curstate.rendercolor.r = 255;
|
||||
view->curstate.rendercolor.g = 128;
|
||||
view->curstate.rendercolor.b = 0;
|
||||
view->curstate.renderamt = 100;
|
||||
view->curstate.renderamt = 150;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ void CL_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_
|
|||
}
|
||||
}
|
||||
|
||||
static void CL_CopyEntityToPhysEnt( physent_t *pe, entity_state_t *state )
|
||||
static void CL_CopyEntityToPhysEnt( physent_t *pe, entity_state_t *state, qboolean visent )
|
||||
{
|
||||
model_t *mod = Mod_Handle( state->modelindex );
|
||||
|
||||
|
@ -361,31 +361,26 @@ static void CL_CopyEntityToPhysEnt( physent_t *pe, entity_state_t *state )
|
|||
|
||||
pe->model = pe->studiomodel = NULL;
|
||||
|
||||
switch( state->solid )
|
||||
VectorCopy( state->mins, pe->mins );
|
||||
VectorCopy( state->maxs, pe->maxs );
|
||||
|
||||
if( state->solid == SOLID_BBOX )
|
||||
{
|
||||
case SOLID_NOT:
|
||||
case SOLID_BSP:
|
||||
pe->model = mod;
|
||||
VectorClear( pe->mins );
|
||||
VectorClear( pe->maxs );
|
||||
break;
|
||||
case SOLID_BBOX:
|
||||
if( mod && mod->type == mod_studio && mod->flags & STUDIO_TRACE_HITBOX )
|
||||
if( FBitSet( mod->flags, STUDIO_TRACE_HITBOX ))
|
||||
pe->studiomodel = mod;
|
||||
VectorCopy( state->mins, pe->mins );
|
||||
VectorCopy( state->maxs, pe->maxs );
|
||||
break;
|
||||
case SOLID_CUSTOM:
|
||||
pe->model = (mod->type == mod_brush) ? mod : NULL;
|
||||
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
|
||||
VectorCopy( state->mins, pe->mins );
|
||||
VectorCopy( state->maxs, pe->maxs );
|
||||
break;
|
||||
default:
|
||||
pe->studiomodel = (mod->type == mod_studio) ? mod : NULL;
|
||||
VectorCopy( state->mins, pe->mins );
|
||||
VectorCopy( state->maxs, pe->maxs );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pe->solid != SOLID_BSP && mod->type == mod_studio )
|
||||
pe->studiomodel = mod;
|
||||
else pe->model = mod;
|
||||
}
|
||||
|
||||
// rare case: not solid entities in vistrace
|
||||
if( visent && VectorIsNull( pe->mins ))
|
||||
{
|
||||
VectorCopy( mod->mins, pe->mins );
|
||||
VectorCopy( mod->maxs, pe->maxs );
|
||||
}
|
||||
|
||||
pe->info = state->number;
|
||||
|
@ -458,7 +453,7 @@ void CL_AddLinksToPmove( frame_t *frame )
|
|||
if(( model->hulls[1].firstclipnode || model->type == mod_studio ) && clgame.pmove->numvisent < MAX_PHYSENTS )
|
||||
{
|
||||
pe = &clgame.pmove->visents[clgame.pmove->numvisent];
|
||||
CL_CopyEntityToPhysEnt( pe, state );
|
||||
CL_CopyEntityToPhysEnt( pe, state, true );
|
||||
clgame.pmove->numvisent++;
|
||||
}
|
||||
|
||||
|
@ -482,7 +477,7 @@ void CL_AddLinksToPmove( frame_t *frame )
|
|||
continue;
|
||||
|
||||
pe = &clgame.pmove->moveents[clgame.pmove->nummoveent];
|
||||
CL_CopyEntityToPhysEnt( pe, state );
|
||||
CL_CopyEntityToPhysEnt( pe, state, false );
|
||||
clgame.pmove->nummoveent++;
|
||||
}
|
||||
else
|
||||
|
@ -492,7 +487,7 @@ void CL_AddLinksToPmove( frame_t *frame )
|
|||
continue;
|
||||
|
||||
pe = &clgame.pmove->physents[clgame.pmove->numphysent];
|
||||
CL_CopyEntityToPhysEnt( pe, state );
|
||||
CL_CopyEntityToPhysEnt( pe, state, false );
|
||||
clgame.pmove->numphysent++;
|
||||
}
|
||||
}
|
||||
|
@ -576,7 +571,7 @@ void CL_SetSolidPlayers( int playernum )
|
|||
break;
|
||||
|
||||
pe = &clgame.pmove->physents[clgame.pmove->numphysent];
|
||||
CL_CopyEntityToPhysEnt( pe, state );
|
||||
CL_CopyEntityToPhysEnt( pe, state, false );
|
||||
clgame.pmove->numphysent++;
|
||||
|
||||
// some fields needs to be override from cls.predicted_players
|
||||
|
@ -715,15 +710,35 @@ pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags )
|
|||
{
|
||||
int old_usehull;
|
||||
pmtrace_t tr;
|
||||
|
||||
|
||||
old_usehull = clgame.pmove->usehull;
|
||||
clgame.pmove->usehull = 2;
|
||||
clgame.pmove->usehull = 2;
|
||||
tr = PM_PlayerTraceExt( clgame.pmove, start, end, flags, clgame.pmove->numphysent, clgame.pmove->physents, -1, NULL );
|
||||
clgame.pmove->usehull = old_usehull;
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CL_VisTraceLine
|
||||
|
||||
trace by visible objects (thats can be non-solid)
|
||||
=============
|
||||
*/
|
||||
pmtrace_t CL_VisTraceLine( vec3_t start, vec3_t end, int flags )
|
||||
{
|
||||
int old_usehull;
|
||||
pmtrace_t tr;
|
||||
|
||||
old_usehull = clgame.pmove->usehull;
|
||||
clgame.pmove->usehull = 2;
|
||||
tr = PM_PlayerTraceExt( clgame.pmove, start, end, flags, clgame.pmove->numvisent, clgame.pmove->visents, -1, NULL );
|
||||
clgame.pmove->usehull = old_usehull;
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
CL_GetWaterEntity
|
||||
|
|
|
@ -544,15 +544,12 @@ void SCR_InstallParticlePalette( void )
|
|||
|
||||
void SCR_RegisterTextures( void )
|
||||
{
|
||||
cls.fillImage = GL_LoadTexture( "*white", NULL, 0, TF_IMAGE, NULL ); // used for FillRGBA
|
||||
cls.particleImage = GL_LoadTexture( "*particle", NULL, 0, TF_IMAGE, NULL );
|
||||
|
||||
// register gfx.wad images
|
||||
cls.pauseIcon = GL_LoadTexture( "gfx.wad/paused.lmp", NULL, 0, TF_IMAGE, NULL );
|
||||
if( cl_allow_levelshots->value )
|
||||
cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE, NULL );
|
||||
else cls.loadingBar = GL_LoadTexture( "gfx.wad/lambda.lmp", NULL, 0, TF_IMAGE, NULL );
|
||||
cls.tileImage = GL_LoadTexture( "gfx.wad/backtile.lmp", NULL, 0, TF_UNCOMPRESSED|TF_NOPICMIP|TF_NOMIPMAP, NULL );
|
||||
cls.tileImage = GL_LoadTexture( "gfx.wad/backtile.lmp", NULL, 0, TF_IMAGE, NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -94,27 +94,39 @@ int CL_FxBlend( cl_entity_t *e )
|
|||
break;
|
||||
// JAY: HACK for now -- not time based
|
||||
case kRenderFxFadeSlow:
|
||||
if( e->curstate.renderamt > 0 )
|
||||
e->curstate.renderamt -= 1;
|
||||
else e->curstate.renderamt = 0;
|
||||
if( tr.frametime )
|
||||
{
|
||||
if( e->curstate.renderamt > 0 )
|
||||
e->curstate.renderamt -= 1;
|
||||
else e->curstate.renderamt = 0;
|
||||
}
|
||||
blend = e->curstate.renderamt;
|
||||
break;
|
||||
case kRenderFxFadeFast:
|
||||
if( e->curstate.renderamt > 3 )
|
||||
e->curstate.renderamt -= 4;
|
||||
else e->curstate.renderamt = 0;
|
||||
if( tr.frametime )
|
||||
{
|
||||
if( e->curstate.renderamt > 3 )
|
||||
e->curstate.renderamt -= 4;
|
||||
else e->curstate.renderamt = 0;
|
||||
}
|
||||
blend = e->curstate.renderamt;
|
||||
break;
|
||||
case kRenderFxSolidSlow:
|
||||
if( e->curstate.renderamt < 255 )
|
||||
e->curstate.renderamt += 1;
|
||||
else e->curstate.renderamt = 255;
|
||||
if( tr.frametime )
|
||||
{
|
||||
if( e->curstate.renderamt < 255 )
|
||||
e->curstate.renderamt += 1;
|
||||
else e->curstate.renderamt = 255;
|
||||
}
|
||||
blend = e->curstate.renderamt;
|
||||
break;
|
||||
case kRenderFxSolidFast:
|
||||
if( e->curstate.renderamt < 252 )
|
||||
e->curstate.renderamt += 4;
|
||||
else e->curstate.renderamt = 255;
|
||||
if( tr.frametime )
|
||||
{
|
||||
if( e->curstate.renderamt < 252 )
|
||||
e->curstate.renderamt += 4;
|
||||
else e->curstate.renderamt = 255;
|
||||
}
|
||||
blend = e->curstate.renderamt;
|
||||
break;
|
||||
case kRenderFxStrobeSlow:
|
||||
|
@ -184,6 +196,9 @@ void CL_InitTempEnts( void )
|
|||
{
|
||||
cl_tempents = Mem_Alloc( cls.mempool, sizeof( TEMPENTITY ) * GI->max_tents );
|
||||
CL_ClearTempEnts();
|
||||
|
||||
// load tempent sprites (glowshell, muzzleflashes etc)
|
||||
CL_LoadClientSprites ();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2636,15 +2651,18 @@ void CL_UpdateFlashlight( cl_entity_t *ent )
|
|||
VectorAdd( ent->origin, view_ofs, vecSrc );
|
||||
VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd );
|
||||
|
||||
trace = CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
|
||||
trace = CL_VisTraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
|
||||
|
||||
// update flashlight endpos
|
||||
dl = CL_AllocDlight( ent->index );
|
||||
|
||||
if( trace.ent > 0 && clgame.pmove->physents[trace.ent].studiomodel )
|
||||
VectorCopy( clgame.pmove->physents[trace.ent].origin, dl->origin );
|
||||
#if 0
|
||||
// g-cont. disabled until studio lighting will be finished
|
||||
if( trace.ent > 0 && clgame.pmove->visents[trace.ent].studiomodel )
|
||||
VectorCopy( clgame.pmove->visents[trace.ent].origin, dl->origin );
|
||||
else VectorCopy( trace.endpos, dl->origin );
|
||||
|
||||
#else
|
||||
VectorCopy( trace.endpos, dl->origin );
|
||||
#endif
|
||||
// compute falloff
|
||||
falloff = trace.fraction * FLASHLIGHT_DISTANCE;
|
||||
if( falloff < 500.0f ) falloff = 1.0f;
|
||||
|
|
|
@ -528,13 +528,10 @@ typedef struct
|
|||
int lastoutgoingcommand; // sequence number of last outgoing command
|
||||
int lastupdate_sequence; // prediction stuff
|
||||
|
||||
// internal images
|
||||
int fillImage; // used for emulate FillRGBA to avoid wrong draw-sort
|
||||
int particleImage; // built-in particle and sparks image
|
||||
// game images
|
||||
int pauseIcon; // draw 'paused' when game in-pause
|
||||
int loadingBar; // 'loading' progress bar
|
||||
int glowShell; // for renderFxGlowShell
|
||||
int tileImage; // for draw any areas not covered by the refresh
|
||||
int loadingBar; // 'loading' progress bar
|
||||
cl_font_t creditsFont; // shared creditsfont
|
||||
|
||||
float latency; // rolling average of frame latencey (receivedtime - senttime) values.
|
||||
|
@ -620,6 +617,7 @@ extern convar_t *cl_clockreset;
|
|||
extern convar_t *cl_fixtimerate;
|
||||
extern convar_t *gl_showtextures;
|
||||
extern convar_t *cl_bmodelinterp;
|
||||
extern convar_t *cl_righthand;
|
||||
extern convar_t *cl_lw; // local weapons
|
||||
extern convar_t *cl_showevents;
|
||||
extern convar_t *scr_centertime;
|
||||
|
@ -803,6 +801,7 @@ int CL_PointContents( const vec3_t p );
|
|||
int CL_WaterEntity( const float *rgflPos );
|
||||
cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
|
||||
void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, qboolean runfuncs, double time );
|
||||
pmtrace_t CL_VisTraceLine( vec3_t start, vec3_t end, int flags );
|
||||
pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags );
|
||||
void CL_MoveSpectatorCamera( void );
|
||||
void CL_SetLastUpdate( void );
|
||||
|
|
|
@ -41,43 +41,43 @@ qboolean R_CullBox( const vec3_t mins, const vec3_t maxs, uint clipflags )
|
|||
if( r_nocull->value )
|
||||
return false;
|
||||
|
||||
for( i = sizeof( RI.frustum ) / sizeof( RI.frustum[0] ), bit = 1, p = RI.frustum; i > 0; i--, bit<<=1, p++ )
|
||||
for( i = sizeof( RI.frustum ) / sizeof( RI.frustum[0] ), bit = 1, p = RI.frustum; i > 0; i--, bit++, p++ )
|
||||
{
|
||||
if( !( clipflags & bit ))
|
||||
if( !FBitSet( clipflags, BIT( bit )))
|
||||
continue;
|
||||
|
||||
switch( p->signbits )
|
||||
{
|
||||
case 0:
|
||||
if( p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist )
|
||||
if( p->normal[0] * maxs[0] + p->normal[1] * maxs[1] + p->normal[2] * maxs[2] < p->dist )
|
||||
return true;
|
||||
break;
|
||||
case 1:
|
||||
if( p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist )
|
||||
if( p->normal[0] * mins[0] + p->normal[1] * maxs[1] + p->normal[2] * maxs[2] < p->dist )
|
||||
return true;
|
||||
break;
|
||||
case 2:
|
||||
if( p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist )
|
||||
if( p->normal[0] * maxs[0] + p->normal[1] * mins[1] + p->normal[2] * maxs[2] < p->dist )
|
||||
return true;
|
||||
break;
|
||||
case 3:
|
||||
if( p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist )
|
||||
if( p->normal[0] * mins[0] + p->normal[1] * mins[1] + p->normal[2] * maxs[2] < p->dist )
|
||||
return true;
|
||||
break;
|
||||
case 4:
|
||||
if( p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist )
|
||||
if( p->normal[0] * maxs[0] + p->normal[1] * maxs[1] + p->normal[2] * mins[2] < p->dist )
|
||||
return true;
|
||||
break;
|
||||
case 5:
|
||||
if( p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist )
|
||||
if( p->normal[0] * mins[0] + p->normal[1] * maxs[1] + p->normal[2] * mins[2] < p->dist )
|
||||
return true;
|
||||
break;
|
||||
case 6:
|
||||
if( p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist )
|
||||
if( p->normal[0] * maxs[0] + p->normal[1] * mins[1] + p->normal[2] * mins[2] < p->dist )
|
||||
return true;
|
||||
break;
|
||||
case 7:
|
||||
if( p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist )
|
||||
if( p->normal[0] * mins[0] + p->normal[1] * mins[1] + p->normal[2] * mins[2] < p->dist )
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
|
@ -96,19 +96,22 @@ Returns true if the sphere is completely outside the frustum
|
|||
*/
|
||||
qboolean R_CullSphere( const vec3_t centre, const float radius, const uint clipflags )
|
||||
{
|
||||
uint i, bit;
|
||||
const mplane_t *p;
|
||||
uint i, bit;
|
||||
const mplane_t *p;
|
||||
|
||||
// client.dll may use additional passes for render custom mirrors etc
|
||||
if( r_nocull->value )
|
||||
return false;
|
||||
|
||||
for( i = sizeof( RI.frustum ) / sizeof( RI.frustum[0] ), bit = 1, p = RI.frustum; i > 0; i--, bit<<=1, p++ )
|
||||
for( i = sizeof( RI.frustum ) / sizeof( RI.frustum[0] ), bit = 1, p = RI.frustum; i > 0; i--, bit++, p++ )
|
||||
{
|
||||
if(!( clipflags & bit )) continue;
|
||||
if( !FBitSet( clipflags, BIT( bit )))
|
||||
continue;
|
||||
|
||||
if( DotProduct( centre, p->normal ) - p->dist <= -radius )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -117,30 +120,35 @@ qboolean R_CullSphere( const vec3_t centre, const float radius, const uint clipf
|
|||
R_CullModel
|
||||
=============
|
||||
*/
|
||||
int R_CullModel( cl_entity_t *e, vec3_t origin, vec3_t mins, vec3_t maxs, float radius )
|
||||
int R_CullModel( cl_entity_t *e, const vec3_t absmin, const vec3_t absmax )
|
||||
{
|
||||
if( e == &clgame.viewent )
|
||||
{
|
||||
if( RI.params & RP_NONVIEWERREF )
|
||||
if( CL_IsDevOverviewMode( ))
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
if( RP_NORMALPASS() && !RI.thirdPerson && cl.viewentity == ( cl.playernum + 1 ))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// don't reflect this entity in mirrors
|
||||
if( e->curstate.effects & EF_NOREFLECT && RI.params & RP_MIRRORVIEW )
|
||||
if( FBitSet( e->curstate.effects, EF_NOREFLECT ) && FBitSet( RI.params, RP_MIRRORVIEW ))
|
||||
return 1;
|
||||
|
||||
// draw only in mirrors
|
||||
if( e->curstate.effects & EF_REFLECTONLY && !( RI.params & RP_MIRRORVIEW ))
|
||||
if( FBitSet( e->curstate.effects, EF_REFLECTONLY ) && !FBitSet( RI.params, RP_MIRRORVIEW ))
|
||||
return 1;
|
||||
|
||||
// local client can't view himself if camera or thirdperson is not active
|
||||
if( RP_LOCALCLIENT( e ) && !RI.thirdPerson && cl.viewentity == ( cl.playernum + 1 ))
|
||||
{
|
||||
if(!( RI.params & RP_MIRRORVIEW ))
|
||||
if( !FBitSet( RI.params, RP_MIRRORVIEW ))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( R_CullSphere( origin, radius, RI.clipFlags ))
|
||||
if( R_CullBox( absmin, absmax, RI.clipFlags ))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -18,27 +18,16 @@ GNU General Public License for more details.
|
|||
#include "gl_local.h"
|
||||
#include "studio.h"
|
||||
|
||||
#define TEXTURES_HASH_SIZE (MAX_TEXTURES >> 2)
|
||||
#define TEXTURES_HASH_SIZE (MAX_TEXTURES >> 2)
|
||||
|
||||
static gltexture_t r_textures[MAX_TEXTURES];
|
||||
static gltexture_t *r_texturesHashTable[TEXTURES_HASH_SIZE];
|
||||
static int r_numTextures;
|
||||
static byte data2D[BLOCK_SIZE_MAX*BLOCK_SIZE_MAX*4]; // intermediate texbuffer
|
||||
static int r_numTextures;
|
||||
static rgbdata_t r_image; // generic pixelbuffer used for internal textures
|
||||
|
||||
// internal tables
|
||||
static vec3_t r_luminanceTable[256]; // RGB to luminance
|
||||
static byte r_particleTexture[8][8] =
|
||||
{
|
||||
{0,0,0,0,0,0,0,0},
|
||||
{0,0,0,1,1,0,0,0},
|
||||
{0,0,0,1,1,0,0,0},
|
||||
{0,1,1,1,1,1,1,0},
|
||||
{0,1,1,1,1,1,1,0},
|
||||
{0,0,0,1,1,0,0,0},
|
||||
{0,0,0,1,1,0,0,0},
|
||||
{0,0,0,0,0,0,0,0},
|
||||
};
|
||||
static vec3_t r_luminanceTable[256]; // RGB to luminance
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -1896,71 +1885,6 @@ static rgbdata_t *R_InitDefaultTexture( texFlags_t *flags )
|
|||
return &r_image;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitParticleTexture
|
||||
==================
|
||||
*/
|
||||
static rgbdata_t *R_InitParticleTexture( texFlags_t *flags )
|
||||
{
|
||||
int x, y;
|
||||
int dx2, dy, d;
|
||||
|
||||
// particle texture
|
||||
r_image.width = r_image.height = 16;
|
||||
r_image.buffer = data2D;
|
||||
r_image.flags = (IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA);
|
||||
r_image.type = PF_RGBA_32;
|
||||
r_image.size = r_image.width * r_image.height * 4;
|
||||
|
||||
*flags = TF_NOPICMIP|TF_NOMIPMAP;
|
||||
|
||||
for( x = 0; x < 16; x++ )
|
||||
{
|
||||
dx2 = x - 8;
|
||||
dx2 = dx2 * dx2;
|
||||
|
||||
for( y = 0; y < 16; y++ )
|
||||
{
|
||||
dy = y - 8;
|
||||
d = 255 - 35 * sqrt( dx2 + dy * dy );
|
||||
data2D[( y*16 + x ) * 4 + 3] = bound( 0, d, 255 );
|
||||
}
|
||||
}
|
||||
return &r_image;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitParticleTexture2
|
||||
==================
|
||||
*/
|
||||
static rgbdata_t *R_InitParticleTexture2( texFlags_t *flags )
|
||||
{
|
||||
int x, y;
|
||||
|
||||
// particle texture
|
||||
r_image.width = r_image.height = 8;
|
||||
r_image.buffer = data2D;
|
||||
r_image.flags = (IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA);
|
||||
r_image.type = PF_RGBA_32;
|
||||
r_image.size = r_image.width * r_image.height * 4;
|
||||
|
||||
*flags = TF_NOPICMIP|TF_NOMIPMAP;
|
||||
|
||||
for( x = 0; x < 8; x++ )
|
||||
{
|
||||
for( y = 0; y < 8; y++ )
|
||||
{
|
||||
data2D[(y * 8 + x) * 4 + 0] = 255;
|
||||
data2D[(y * 8 + x) * 4 + 1] = 255;
|
||||
data2D[(y * 8 + x) * 4 + 2] = 255;
|
||||
data2D[(y * 8 + x) * 4 + 3] = r_particleTexture[x][y] * 255;
|
||||
}
|
||||
}
|
||||
return &r_image;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitSkyTexture
|
||||
|
@ -2477,8 +2401,6 @@ static void R_InitBuiltinTextures( void )
|
|||
{ "*white", &tr.whiteTexture, R_InitWhiteTexture },
|
||||
{ "*gray", &tr.grayTexture, R_InitGrayTexture },
|
||||
{ "*black", &tr.blackTexture, R_InitBlackTexture },
|
||||
{ "*particle", &tr.particleTexture, R_InitParticleTexture },
|
||||
{ "*particle2", &tr.particleTexture2, R_InitParticleTexture2 },
|
||||
{ "*cintexture", &tr.cinTexture, R_InitCinematicTexture }, // force linear filter
|
||||
{ "*dlight", &tr.dlightTexture, R_InitDlightTexture },
|
||||
{ "*dlight2", &tr.dlightTexture2, R_InitDlightTexture2 },
|
||||
|
|
|
@ -162,8 +162,6 @@ typedef struct
|
|||
int grayTexture;
|
||||
int blackTexture;
|
||||
int defaultTexture; // use for bad textures
|
||||
int particleTexture; // particle texture
|
||||
int particleTexture2; // unsmoothed particle texture
|
||||
int solidskyTexture; // quake1 solid-sky layer
|
||||
int alphaskyTexture; // quake1 alpha-sky layer
|
||||
int lightmapTextures[MAX_LIGHTMAPS];
|
||||
|
@ -213,6 +211,7 @@ typedef struct
|
|||
float lightcache[MAX_LIGHTSTYLES];
|
||||
|
||||
double frametime; // special frametime for multipass rendering (will set to 0 on a nextview)
|
||||
float blend; // global blend value
|
||||
|
||||
// cull info
|
||||
vec3_t modelorg; // relative to viewpoint
|
||||
|
@ -279,7 +278,7 @@ void R_ShowTextures( void );
|
|||
//
|
||||
// gl_cull.c
|
||||
//
|
||||
int R_CullModel( cl_entity_t *e, vec3_t origin, vec3_t mins, vec3_t maxs, float radius );
|
||||
int R_CullModel( cl_entity_t *e, const vec3_t absmin, const vec3_t absmax );
|
||||
qboolean R_CullBox( const vec3_t mins, const vec3_t maxs, uint clipflags );
|
||||
qboolean R_CullSphere( const vec3_t centre, const float radius, const uint clipflags );
|
||||
qboolean R_CullSurface( msurface_t *surf, uint clipflags );
|
||||
|
@ -342,8 +341,8 @@ void R_PushDlights( void );
|
|||
void R_AnimateLight( void );
|
||||
void R_GetLightSpot( vec3_t lightspot );
|
||||
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
|
||||
void R_LightDir( const vec3_t origin, vec3_t lightDir, float radius );
|
||||
void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLight, qboolean useAmbient, float radius );
|
||||
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot );
|
||||
int R_CountSurfaceDlights( msurface_t *surf );
|
||||
int R_CountDlights( void );
|
||||
|
||||
|
@ -417,6 +416,7 @@ void R_DrawSpriteModel( cl_entity_t *e );
|
|||
//
|
||||
void R_StudioInit( void );
|
||||
void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded );
|
||||
void R_StudioLerpStepMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles );
|
||||
struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e );
|
||||
float CL_GetStudioEstimatedFrame( cl_entity_t *ent );
|
||||
void R_DrawStudioModel( cl_entity_t *e );
|
||||
|
@ -666,13 +666,12 @@ extern convar_t *r_detailtextures;
|
|||
extern convar_t *r_faceplanecull;
|
||||
extern convar_t *r_drawentities;
|
||||
extern convar_t *r_adjust_fov;
|
||||
extern convar_t *r_lefthand;
|
||||
extern convar_t *r_flaresize;
|
||||
extern convar_t *r_decals;
|
||||
extern convar_t *r_novis;
|
||||
extern convar_t *r_nocull;
|
||||
extern convar_t *r_lockpvs;
|
||||
extern convar_t *r_lockcull;
|
||||
extern convar_t *r_lockfrustum;
|
||||
extern convar_t *r_dynamic;
|
||||
extern convar_t *r_lightmap;
|
||||
extern convar_t *r_fastsky;
|
||||
|
|
|
@ -226,17 +226,17 @@ int R_CountSurfaceDlights( msurface_t *surf )
|
|||
|
||||
=======================================================================
|
||||
*/
|
||||
static uint r_pointColor[3];
|
||||
static vec3_t r_lightSpot;
|
||||
static float g_trace_fraction;
|
||||
static vec3_t g_trace_lightspot;
|
||||
|
||||
/*
|
||||
=================
|
||||
R_RecursiveLightPoint
|
||||
=================
|
||||
*/
|
||||
static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3_t start, const vec3_t end )
|
||||
static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, float p2f, colorVec *cv, const vec3_t start, const vec3_t end )
|
||||
{
|
||||
float front, back, frac;
|
||||
float front, back, frac, midf;
|
||||
int i, map, side, size, s, t;
|
||||
int sample_size;
|
||||
msurface_t *surf;
|
||||
|
@ -246,7 +246,10 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3
|
|||
|
||||
// didn't hit anything
|
||||
if( !node || node->contents < 0 )
|
||||
{
|
||||
cv->r = cv->g = cv->b = cv->a = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate mid point
|
||||
front = PlaneDiff( start, node->plane );
|
||||
|
@ -254,24 +257,27 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3
|
|||
|
||||
side = front < 0;
|
||||
if(( back < 0 ) == side )
|
||||
return R_RecursiveLightPoint( model, node->children[side], start, end );
|
||||
return R_RecursiveLightPoint( model, node->children[side], p1f, p2f, cv, start, end );
|
||||
|
||||
frac = front / ( front - back );
|
||||
|
||||
VectorLerp( start, frac, end, mid );
|
||||
midf = p1f + ( p2f - p1f ) * frac;
|
||||
|
||||
// co down front side
|
||||
if( R_RecursiveLightPoint( model, node->children[side], start, mid ))
|
||||
if( R_RecursiveLightPoint( model, node->children[side], p1f, midf, cv, start, mid ))
|
||||
return true; // hit something
|
||||
|
||||
if(( back < 0 ) == side )
|
||||
return false;// didn't hit anything
|
||||
|
||||
VectorCopy( mid, r_lightSpot );
|
||||
{
|
||||
cv->r = cv->g = cv->b = cv->a = 0;
|
||||
return false; // didn't hit anything
|
||||
}
|
||||
|
||||
// check for impact on this node
|
||||
surf = model->surfaces + node->firstsurface;
|
||||
sample_size = Mod_SampleSizeForFace( surf );
|
||||
VectorCopy( mid, g_trace_lightspot );
|
||||
|
||||
for( i = 0; i < node->numsurfaces; i++, surf++ )
|
||||
{
|
||||
|
@ -289,29 +295,31 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3
|
|||
s /= sample_size;
|
||||
t /= sample_size;
|
||||
|
||||
cv->r = cv->g = cv->b = cv->a = 0;
|
||||
|
||||
if( !surf->samples )
|
||||
return true;
|
||||
|
||||
VectorClear( r_pointColor );
|
||||
|
||||
lm = surf->samples + (t * ((surf->extents[0] / sample_size) + 1) + s);
|
||||
size = ((surf->extents[0] / sample_size) + 1) * ((surf->extents[1] / sample_size) + 1);
|
||||
size = ((surf->extents[0] / sample_size) + 1) * ((surf->extents[1] / sample_size) + 1);
|
||||
g_trace_fraction = midf;
|
||||
|
||||
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
|
||||
{
|
||||
uint scale = tr.lightstylevalue[surf->styles[map]];
|
||||
|
||||
r_pointColor[0] += TextureToTexGamma( lm->r ) * scale;
|
||||
r_pointColor[1] += TextureToTexGamma( lm->g ) * scale;
|
||||
r_pointColor[2] += TextureToTexGamma( lm->b ) * scale;
|
||||
cv->r += TextureToTexGamma( lm->r ) * scale;
|
||||
cv->g += TextureToTexGamma( lm->g ) * scale;
|
||||
cv->b += TextureToTexGamma( lm->b ) * scale;
|
||||
|
||||
lm += size; // skip to next lightmap
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// go down back side
|
||||
return R_RecursiveLightPoint( model, node->children[!side], mid, end );
|
||||
return R_RecursiveLightPoint( model, node->children[!side], midf, p2f, cv, mid, end );
|
||||
}
|
||||
|
||||
int R_LightTraceFilter( physent_t *pe )
|
||||
|
@ -331,6 +339,7 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
|
|||
{
|
||||
dlight_t *dl;
|
||||
pmtrace_t trace;
|
||||
colorVec light;
|
||||
cl_entity_t *m_pGround;
|
||||
vec3_t start, end, dir;
|
||||
qboolean secondpass = false;
|
||||
|
@ -405,13 +414,11 @@ get_light:
|
|||
VectorCopy( end_l, end );
|
||||
}
|
||||
|
||||
VectorClear( r_pointColor );
|
||||
|
||||
if( R_RecursiveLightPoint( pmodel, pnodes, start, end ))
|
||||
if( R_RecursiveLightPoint( pmodel, pnodes, 0.0f, 1.0f, &light, start, end ))
|
||||
{
|
||||
ambientLight->r = min((r_pointColor[0] >> 7), 255 );
|
||||
ambientLight->g = min((r_pointColor[1] >> 7), 255 );
|
||||
ambientLight->b = min((r_pointColor[2] >> 7), 255 );
|
||||
ambientLight->r = Q_min(( light.r >> 7 ), 255 );
|
||||
ambientLight->g = Q_min(( light.g >> 7 ), 255 );
|
||||
ambientLight->b = Q_min(( light.b >> 7 ), 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -439,7 +446,7 @@ get_light:
|
|||
int lnum, total;
|
||||
float f;
|
||||
|
||||
VectorClear( r_pointColor );
|
||||
light.r = light.g = light.b = light.a = 0;
|
||||
|
||||
for( total = lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ )
|
||||
{
|
||||
|
@ -453,87 +460,101 @@ get_light:
|
|||
continue;
|
||||
|
||||
add = 1.0f - (dist / ( dl->radius + radius ));
|
||||
r_pointColor[0] += TextureToTexGamma( dl->color.r ) * add;
|
||||
r_pointColor[1] += TextureToTexGamma( dl->color.g ) * add;
|
||||
r_pointColor[2] += TextureToTexGamma( dl->color.b ) * add;
|
||||
light.r += TextureToTexGamma( dl->color.r ) * add;
|
||||
light.g += TextureToTexGamma( dl->color.g ) * add;
|
||||
light.b += TextureToTexGamma( dl->color.b ) * add;
|
||||
total++;
|
||||
}
|
||||
|
||||
if( total != 0 )
|
||||
{
|
||||
r_pointColor[0] += ambientLight->r;
|
||||
r_pointColor[1] += ambientLight->g;
|
||||
r_pointColor[2] += ambientLight->b;
|
||||
light.r += ambientLight->r;
|
||||
light.g += ambientLight->g;
|
||||
light.b += ambientLight->b;
|
||||
|
||||
f = max( max( r_pointColor[0], r_pointColor[1] ), r_pointColor[2] );
|
||||
if( f > 1.0f ) VectorScale( r_pointColor, ( 255.0f / f ), r_pointColor );
|
||||
f = max( max( light.r, light.g ), light.b );
|
||||
if( f > 1.0f )
|
||||
{
|
||||
light.r *= (255.0f / f);
|
||||
light.r *= (255.0f / f);
|
||||
light.r *= ( 255.0f / f);
|
||||
}
|
||||
|
||||
ambientLight->r = r_pointColor[0];
|
||||
ambientLight->g = r_pointColor[1];
|
||||
ambientLight->b = r_pointColor[2];
|
||||
ambientLight->r = light.r;
|
||||
ambientLight->g = light.g;
|
||||
ambientLight->b = light.b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_GetLightSpot
|
||||
R_LightVec
|
||||
|
||||
NOTE: must call R_LightForPoint first
|
||||
check bspmodels to get light from
|
||||
=================
|
||||
*/
|
||||
void R_GetLightSpot( vec3_t lightspot )
|
||||
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot )
|
||||
{
|
||||
if( lightspot ) VectorCopy( r_lightSpot, lightspot );
|
||||
}
|
||||
float last_fraction;
|
||||
int i, maxEnts = 1;
|
||||
colorVec light, cv;
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LightDir
|
||||
=================
|
||||
*/
|
||||
void R_LightDir( const vec3_t origin, vec3_t lightDir, float radius )
|
||||
{
|
||||
dlight_t *dl;
|
||||
vec3_t dir, local;
|
||||
float dist;
|
||||
int lnum;
|
||||
|
||||
VectorClear( local );
|
||||
|
||||
// add dynamic lights
|
||||
if( radius > 0.0f && r_dynamic->value )
|
||||
if( cl.worldmodel->lightdata )
|
||||
{
|
||||
for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ )
|
||||
light.r = light.b = light.b = light.a = 0;
|
||||
last_fraction = 1.0f;
|
||||
|
||||
// get light from bmodels too
|
||||
if( r_lighting_extended->value )
|
||||
maxEnts = clgame.pmove->numphysent;
|
||||
|
||||
// check al the bsp-models
|
||||
for( i = 0; i < maxEnts; i++ )
|
||||
{
|
||||
if( dl->die < cl.time || !dl->radius )
|
||||
continue;
|
||||
physent_t *pe = &clgame.pmove->physents[i];
|
||||
vec3_t offset, start_l, end_l;
|
||||
mnode_t *pnodes;
|
||||
matrix4x4 matrix;
|
||||
|
||||
VectorSubtract( dl->origin, origin, dir );
|
||||
dist = VectorLength( dir );
|
||||
if( !pe->model || pe->model->type != mod_brush )
|
||||
continue; // skip non-bsp models
|
||||
|
||||
if( !dist || dist > dl->radius + radius )
|
||||
continue;
|
||||
VectorAdd( local, dir, local );
|
||||
}
|
||||
pnodes = &pe->model->nodes[pe->model->hulls[0].firstclipnode];
|
||||
VectorSubtract( pe->model->hulls[0].clip_mins, vec3_origin, offset );
|
||||
VectorAdd( offset, pe->origin, offset );
|
||||
VectorSubtract( start, offset, start_l );
|
||||
VectorSubtract( end, offset, end_l );
|
||||
|
||||
for( lnum = 0, dl = cl_elights; lnum < MAX_ELIGHTS; lnum++, dl++ )
|
||||
{
|
||||
if( dl->die < cl.time || !dl->radius )
|
||||
continue;
|
||||
// rotate start and end into the models frame of reference
|
||||
if( !VectorIsNull( pe->angles ))
|
||||
{
|
||||
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
|
||||
Matrix4x4_VectorITransform( matrix, start, start_l );
|
||||
Matrix4x4_VectorITransform( matrix, end, end_l );
|
||||
}
|
||||
|
||||
VectorSubtract( dl->origin, origin, dir );
|
||||
dist = VectorLength( dir );
|
||||
VectorClear( g_trace_lightspot );
|
||||
g_trace_fraction = 1.0f;
|
||||
|
||||
if( !dist || dist > dl->radius + radius )
|
||||
continue;
|
||||
VectorAdd( local, dir, local );
|
||||
}
|
||||
if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l ))
|
||||
continue; // didn't hit anything
|
||||
|
||||
if( !VectorIsNull( local ))
|
||||
{
|
||||
VectorNormalize( local );
|
||||
VectorCopy( local, lightDir );
|
||||
if( g_trace_fraction < last_fraction )
|
||||
{
|
||||
if( lspot ) VectorCopy( g_trace_lightspot, lspot );
|
||||
light.r = Q_min(( cv.r >> 7 ), 255 );
|
||||
light.g = Q_min(( cv.g >> 7 ), 255 );
|
||||
light.b = Q_min(( cv.b >> 7 ), 255 );
|
||||
last_fraction = g_trace_fraction;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
light.r = light.g = light.b = 255;
|
||||
light.a = 0;
|
||||
}
|
||||
|
||||
return light;
|
||||
}
|
|
@ -283,8 +283,6 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
|
|||
if( clent->curstate.effects & EF_NODRAW )
|
||||
return false; // done
|
||||
|
||||
clent->curstate.renderamt = CL_FxBlend( clent );
|
||||
|
||||
if( clent->curstate.rendermode != kRenderNormal && clent->curstate.renderamt <= 0.0f )
|
||||
return true; // invisible
|
||||
|
||||
|
@ -451,7 +449,7 @@ void R_SetupFrustum( void )
|
|||
// build the transformation matrix for the given view angles
|
||||
AngleVectors( RI.viewangles, RI.vforward, RI.vright, RI.vup );
|
||||
|
||||
if( !r_lockcull->value )
|
||||
if( !r_lockfrustum->value )
|
||||
{
|
||||
VectorCopy( RI.vieworg, RI.cullorigin );
|
||||
VectorCopy( RI.vforward, RI.cull_vforward );
|
||||
|
@ -914,6 +912,7 @@ void R_DrawEntitiesOnList( void )
|
|||
int i;
|
||||
|
||||
glState.drawTrans = false;
|
||||
tr.blend = 1.0f;
|
||||
|
||||
// draw the solid submodels fog
|
||||
R_DrawFog ();
|
||||
|
@ -966,6 +965,8 @@ void R_DrawEntitiesOnList( void )
|
|||
{
|
||||
RI.currententity = tr.trans_entities[i];
|
||||
RI.currentmodel = RI.currententity->model;
|
||||
tr.blend = CL_FxBlend( RI.currententity ) / 255.0f;
|
||||
if( tr.blend <= 0.0f ) continue;
|
||||
|
||||
ASSERT( RI.currententity != NULL );
|
||||
ASSERT( RI.currententity->model != NULL );
|
||||
|
|
|
@ -1485,7 +1485,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
case kRenderTransTexture:
|
||||
need_sort = true;
|
||||
case kRenderGlow:
|
||||
pglColor4ub( 255, 255, 255, e->curstate.renderamt );
|
||||
pglColor4f( 1.0f, 1.0f, 1.0f, tr.blend );
|
||||
break;
|
||||
case kRenderTransColor:
|
||||
pglDisable( GL_TEXTURE_2D );
|
||||
|
@ -1929,6 +1929,7 @@ void R_DrawWorld( void )
|
|||
|
||||
GL_SetRenderMode( kRenderNormal );
|
||||
gl_lms.dynamic_surfaces = NULL;
|
||||
tr.blend = 1.0f;
|
||||
|
||||
R_ClearSkyBox ();
|
||||
|
||||
|
|
|
@ -29,9 +29,8 @@ GNU General Public License for more details.
|
|||
convar_t *r_sprite_lerping;
|
||||
convar_t *r_sprite_lighting;
|
||||
char group_suffix[8];
|
||||
static vec3_t sprite_mins, sprite_maxs;
|
||||
static float sprite_radius;
|
||||
static uint r_texFlags = 0;
|
||||
float sprite_radius;
|
||||
|
||||
/*
|
||||
====================
|
||||
|
@ -710,41 +709,6 @@ float R_GetSpriteFrameInterpolant( cl_entity_t *ent, mspriteframe_t **oldframe,
|
|||
return lerpFrac;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_StudioComputeBBox
|
||||
|
||||
Compute a full bounding box for current sequence
|
||||
================
|
||||
*/
|
||||
qboolean R_SpriteComputeBBox( cl_entity_t *e, vec3_t bbox[8] )
|
||||
{
|
||||
float scale = 1.0f;
|
||||
vec3_t p1;
|
||||
int i;
|
||||
|
||||
// copy original bbox (no rotation for sprites)
|
||||
VectorCopy( e->model->mins, sprite_mins );
|
||||
VectorCopy( e->model->maxs, sprite_maxs );
|
||||
|
||||
// compute a full bounding box
|
||||
for( i = 0; bbox && i < 8; i++ )
|
||||
{
|
||||
p1[0] = ( i & 1 ) ? sprite_mins[0] : sprite_maxs[0];
|
||||
p1[1] = ( i & 2 ) ? sprite_mins[1] : sprite_maxs[1];
|
||||
p1[2] = ( i & 4 ) ? sprite_mins[2] : sprite_maxs[2];
|
||||
|
||||
VectorCopy( p1, bbox[i] );
|
||||
}
|
||||
|
||||
if( e->curstate.scale > 0.0f )
|
||||
scale = e->curstate.scale;
|
||||
|
||||
sprite_radius = RadiusFromBounds( sprite_mins, sprite_maxs ) * scale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_CullSpriteModel
|
||||
|
@ -754,16 +718,25 @@ Cull sprite model by bbox
|
|||
*/
|
||||
qboolean R_CullSpriteModel( cl_entity_t *e, vec3_t origin )
|
||||
{
|
||||
vec3_t sprite_mins, sprite_maxs;
|
||||
float scale = 1.0f;
|
||||
|
||||
if( !e->model->cache.data )
|
||||
return true;
|
||||
|
||||
if( e == &clgame.viewent && r_lefthand->value >= 2 )
|
||||
return true;
|
||||
if( e->curstate.scale > 0.0f )
|
||||
scale = e->curstate.scale;
|
||||
|
||||
if( !R_SpriteComputeBBox( e, NULL ))
|
||||
return true; // invalid frame
|
||||
// scale original bbox (no rotation for sprites)
|
||||
VectorScale( e->model->mins, scale, sprite_mins );
|
||||
VectorScale( e->model->maxs, scale, sprite_maxs );
|
||||
|
||||
return R_CullModel( e, origin, sprite_mins, sprite_maxs, sprite_radius );
|
||||
sprite_radius = RadiusFromBounds( sprite_mins, sprite_maxs );
|
||||
|
||||
VectorAdd( sprite_mins, origin, sprite_mins );
|
||||
VectorAdd( sprite_maxs, origin, sprite_maxs );
|
||||
|
||||
return R_CullModel( e, sprite_mins, sprite_maxs );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -66,12 +66,11 @@ convar_t *r_faceplanecull;
|
|||
convar_t *r_drawentities;
|
||||
convar_t *r_adjust_fov;
|
||||
convar_t *r_flaresize;
|
||||
convar_t *r_lefthand;
|
||||
convar_t *r_decals;
|
||||
convar_t *r_novis;
|
||||
convar_t *r_nocull;
|
||||
convar_t *r_lockpvs;
|
||||
convar_t *r_lockcull;
|
||||
convar_t *r_lockfrustum;
|
||||
convar_t *r_dynamic;
|
||||
convar_t *r_lightmap;
|
||||
convar_t *r_fastsky;
|
||||
|
@ -1749,13 +1748,12 @@ void GL_InitCommands( void )
|
|||
r_faceplanecull = Cvar_Get( "r_faceplanecull", "1", 0, "ignore face plane culling (perfomance test)" );
|
||||
r_detailtextures = Cvar_Get( "r_detailtextures", "1", FCVAR_ARCHIVE, "enable detail textures support, use '2' for autogenerate detail.txt" );
|
||||
r_lockpvs = Cvar_Get( "r_lockpvs", "0", FCVAR_CHEAT, "lockpvs area at current point (pvs test)" );
|
||||
r_lockcull = Cvar_Get( "r_lockcull", "0", FCVAR_CHEAT, "lock frustrum area at current point (cull test)" );
|
||||
r_lockfrustum = Cvar_Get( "r_lockfrustum", "0", FCVAR_CHEAT, "lock frustrum area at current point (cull test)" );
|
||||
r_dynamic = Cvar_Get( "r_dynamic", "1", FCVAR_ARCHIVE, "allow dynamic lighting (dlights, lightstyles)" );
|
||||
r_lightmap = Cvar_Get( "r_lightmap", "0", FCVAR_CHEAT, "lightmap debugging tool" );
|
||||
r_fastsky = Cvar_Get( "r_fastsky", "0", FCVAR_ARCHIVE, "enable algorhytm fo fast sky rendering (for old machines)" );
|
||||
r_drawentities = Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT|FCVAR_ARCHIVE, "render entities" );
|
||||
r_flaresize = Cvar_Get( "r_flaresize", "200", FCVAR_ARCHIVE, "set flares size" );
|
||||
r_lefthand = Cvar_Get( "hand", "0", FCVAR_ARCHIVE, "viewmodel handedness" );
|
||||
r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
|
||||
r_xpos = Cvar_Get( "r_xpos", "130", FCVAR_RENDERINFO, "window position by horizontal" );
|
||||
r_ypos = Cvar_Get( "r_ypos", "48", FCVAR_RENDERINFO, "window position by vertical" );
|
||||
|
|
|
@ -135,7 +135,7 @@ void VGUI_CreateTexture( int id, int width, int height )
|
|||
|
||||
void VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight )
|
||||
{
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES || g_textures[id] == 0 || g_textures[id] == cls.fillImage )
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES || g_textures[id] == 0 || g_textures[id] == tr.whiteTexture )
|
||||
{
|
||||
MsgDev( D_ERROR, "VGUI_UploadTextureBlock: bad texture %i. Ignored\n", id );
|
||||
return;
|
||||
|
|
|
@ -15,8 +15,24 @@ GNU General Public License for more details.
|
|||
|
||||
#include "common.h"
|
||||
#include "mathlib.h"
|
||||
#include "eiface.h"
|
||||
|
||||
vec3_t vec3_origin = { 0, 0, 0 };
|
||||
#define NUM_HULL_ROUNDS ARRAYSIZE( hull_table )
|
||||
#define HULL_PRECISION 4
|
||||
|
||||
vec3_t vec3_origin = { 0, 0, 0 };
|
||||
|
||||
static word hull_table[] = { 2, 4, 6, 8, 12, 16, 18, 24, 28, 32, 36, 40, 48, 54, 56, 60, 64, 72, 80, 112, 120, 128, 140, 176 };
|
||||
|
||||
int boxpnt[6][4] =
|
||||
{
|
||||
{ 0, 4, 6, 2 }, // +X
|
||||
{ 0, 1, 5, 4 }, // +Y
|
||||
{ 0, 2, 3, 1 }, // +Z
|
||||
{ 7, 5, 1, 3 }, // -X
|
||||
{ 7, 3, 2, 6 }, // -Y
|
||||
{ 7, 6, 4, 5 }, // -Z
|
||||
};
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -75,6 +91,56 @@ float HalfToFloat( word h )
|
|||
return *((float *)&f);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
RoundUpHullSize
|
||||
|
||||
round the hullsize to nearest 'right' value
|
||||
=================
|
||||
*/
|
||||
void RoundUpHullSize( vec3_t size )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for( i = 0; i < 3; i++)
|
||||
{
|
||||
qboolean negative = false;
|
||||
float result, value;
|
||||
|
||||
value = size[i];
|
||||
if( value < 0.0f ) negative = true;
|
||||
value = Q_ceil( fabs( value ));
|
||||
|
||||
// lookup hull table to find nearest supposed value
|
||||
for( j = 0; j < NUM_HULL_ROUNDS; j++ )
|
||||
{
|
||||
if( value > hull_table[j] )
|
||||
continue; // ceil only
|
||||
|
||||
if( negative )
|
||||
{
|
||||
result = ( value - hull_table[j] );
|
||||
if( result <= HULL_PRECISION )
|
||||
{
|
||||
result = -hull_table[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ( value - hull_table[j] );
|
||||
if( result <= HULL_PRECISION )
|
||||
{
|
||||
result = hull_table[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size[i] = result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SignbitsForPlane
|
||||
|
@ -370,6 +436,29 @@ qboolean BoundsAndSphereIntersect( const vec3_t mins, const vec3_t maxs, const v
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SphereIntersect
|
||||
=================
|
||||
*/
|
||||
qboolean SphereIntersect( const vec3_t vSphereCenter, float fSphereRadiusSquared, const vec3_t vLinePt, const vec3_t vLineDir )
|
||||
{
|
||||
float a, b, c, insideSqr;
|
||||
vec3_t p;
|
||||
|
||||
// translate sphere to origin.
|
||||
VectorSubtract( vLinePt, vSphereCenter, p );
|
||||
|
||||
a = DotProduct( vLineDir, vLineDir );
|
||||
b = 2.0f * DotProduct( p, vLineDir );
|
||||
c = DotProduct( p, p ) - fSphereRadiusSquared;
|
||||
|
||||
insideSqr = b * b - 4.0f * a * c;
|
||||
if( insideSqr <= 0.000001f )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
RadiusFromBounds
|
||||
|
@ -469,52 +558,70 @@ void QuaternionAngle( const vec4_t q, vec3_t angles )
|
|||
|
||||
/*
|
||||
====================
|
||||
QuaternionSlerp
|
||||
QuaternionAlign
|
||||
|
||||
make sure quaternions are within 180 degrees of one another,
|
||||
if not, reverse q
|
||||
====================
|
||||
*/
|
||||
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt )
|
||||
void QuaternionAlign( const vec4_t p, const vec4_t q, vec4_t qt )
|
||||
{
|
||||
float omega, sclp, sclq;
|
||||
float cosom, sinom;
|
||||
// decide if one of the quaternions is backwards
|
||||
float a = 0.0f;
|
||||
float b = 0.0f;
|
||||
int i;
|
||||
|
||||
// decide if one of the quaternions is backwards
|
||||
for( i = 0; i < 4; i++ )
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
a += (p[i] - q[i]) * (p[i] - q[i]);
|
||||
b += (p[i] + q[i]) * (p[i] + q[i]);
|
||||
}
|
||||
|
||||
if( a > b )
|
||||
if( a > b )
|
||||
{
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
q[i] = -q[i];
|
||||
}
|
||||
for( i = 0; i < 4; i++ )
|
||||
qt[i] = -q[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < 4; i++ )
|
||||
qt[i] = q[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
QuaternionSlerpNoAlign
|
||||
====================
|
||||
*/
|
||||
void QuaternionSlerpNoAlign( const vec4_t p, const vec4_t q, float t, vec4_t qt )
|
||||
{
|
||||
float omega, cosom, sinom, sclp, sclq;
|
||||
int i;
|
||||
|
||||
// 0.0 returns p, 1.0 return q.
|
||||
cosom = p[0] * q[0] + p[1] * q[1] + p[2] * q[2] + p[3] * q[3];
|
||||
|
||||
if(( 1.0 + cosom ) > 0.000001f )
|
||||
if(( 1.0f + cosom ) > 0.000001f )
|
||||
{
|
||||
if(( 1.0f - cosom ) > 0.000001f )
|
||||
{
|
||||
omega = acos( cosom );
|
||||
sinom = sin( omega );
|
||||
sclp = sin(( 1.0f - t ) * omega ) / sinom;
|
||||
sclp = sin( (1.0f - t) * omega) / sinom;
|
||||
sclq = sin( t * omega ) / sinom;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: add short circuit for cosom == 1.0f?
|
||||
sclp = 1.0f - t;
|
||||
sclq = t;
|
||||
}
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
qt[i] = sclp * p[i] + sclq * q[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -526,6 +633,26 @@ void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt )
|
|||
sclq = sin( t * ( 0.5f * M_PI ));
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
qt[i] = sclp * p[i] + sclq * qt[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
QuaternionSlerp
|
||||
|
||||
Quaternion sphereical linear interpolation
|
||||
====================
|
||||
*/
|
||||
void QuaternionSlerp( const vec4_t p, const vec4_t q, float t, vec4_t qt )
|
||||
{
|
||||
vec4_t q2;
|
||||
|
||||
// 0.0 returns p, 1.0 return q.
|
||||
// decide if one of the quaternions is backwards
|
||||
QuaternionAlign( p, q, q2 );
|
||||
|
||||
QuaternionSlerpNoAlign( p, q2, t, qt );
|
||||
}
|
|
@ -119,6 +119,7 @@ float rsqrt( float number );
|
|||
float anglemod( const float a );
|
||||
word FloatToHalf( float v );
|
||||
float HalfToFloat( word h );
|
||||
void RoundUpHullSize( vec3_t size );
|
||||
int SignbitsForPlane( const vec3_t normal );
|
||||
int NearestPOW( int value, qboolean roundDown );
|
||||
void SinCos( float radians, float *sine, float *cosine );
|
||||
|
@ -133,11 +134,12 @@ void ClearBounds( vec3_t mins, vec3_t maxs );
|
|||
void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs );
|
||||
qboolean BoundsIntersect( const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2 );
|
||||
qboolean BoundsAndSphereIntersect( const vec3_t mins, const vec3_t maxs, const vec3_t origin, float radius );
|
||||
qboolean SphereIntersect( const vec3_t vSphereCenter, float fSphereRadiusSquared, const vec3_t vLinePt, const vec3_t vLineDir );
|
||||
float RadiusFromBounds( const vec3_t mins, const vec3_t maxs );
|
||||
|
||||
void AngleQuaternion( const vec3_t angles, vec4_t q, qboolean studio );
|
||||
void QuaternionAngle( const vec4_t q, vec3_t angles );
|
||||
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt );
|
||||
void QuaternionSlerp( const vec4_t p, const vec4_t q, float t, vec4_t qt );
|
||||
float RemapVal( float val, float A, float B, float C, float D );
|
||||
float ApproachVal( float target, float value, float speed );
|
||||
|
||||
|
@ -180,6 +182,7 @@ void Matrix4x4_Transpose( matrix4x4 out, const matrix4x4 in1 );
|
|||
qboolean Matrix4x4_Invert_Full( matrix4x4 out, const matrix4x4 in1 );
|
||||
|
||||
extern vec3_t vec3_origin;
|
||||
extern int boxpnt[6][4];
|
||||
extern const matrix3x4 matrix3x4_identity;
|
||||
extern const matrix4x4 matrix4x4_identity;
|
||||
|
||||
|
|
|
@ -166,6 +166,9 @@ qboolean Mod_GetStudioBounds( const char *name, vec3_t mins, vec3_t maxs );
|
|||
void Mod_StudioGetAttachment( const edict_t *e, int iAttachment, float *org, float *ang );
|
||||
void Mod_GetBonePosition( const edict_t *e, int iBone, float *org, float *ang );
|
||||
hull_t *Mod_HullForStudio( model_t *m, float frame, int seq, vec3_t ang, vec3_t org, vec3_t size, byte *pcnt, byte *pbl, int *hitboxes, edict_t *ed );
|
||||
void R_StudioCalcBoneQuaternion( int frame, float s, void *pbone, void *panim, float *adj, vec4_t q );
|
||||
void R_StudioCalcBonePosition( int frame, float s, void *pbone, void *panim, vec3_t adj, vec3_t pos );
|
||||
void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs );
|
||||
int Mod_HitgroupForStudioHull( int index );
|
||||
|
||||
#endif//MOD_LOCAL_H
|
|
@ -330,162 +330,6 @@ static void Mod_StudioCalcBoneAdj( float *adj, const byte *pcontroller )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
StudioCalcBoneQuaterion
|
||||
|
||||
====================
|
||||
*/
|
||||
static void Mod_StudioCalcBoneQuaterion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *q )
|
||||
{
|
||||
int j, k;
|
||||
vec4_t q1, q2;
|
||||
vec3_t angle1, angle2;
|
||||
mstudioanimvalue_t *panimvalue;
|
||||
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
if( panim->offset[j+3] == 0 )
|
||||
{
|
||||
angle2[j] = angle1[j] = pbone->value[j+3]; // default;
|
||||
}
|
||||
else
|
||||
{
|
||||
panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
|
||||
k = frame;
|
||||
|
||||
// debug
|
||||
if( panimvalue->num.total < panimvalue->num.valid )
|
||||
k = 0;
|
||||
|
||||
while( panimvalue->num.total <= k )
|
||||
{
|
||||
k -= panimvalue->num.total;
|
||||
panimvalue += panimvalue->num.valid + 1;
|
||||
// DEBUG
|
||||
if( panimvalue->num.total < panimvalue->num.valid )
|
||||
k = 0;
|
||||
}
|
||||
// Bah, missing blend!
|
||||
if( panimvalue->num.valid > k )
|
||||
{
|
||||
angle1[j] = panimvalue[k+1].value;
|
||||
|
||||
if( panimvalue->num.valid > k + 1 )
|
||||
{
|
||||
angle2[j] = panimvalue[k+2].value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( panimvalue->num.total > k + 1 )
|
||||
angle2[j] = angle1[j];
|
||||
else angle2[j] = panimvalue[panimvalue->num.valid+2].value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
angle1[j] = panimvalue[panimvalue->num.valid].value;
|
||||
if( panimvalue->num.total > k + 1 )
|
||||
{
|
||||
angle2[j] = angle1[j];
|
||||
}
|
||||
else
|
||||
{
|
||||
angle2[j] = panimvalue[panimvalue->num.valid + 2].value;
|
||||
}
|
||||
}
|
||||
angle1[j] = pbone->value[j+3] + angle1[j] * pbone->scale[j+3];
|
||||
angle2[j] = pbone->value[j+3] + angle2[j] * pbone->scale[j+3];
|
||||
}
|
||||
|
||||
if( pbone->bonecontroller[j+3] != -1 )
|
||||
{
|
||||
angle1[j] += adj[pbone->bonecontroller[j+3]];
|
||||
angle2[j] += adj[pbone->bonecontroller[j+3]];
|
||||
}
|
||||
}
|
||||
|
||||
if( !VectorCompare( angle1, angle2 ))
|
||||
{
|
||||
AngleQuaternion( angle1, q1, true );
|
||||
AngleQuaternion( angle2, q2, true );
|
||||
QuaternionSlerp( q1, q2, s, q );
|
||||
}
|
||||
else
|
||||
{
|
||||
AngleQuaternion( angle1, q, true );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
StudioCalcBonePosition
|
||||
|
||||
====================
|
||||
*/
|
||||
static void Mod_StudioCalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *pos )
|
||||
{
|
||||
int j, k;
|
||||
mstudioanimvalue_t *panimvalue;
|
||||
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
pos[j] = pbone->value[j]; // default;
|
||||
if( panim->offset[j] != 0.0f )
|
||||
{
|
||||
panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
|
||||
|
||||
k = frame;
|
||||
|
||||
// debug
|
||||
if( panimvalue->num.total < panimvalue->num.valid )
|
||||
k = 0;
|
||||
|
||||
// find span of values that includes the frame we want
|
||||
while( panimvalue->num.total <= k )
|
||||
{
|
||||
k -= panimvalue->num.total;
|
||||
panimvalue += panimvalue->num.valid + 1;
|
||||
|
||||
// DEBUG
|
||||
if( panimvalue->num.total < panimvalue->num.valid )
|
||||
k = 0;
|
||||
}
|
||||
|
||||
// if we're inside the span
|
||||
if( panimvalue->num.valid > k )
|
||||
{
|
||||
// and there's more data in the span
|
||||
if( panimvalue->num.valid > k + 1 )
|
||||
{
|
||||
pos[j] += (panimvalue[k+1].value * (1.0f - s) + s * panimvalue[k+2].value) * pbone->scale[j];
|
||||
}
|
||||
else
|
||||
{
|
||||
pos[j] += panimvalue[k+1].value * pbone->scale[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// are we at the end of the repeating values section and there's another section with data?
|
||||
if( panimvalue->num.total <= k + 1 )
|
||||
{
|
||||
pos[j] += (panimvalue[panimvalue->num.valid].value * (1.0f - s) + s * panimvalue[panimvalue->num.valid + 2].value) * pbone->scale[j];
|
||||
}
|
||||
else
|
||||
{
|
||||
pos[j] += panimvalue[panimvalue->num.valid].value * pbone->scale[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pbone->bonecontroller[j] != -1 && adj )
|
||||
{
|
||||
pos[j] += adj[pbone->bonecontroller[j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
StudioCalcRotations
|
||||
|
@ -515,8 +359,8 @@ static void Mod_StudioCalcRotations( int boneused[], int numbones, const byte *p
|
|||
for( j = numbones - 1; j >= 0; j-- )
|
||||
{
|
||||
i = boneused[j];
|
||||
Mod_StudioCalcBoneQuaterion( frame, s, &pbone[i], &panim[i], adj, q[i] );
|
||||
Mod_StudioCalcBonePosition( frame, s, &pbone[i], &panim[i], adj, pos[i] );
|
||||
R_StudioCalcBoneQuaternion( frame, s, &pbone[i], &panim[i], adj, q[i] );
|
||||
R_StudioCalcBonePosition( frame, s, &pbone[i], &panim[i], adj, pos[i] );
|
||||
}
|
||||
|
||||
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
|
||||
|
@ -869,8 +713,10 @@ void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs )
|
|||
studiohdr_t *pstudiohdr;
|
||||
mstudiobodyparts_t *pbodypart;
|
||||
mstudiomodel_t *m_pSubModel;
|
||||
mstudioseqgroup_t *pseqgroup;
|
||||
mstudioseqdesc_t *pseqdesc;
|
||||
mstudiobone_t *pbones;
|
||||
mstudioanim_t *panim;
|
||||
vec3_t vecmins1, vecmaxs1;
|
||||
vec3_t vecmins2, vecmaxs2;
|
||||
int counter1, counter2;
|
||||
|
@ -905,17 +751,21 @@ void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs )
|
|||
}
|
||||
|
||||
pbones = (mstudiobone_t *)((byte *)pstudiohdr + pstudiohdr->boneindex);
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
|
||||
|
||||
for( i = 0; i < pstudiohdr->numseq; i++ )
|
||||
{
|
||||
mstudioanim_t *panim = (mstudioanim_t *) (((byte *)buffer) + pseqdesc[i].animindex);
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + i;
|
||||
pseqgroup = (mstudioseqgroup_t *)((byte *)pstudiohdr + pstudiohdr->seqgroupindex) + pseqdesc->seqgroup;
|
||||
|
||||
if( pseqdesc->seqgroup == 0 )
|
||||
panim = (mstudioanim_t *)((byte *)pstudiohdr + pseqgroup->data + pseqdesc->animindex);
|
||||
else continue;
|
||||
|
||||
for( j = 0; j < pstudiohdr->numbones; j++ )
|
||||
{
|
||||
for( k = 0; k < pseqdesc[i].numframes; k++ )
|
||||
for( k = 0; k < pseqdesc->numframes; k++ )
|
||||
{
|
||||
Mod_StudioCalcBonePosition( k, 0, &pbones[j], panim, NULL, pos );
|
||||
R_StudioCalcBonePosition( k, 0, &pbones[j], panim, NULL, pos );
|
||||
Mod_StudioBoundVertex( vecmins2, vecmaxs2, &counter2, pos );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,16 +20,6 @@ GNU General Public License for more details.
|
|||
// expand debugging BBOX particle hulls by this many units.
|
||||
#define BOX_GAP 0.0f
|
||||
|
||||
static int boxpnt[6][4] =
|
||||
{
|
||||
{ 0, 4, 6, 2 }, // +X
|
||||
{ 0, 1, 5, 4 }, // +Y
|
||||
{ 0, 2, 3, 1 }, // +Z
|
||||
{ 7, 5, 1, 3 }, // -X
|
||||
{ 7, 3, 2, 6 }, // -Y
|
||||
{ 7, 6, 4, 5 }, // -Z
|
||||
};
|
||||
|
||||
/*
|
||||
===============
|
||||
PM_ParticleLine
|
||||
|
|
|
@ -22,6 +22,8 @@ GNU General Public License for more details.
|
|||
#include "studio.h"
|
||||
#include "world.h"
|
||||
|
||||
#define PM_AllowHitBoxTrace( model, hull ) ( model && model->type == mod_studio && ( FBitSet( model->flags, STUDIO_TRACE_HITBOX ) || hull == 2 ))
|
||||
|
||||
static mplane_t pm_boxplanes[6];
|
||||
static dclipnode_t pm_boxclipnodes[6];
|
||||
static hull_t pm_boxhull;
|
||||
|
@ -341,22 +343,23 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
|
|||
VectorCopy( pmove->player_maxs[pmove->usehull], maxs );
|
||||
VectorClear( offset );
|
||||
}
|
||||
else if( !pe->model )
|
||||
else if( pe->model )
|
||||
{
|
||||
if( !pe->studiomodel )
|
||||
hull = PM_HullForBsp( pe, pmove, offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pe->studiomodel )
|
||||
{
|
||||
VectorSubtract( pe->mins, pmove->player_maxs[pmove->usehull], mins );
|
||||
VectorSubtract( pe->maxs, pmove->player_mins[pmove->usehull], maxs );
|
||||
|
||||
hull = PM_HullForBox( mins, maxs );
|
||||
VectorCopy( pe->origin, offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( flags & PM_STUDIO_IGNORE )
|
||||
if( FBitSet( flags, PM_STUDIO_IGNORE ))
|
||||
continue;
|
||||
|
||||
if( pe->studiomodel->type != mod_studio || (!( pe->studiomodel->flags & STUDIO_TRACE_HITBOX ) && ( pmove->usehull != 2 || flags & PM_STUDIO_BOX )))
|
||||
if( PM_AllowHitBoxTrace( pe->studiomodel, pmove->usehull ) && !FBitSet( flags, PM_STUDIO_BOX ))
|
||||
{
|
||||
hull = PM_HullForStudio( pe, pmove, &hullcount );
|
||||
VectorClear( offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSubtract( pe->mins, pmove->player_maxs[pmove->usehull], mins );
|
||||
VectorSubtract( pe->maxs, pmove->player_mins[pmove->usehull], maxs );
|
||||
|
@ -364,16 +367,16 @@ pmtrace_t PM_PlayerTraceExt( playermove_t *pmove, vec3_t start, vec3_t end, int
|
|||
hull = PM_HullForBox( mins, maxs );
|
||||
VectorCopy( pe->origin, offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
hull = PM_HullForStudio( pe, pmove, &hullcount );
|
||||
VectorClear( offset );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSubtract( pe->mins, pmove->player_maxs[pmove->usehull], mins );
|
||||
VectorSubtract( pe->maxs, pmove->player_mins[pmove->usehull], maxs );
|
||||
|
||||
hull = PM_HullForBox( mins, maxs );
|
||||
VectorCopy( pe->origin, offset );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hull = PM_HullForBsp( pe, pmove, offset );
|
||||
|
||||
}
|
||||
|
||||
if( pe->solid == SOLID_BSP && !VectorIsNull( pe->angles ))
|
||||
|
@ -538,7 +541,12 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p
|
|||
{
|
||||
hull = PM_HullForBsp( pe, pmove, offset );
|
||||
}
|
||||
else if( !pe->studiomodel || pe->studiomodel->type != mod_studio || (!( pe->studiomodel->flags & STUDIO_TRACE_HITBOX ) && pmove->usehull != 2 ))
|
||||
else if( PM_AllowHitBoxTrace( pe->studiomodel, pmove->usehull ))
|
||||
{
|
||||
hull = PM_HullForStudio( pe, pmove, &hullcount );
|
||||
VectorClear( offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSubtract( pe->mins, pmove->player_maxs[pmove->usehull], mins );
|
||||
VectorSubtract( pe->maxs, pmove->player_mins[pmove->usehull], maxs );
|
||||
|
@ -546,11 +554,6 @@ int PM_TestPlayerPosition( playermove_t *pmove, vec3_t pos, pmtrace_t *ptrace, p
|
|||
hull = PM_HullForBox( mins, maxs );
|
||||
VectorCopy( pe->origin, offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
hull = PM_HullForStudio( pe, pmove, &hullcount );
|
||||
VectorClear( offset );
|
||||
}
|
||||
|
||||
// CM_TransformedPointContents :-)
|
||||
if( pe->solid == SOLID_BSP && !VectorIsNull( pe->angles ))
|
||||
|
|
|
@ -125,6 +125,7 @@ SV_CheckVelocity
|
|||
void SV_CheckVelocity( edict_t *ent )
|
||||
{
|
||||
float wishspd;
|
||||
float maxspd;
|
||||
int i;
|
||||
|
||||
// bound velocity
|
||||
|
@ -144,10 +145,11 @@ void SV_CheckVelocity( edict_t *ent )
|
|||
}
|
||||
|
||||
wishspd = DotProduct( ent->v.velocity, ent->v.velocity );
|
||||
maxspd = sv_maxvelocity.value * sv_maxvelocity.value * 1.73f; // half-diagonal
|
||||
|
||||
if( wishspd > ( sv_maxvelocity.value * sv_maxvelocity.value ))
|
||||
if( wishspd > maxspd )
|
||||
{
|
||||
MsgDev( D_INFO, "Got a velocity too high on %s\n", STRING( ent->v.classname ));
|
||||
MsgDev( D_INFO, "Got a velocity too high on %s ( %.2f > %.2f )\n", STRING( ent->v.classname ), sqrt( wishspd ), sqrt( maxspd ));
|
||||
wishspd = sv_maxvelocity.value / sqrt( wishspd );
|
||||
VectorScale( ent->v.velocity, wishspd, ent->v.velocity );
|
||||
}
|
||||
|
|
|
@ -107,6 +107,48 @@ void SV_StudioPlayerBlend( mstudioseqdesc_t *pseqdesc, int *pBlend, float *pPitc
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
SV_CheckSphereIntersection
|
||||
|
||||
check clients only
|
||||
====================
|
||||
*/
|
||||
qboolean SV_CheckSphereIntersection( edict_t *ent, const vec3_t start, const vec3_t end )
|
||||
{
|
||||
int i, sequence;
|
||||
float radiusSquared;
|
||||
vec3_t traceOrg, traceDir;
|
||||
studiohdr_t *pstudiohdr;
|
||||
mstudioseqdesc_t *pseqdesc;
|
||||
model_t *mod;
|
||||
|
||||
if( !FBitSet( ent->v.flags, FL_CLIENT|FL_FAKECLIENT ))
|
||||
return true;
|
||||
|
||||
if(( mod = Mod_Handle( ent->v.modelindex )) == NULL )
|
||||
return true;
|
||||
|
||||
if(( pstudiohdr = (studiohdr_t *)Mod_Extradata( mod )) == NULL )
|
||||
return true;
|
||||
|
||||
sequence = ent->v.sequence;
|
||||
if( sequence < 0 || sequence >= pstudiohdr->numseq )
|
||||
sequence = 0;
|
||||
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence;
|
||||
|
||||
VectorCopy( start, traceOrg );
|
||||
VectorSubtract( end, start, traceDir );
|
||||
radiusSquared = 0.0f;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
radiusSquared += Q_max( fabs( pseqdesc->bbmin[i] ), fabs( pseqdesc->bbmax[i] ));
|
||||
|
||||
return SphereIntersect( ent->v.origin, radiusSquared, traceOrg, traceDir );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
SV_HullForBox
|
||||
|
@ -1141,6 +1183,10 @@ static void SV_ClipToLinks( areanode_t *node, moveclip_t *clip )
|
|||
if( !BoundsIntersect( clip->boxmins, clip->boxmaxs, touch->v.absmin, touch->v.absmax ))
|
||||
continue;
|
||||
|
||||
// aditional check to intersects clients with sphere
|
||||
if( touch->v.solid != SOLID_SLIDEBOX && !SV_CheckSphereIntersection( touch, clip->start, clip->end ))
|
||||
continue;
|
||||
|
||||
// Xash3D extension
|
||||
if( SV_IsValidEdict( clip->passedict ) && clip->passedict->v.solid == SOLID_TRIGGER )
|
||||
{
|
||||
|
|
|
@ -57,8 +57,9 @@ Studio models are position independent, so the cache manager can move them.
|
|||
#define STUDIO_ZOMGIB 0x0020 // small blood trail
|
||||
#define STUDIO_TRACER2 0x0040 // orange split trail + rotate
|
||||
#define STUDIO_TRACER3 0x0080 // purple trail
|
||||
#define STUDIO_DYNAMIC_LIGHT 0x0100 // dynamically get lighting from floor or ceil (flying monsters)
|
||||
#define STUDIO_AMBIENT_LIGHT 0x0100 // force to use ambient shading
|
||||
#define STUDIO_TRACE_HITBOX 0x0200 // always use hitbox trace instead of bbox
|
||||
#define STUDIO_FORCE_SKYLIGHT 0x0400 // always grab lightvalues from the sky settings (even if sky is invisible)
|
||||
|
||||
// lighting & rendermode options
|
||||
#define STUDIO_NF_FLATSHADE 0x0001
|
||||
|
@ -97,7 +98,6 @@ Studio models are position independent, so the cache manager can move them.
|
|||
|
||||
// sequence flags
|
||||
#define STUDIO_LOOPING 0x0001
|
||||
#define STUDIO_STATIC 0x8000 // studiomodel is static
|
||||
|
||||
// bone flags
|
||||
#define STUDIO_HAS_NORMALS 0x0001
|
||||
|
|
Reference in New Issue