本文整理汇总了C++中VectorLengthSquared函数的典型用法代码示例。如果您正苦于以下问题:C++ VectorLengthSquared函数的具体用法?C++ VectorLengthSquared怎么用?C++ VectorLengthSquared使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了VectorLengthSquared函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: S_AddLoopingSound
/*
==================
S_AddLoopingSound
Called during entity generation for a frame
Include velocity in case I get around to doing doppler...
==================
*/
void S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle )
{
sfx_t *sfx;
if ( !s_soundStarted || s_soundMuted )
{
return;
}
if ( sfxHandle < 0 || sfxHandle >= s_numSfx )
{
Com_Printf( S_COLOR_YELLOW, "S_AddLoopingSound: handle %i out of range\n", sfxHandle );
return;
}
sfx = &s_knownSfx[ sfxHandle ];
if (sfx->inMemory == qfalse)
{
S_memoryLoad(sfx);
}
if ( !sfx->soundLength )
{
Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
}
VectorCopy( origin, loopSounds[entityNum].origin );
VectorCopy( velocity, loopSounds[entityNum].velocity );
loopSounds[entityNum].active = qtrue;
loopSounds[entityNum].kill = qtrue;
loopSounds[entityNum].doppler = qfalse;
loopSounds[entityNum].oldDopplerScale = 1.0;
loopSounds[entityNum].dopplerScale = 1.0;
loopSounds[entityNum].sfx = sfx;
if (s_doppler->integer && VectorLengthSquared(velocity)>0.0)
{
vec3_t out;
float lena, lenb;
loopSounds[entityNum].doppler = qtrue;
lena = DistanceSquared(loopSounds[listener_number].origin, loopSounds[entityNum].origin);
VectorAdd(loopSounds[entityNum].origin, loopSounds[entityNum].velocity, out);
lenb = DistanceSquared(loopSounds[listener_number].origin, out);
if ((loopSounds[entityNum].framenum+1) != cls.framecount)
{
loopSounds[entityNum].oldDopplerScale = 1.0;
}
else
{
loopSounds[entityNum].oldDopplerScale = loopSounds[entityNum].dopplerScale;
}
loopSounds[entityNum].dopplerScale = lenb/(lena*100);
if (loopSounds[entityNum].dopplerScale<=1.0)
{
loopSounds[entityNum].doppler = qfalse; // don't bother doing the math
}
}
loopSounds[entityNum].framenum = cls.framecount;
}
示例2: CM_TraceThroughLeaf
static void CM_TraceThroughLeaf( traceWork_t* tw, const cLeaf_t* leaf )
{
int k;
int brushnum;
cbrush_t *b;
cPatch_t *patch;
// trace line against all brushes in the leaf
for ( k = 0 ; k < leaf->numLeafBrushes ; k++ ) {
brushnum = cm.leafbrushes[leaf->firstLeafBrush+k];
b = &cm.brushes[brushnum];
if ( b->checkcount == cm.checkcount ) {
continue; // already checked this brush in another leaf
}
b->checkcount = cm.checkcount;
if ( !(b->contents & tw->contents) ) {
continue;
}
if (!CM_BoundsIntersect( tw->bounds[0], tw->bounds[1], b->bounds[0], b->bounds[1] ))
continue;
CM_TraceThroughBrush( tw, b );
if ( !tw->trace.fraction ) {
return;
}
}
// trace line against all patches in the leaf
#ifdef BSPC
if (1) {
#else
if ( !cm_noCurves->integer ) {
#endif
for ( k = 0 ; k < leaf->numLeafSurfaces ; k++ ) {
patch = cm.surfaces[ cm.leafsurfaces[ leaf->firstLeafSurface + k ] ];
if ( !patch ) {
continue;
}
if ( patch->checkcount == cm.checkcount ) {
continue; // already checked this patch in another leaf
}
patch->checkcount = cm.checkcount;
if ( !(patch->contents & tw->contents) ) {
continue;
}
CM_TraceThroughPatch( tw, patch );
if ( !tw->trace.fraction ) {
return;
}
}
}
}
#define RADIUS_EPSILON 1.0f
/*
================
CM_TraceThroughSphere
get the first intersection of the ray with the sphere
================
*/
void CM_TraceThroughSphere( traceWork_t *tw, vec3_t origin, float radius, vec3_t start, vec3_t end ) {
float l1, l2, length, scale, fraction;
float a, b, c, d, sqrtd;
vec3_t v1, dir, intersection;
// if inside the sphere
VectorSubtract(start, origin, dir);
l1 = VectorLengthSquared(dir);
if (l1 < Square(radius)) {
tw->trace.fraction = 0;
tw->trace.startsolid = qtrue;
// test for allsolid
VectorSubtract(end, origin, dir);
l1 = VectorLengthSquared(dir);
if (l1 < Square(radius)) {
tw->trace.allsolid = qtrue;
}
return;
}
//
VectorSubtract(end, start, dir);
length = VectorNormalize(dir);
//
l1 = CM_DistanceFromLineSquared(origin, start, end, dir);
VectorSubtract(end, origin, v1);
l2 = VectorLengthSquared(v1);
// if no intersection with the sphere and the end point is at least an epsilon away
if (l1 >= Square(radius) && l2 > Square(radius+SURFACE_CLIP_EPSILON)) {
return;
}
//
// | origin - (start + t * dir) | = radius
// a = dir[0]^2 + dir[1]^2 + dir[2]^2;
//.........这里部分代码省略.........
示例3: VEH_TurretThink
void VEH_TurretThink( Vehicle_t *pVeh, gentity_t *parent, int turretNum )
//-----------------------------------------------------
{
qboolean doAim = qfalse;
float enemyDist, rangeSq;
vec3_t enemyDir;
turretStats_t *turretStats = &pVeh->m_pVehicleInfo->turret[turretNum];
vehWeaponInfo_t *vehWeapon = NULL;
gentity_t *turretEnemy = NULL;
int curMuzzle = 0;//?
if ( !turretStats || !turretStats->iAmmoMax )
{//not a valid turret
return;
}
if ( turretStats->passengerNum
&& pVeh->m_iNumPassengers >= turretStats->passengerNum )
{//the passenger that has control of this turret is on the ship
VEH_TurretObeyPassengerControl( pVeh, parent, turretNum );
return;
}
else if ( !turretStats->bAI )//try AI
{//this turret does not think on its own.
return;
}
vehWeapon = &g_vehWeaponInfo[turretStats->iWeapon];
rangeSq = (turretStats->fAIRange*turretStats->fAIRange);
curMuzzle = pVeh->turretStatus[turretNum].nextMuzzle;
if ( pVeh->turretStatus[turretNum].enemyEntNum < ENTITYNUM_WORLD )
{
turretEnemy = &g_entities[pVeh->turretStatus[turretNum].enemyEntNum];
if ( turretEnemy->health < 0
|| !turretEnemy->inuse
|| turretEnemy == ((gentity_t*)pVeh->m_pPilot)//enemy became my pilot///?
|| turretEnemy == parent
|| turretEnemy->r.ownerNum == parent->s.number // a passenger?
|| ( turretEnemy->client && turretEnemy->client->sess.sessionTeam == TEAM_SPECTATOR )
|| ( turretEnemy->client && turretEnemy->client->tempSpectate >= level.time ) )
{//don't keep going after spectators, pilot, self, dead people, etc.
turretEnemy = NULL;
pVeh->turretStatus[turretNum].enemyEntNum = ENTITYNUM_NONE;
}
}
if ( pVeh->turretStatus[turretNum].enemyHoldTime < level.time )
{
if ( VEH_TurretFindEnemies( pVeh, parent, turretStats, turretNum, curMuzzle ) )
{
turretEnemy = &g_entities[pVeh->turretStatus[turretNum].enemyEntNum];
doAim = qtrue;
}
else if ( parent->enemy && parent->enemy->s.number < ENTITYNUM_WORLD )
{
turretEnemy = parent->enemy;
doAim = qtrue;
}
if ( turretEnemy )
{//found one
if ( turretEnemy->client )
{//hold on to clients for a min of 3 seconds
pVeh->turretStatus[turretNum].enemyHoldTime = level.time + 3000;
}
else
{//hold less
pVeh->turretStatus[turretNum].enemyHoldTime = level.time + 500;
}
}
}
if ( turretEnemy != NULL )
{
if ( turretEnemy->health > 0 )
{
// enemy is alive
WP_CalcVehMuzzle( parent, curMuzzle );
VectorSubtract( turretEnemy->r.currentOrigin, pVeh->m_vMuzzlePos[curMuzzle], enemyDir );
enemyDist = VectorLengthSquared( enemyDir );
if ( enemyDist < rangeSq )
{
// was in valid radius
if ( trap_InPVS( pVeh->m_vMuzzlePos[curMuzzle], turretEnemy->r.currentOrigin ) )
{
// Every now and again, check to see if we can even trace to the enemy
trace_t tr;
vec3_t start, end;
VectorCopy( pVeh->m_vMuzzlePos[curMuzzle], start );
VectorCopy( turretEnemy->r.currentOrigin, end );
trap_Trace( &tr, start, NULL, NULL, end, parent->s.number, MASK_SHOT );
if ( tr.entityNum == turretEnemy->s.number
|| (!tr.allsolid && !tr.startsolid ) )
{
doAim = qtrue; // Can see our enemy
}
}
//.........这里部分代码省略.........
示例4: CalcEntitySpot
void CalcEntitySpot ( const gentity_t *ent, const spot_t spot, vec3_t point )
{
vec3_t forward, up, right;
vec3_t start, end;
trace_t tr;
if ( !ent )
{
return;
}
ViewHeightFix(ent);
switch ( spot )
{
case SPOT_ORIGIN:
if(VectorCompare(ent->currentOrigin, vec3_origin))
{//brush
VectorSubtract(ent->absmax, ent->absmin, point);//size
VectorMA(ent->absmin, 0.5, point, point);
}
else
{
VectorCopy ( ent->currentOrigin, point );
}
break;
case SPOT_CHEST:
case SPOT_HEAD:
if ( ent->client && VectorLengthSquared( ent->client->renderInfo.eyePoint ) && (ent->client->ps.viewEntity <= 0 || ent->client->ps.viewEntity >= ENTITYNUM_WORLD) )
{//Actual tag_head eyespot!
//FIXME: Stasis aliens may have a problem here...
VectorCopy( ent->client->renderInfo.eyePoint, point );
if ( ent->client->NPC_class == CLASS_ATST )
{//adjust up some
point[2] += 28;//magic number :)
}
if ( ent->NPC )
{//always aim from the center of my bbox, so we don't wiggle when we lean forward or backwards
point[0] = ent->currentOrigin[0];
point[1] = ent->currentOrigin[1];
}
else if ( !ent->s.number )
{
SubtractLeanOfs( ent, point );
}
}
else
{
VectorCopy ( ent->currentOrigin, point );
if ( ent->client )
{
point[2] += ent->client->ps.viewheight;
}
}
if ( spot == SPOT_CHEST && ent->client )
{
if ( ent->client->NPC_class != CLASS_ATST )
{//adjust up some
point[2] -= ent->maxs[2]*0.2f;
}
}
break;
case SPOT_HEAD_LEAN:
if ( ent->client && VectorLengthSquared( ent->client->renderInfo.eyePoint ) && (ent->client->ps.viewEntity <= 0 || ent->client->ps.viewEntity >= ENTITYNUM_WORLD) )
{//Actual tag_head eyespot!
//FIXME: Stasis aliens may have a problem here...
VectorCopy( ent->client->renderInfo.eyePoint, point );
if ( ent->client->NPC_class == CLASS_ATST )
{//adjust up some
point[2] += 28;//magic number :)
}
if ( ent->NPC )
{//always aim from the center of my bbox, so we don't wiggle when we lean forward or backwards
point[0] = ent->currentOrigin[0];
point[1] = ent->currentOrigin[1];
}
else if ( !ent->s.number )
{
SubtractLeanOfs( ent, point );
}
//NOTE: automatically takes leaning into account!
}
else
{
VectorCopy ( ent->currentOrigin, point );
if ( ent->client )
{
point[2] += ent->client->ps.viewheight;
}
//AddLeanOfs ( ent, point );
}
break;
//FIXME: implement...
//case SPOT_CHEST:
//Returns point 3/4 from tag_torso to tag_head?
//break;
case SPOT_LEGS:
VectorCopy ( ent->currentOrigin, point );
//.........这里部分代码省略.........
示例5: CM_VectorDistanceSquared
/*
================
CM_VectorDistanceSquared
================
*/
float CM_VectorDistanceSquared(vec3_t p1, vec3_t p2) {
vec3_t dir;
VectorSubtract(p2, p1, dir);
return VectorLengthSquared(dir);
}
示例6: S_Base_AddLoopingSound
void S_Base_AddLoopingSound(const vec3_t origin, const vec3_t velocity, int range, sfxHandle_t sfxHandle, int volume, int soundTime)
{
sfx_t *sfx;
if (!s_soundStarted || s_soundMuted || !volume)
{
return;
}
if (numLoopSounds >= MAX_LOOP_SOUNDS)
{
return;
}
if (sfxHandle < 0 || sfxHandle >= numSfx)
{
Com_Printf(S_COLOR_YELLOW "S_AddLoopingSound: handle %i out of range\n", sfxHandle);
return;
}
sfx = &knownSfx[sfxHandle];
if (sfx->inMemory == qfalse)
{
S_memoryLoad(sfx);
}
if (!sfx->soundLength)
{
Com_Error(ERR_DROP, "%s has length 0", sfx->soundName);
}
VectorCopy(origin, loopSounds[numLoopSounds].origin);
VectorCopy(velocity, loopSounds[numLoopSounds].velocity);
loopSounds[numLoopSounds].startSample = soundTime % sfx->soundLength;
loopSounds[numLoopSounds].active = qtrue;
loopSounds[numLoopSounds].kill = qtrue;
loopSounds[numLoopSounds].doppler = qfalse;
loopSounds[numLoopSounds].oldDopplerScale = 1;
loopSounds[numLoopSounds].dopplerScale = 1;
loopSounds[numLoopSounds].sfx = sfx;
loopSounds[numLoopSounds].range = range ? range : SOUND_RANGE_DEFAULT;
loopSounds[numLoopSounds].loudUnderWater = (volume & 1 << UNDERWATER_BIT) != 0;
if (volume > 65535)
{
volume = 65535;
}
else if (volume < 0)
{
volume = 0;
}
loopSounds[numLoopSounds].volume = (int)((float)volume * s_volCurrent);
if (s_doppler->integer && VectorLengthSquared(velocity) > 0)
{
vec3_t out;
float lena, lenb;
// don't do the doppler effect when trumpets of train and station are at the same position
if (entityPositions[listener_number] != entityPositions[numLoopSounds])
{
loopSounds[numLoopSounds].doppler = qtrue;
}
else
{
loopSounds[numLoopSounds].doppler = qfalse;
}
lena = DistanceSquared(entityPositions[listener_number], entityPositions[numLoopSounds]);
VectorAdd(entityPositions[numLoopSounds], loopSounds[numLoopSounds].velocity, out);
lenb = DistanceSquared(entityPositions[listener_number], out);
if ((loopSounds[numLoopSounds].framenum + 1) != cls.framecount)
{
loopSounds[numLoopSounds].oldDopplerScale = 1;
}
else
{
loopSounds[numLoopSounds].oldDopplerScale = loopSounds[numLoopSounds].dopplerScale;
}
if (lena == 0) // div/0
{
loopSounds[numLoopSounds].dopplerScale = 1; // no doppler
}
else
{
loopSounds[numLoopSounds].dopplerScale = lenb / (lena * 100);
}
if (loopSounds[numLoopSounds].dopplerScale <= 1)
{
loopSounds[numLoopSounds].doppler = qfalse; // don't bother doing the math
}
else if (loopSounds[numLoopSounds].dopplerScale > MAX_DOPPLER_SCALE)
{
loopSounds[numLoopSounds].dopplerScale = MAX_DOPPLER_SCALE;
}
//.........这里部分代码省略.........
示例7: MakeMeshNormals
/*
=================
MakeMeshNormals
Handles all the complicated wrapping and degenerate cases
=================
*/
static void MakeMeshNormals( int width, int height, drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE] ) {
int i, j, k, dist;
vec3_t normal;
vec3_t sum;
int count;
vec3_t base;
vec3_t delta;
int x, y;
drawVert_t *dv;
vec3_t around[8], temp;
qboolean good[8];
qboolean wrapWidth, wrapHeight;
float len;
static int neighbors[8][2] = {
{0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1}
};
wrapWidth = qfalse;
for ( i = 0 ; i < height ; i++ ) {
VectorSubtract( ctrl[i][0].xyz, ctrl[i][width-1].xyz, delta );
len = VectorLengthSquared( delta );
if ( len > 1.0 ) {
break;
}
}
if ( i == height ) {
wrapWidth = qtrue;
}
wrapHeight = qfalse;
for ( i = 0 ; i < width ; i++ ) {
VectorSubtract( ctrl[0][i].xyz, ctrl[height-1][i].xyz, delta );
len = VectorLengthSquared( delta );
if ( len > 1.0 ) {
break;
}
}
if ( i == width) {
wrapHeight = qtrue;
}
for ( i = 0 ; i < width ; i++ ) {
for ( j = 0 ; j < height ; j++ ) {
count = 0;
dv = &ctrl[j][i];
VectorCopy( dv->xyz, base );
for ( k = 0 ; k < 8 ; k++ ) {
VectorClear( around[k] );
good[k] = qfalse;
for ( dist = 1 ; dist <= 3 ; dist++ ) {
x = i + neighbors[k][0] * dist;
y = j + neighbors[k][1] * dist;
if ( wrapWidth ) {
if ( x < 0 ) {
x = width - 1 + x;
} else if ( x >= width ) {
x = 1 + x - width;
}
}
if ( wrapHeight ) {
if ( y < 0 ) {
y = height - 1 + y;
} else if ( y >= height ) {
y = 1 + y - height;
}
}
if ( x < 0 || x >= width || y < 0 || y >= height ) {
break; // edge of patch
}
VectorSubtract( ctrl[y][x].xyz, base, temp );
if ( VectorNormalize2( temp, temp ) == 0 ) {
continue; // degenerate edge, get more dist
} else {
good[k] = qtrue;
VectorCopy( temp, around[k] );
break; // good edge
}
}
}
VectorClear( sum );
for ( k = 0 ; k < 8 ; k++ ) {
if ( !good[k] || !good[(k+1)&7] ) {
continue; // didn't get two points
}
CrossProduct( around[(k+1)&7], around[k], normal );
if ( VectorNormalize2( normal, normal ) == 0 ) {
continue;
}
VectorAdd( normal, sum, sum );
//.........这里部分代码省略.........
示例8: G2_RadiusTracePolys
// now we're at poly level, check each model space transformed poly against the model world transfomed ray
static bool G2_RadiusTracePolys(
const mdxmSurface_t *surface,
CTraceSurface &TS
)
{
int i,j;
vec3_t basis1;
vec3_t basis2;
vec3_t taxis;
vec3_t saxis;
basis2[0]=0.0f;
basis2[1]=0.0f;
basis2[2]=1.0f;
vec3_t v3RayDir;
VectorSubtract(TS.rayEnd, TS.rayStart, v3RayDir);
CrossProduct(v3RayDir,basis2,basis1);
if (DotProduct(basis1,basis1)<.1f)
{
basis2[0]=0.0f;
basis2[1]=1.0f;
basis2[2]=0.0f;
CrossProduct(v3RayDir,basis2,basis1);
}
CrossProduct(v3RayDir,basis1,basis2);
// Give me a shot direction not a bunch of zeros :) -Gil
// assert(DotProduct(basis1,basis1)>.0001f);
// assert(DotProduct(basis2,basis2)>.0001f);
VectorNormalize(basis1);
VectorNormalize(basis2);
const float c=cosf(0);//theta
const float s=sinf(0);//theta
VectorScale(basis1, 0.5f * c / TS.m_fRadius,taxis);
VectorMA(taxis, 0.5f * s / TS.m_fRadius,basis2,taxis);
VectorScale(basis1,-0.5f * s /TS.m_fRadius,saxis);
VectorMA( saxis, 0.5f * c /TS.m_fRadius,basis2,saxis);
const float * const verts = (float *)TS.TransformedVertsArray[surface->thisSurfaceIndex];
const int numVerts = surface->numVerts;
int flags=63;
//rayDir/=lengthSquared(raydir);
const float f = VectorLengthSquared(v3RayDir);
v3RayDir[0]/=f;
v3RayDir[1]/=f;
v3RayDir[2]/=f;
for ( j = 0; j < numVerts; j++ )
{
const int pos=j*5;
vec3_t delta;
delta[0]=verts[pos+0]-TS.rayStart[0];
delta[1]=verts[pos+1]-TS.rayStart[1];
delta[2]=verts[pos+2]-TS.rayStart[2];
const float s=DotProduct(delta,saxis)+0.5f;
const float t=DotProduct(delta,taxis)+0.5f;
const float u=DotProduct(delta,v3RayDir);
int vflags=0;
if (s>0)
{
vflags|=1;
}
if (s<1)
{
vflags|=2;
}
if (t>0)
{
vflags|=4;
}
if (t<1)
{
vflags|=8;
}
if (u>0)
{
vflags|=16;
}
if (u<1)
{
vflags|=32;
}
vflags=(~vflags);
flags&=vflags;
GoreVerts[j].flags=vflags;
}
if (flags)
{
//.........这里部分代码省略.........
示例9: PM_StepSlideMove
//.........这里部分代码省略.........
VectorCopy (start_o, up);
up[2] += stepSize;
// test the player position if they were a stepheight higher
pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
if ( trace.allsolid || trace.startsolid || trace.fraction == 0) {
if ( pm->debugLevel ) {
Com_Printf("%i:bend can't step\n", c_pmove);
}
return; // can't step up
}
if ( pm->debugLevel )
{
G_DebugLine(start_o,trace.endpos,2000,0xffffff,qtrue);
}
//===Another slidemove forward================================================================================
// try slidemove from this position
VectorCopy( trace.endpos, pm->ps->origin );
VectorCopy( start_v, pm->ps->velocity );
cantStepUpFwd = PM_SlideMove( gravMod );
//===Another slidemove forward================================================================================
if ( pm->debugLevel )
{
G_DebugLine(trace.endpos,pm->ps->origin,2000,0xffffff,qtrue);
}
//compare the initial slidemove and this slidemove from a step up position
VectorSubtract( down_o, start_o, slideMove );
VectorSubtract( trace.endpos, pm->ps->origin, stepUpMove );
if ( fabs(stepUpMove[0]) < 0.1 && fabs(stepUpMove[1]) < 0.1 && VectorLengthSquared( slideMove ) > VectorLengthSquared( stepUpMove ) )
{
//slideMove was better, use it
VectorCopy (down_o, pm->ps->origin);
VectorCopy (down_v, pm->ps->velocity);
}
else
{
qboolean skipStep = qfalse;
// push down the final amount
VectorCopy (pm->ps->origin, down);
down[2] -= stepSize;
pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
if ( pm->debugLevel )
{
G_DebugLine(pm->ps->origin,trace.endpos,2000,0xffffff,qtrue);
}
if ( g_stepSlideFix->integer )
{
if ( pm->ps->clientNum < MAX_CLIENTS
&& trace.plane.normal[2] < MIN_WALK_NORMAL )
{//normal players cannot step up slopes that are too steep to walk on!
vec3_t stepVec;
//okay, the step up ends on a slope that it too steep to step up onto,
//BUT:
//If the step looks like this:
// (B)\__
// \_____(A)
//Then it might still be okay, so we figure out the slope of the entire move
//from (A) to (B) and if that slope is walk-upabble, then it's okay
VectorSubtract( trace.endpos, down_o, stepVec );
VectorNormalize( stepVec );
if ( stepVec[2] > (1.0f-MIN_WALK_NORMAL) )
示例10: CGCam_FollowUpdate
//.........这里部分代码省略.........
else
{
VectorCopy( fromCent->lerpOrigin, focus[num_subjects] );
}
}
else
{
VectorCopy(from->currentOrigin, focus[num_subjects]);
}
//FIXME: make a list here of their s.numbers instead so we can do other stuff with the list below
if ( from->client )
{//Track to their eyes - FIXME: maybe go off a tag?
//FIXME:
//Based on FOV and distance to subject from camera, pick the point that
//keeps eyes 3/4 up from bottom of screen... what about bars?
focus[num_subjects][2] += from->client->ps.viewheight;
}
}
if ( client_camera.cameraGroupZOfs )
{
focus[num_subjects][2] += client_camera.cameraGroupZOfs;
}
num_subjects++;
}
if ( !num_subjects ) // Bad cameragroup
{
#ifndef FINAL_BUILD
gi.Printf(S_COLOR_RED"ERROR: Camera Focus unable to locate cameragroup: %s\n", client_camera.cameraGroup);
#endif
return;
}
//Now average all points
VectorCopy( focus[0], center );
for( i = 1; i < num_subjects; i++ )
{
VectorAdd( focus[i], center, center );
}
VectorScale( center, 1.0f/((float)num_subjects), center );
}
else
{
return;
}
//Need to set a speed to keep a distance from
//the subject- fixme: only do this if have a distance
//set
VectorSubtract( client_camera.subjectPos, center, vec );
client_camera.subjectSpeed = VectorLengthSquared( vec ) * 100.0f / cg.frametime;
/*
if ( !cg_skippingcin.integer )
{
Com_Printf( S_COLOR_RED"org: %s\n", vtos(center) );
}
*/
VectorCopy( center, client_camera.subjectPos );
VectorSubtract( center, cg.refdef.vieworg, dir );//can't use client_camera.origin because it's not updated until the end of the move.
//Get desired angle
vectoangles(dir, cameraAngles);
if ( client_camera.followInitLerp )
{//Lerping
float frac = cg.frametime/100.0f * client_camera.followSpeed/100.f;
for( i = 0; i < 3; i++ )
{
cameraAngles[i] = AngleNormalize180( cameraAngles[i] );
cameraAngles[i] = AngleNormalize180( client_camera.angles[i] + frac * AngleNormalize180(cameraAngles[i] - client_camera.angles[i]) );
cameraAngles[i] = AngleNormalize180( cameraAngles[i] );
}
#if 0
Com_Printf( "%s\n", vtos(cameraAngles) );
#endif
}
else
{//Snapping, should do this first time if follow_lerp_to_start_duration is zero
//will lerp from this point on
client_camera.followInitLerp = qtrue;
for( i = 0; i < 3; i++ )
{//normalize so that when we start lerping, it doesn't freak out
cameraAngles[i] = AngleNormalize180( cameraAngles[i] );
}
//So tracker doesn't move right away thinking the first angle change
//is the subject moving... FIXME: shouldn't set this until lerp done OR snapped?
client_camera.subjectSpeed = 0;
}
//Point camera to lerp angles
/*
if ( !cg_skippingcin.integer )
{
Com_Printf( "ang: %s\n", vtos(cameraAngles) );
}
*/
VectorCopy( cameraAngles, client_camera.angles );
}
示例11: CGCam_TrackEntUpdate
void CGCam_TrackEntUpdate ( void )
{//FIXME: only do every 100 ms
gentity_t *trackEnt = NULL;
gentity_t *newTrackEnt = NULL;
qboolean reached = qfalse;
vec3_t vec;
float dist;
if ( client_camera.trackEntNum >= 0 && client_camera.trackEntNum < ENTITYNUM_WORLD )
{//We're already heading to a path_corner
trackEnt = &g_entities[client_camera.trackEntNum];
VectorSubtract( trackEnt->currentOrigin, client_camera.origin, vec );
dist = VectorLengthSquared( vec );
if ( dist < 256 )//16 squared
{//FIXME: who should be doing the using here?
G_UseTargets( trackEnt, trackEnt );
reached = qtrue;
}
}
if ( trackEnt && reached )
{
if ( trackEnt->target && trackEnt->target[0] )
{//Find our next path_corner
newTrackEnt = G_Find( NULL, FOFS(targetname), trackEnt->target );
if ( newTrackEnt )
{
if ( newTrackEnt->radius < 0 )
{//Don't bother trying to maintain a radius
client_camera.distance = 0;
client_camera.speed = client_camera.initSpeed;
}
else if ( newTrackEnt->radius > 0 )
{
client_camera.distance = newTrackEnt->radius;
}
if ( newTrackEnt->speed < 0 )
{//go back to our default speed
client_camera.speed = client_camera.initSpeed;
}
else if ( newTrackEnt->speed > 0 )
{
client_camera.speed = newTrackEnt->speed/10.0f;
}
}
}
else
{//stop thinking if this is the last one
CGCam_TrackDisable();
}
}
if ( newTrackEnt )
{//Update will lerp this
client_camera.info_state |= CAMERA_TRACKING;
client_camera.trackEntNum = newTrackEnt->s.number;
VectorCopy( newTrackEnt->currentOrigin, client_camera.trackToOrg );
}
client_camera.nextTrackEntUpdateTime = cg.time + 100;
}
示例12: SV_AddEntitiesVisibleFromPoint
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint( int psIndex, int clientNum, vec3_t origin, clientSnapshot_t *frame,
snapshotEntityNumbers_t *eNums, qboolean portal ) {
int e, i;
sharedEntity_t *ent;
svEntity_t *svEnt;
int l;
int clientarea, clientcluster;
int leafnum;
byte *clientpvs;
byte *bitvector;
// during an error shutdown message we may need to transmit
// the shutdown message after the server has shutdown, so
// specfically check for it
if ( !sv.state ) {
return;
}
leafnum = CM_PointLeafnum (origin);
clientarea = CM_LeafArea (leafnum);
clientcluster = CM_LeafCluster (leafnum);
// calculate the visible areas
frame->areabytes[psIndex] = CM_WriteAreaBits( frame->areabits[psIndex], clientarea );
clientpvs = CM_ClusterPVS (clientcluster);
for ( e = 0 ; e < sv.num_entities ; e++ ) {
ent = SV_GentityNum(e);
// never send entities that aren't linked in
if ( !ent->r.linked ) {
continue;
}
if (ent->s.number != e) {
Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
ent->s.number = e;
}
// entities can be flagged to explicitly not be sent to the client
if ( ent->r.svFlags & SVF_NOCLIENT ) {
continue;
}
// entities can be flagged to be sent to a given mask of clients
if ( ent->r.svFlags & SVF_CLIENTMASK ) {
if ( !Com_ClientListContains( &ent->r.sendClients, clientNum ) )
continue;
}
svEnt = SV_SvEntityForGentity( ent );
// don't double add an entity through portals
if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
continue;
}
// limit based on distance
if ( ent->r.cullDistance ) {
vec3_t dir;
VectorSubtract(ent->s.origin, origin, dir);
if ( VectorLengthSquared(dir) > (float) ent->r.cullDistance * ent->r.cullDistance ) {
continue;
}
}
// broadcast entities are always sent
if ( ent->r.svFlags & SVF_BROADCAST ) {
SV_AddEntToSnapshot( frame, svEnt, ent, eNums );
continue;
}
// ignore if not touching a PV leaf
// check area
if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
// doors can legally straddle two areas, so
// we may need to check another one
if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
continue; // blocked by a door
}
}
bitvector = clientpvs;
// check individual leafs
if ( !svEnt->numClusters ) {
continue;
}
l = 0;
for ( i=0 ; i < svEnt->numClusters ; i++ ) {
l = svEnt->clusternums[i];
if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
break;
}
//.........这里部分代码省略.........
示例13: GCam_FollowUpdate
void GCam_FollowUpdate ( void )
{
vec3_t center, dir, cameraAngles, vec, focus[MAX_CAMERA_GROUP_SUBJECTS];//No more than 16 subjects in a cameraGroup
gentity_t *from = NULL;
//centity_t *fromCent = NULL;
int num_subjects = 0, i;
qboolean focused = qfalse;
if ( client_camera.cameraGroup[0] == -1 )
{//follow disabled
return;
}
for( i = 0; i < MAX_CAMERA_GROUP_SUBJECTS; i++ )
{
//fromCent = &cg_entities[client_camera.cameraGroup[i]];
from = &g_entities[client_camera.cameraGroup[i]];
if ( !from )
{
continue;
}
focused = qfalse;
if ( (from->s.eType == ET_PLAYER
|| from->s.eType == ET_NPC
|| from->s.number < MAX_CLIENTS)
&& client_camera.cameraGroupTag && client_camera.cameraGroupTag[0] )
{
int newBolt = trap_G2API_AddBolt( &from->ghoul2, 0, client_camera.cameraGroupTag );
if ( newBolt != -1 )
{
mdxaBone_t boltMatrix;
vec3_t angle;
VectorSet(angle, 0, from->client->ps.viewangles[YAW], 0);
trap_G2API_GetBoltMatrix( &from->ghoul2, 0, newBolt, &boltMatrix, angle, from->client->ps.origin, level.time, NULL, from->modelScale );
BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, focus[num_subjects] );
focused = qtrue;
}
}
if ( !focused )
{
VectorCopy(from->r.currentOrigin, focus[num_subjects]);
if ( from->s.eType == ET_PLAYER
|| from->s.eType == ET_NPC
|| from->s.number < MAX_CLIENTS )
{//Track to their eyes - FIXME: maybe go off a tag?
focus[num_subjects][2] += from->client->ps.viewheight;
}
}
if ( client_camera.cameraGroupZOfs )
{
focus[num_subjects][2] += client_camera.cameraGroupZOfs;
}
num_subjects++;
}
if ( !num_subjects ) // Bad cameragroup
{
#ifndef FINAL_BUILD
G_Printf(S_COLOR_RED"ERROR: Camera Focus unable to locate cameragroup: %s\n", client_camera.cameraGroup);
#endif
return;
}
//Now average all points
VectorCopy( focus[0], center );
for( i = 1; i < num_subjects; i++ )
{
VectorAdd( focus[i], center, center );
}
VectorScale( center, 1.0f/((float)num_subjects), center );
//Need to set a speed to keep a distance from
//the subject- fixme: only do this if have a distance
//set
VectorSubtract( client_camera.subjectPos, center, vec );
client_camera.subjectSpeed = VectorLengthSquared( vec ) * 100.0f / g_TimeSinceLastFrame;
VectorCopy( center, client_camera.subjectPos );
VectorSubtract( center, camerapos, dir );//can't use client_camera.origin because it's not updated until the end of the move.
//Get desired angle
vectoangles(dir, cameraAngles);
if ( client_camera.followInitLerp )
{//Lerping
float frac = g_TimeSinceLastFrame/100.0f * client_camera.followSpeed/100.f;
for( i = 0; i < 3; i++ )
{
cameraAngles[i] = AngleNormalize180( cameraAngles[i] );
cameraAngles[i] = AngleNormalize180( client_camera.angles[i] + frac * AngleNormalize180(cameraAngles[i] - client_camera.angles[i]) );
cameraAngles[i] = AngleNormalize180( cameraAngles[i] );
}
}
else
//.........这里部分代码省略.........
示例14: SurfIsOffscreen
/*
** SurfIsOffscreen
**
** Determines if a surface is completely offscreen.
*/
static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128] ) {
float shortest = 100000000;
int entityNum;
int numTriangles;
shader_t *shader;
int fogNum;
int dlighted;
vec4_t clip, eye;
int i;
unsigned int pointOr = 0;
unsigned int pointAnd = (unsigned int)~0;
if ( glConfig.smpActive ) { // FIXME! we can't do RB_BeginSurface/RB_EndSurface stuff with smp!
return qfalse;
}
R_RotateForViewer();
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted );
RB_BeginSurface( shader, fogNum );
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
assert( tess.numVertexes < 128 );
for ( i = 0; i < tess.numVertexes; i++ )
{
int j;
unsigned int pointFlags = 0;
R_TransformModelToClip( tess.xyz[i], tr.or.modelMatrix, tr.viewParms.projectionMatrix, eye, clip );
for ( j = 0; j < 3; j++ )
{
if ( clip[j] >= clip[3] )
{
pointFlags |= (1 << (j*2));
}
else if ( clip[j] <= -clip[3] )
{
pointFlags |= ( 1 << (j*2+1));
}
}
pointAnd &= pointFlags;
pointOr |= pointFlags;
}
// trivially reject
if ( pointAnd )
{
return qtrue;
}
// determine if this surface is backfaced and also determine the distance
// to the nearest vertex so we can cull based on portal range. Culling
// based on vertex distance isn't 100% correct (we should be checking for
// range to the surface), but it's good enough for the types of portals
// we have in the game right now.
numTriangles = tess.numIndexes / 3;
for ( i = 0; i < tess.numIndexes; i += 3 )
{
vec3_t normal;
float len;
VectorSubtract( tess.xyz[tess.indexes[i]], tr.viewParms.or.origin, normal );
len = VectorLengthSquared( normal ); // lose the sqrt
if ( len < shortest )
{
shortest = len;
}
if ( DotProduct( normal, tess.normal[tess.indexes[i]] ) >= 0 )
{
numTriangles--;
}
}
if ( !numTriangles )
{
return qtrue;
}
// mirrors can early out at this point, since we don't do a fade over distance
// with them (although we could)
if ( IsMirror( drawSurf, entityNum ) )
{
return qfalse;
}
if ( shortest > (tess.shader->portalRange*tess.shader->portalRange) )
{
return qtrue;
}
return qfalse;
//.........这里部分代码省略.........
示例15: SVT3_AddEntitiesVisibleFromPoint
//.........这里部分代码省略.........
// check overflow clusters that coudln't be stored
if ( i == svEnt->numClusters ) {
if ( svEnt->lastCluster ) {
for (; l <= svEnt->lastCluster; l++ ) {
if ( bitvector[ l >> 3 ] & ( 1 << ( l & 7 ) ) ) {
break;
}
}
if ( l == svEnt->lastCluster ) {
goto notVisible; // not visible
}
} else {
goto notVisible;
}
}
//----(SA) added "visibility dummies"
if ( ent->GetSvFlags() & WOLFSVF_VISDUMMY ) {
//find master;
idEntity3* ment = SVT3_EntityNum( ent->GetOtherEntityNum() );
q3svEntity_t* master = &sv.q3_svEntities[ ent->GetOtherEntityNum() ];
if ( master->snapshotCounter == sv.q3_snapshotCounter || !ment->GetLinked() ) {
goto notVisible;
}
SVT3_AddEntToSnapshot( clientNum, master, ment, eNums );
// master needs to be added, but not this dummy ent
goto notVisible;
} else if ( ent->GetSvFlags() & WOLFSVF_VISDUMMY_MULTIPLE ) {
{
for ( int h = 0; h < sv.q3_num_entities; h++ ) {
idEntity3* ment = SVT3_EntityNum( h );
if ( ment == ent ) {
continue;
}
q3svEntity_t* master = &sv.q3_svEntities[ h ];
if ( !ment->GetLinked() ) {
continue;
}
if ( ment->GetNumber() != h ) {
common->DPrintf( "FIXING vis dummy multiple ment->S.NUMBER!!!\n" );
ment->SetNumber( h );
}
if ( ment->GetSvFlags() & Q3SVF_NOCLIENT ) {
continue;
}
if ( master->snapshotCounter == sv.q3_snapshotCounter ) {
continue;
}
if ( ment->GetOtherEntityNum() == ent->GetNumber() ) {
SVT3_AddEntToSnapshot( clientNum, master, ment, eNums );
}
}
goto notVisible;
}
}
// add it
SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );
// if its a portal entity, add everything visible from its camera position
if ( ent->GetSvFlags() & Q3SVF_PORTAL ) {
if ( ent->GetGeneric1() ) {
vec3_t dir;
VectorSubtract( ent->GetOrigin(), origin, dir );
if ( VectorLengthSquared( dir ) > ( float )ent->GetGeneric1() * ent->GetGeneric1() ) {
continue;
}
}
SVT3_AddEntitiesVisibleFromPoint( clientNum, ent->GetOrigin2(), frame, eNums, true, localClient );
}
continue;
notVisible:
// Ridah, if this entity has changed events, then send it regardless of whether we can see it or not
// DHM - Nerve :: not in multiplayer please
if ( GGameType & ( GAME_WolfSP | GAME_WolfMP ) && svt3_gametype->integer == Q3GT_SINGLE_PLAYER && localClient ) {
if ( ent->GetEventTime() == svs.q3_time ) {
ent->SetEFlagNoDraw(); // don't draw, just process event
SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );
} else if ( ent->GetEType() == Q3ET_PLAYER ) {
// keep players around if they are alive and active (so sounds dont get messed up)
if ( !ent->GetEFlagDead() ) {
ent->SetEFlagNoDraw(); // don't draw, just process events and sounds
SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );
}
}
}
}