int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char *tagName ) { md3Tag_t *start, *end; #ifdef RAVENMD4 md3Tag_t start_space, end_space; #endif int i; float frontLerp, backLerp; model_t *model; model = R_GetModelByHandle( handle ); if ( !model->md3[0] ) { #ifdef RAVENMD4 if(model->type == MOD_MDR) { start = &start_space; end = &end_space; R_GetAnimTag((mdrHeader_t *) model->modelData, startFrame, tagName, start); R_GetAnimTag((mdrHeader_t *) model->modelData, endFrame, tagName, end); } else #endif if( model->type == MOD_IQM ) { return R_IQMLerpTag( tag, model->modelData, startFrame, endFrame, frac, tagName ); } else { AxisClear( tag->axis ); VectorClear( &tag->origin ); return qfalse; } } else { start = R_GetTag( model->md3[0], startFrame, tagName ); end = R_GetTag( model->md3[0], endFrame, tagName ); if ( !start || !end ) { AxisClear( tag->axis ); VectorClear( &tag->origin ); return qfalse; } } frontLerp = frac; backLerp = 1.0f - frac; for ( i = 0 ; i < 3 ; i++ ) { tag->origin.data[i] = start->origin.data[i] * backLerp + end->origin.data[i] * frontLerp; tag->axis[0].data[i] = start->axis[0].data[i] * backLerp + end->axis[0].data[i] * frontLerp; tag->axis[1].data[i] = start->axis[1].data[i] * backLerp + end->axis[1].data[i] * frontLerp; tag->axis[2].data[i] = start->axis[2].data[i] * backLerp + end->axis[2].data[i] * frontLerp; } VectorNormalize( &tag->axis[0] ); VectorNormalize( &tag->axis[1] ); VectorNormalize( &tag->axis[2] ); return qtrue; }
int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char *tagName ) { const model_t* model = R_GetModelByHandle( handle ); if ( !model->md3[0] ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return qfalse; } const md3Tag_t* start = R_GetTag( model->md3[0], startFrame, tagName ); const md3Tag_t* end = R_GetTag( model->md3[0], endFrame, tagName ); if ( !start || !end ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return qfalse; } float backLerp = 1.0f - frac; for ( int i = 0; i < 3; ++i ) { tag->origin[i] = start->origin[i] * backLerp + end->origin[i] * frac; tag->axis[0][i] = start->axis[0][i] * backLerp + end->axis[0][i] * frac; tag->axis[1][i] = start->axis[1][i] * backLerp + end->axis[1][i] * frac; tag->axis[2][i] = start->axis[2][i] * backLerp + end->axis[2][i] * frac; } VectorNormalize( tag->axis[0] ); VectorNormalize( tag->axis[1] ); VectorNormalize( tag->axis[2] ); return qtrue; }
bool R_LerpTag( orientation_t* tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char* tagName ) { int i; float frontLerp, backLerp; idRenderModel* model = R_GetModelByHandle( handle ); if ( !model->q3_md3[ 0 ].header ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return false; } md3Tag_t* start = R_GetTag( model->q3_md3[ 0 ].header, startFrame, tagName ); md3Tag_t* end = R_GetTag( model->q3_md3[ 0 ].header, endFrame, tagName ); if ( !start || !end ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return false; } frontLerp = frac; backLerp = 1.0f - frac; for ( i = 0; i < 3; i++ ) { tag->origin[ i ] = start->origin[ i ] * backLerp + end->origin[ i ] * frontLerp; tag->axis[ 0 ][ i ] = start->axis[ 0 ][ i ] * backLerp + end->axis[ 0 ][ i ] * frontLerp; tag->axis[ 1 ][ i ] = start->axis[ 1 ][ i ] * backLerp + end->axis[ 1 ][ i ] * frontLerp; tag->axis[ 2 ][ i ] = start->axis[ 2 ][ i ] * backLerp + end->axis[ 2 ][ i ] * frontLerp; } VectorNormalize( tag->axis[ 0 ] ); VectorNormalize( tag->axis[ 1 ] ); VectorNormalize( tag->axis[ 2 ] ); return true; }
/* ================ RE_LerpTagQ3A ================ */ int RE_LerpTagQ3A( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char *tagNameIn ) { mdvTag_t *start, *end; int i; float frontLerp, backLerp; model_t *model; char tagName[ MAX_QPATH ]; int retval; Q_strncpyz( tagName, tagNameIn, MAX_QPATH ); model = R_GetModelByHandle( handle ); if ( !model->mdv[ 0 ] ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return -1; } start = end = NULL; retval = R_GetTag( model->mdv[ 0 ], startFrame, tagName, 0, &start ); retval = R_GetTag( model->mdv[ 0 ], endFrame, tagName, 0, &end ); if ( !start || !end ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return -1; } frontLerp = frac; backLerp = 1.0f - frac; for ( i = 0; i < 3; i++ ) { tag->origin[ i ] = start->origin[ i ] * backLerp + end->origin[ i ] * frontLerp; tag->axis[ 0 ][ i ] = start->axis[ 0 ][ i ] * backLerp + end->axis[ 0 ][ i ] * frontLerp; tag->axis[ 1 ][ i ] = start->axis[ 1 ][ i ] * backLerp + end->axis[ 1 ][ i ] * frontLerp; tag->axis[ 2 ][ i ] = start->axis[ 2 ][ i ] * backLerp + end->axis[ 2 ][ i ] * frontLerp; } VectorNormalize( tag->axis[ 0 ] ); VectorNormalize( tag->axis[ 1 ] ); VectorNormalize( tag->axis[ 2 ] ); return retval; }
/* ================== CG_SpawnEffect Player teleporting in or out ================== */ void CG_SpawnEffect( bvec3_t org ) { localEntity_t *le; refEntity_t *re; le = CG_AllocLocalEntity(); le->leFlags = 0; le->leType = LE_FADE_RGB; le->startTime = cg.time; le->endTime = cg.time + 500; le->lifeRate = FIXED_INT32RATIO_G(1,( le->endTime - le->startTime )); le->color[0] = le->color[1] = le->color[2] = le->color[3] = GFIXED_1; re = &le->refEntity; re->reType = RT_MODEL; re->shaderTime = MSECTIME_G(cg.time); #ifndef MISSIONPACK re->customShader = cgs.media.teleportEffectShader; #endif re->hModel = cgs.media.teleportEffectModel; AxisClear( re->axis ); VectorCopy( org, re->origin ); #ifdef MISSIONPACK re->origin[2] += BFIXED(16,0); #else re->origin[2] -= BFIXED(24,0); #endif }
/* ================= CL_ParseLaser ================= */ static void CL_ParseLaser (sizebuf_t *msg, int colors) { vec3_t start; vec3_t end; laser_t *l; int i; MSG_ReadPos (msg, start); MSG_ReadPos (msg, end); for (i = 0, l = cl_lasers; i < MAX_LASERS; i++, l++) { if (l->endtime < cl.time) { l->ent.flags = RF_TRANSLUCENT | RF_BEAM; VectorCopy (start, l->ent.origin); VectorCopy (end, l->ent.oldorigin); l->ent.alpha = 0.30f; l->ent.skinnum = (colors >> ((rand() % 4)*8)) & 0xff; l->ent.model = NULL; l->ent.frame = 4; l->endtime = cl.time + 100; #ifdef GL_QUAKE AxisClear(l->ent.axis); #endif return; } }
/* ==================== CG_MakeExplosion ==================== */ localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir, qhandle_t hModel, qhandle_t shader, int offset, int duration, bool isSprite ) { float ang; localEntity_t *ex; vec3_t tmpVec, newOrigin; if ( duration <= 0 ) { Com_Error( ERR_DROP, "CG_MakeExplosion: duration = %i", duration ); } // skew the time a bit so they aren't all in sync offset += rand() & 63; ex = CG_AllocLocalEntity(); if ( isSprite ) { ex->leType = LE_SPRITE_EXPLOSION; // randomly rotate sprite orientation ex->refEntity.rotation = rand() % 360; VectorScale( dir, 16, tmpVec ); VectorAdd( tmpVec, origin, newOrigin ); } else { ex->leType = LE_EXPLOSION; VectorCopy( origin, newOrigin ); // set axis with random rotate if ( !dir ) { AxisClear( ex->refEntity.axis ); } else { ang = rand() % 360; VectorCopy( dir, ex->refEntity.axis[0] ); RotateAroundDirection( ex->refEntity.axis, ang ); } } // calc the timings ex->startTime = cg.time + offset; ex->endTime = ex->startTime + duration; // bias the time so all shader effects start correctly ex->refEntity.shaderTime = ex->startTime / 1000.0f; ex->refEntity.hModel = hModel; ex->refEntity.customShader = shader; // set origin VectorCopy( newOrigin, ex->refEntity.origin ); VectorCopy( newOrigin, ex->refEntity.oldorigin ); ex->color[0] = ex->color[1] = ex->color[2] = 1; return ex; }
/* ========================== CG_GrappleTrail ========================== */ void CG_GrappleTrail( centity_t *ent, const weaponInfo_t *wi ) { vec3_t origin; entityState_t *es; vec3_t forward, up; refEntity_t beam; es = &ent->currentState; BG_EvaluateTrajectory( &es->pos, cg.time, origin ); ent->trailTime = cg.time; memset( &beam, 0, sizeof( beam ) ); //FIXME adjust for muzzle position VectorCopy ( cg_entities[ ent->currentState.otherEntityNum ].lerpOrigin, beam.origin ); beam.origin[2] += 26; AngleVectors( cg_entities[ ent->currentState.otherEntityNum ].lerpAngles, forward, NULL, up ); VectorMA( beam.origin, -6, up, beam.origin ); VectorCopy( origin, beam.oldorigin ); if (Distance( beam.origin, beam.oldorigin ) < 64 ) return; // Don't draw if close beam.reType = RT_LIGHTNING; beam.customShader = cgs.media.lightningShader; AxisClear( beam.axis ); beam.shaderRGBA[0] = 0xff; beam.shaderRGBA[1] = 0xff; beam.shaderRGBA[2] = 0xff; beam.shaderRGBA[3] = 0xff; trap_R_AddRefEntityToScene( &beam ); }
/* ================== CG_SpawnEffect Player teleporting in or out RPG-X: RedTechie Added refEntity_t *ent_legs, refEntity_t *ent_torso, refEntity_t *ent_head ================== */ void CG_SpawnEffect( vec3_t org, refEntity_t *ent_legs, refEntity_t *ent_torso, refEntity_t *ent_head ) { localEntity_t *le; refEntity_t *re; FX_Transporter(org); le = CG_AllocLocalEntity(); le->leFlags = 0; le->leType = LE_FADE_RGB; le->startTime = cg.time; le->endTime = cg.time + 500; le->lifeRate = 1.0 / ( le->endTime - le->startTime ); le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0; re = &le->refEntity; //RPG-X: RedTechie - Playing with transporter crap re->shaderTime = cg.time * 0.001f; re = &le->refEntity; re->reType = RT_MODEL; re->shaderTime = cg.time * 0.001f; re->customShader = cgs.media.teleportEffectShader; re->hModel = cgs.media.teleportEffectModel; AxisClear( re->axis ); VectorCopy( org, re->origin ); re->origin[2] -= 24; }
/* ================== CG_SpawnEffect Player teleporting in or out ================== */ void CG_SpawnEffect(vec3_t org) { localEntity_t *le; refEntity_t *re; return; // (SA) don't play spawn in effect right now le = CG_AllocLocalEntity(); le->leFlags = 0; le->leType = LE_FADE_RGB; le->startTime = cg.time; le->endTime = cg.time + 500; le->lifeRate = 1.0 / (le->endTime - le->startTime); le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0; re = &le->refEntity; re->reType = RT_MODEL; re->shaderTime = cg.time / 1000.0f; re->customShader = cgs.media.teleportEffectShader; re->hModel = cgs.media.teleportEffectModel; AxisClear(re->axis); VectorCopy(org, re->origin); re->origin[2] -= 24; }
/* ================== CG_SpawnEffect Player teleporting in or out ================== */ void CG_SpawnEffect( vec3_t org ) { localEntity_t *le; refEntity_t *re; le = CG_AllocLocalEntity(); le->leFlags = 0; le->leType = LE_FADE_RGB; le->startTime = cg.time; le->endTime = cg.time + 500; le->lifeRate = 1.0 / ( le->endTime - le->startTime ); le->color[0] = le->color[1] = le->color[2] = le->color[3] = 1.0; re = &le->refEntity; re->reType = RT_MODEL; re->shaderTime = cg.time / 1000.0f; #ifndef MISSIONPACK re->customShader = cgs.media.teleportEffectShader; #endif re->hModel = cgs.media.teleportEffectModel; AxisClear( re->axis ); VectorCopy( org, re->origin ); #ifdef MISSIONPACK re->origin[2] += 16; #else re->origin[2] -= 24; #endif }
/* ================ R_LerpTag ================ */ void R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char *tagName ) { md3Tag_t *start, *finish; int i; float frontLerp, backLerp; model_t *model; model = R_GetModelByHandle( handle ); if ( model->md3[0] ) { start = R_GetTag( model->md3[0], startFrame, tagName ); finish = R_GetTag( model->md3[0], endFrame, tagName ); } else if ( model->md4 ) { md3Tag_t tstart, tfinish; start = &tstart; R_GetAnimTag( model->md4, startFrame, tagName, start ); finish = &tfinish; R_GetAnimTag( model->md4, endFrame, tagName, finish ); } else { AxisClear( tag->axis ); VectorClear( tag->origin ); return; } if ( !start || !finish ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return; } frontLerp = frac; backLerp = 1.0 - frac; for ( i = 0 ; i < 3 ; i++ ) { tag->origin[i] = start->origin[i] * backLerp + finish->origin[i] * frontLerp; tag->axis[0][i] = start->axis[0][i] * backLerp + finish->axis[0][i] * frontLerp; tag->axis[1][i] = start->axis[1][i] * backLerp + finish->axis[1][i] * frontLerp; tag->axis[2][i] = start->axis[2][i] * backLerp + finish->axis[2][i] * frontLerp; } VectorNormalize( tag->axis[0] ); VectorNormalize( tag->axis[1] ); VectorNormalize( tag->axis[2] ); }
/* ================ R_GetAnimTag for MD4s or MDRs... ================ */ static void R_GetAnimTag( md4Header_t *mod, int framenum, const char *tagName ,md3Tag_t * dest) { int i; int frameSize; md4Frame_t *frame; md4CompFrame_t *cframe; md4Tag_t *tag; md4Bone_t tbone; if ( framenum >= mod->numFrames ) { // it is possible to have a bad frame while changing models, so don't error framenum = mod->numFrames - 1; } tag = (md4Tag_t *)((byte *)mod + mod->ofsTags); for ( i = 0 ; i < mod->numTags ; i++, tag++ ) { if ( !strcmp( tag->name, tagName ) ) { if (mod->ofsFrames<0) //compressed model { frameSize = (int)( &((md4CompFrame_t *)0)->bones[ mod->numBones ] ); cframe = (md4CompFrame_t *)((byte *)mod - mod->ofsFrames + framenum * frameSize ); MC_UnCompress(tbone.matrix,cframe->bones[tag->boneIndex].Comp); { int j,k; for (j=0;j<3;j++) { for (k=0;k<3;k++) dest->axis[j][k]=tbone.matrix[k][j]; } } dest->origin[0]=tbone.matrix[0][3]; dest->origin[1]=tbone.matrix[1][3]; dest->origin[2]=tbone.matrix[2][3]; } else { frameSize = (int)( &((md4Frame_t *)0)->bones[ mod->numBones ] ); frame = (md4Frame_t *)((byte *)mod + mod->ofsFrames + framenum * frameSize ); { int j,k; for (j=0;j<3;j++) { for (k=0;k<3;k++) dest->axis[j][k]=frame->bones[tag->boneIndex].matrix[k][j]; } } dest->origin[0]=frame->bones[tag->boneIndex].matrix[0][3]; dest->origin[1]=frame->bones[tag->boneIndex].matrix[1][3]; dest->origin[2]=frame->bones[tag->boneIndex].matrix[2][3]; } return; } } AxisClear( dest->axis ); VectorClear( dest->origin ); }
/* ==================== CG_MakeExplosion ==================== */ localEntity_t *CG_MakeExplosion( bvec3_t origin, avec3_t dir, qhandle_t hModel, qhandle_t shader, int msec, qboolean isSprite ) { afixed ang; localEntity_t *ex; int offset; bvec3_t tmpVec, newOrigin; if ( msec <= 0 ) { CG_Error( "CG_MakeExplosion: msec = %i", msec ); } // skew the time a bit so they aren't all in sync offset = rand() & 63; ex = CG_AllocLocalEntity(); if ( isSprite ) { ex->leType = LE_SPRITE_EXPLOSION; // randomly rotate sprite orientation ex->refEntity.rotation =MAKE_AFIXED(rand() % 360); FIXED_VEC3SCALE_R( dir, BFIXED(16,0), tmpVec ); VectorAdd( tmpVec, origin, newOrigin ); } else { ex->leType = LE_EXPLOSION; VectorCopy( origin, newOrigin ); // set axis with random rotate if ( !dir ) { AxisClear( ex->refEntity.axis ); } else { ang = MAKE_AFIXED(rand() % 360); VectorCopy( dir, ex->refEntity.axis[0] ); RotateAroundDirection( ex->refEntity.axis, ang ); } } ex->startTime = cg.time - offset; ex->endTime = ex->startTime + msec; // bias the time so all shader effects start correctly ex->refEntity.shaderTime = MSECTIME_G(ex->startTime); ex->refEntity.hModel = hModel; ex->refEntity.customShader = shader; // set origin VectorCopy( newOrigin, ex->refEntity.origin ); VectorCopy( newOrigin, ex->refEntity.oldorigin ); ex->color[0] = ex->color[1] = ex->color[2] = GFIXED_1; return ex; }
//TiM - Beam FX for the Neutrino Probe weapon void FX_ProbeBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire ) { trace_t tr; refEntity_t beam; vec3_t end; float scale; memset( &beam, 0, sizeof( beam ) ); if ( alt_fire ) scale = flrandom(7.0f, 12.0f); else scale = Q_fabs( 12.0f * sin( cg.time * 0.1f ) ); VectorMA( origin, PROBE_BEAM_LENGTH, dir, end ); CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID ); trap_R_AddLightToScene( origin, 20, 114.0f / 255, 164.0f / 255, 1.0f ); VectorCopy( origin, beam.origin); VectorCopy( tr.endpos, beam.oldorigin ); beam.reType = RT_LINE; beam.customShader = cgs.media.probeBeam; beam.shaderRGBA[0] = 0xff; beam.shaderRGBA[1] = 0xff; beam.shaderRGBA[2] = 0xff; beam.shaderRGBA[3] = 0xff; AxisClear( beam.axis ); beam.data.line.width = scale*0.1; beam.data.line.width2 = scale; beam.data.line.stscale = 1.0; trap_R_AddRefEntityToScene( &beam ); if ( tr.fraction != 1.0f ) { float radius; if ( alt_fire ) radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3)); else radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3)); if ( !radius ) return; CG_ImpactMark( cgs.media.probeDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue ); trap_R_AddLightToScene( origin, radius*5, 114.0f / 255, 164.0f / 255, 1.0f ); } }
/* ================ R_LerpTag ================ */ int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame, float frac, const char *tagName ) { md3Tag_t *start, *end; md3Tag_t start_space, end_space; int i; float frontLerp, backLerp; model_t *model; model = R_GetModelByHandle( handle ); if ( !model->md3[0] ) { if(model->type == MOD_MDR) { start = R_GetAnimTag((mdrHeader_t *) model->modelData, startFrame, tagName, &start_space); end = R_GetAnimTag((mdrHeader_t *) model->modelData, endFrame, tagName, &end_space); } else if( model->type == MOD_IQM ) { return R_IQMLerpTag( tag, (iqmData_t *)model->modelData, startFrame, endFrame, frac, tagName ); } else { start = end = NULL; } } else { start = R_GetTag( model->md3[0], startFrame, tagName ); end = R_GetTag( model->md3[0], endFrame, tagName ); } if ( !start || !end ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return false; } frontLerp = frac; backLerp = 1.0f - frac; for ( i = 0 ; i < 3 ; i++ ) { tag->origin[i] = start->origin[i] * backLerp + end->origin[i] * frontLerp; tag->axis[0][i] = start->axis[0][i] * backLerp + end->axis[0][i] * frontLerp; tag->axis[1][i] = start->axis[1][i] * backLerp + end->axis[1][i] * frontLerp; tag->axis[2][i] = start->axis[2][i] * backLerp + end->axis[2][i] * frontLerp; } VectorNormalize( tag->axis[0] ); VectorNormalize( tag->axis[1] ); VectorNormalize( tag->axis[2] ); return true; }
void R_GetAnimTag( mdrHeader_t *mod, int framenum, const char *tagName, md3Tag_t * dest) { int i; int frameSize; mdrFrame_t *frame; mdrTag_t *tag; if ( framenum >= mod->numFrames ) { // it is possible to have a bad frame while changing models, so don't error framenum = mod->numFrames - 1; } tag = (mdrTag_t *)((byte *)mod + mod->ofsTags); for ( i = 0 ; i < mod->numTags ; i++, tag++ ) { if ( !strcmp( tag->name, tagName ) ) { Q_strncpyz(dest->name, tag->name, sizeof(dest->name)); // uncompressed model... // frameSize = (long)( &((mdrFrame_t *)0)->bones[ mod->numBones ] ); frame = (mdrFrame_t *)((byte *)mod + mod->ofsFrames + framenum * frameSize ); #if 1 VectorCopy(&frame->bones[tag->boneIndex].matrix[0][0], dest->axis[0] ); VectorCopy(&frame->bones[tag->boneIndex].matrix[1][0], dest->axis[1] ); VectorCopy(&frame->bones[tag->boneIndex].matrix[2][0], dest->axis[2] ); #else { int j,k; for (j=0;j<3;j++) { for (k=0;k<3;k++) dest->axis[j][k]=frame->bones[tag->boneIndex].matrix[k][j]; } } #endif dest->origin[0]=frame->bones[tag->boneIndex].matrix[0][3]; dest->origin[1]=frame->bones[tag->boneIndex].matrix[1][3]; dest->origin[2]=frame->bones[tag->boneIndex].matrix[2][3]; return; } } AxisClear( dest->axis ); VectorClear( dest->origin ); strcpy(dest->name,""); }
int R_IQMLerpTag( orientation_t *tag, iqmData_t *data, qhandle_t frameModel, int startFrame, qhandle_t endFrameModel, int endFrame, float frac, const char *tagName ) { iqmData_t *startSkeleton, *endSkeleton; float jointMats[IQM_MAX_JOINTS * 12]; int joint; char *names = data->names; // get joint number by reading the joint names for( joint = 0; joint < data->num_joints; joint++ ) { if( !strcmp( tagName, names ) ) break; names += strlen( names ) + 1; } if( joint >= data->num_joints ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return qfalse; } startSkeleton = R_GetIQMModelDataByHandle( frameModel, data ); endSkeleton = R_GetIQMModelDataByHandle( endFrameModel, data ); ComputeJointMats( data, startSkeleton, endSkeleton, startFrame, endFrame, frac, jointMats ); tag->axis[0][0] = jointMats[12 * joint + 0]; tag->axis[1][0] = jointMats[12 * joint + 1]; tag->axis[2][0] = jointMats[12 * joint + 2]; tag->origin[0] = jointMats[12 * joint + 3]; tag->axis[0][1] = jointMats[12 * joint + 4]; tag->axis[1][1] = jointMats[12 * joint + 5]; tag->axis[2][1] = jointMats[12 * joint + 6]; tag->origin[1] = jointMats[12 * joint + 7]; tag->axis[0][2] = jointMats[12 * joint + 8]; tag->axis[1][2] = jointMats[12 * joint + 9]; tag->axis[2][2] = jointMats[12 * joint + 10]; tag->origin[2] = jointMats[12 * joint + 11]; return qtrue; }
void CG_Draw3DModel( float x, float y, float w, float h, qhandle_t model, qhandle_t skin, vec3_t origin, vec3_t angles ) { refdef_t refdef; refEntity_t ent; if ( !cg_draw3dIcons.integer || !cg_drawIcons.integer ) { return; } CG_AdjustFrom640( &x, &y, &w, &h ); memset( &refdef, 0, sizeof( refdef ) ); memset( &ent, 0, sizeof( ent ) ); AnglesToAxis( angles, ent.axis ); VectorCopy( origin, ent.origin ); ent.hModel = model; ent.customSkin = skin; ent.renderfx = RF_NOSHADOW; // no stencil shadows refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); refdef.fov_x = 30; refdef.fov_y = 30; refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.time = cg.time; trap_R_ClearScene(); trap_R_AddRefEntityToScene( &ent ); trap_MME_TimeFraction(cg.timeFraction); trap_R_RenderScene( &refdef ); }
/* ================ CG_Draw3DModel ================ */ void CG_Draw3DModel( float x, float y, float w, float h, qhandle_t model, qhandle_t skin, vec3_t origin, vec3_t angles ) { refdef_t refdef; refEntity_t ent; CG_AdjustFrom640( &x, &y, &w, &h,qtrue); memset( &refdef, 0, sizeof( refdef ) ); memset( &ent, 0, sizeof( ent ) ); AnglesToAxis( angles, ent.axis ); VectorCopy( origin, ent.origin ); ent.hModel = model; ent.customSkin = skin; ent.renderfx = RF_NOSHADOW | RF_DEPTHHACK | RF_LIGHTING_ORIGIN; refdef.rdflags = RDF_NOWORLDMODEL; AxisClear(refdef.viewaxis); refdef.fov_x = 30; refdef.fov_y = 30; refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.time = cg.time; trap_R_ClearScene(); trap_R_AddRefEntityToScene(&ent); trap_R_RenderScene(&refdef); }
int R_IQMLerpTag( orientation_t *tag, iqmData_t *data, int startFrame, int endFrame, float frac, const char *tagName, int startIndex ) { float jointMats[IQM_MAX_JOINTS * 12]; int joint; char *names = data->names; // get joint number by reading the joint names for( joint = 0; joint < data->num_joints; joint++ ) { if( joint >= startIndex && !strcmp( tagName, names ) ) break; names += strlen( names ) + 1; } if( joint >= data->num_joints ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return -1; } ComputeJointMats( data, startFrame, endFrame, frac, jointMats ); tag->axis[0][0] = jointMats[12 * joint + 0]; tag->axis[1][0] = jointMats[12 * joint + 1]; tag->axis[2][0] = jointMats[12 * joint + 2]; tag->origin[0] = jointMats[12 * joint + 3]; tag->axis[0][1] = jointMats[12 * joint + 4]; tag->axis[1][1] = jointMats[12 * joint + 5]; tag->axis[2][1] = jointMats[12 * joint + 6]; tag->origin[1] = jointMats[12 * joint + 7]; tag->axis[0][2] = jointMats[12 * joint + 8]; tag->axis[1][2] = jointMats[12 * joint + 9]; tag->axis[2][2] = jointMats[12 * joint + 10]; tag->origin[2] = jointMats[12 * joint + 11]; return joint; }
void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) { refdef_t refdef; refEntity_t legs = {0}; refEntity_t torso = {0}; refEntity_t head = {0}; refEntity_t gun = {0}; refEntity_t backpack = {0}; refEntity_t helmet = {0}; // refEntity_t barrel = {0}; refEntity_t flash = {0}; vec3_t origin; int renderfx; vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; float len; float xx; vec4_t hcolor = { 1, 0, 0, 0.5 }; const char *torso_anim = NULL, *legs_anim = NULL; if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) { return; } dp_realtime = time; if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) { pi->weapon = pi->pendingWeapon; pi->lastWeapon = pi->pendingWeapon; pi->pendingWeapon = WP_NUM_WEAPONS; pi->weaponTimer = 0; if ( pi->currentWeapon != pi->weapon ) { trap_S_StartLocalSound( trap_S_RegisterSound( "sound/weapons/change.wav" ), CHAN_LOCAL ); } } UI_AdjustFrom640( &x, &y, &w, &h ); y -= jumpHeight; memset( &refdef, 0, sizeof( refdef ) ); memset( &legs, 0, sizeof( legs ) ); memset( &torso, 0, sizeof( torso ) ); memset( &head, 0, sizeof( head ) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.fov_x = (int)((float)refdef.width / uiInfo.uiDC.xscale / 640.0f * 90.0f); xx = refdef.width / uiInfo.uiDC.xscale / tan( refdef.fov_x / 360 * M_PI ); refdef.fov_y = atan2( refdef.height / uiInfo.uiDC.yscale, xx ); refdef.fov_y *= ( 360 / M_PI ); // calculate distance so the player nearly fills the box len = 1.01 * ( maxs[2] - mins[2] ); // NERVE - SMF - changed from 0.7 origin[0] = len / tan( DEG2RAD( refdef.fov_x ) * 0.5 ); origin[1] = 0.5 * ( mins[1] + maxs[1] ); origin[2] = -0.5 * ( mins[2] + maxs[2] ); refdef.time = dp_realtime; trap_R_SetColor( hcolor ); trap_R_ClearScene(); trap_R_SetColor( NULL ); // get the rotation information UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis ); // get the animation state (after rotation, to allow feet shuffle) // UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp, // &torso.oldframe, &torso.frame, &torso.backlerp ); renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; // // add the body // legs.hModel = pi->legsModel; legs.customSkin = pi->legsSkin; legs.renderfx = renderfx; VectorCopy( origin, legs.origin ); VectorCopy( origin, legs.lightingOrigin ); VectorCopy( legs.origin, legs.oldorigin ); WM_getWeaponAnim( &torso_anim, &legs_anim ); if ( torso_anim ) { legs.torsoFrame = UI_GetAnimation( pi, torso_anim ); legs.oldTorsoFrame = UI_GetAnimation( pi, torso_anim ); } legs.torsoBacklerp = 0; //torso.backlerp; if ( legs_anim ) { legs.frame = UI_GetAnimation( pi, legs_anim ); legs.oldframe = UI_GetAnimation( pi, legs_anim ); } legs.backlerp = 0; memcpy( legs.torsoAxis, torso.axis, sizeof( torso.axis ) ); torso = legs; trap_R_AddRefEntityToScene( &torso ); // // add the head // head.hModel = pi->headModel; if ( !head.hModel ) { return; } head.customSkin = pi->headSkin; VectorCopy( origin, head.lightingOrigin ); UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head" ); head.renderfx = renderfx; trap_R_AddRefEntityToScene( &head ); // // add the gun // if ( pi->currentWeapon != WP_NONE ) { memset( &gun, 0, sizeof( gun ) ); gun.hModel = pi->weaponModel; VectorCopy( origin, gun.lightingOrigin ); UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon" ); gun.renderfx = renderfx; trap_R_AddRefEntityToScene( &gun ); } // // add muzzle flash // if ( dp_realtime <= pi->muzzleFlashTime ) { if ( pi->flashModel ) { memset( &flash, 0, sizeof( flash ) ); flash.hModel = pi->flashModel; VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash" ); flash.renderfx = renderfx; trap_R_AddRefEntityToScene( &flash ); } // make a dlight for the flash if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { trap_R_AddLightToScene( flash.origin, 200 + ( rand() & 31 ), pi->flashDlightColor[0], pi->flashDlightColor[1], pi->flashDlightColor[2], 0 ); } } // // add the backpack // if ( pi->backpackModel ) { memset( &backpack, 0, sizeof( backpack ) ); backpack.hModel = pi->backpackModel; VectorCopy( origin, backpack.lightingOrigin ); UI_PositionEntityOnTag( &backpack, &torso, pi->torsoModel, "tag_back" ); backpack.renderfx = renderfx; trap_R_AddRefEntityToScene( &backpack ); } // // add the helmet // if ( pi->helmetModel ) { memset( &helmet, 0, sizeof( helmet ) ); helmet.hModel = pi->helmetModel; VectorCopy( origin, helmet.lightingOrigin ); UI_PositionEntityOnTag( &helmet, &head, pi->headModel, "tag_mouth" ); helmet.renderfx = renderfx; trap_R_AddRefEntityToScene( &helmet ); } // // add the chat icon // if ( pi->chat ) { UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) ); } // // add an accent light // // origin[0] -= 100; // + = behind, - = in front // origin[1] += 100; // + = left, - = right // origin[2] += 100; // + = above, - = below trap_R_AddLightToScene( origin, 500, 1.0, 1.0, 1.0, 0 ); origin[0] -= 100; origin[1] -= 100; origin[2] -= 100; trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0, 0 ); trap_R_RenderScene( &refdef ); }
/* =============== UI_DrawPlayer =============== */ void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) { refdef_t refdef; refEntity_t legs; refEntity_t torso; refEntity_t head; refEntity_t gun; refEntity_t flash; vec3_t origin; int renderfx; vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; float len; float xx; if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) { return; } // this allows the ui to cache the player model on the main menu if (w == 0 || h == 0) { return; } dp_realtime = time; if ( pi->pendingWeapon != -1 && dp_realtime > pi->weaponTimer ) { pi->weapon = pi->pendingWeapon; pi->lastWeapon = pi->pendingWeapon; pi->pendingWeapon = -1; pi->weaponTimer = 0; if( pi->currentWeapon != pi->weapon ) { trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL ); } } UI_AdjustFrom640( &x, &y, &w, &h ); y -= jumpHeight; memset( &refdef, 0, sizeof( refdef ) ); memset( &legs, 0, sizeof(legs) ); memset( &torso, 0, sizeof(torso) ); memset( &head, 0, sizeof(head) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f); xx = refdef.width / tan( refdef.fov_x / 360 * M_PI ); refdef.fov_y = atan2( refdef.height, xx ); refdef.fov_y *= ( 360 / (float)M_PI ); // calculate distance so the player nearly fills the box len = 0.72 * ( maxs[2] - mins[2] ); origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ); origin[1] = 0.5 * ( mins[1] + maxs[1] ); origin[2] = -0.5 * ( mins[2] + maxs[2] ); refdef.time = dp_realtime; trap_R_ClearScene(); // get the rotation information UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis ); // get the animation state (after rotation, to allow feet shuffle) UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp, &torso.oldframe, &torso.frame, &torso.backlerp ); renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; // // add the legs // legs.hModel = pi->legsModel; legs.customSkin = pi->legsSkin; VectorCopy( origin, legs.origin ); VectorCopy( origin, legs.lightingOrigin ); legs.renderfx = renderfx; VectorCopy (legs.origin, legs.oldorigin); trap_R_AddRefEntityToScene( &legs ); if (!legs.hModel) { return; } // // add the torso // torso.hModel = pi->torsoModel; if (!torso.hModel) { return; } torso.customSkin = pi->torsoSkin; VectorCopy( origin, torso.lightingOrigin ); UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso"); torso.renderfx = renderfx; trap_R_AddRefEntityToScene( &torso ); // // add the head // head.hModel = pi->headModel; if (!head.hModel) { return; } head.customSkin = pi->headSkin; VectorCopy( origin, head.lightingOrigin ); UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head"); head.renderfx = renderfx; trap_R_AddRefEntityToScene( &head ); // // add the gun // if ( pi->currentWeapon != WP_NONE ) { memset( &gun, 0, sizeof(gun) ); gun.hModel = pi->weaponModel; VectorCopy( origin, gun.lightingOrigin ); UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon"); gun.renderfx = renderfx; trap_R_AddRefEntityToScene( &gun ); } // // add the spinning barrel // // // add muzzle flash // if ( dp_realtime <= pi->muzzleFlashTime ) { if ( pi->flashModel ) { memset( &flash, 0, sizeof(flash) ); flash.hModel = pi->flashModel; VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash"); flash.renderfx = renderfx; trap_R_AddRefEntityToScene( &flash ); } // make a dlight for the flash if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), pi->flashDlightColor[0], pi->flashDlightColor[1], pi->flashDlightColor[2] ); } } // // add the chat icon // if ( pi->chat ) { UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) ); } // // add an accent light // origin[0] -= 100; // + = behind, - = in front origin[1] += 100; // + = left, - = right origin[2] += 100; // + = above, - = below trap_R_AddLightToScene( origin, 500, 1.0, 1.0, 1.0 ); origin[0] -= 100; origin[1] -= 100; origin[2] -= 100; trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0 ); trap_R_RenderScene( &refdef ); }
/* ==================== CG_MakeExplosion ==================== */ localEntity_t *CG_MakeExplosion(vec3_t origin, vec3_t dir, qhandle_t hModel, qhandle_t shader, int msec, qboolean isSprite) { float ang; localEntity_t *ex; int offset; vec3_t tmpVec, newOrigin; if (msec <= 0) { CG_Error("CG_MakeExplosion: msec = %i", msec); } // skew the time a bit so they aren't all in sync offset = rand() & 63; ex = CG_AllocLocalEntity(); if (isSprite) { ex->leType = LE_SPRITE_EXPLOSION; // randomly rotate sprite orientation ex->refEntity.rotation = rand() % 360; VectorScale(dir, 16, tmpVec); VectorAdd(tmpVec, origin, newOrigin); } else { ex->leType = LE_EXPLOSION; VectorCopy(origin, newOrigin); // set axis with random rotate if (!dir) { AxisClear(ex->refEntity.axis); } else { ang = rand() % 360; VectorCopy(dir, ex->refEntity.axis[0]); RotateAroundDirection(ex->refEntity.axis, ang); } } ex->startTime = cg.time - offset; ex->endTime = ex->startTime + msec; // bias the time so all shader effects start correctly ex->refEntity.shaderTime = ex->startTime / 1000.0f; ex->refEntity.hModel = hModel; ex->refEntity.customShader = shader; // set origin VectorCopy(newOrigin, ex->refEntity.origin); VectorCopy(newOrigin, ex->refEntity.oldorigin); // Ridah, move away from the wall as the sprite expands ex->pos.trType = TR_LINEAR; ex->pos.trTime = cg.time; VectorCopy(newOrigin, ex->pos.trBase); VectorScale(dir, 48, ex->pos.trDelta); // done. ex->color[0] = ex->color[1] = ex->color[2] = 1.0; return ex; }
void FX_PhaserFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty ) { refEntity_t beam; sfxHandle_t sfx; float size; vec3_t velocity; int sparks; vec3_t rgb = { 1,0.9,0.6}, rgb2={1,0.3,0}; //vec3_t rgb3 = { 1.0, 1.0, 1.0 }; sfx = 0; // Draw beam first. memset( &beam, 0, sizeof( beam ) ); VectorCopy( startpos, beam.origin); VectorCopy( endpos, beam.oldorigin ); beam.reType = RT_LINE; if (empty) { beam.customShader = cgs.media.phaserEmptyShader; } else { beam.customShader = cgs.media.phaserShader; } AxisClear( beam.axis ); beam.shaderRGBA[0] = 0xff; beam.shaderRGBA[1] = 0xff; beam.shaderRGBA[2] = 0xff; beam.shaderRGBA[3] = 0xff; if (empty) { beam.data.line.width = 1.0f + ( crandom() * 0.6f ); } else { beam.data.line.width = 2.0f + ( crandom() * 0.6f ); } beam.data.line.stscale = 5.0; trap_R_AddRefEntityToScene( &beam ); // Now draw the hit graphic // no explosion at LG impact, it is added with the beam if ( sfx ) { Com_Printf("playing %s\n", "phaser sound"); trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx ); } // // impact mark // if (impact) { if (!empty) { // normal. CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse, random() + 1, qfalse ); //VectorCopy( endpos, phaserFlare.worldCoord ); /*CG_InitLensFlare( endpos, 80, 80, rgb, 1.2, 1.5, 1600, 200, colorTable[CT_BLACK], 1600, 200, 80, 5, qfalse, 5, 40, qfalse, qfalse, qfalse, 1.0, 1.0, 200.0, 200.0, 200.0 );*/ //CG_InitLensFlare( endpos, // 30, 30, // rgb, 1.2, 2.0, 1600, 200, // colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse, // 0, 0, qfalse, qtrue, // qfalse, 1.0, cg.time, 0, 0, 50); //TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :) //CG_DrawLensFlare( &phaserFlare ); //FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f //FX_AddQuad2( endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader ); //eh... looked bad :P FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200, cgs.media.sunnyFlareShader ); } else { // Wuss hit when empty. FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200, cgs.media.sunnyFlareShader ); } } // "Fun" sparks... Not when empty. if ( spark && !empty) { sparks = (rand() & 1) + 1; for(;sparks>0;sparks--) { size = 0.2f + (random() * 0.4); FXE_Spray( normal, 200, 75, 0.8f, velocity); if (rand() & LEF_USE_COLLISION) { // This spark bounces. FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f, size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader); } else { FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f, size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader); } } } }
/* =============== UI_DrawPlayer =============== */ void UI_DrawPlayer( float x, float y, float w, float h, uiPlayerInfo_t *pi, int time ) { refdef_t refdef; refEntity_t legs = {0}; refEntity_t torso = {0}; refEntity_t head = {0}; #ifdef TA_WEAPSYS refEntity_t gun[MAX_HANDS] = {0}; #else refEntity_t gun = {0}; #endif refEntity_t barrel = {0}; refEntity_t flash = {0}; vec3_t origin; int renderfx; vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; float len; float xx; float xscale; float yscale; #ifdef TA_WEAPSYS int i; vec3_t angles; #ifdef TURTLEARENA // PLAYERS char *newTagNames[3] = { "tag_hand_primary", "tag_hand_secondary", NULL }; #endif char *originalTagNames[3] = { "tag_weapon", "tag_flag", NULL }; #endif if ( !pi->legsModel || !pi->torsoModel || !pi->headModel #ifdef TA_PLAYERSYS || !pi->playercfg.animations[0].numFrames ) { #else || !pi->animations[0].numFrames ) { #endif return; } // this allows the ui to cache the player model on the main menu if (w == 0 || h == 0) { return; } dp_realtime = time; if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) { pi->weapon = pi->pendingWeapon; pi->lastWeapon = pi->pendingWeapon; pi->pendingWeapon = WP_NUM_WEAPONS; pi->weaponTimer = 0; #ifndef TA_WEAPSYS_EX if( pi->currentWeapon != pi->weapon ) { trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL ); } #endif } CG_AdjustFrom640( &x, &y, &w, &h ); y -= jumpHeight; memset( &refdef, 0, sizeof( refdef ) ); memset( &legs, 0, sizeof(legs) ); memset( &torso, 0, sizeof(torso) ); memset( &head, 0, sizeof(head) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; if ( ui_stretch.integer ) { xscale = cgs.screenXScaleStretch; yscale = cgs.screenYScaleStretch; } else { xscale = cgs.screenXScale; yscale = cgs.screenYScale; } refdef.fov_x = (int)((float)refdef.width / xscale / 640.0f * 90.0f); xx = refdef.width / xscale / tan( refdef.fov_x / 360 * M_PI ); refdef.fov_y = atan2( refdef.height / yscale, xx ); refdef.fov_y *= ( 360 / (float)M_PI ); // calculate distance so the player nearly fills the box len = 0.7 * ( maxs[2] - mins[2] ); origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ); origin[1] = 0.5 * ( mins[1] + maxs[1] ); origin[2] = -0.5 * ( mins[2] + maxs[2] ); refdef.time = dp_realtime; trap_R_ClearScene(); // get the rotation information UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis ); // get the animation state (after rotation, to allow feet shuffle) UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp, &torso.oldframe, &torso.frame, &torso.backlerp ); renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; // // add the legs // legs.hModel = pi->legsModel; legs.customSkin = CG_AddSkinToFrame( &pi->modelSkin ); VectorCopy( origin, legs.origin ); VectorCopy( origin, legs.lightingOrigin ); legs.renderfx = renderfx; VectorCopy (legs.origin, legs.oldorigin); Byte4Copy( pi->c1RGBA, legs.shaderRGBA ); CG_AddRefEntityWithMinLight( &legs ); if (!legs.hModel) { return; } // // add the torso // torso.hModel = pi->torsoModel; if (!torso.hModel) { return; } torso.customSkin = legs.customSkin; VectorCopy( origin, torso.lightingOrigin ); UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso"); torso.renderfx = renderfx; Byte4Copy( pi->c1RGBA, torso.shaderRGBA ); CG_AddRefEntityWithMinLight( &torso ); // // add the head // head.hModel = pi->headModel; if (!head.hModel) { return; } head.customSkin = legs.customSkin; VectorCopy( origin, head.lightingOrigin ); UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head"); head.renderfx = renderfx; Byte4Copy( pi->c1RGBA, head.shaderRGBA ); CG_AddRefEntityWithMinLight( &head ); // // add the gun // if ( pi->currentWeapon != WP_NONE ) { #ifdef TA_WEAPSYS // get hands from cent for (i = 0; i < MAX_HANDS; i++) { memset( &gun[i], 0, sizeof(gun[i]) ); gun[i].hModel = pi->weaponModel[i]; VectorCopy( origin, gun[i].lightingOrigin ); gun[i].renderfx = renderfx; Byte4Copy( pi->c1RGBA, gun[i].shaderRGBA ); if (!originalTagNames[i] #ifdef TURTLEARENA // PLAYERS || !newTagNames[i] #endif ) { break; } if (!gun[i].hModel) { continue; } if ( #ifdef TURTLEARENA // PLAYERS !UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, newTagNames[i]) && #endif !UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, originalTagNames[i])) { // Failed to find tag continue; } CG_AddRefEntityWithMinLight( &gun[i] ); } #else memset( &gun, 0, sizeof(gun) ); gun.hModel = pi->weaponModel; Byte4Copy( pi->c1RGBA, gun.shaderRGBA ); VectorCopy( origin, gun.lightingOrigin ); UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon"); gun.renderfx = renderfx; CG_AddRefEntityWithMinLight( &gun ); #endif } // // add the spinning barrel // #ifdef TA_WEAPSYS for (i = 0; i < MAX_HANDS; i++) #else if ( pi->barrelModel ) #endif { #ifdef TA_WEAPSYS if (!pi->barrelModel[i]) continue; #else vec3_t angles; #endif memset( &barrel, 0, sizeof(barrel) ); VectorCopy( origin, barrel.lightingOrigin ); barrel.renderfx = renderfx; #ifdef TA_WEAPSYS barrel.hModel = pi->barrelModel[i]; VectorClear(angles); if (bg_weapongroupinfo[pi->realWeapon].weapon[0]->barrelSpin != BS_NONE) { angles[bg_weapongroupinfo[pi->realWeapon].weapon[0]->barrelSpin] = UI_MachinegunSpinAngle( pi ); } #else barrel.hModel = pi->barrelModel; angles[YAW] = 0; angles[PITCH] = 0; angles[ROLL] = UI_MachinegunSpinAngle( pi ); #endif AnglesToAxis( angles, barrel.axis ); #ifdef TA_WEAPSYS UI_PositionRotatedEntityOnTag( &barrel, &gun[i], pi->weaponModel[i], "tag_barrel"); #else UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel"); #endif CG_AddRefEntityWithMinLight( &barrel ); } // // add muzzle flash // if ( dp_realtime <= pi->muzzleFlashTime ) { #ifdef TA_WEAPSYS vec3_t *flashDlightColor; for (i = 0; i < MAX_HANDS; i++) { memset( &flash, 0, sizeof(flash) ); flash.hModel = pi->flashModel[i]; flashDlightColor = &pi->flashDlightColor[i]; Byte4Copy( pi->c1RGBA, flash.shaderRGBA ); if (!flash.hModel) continue; VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun[i], pi->weaponModel[i], "tag_flash"); flash.renderfx = renderfx; trap_R_AddRefEntityToScene( &flash ); // make a dlight for the flash if ( *flashDlightColor[0] || *flashDlightColor[1] || *flashDlightColor[2] ) { trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), 1.0f, *flashDlightColor[0], *flashDlightColor[1], *flashDlightColor[2] ); } } #else if ( pi->flashModel ) { memset( &flash, 0, sizeof(flash) ); flash.hModel = pi->flashModel; Byte4Copy( pi->c1RGBA, flash.shaderRGBA ); VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash"); flash.renderfx = renderfx; CG_AddRefEntityWithMinLight( &flash ); } // make a dlight for the flash if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { trap_R_AddJuniorLightToScene( flash.origin, 200 + (rand()&31), 1.0f, pi->flashDlightColor[0], pi->flashDlightColor[1], pi->flashDlightColor[2] ); } #endif } // // add the chat icon // if ( pi->chat ) { #ifdef TA_DATA // shaders UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/talkBalloon" ) ); #else UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) ); #endif } // // add an accent light // origin[0] -= 100; // + = behind, - = in front origin[1] += 100; // + = left, - = right origin[2] += 100; // + = above, - = below trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 1.0, 1.0 ); origin[0] -= 100; origin[1] -= 100; origin[2] -= 100; trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 0.0, 0.0 ); trap_R_RenderScene( &refdef ); } /* ========================== UI_FileExists ========================== */ static qboolean UI_FileExists(const char *filename) { int len; len = trap_FS_FOpenFile( filename, NULL, FS_READ ); if (len>0) { return qtrue; } return qfalse; }
static void Main_MenuDraw( void ) { refdef_t refdef; //refEntity_t ent; //vec3_t origin; //vec3_t angles; float adjust; float x, y, w, h; vec4_t color = {1, 1, 1, 1}; int sy; // setup the refdef memset( &refdef, 0, sizeof( refdef ) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); x = 0; y = 0; w = 640; h = 120; UI_AdjustFrom640( &x, &y, &w, &h ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); refdef.fov_x = 60 + adjust; refdef.fov_y = 19.6875 + adjust; refdef.time = uis.realtime; //origin[0] = 300; //origin[1] = 0; //origin[2] = -32; trap_R_ClearScene(); #if 0 // add the model memset( &ent, 0, sizeof(ent) ); adjust = 5.0 * sin( (float)uis.realtime / 5000 ); VectorSet( angles, 0, 180 + adjust, 0 ); AnglesToAxis( angles, ent.axis ); ent.hModel = s_main.bannerModel; VectorCopy( origin, ent.origin ); VectorCopy( origin, ent.lightingOrigin ); ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; VectorCopy( ent.origin, ent.oldorigin ); //trap_R_AddRefEntityToScene( &ent ); #endif trap_R_RenderScene( &refdef ); //UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); if (uis.showErrorMenu) { //UI_DrawProportionalString(0, 0, "You need to copy quakelive's baseq3 directory into ", UI_SMALLFONT, color); sy = 0; sy += 2 * SMALLCHAR_HEIGHT; UI_DrawString(0, sy, " Installation is incomplete.", UI_SMALLFONT, color); sy += 2 * SMALLCHAR_HEIGHT; UI_DrawString(0, sy, " You need to copy the files in quakelive's baseq3 directory", UI_SMALLFONT, color); sy += SMALLCHAR_HEIGHT; UI_DrawString(0, sy, " (the files ending with .pk3) into wolfcam's baseq3 directory.", UI_SMALLFONT, color); //return; } if (strlen(s_errorMessage.errorMessage)) { UI_DrawProportionalString_AutoWrapped( 320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); } else { // standard menu drawing Menu_Draw( &s_main.menu ); } #if 0 if (uis.demoversion) { UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } else { UI_DrawString( 320, 450, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } #endif }
/* ==================== CG_MakeExplosion ==================== */ localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir, qhandle_t hModel, int numFrames, qhandle_t shader, int msec, qboolean isSprite, float scale, int flags ) { float ang = 0; localEntity_t *ex; int offset; vec3_t tmpVec, newOrigin; if ( msec <= 0 ) { trap->Error( ERR_DROP, "CG_MakeExplosion: msec = %i", msec ); } // skew the time a bit so they aren't all in sync offset = rand() & 63; ex = CG_AllocLocalEntity(); if ( isSprite ) { ex->leType = LE_SPRITE_EXPLOSION; ex->refEntity.rotation = rand() % 360; ex->radius = scale; VectorScale( dir, 16, tmpVec ); VectorAdd( tmpVec, origin, newOrigin ); } else { ex->leType = LE_EXPLOSION; VectorCopy( origin, newOrigin ); // set axis with random rotate when necessary if ( !dir ) { AxisClear( ex->refEntity.axis ); } else { if ( !(flags & LEF_NO_RANDOM_ROTATE) ) ang = rand() % 360; VectorCopy( dir, ex->refEntity.axis[0] ); RotateAroundDirection( ex->refEntity.axis, ang ); } } ex->startTime = cg.time - offset; ex->endTime = ex->startTime + msec; // bias the time so all shader effects start correctly ex->refEntity.shaderTime = ex->startTime / 1000.0f; ex->refEntity.hModel = hModel; ex->refEntity.customShader = shader; ex->lifeRate = (float)numFrames / msec; ex->leFlags = flags; //Scale the explosion if (scale != 1) { ex->refEntity.nonNormalizedAxes = qtrue; VectorScale( ex->refEntity.axis[0], scale, ex->refEntity.axis[0] ); VectorScale( ex->refEntity.axis[1], scale, ex->refEntity.axis[1] ); VectorScale( ex->refEntity.axis[2], scale, ex->refEntity.axis[2] ); } // set origin VectorCopy ( newOrigin, ex->refEntity.origin); VectorCopy ( newOrigin, ex->refEntity.oldorigin ); ex->color[0] = ex->color[1] = ex->color[2] = 1.0; return ex; }
int RE_LerpTagET( orientation_t *tag, const refEntity_t *refent, const char *tagNameIn, int startIndex ) { mdvTag_t *start, *end; int i; float frontLerp, backLerp; model_t *model; char tagName[ MAX_QPATH ]; //, *ch; int retval; qhandle_t handle; int startFrame, endFrame; float frac; handle = refent->hModel; startFrame = refent->oldframe; endFrame = refent->frame; frac = 1.0 - refent->backlerp; Q_strncpyz( tagName, tagNameIn, MAX_QPATH ); /* // if the tagName has a space in it, then it is passing through the starting tag number if (ch = strrchr(tagName, ' ')) { *ch = 0; ch++; startIndex = atoi(ch); } */ model = R_GetModelByHandle( handle ); /* if(!model->mdv[0]) //if(!model->model.md3[0] && !model->model.mdc[0] && !model->model.mds) { AxisClear(tag->axis); VectorClear(tag->origin); return -1; } */ frontLerp = frac; backLerp = 1.0 - frac; start = end = NULL; /* else if(model->type == MOD_MDS) { // use bone lerping retval = R_GetBoneTag(tag, model->model.mds, startIndex, refent, tagNameIn); if(retval >= 0) { return retval; } // failed return -1; } */ if ( model->type == MOD_MDM ) { // use bone lerping retval = R_MDM_GetBoneTag( tag, model->mdm, startIndex, refent, tagNameIn ); if ( retval >= 0 ) { return retval; } // failed return -1; } else if ( model->type == MOD_MD5 ) { vec3_t tmp; retval = RE_BoneIndex( handle, tagName ); if ( retval <= 0 ) { return -1; } VectorCopy( refent->skeleton.bones[ retval ].origin, tag->origin ); QuatToAxis( refent->skeleton.bones[ retval ].rotation, tag->axis ); VectorCopy( tag->axis[ 2 ], tmp ); VectorCopy( tag->axis[ 1 ], tag->axis[ 2 ] ); VectorCopy( tag->axis[ 0 ], tag->axis[ 1 ] ); VectorCopy( tmp, tag->axis[ 0 ] ); VectorNormalize( tag->axis[ 0 ] ); VectorNormalize( tag->axis[ 1 ] ); VectorNormalize( tag->axis[ 2 ] ); return retval; } /* else { // psuedo-compressed MDC tags mdcTag_t *cstart, *cend; retval = R_GetMDCTag((byte *) model->model.mdc[0], startFrame, tagName, startIndex, &cstart); retval = R_GetMDCTag((byte *) model->model.mdc[0], endFrame, tagName, startIndex, &cend); // uncompress the MDC tags into MD3 style tags if(cstart && cend) { for(i = 0; i < 3; i++) { ustart.origin[i] = (float)cstart->xyz[i] * MD3_XYZ_SCALE; uend.origin[i] = (float)cend->xyz[i] * MD3_XYZ_SCALE; sangles[i] = (float)cstart->angles[i] * MDC_TAG_ANGLE_SCALE; eangles[i] = (float)cend->angles[i] * MDC_TAG_ANGLE_SCALE; } AnglesToAxis(sangles, ustart.axis); AnglesToAxis(eangles, uend.axis); start = &ustart; end = &uend; } else { start = NULL; end = NULL; } } */ else if ( model->type == MOD_MESH ) { // old MD3 style retval = R_GetTag( model->mdv[ 0 ], startFrame, tagName, startIndex, &start ); retval = R_GetTag( model->mdv[ 0 ], endFrame, tagName, startIndex, &end ); if ( !start || !end ) { AxisClear( tag->axis ); VectorClear( tag->origin ); return -1; } for ( i = 0; i < 3; i++ ) { tag->origin[ i ] = start->origin[ i ] * backLerp + end->origin[ i ] * frontLerp; tag->axis[ 0 ][ i ] = start->axis[ 0 ][ i ] * backLerp + end->axis[ 0 ][ i ] * frontLerp; tag->axis[ 1 ][ i ] = start->axis[ 1 ][ i ] * backLerp + end->axis[ 1 ][ i ] * frontLerp; tag->axis[ 2 ][ i ] = start->axis[ 2 ][ i ] * backLerp + end->axis[ 2 ][ i ] * frontLerp; } VectorNormalize( tag->axis[ 0 ] ); VectorNormalize( tag->axis[ 1 ] ); VectorNormalize( tag->axis[ 2 ] ); return retval; } return -1; }
static void Main_MenuDraw( void ) { refdef_t refdef; refEntity_t ent; vec3_t origin; vec3_t angles; float adjust; float x, y, w, h; vec4_t color = {0.5, 0, 0, 1}; // setup the refdef memset( &refdef, 0, sizeof( refdef ) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); x = 0; y = 0; w = 640; h = 120; CG_AdjustFrom640( &x, &y, &w, &h ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); refdef.fov_x = 60 + adjust; refdef.fov_y = 19.6875 + adjust; refdef.time = uis.realtime; origin[0] = 300; origin[1] = 0; origin[2] = -32; trap_R_ClearScene(); // add the model memset( &ent, 0, sizeof(ent) ); adjust = 5.0 * sin( (float)uis.realtime / 5000 ); VectorSet( angles, 0, 180 + adjust, 0 ); AnglesToAxis( angles, ent.axis ); ent.hModel = s_main.bannerModel; VectorCopy( origin, ent.origin ); VectorCopy( origin, ent.lightingOrigin ); ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; VectorCopy( ent.origin, ent.oldorigin ); CG_AddRefEntityWithMinLight( &ent ); trap_R_RenderScene( &refdef ); if (strlen(s_errorMessage.errorMessage)) { UI_DrawProportionalString_AutoWrapped( 320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); } else { // standard menu drawing Menu_Draw( &s_main.menu ); } if (uis.demoversion) { UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } else if (uis.demotestversion) { UI_DrawProportionalString( 320, 372, "DEMOTEST FOR MATURE AUDIENCES DEMOTEST", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 428, "This test may only be distributed electronically. Physical media (e.g. CD-ROM's, floppies, etc.) redistribution of the demo test is prohibited. Refer to the End User License Agreement for further details.", UI_CENTER|UI_SMALLFONT, color ); } else { UI_DrawString( 320, 450, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } }