/* ================ CM_BoxDistanceFromPlane ================ */ static int CM_TraceThroughBounds(traceWork_t *tw, vec3_t mins, vec3_t maxs) { if (mins[0] > tw->bounds[1][0] || maxs[0] < tw->bounds[0][0] || mins[1] > tw->bounds[1][1] || maxs[1] < tw->bounds[0][1] || mins[2] > tw->bounds[1][2] || maxs[2] < tw->bounds[0][2]) { return qfalse; } { vec3_t center, extents; VectorAdd(mins, maxs, center); VectorScale(center, 0.5f, center); VectorSubtract(maxs, center, extents); if (Q_fabs(CM_BoxDistanceFromPlane(center, extents, &tw->tracePlane1)) > tw->traceDist1) { return qfalse; } if (Q_fabs(CM_BoxDistanceFromPlane(center, extents, &tw->tracePlane2)) > tw->traceDist2) { return qfalse; } } // trace might go through the bounds return qtrue; }
/* ================ CM_DistanceFromLineSquared ================ */ float CM_DistanceFromLineSquared(vec3_t p, vec3_t lp1, vec3_t lp2, vec3_t dir) { vec3_t proj, t; int j; CM_ProjectPointOntoVector(p, lp1, dir, proj); for (j = 0; j < 3; j++) if ((proj[j] > lp1[j] && proj[j] > lp2[j]) || (proj[j] < lp1[j] && proj[j] < lp2[j])) { break; } if (j < 3) { if (Q_fabs(proj[j] - lp1[j]) < Q_fabs(proj[j] - lp2[j])) { VectorSubtract(p, lp1, t); } else { VectorSubtract(p, lp2, t); } return VectorLengthSquared(t); } VectorSubtract(p, proj, t); return VectorLengthSquared(t); }
/* * UI_MovedirAdjustment */ static float UI_MovedirAdjustment(Playerinfo *pi) { Vec3 relativeAngles; Vec3 moveVector; subv3(pi->viewAngles, pi->moveAngles, relativeAngles); anglev3s(relativeAngles, moveVector, NULL, NULL); if(Q_fabs(moveVector[0]) < 0.01) moveVector[0] = 0.0; if(Q_fabs(moveVector[1]) < 0.01) moveVector[1] = 0.0; if(moveVector[1] == 0 && moveVector[0] > 0) return 0; if(moveVector[1] < 0 && moveVector[0] > 0) return 22; if(moveVector[1] < 0 && moveVector[0] == 0) return 45; if(moveVector[1] < 0 && moveVector[0] < 0) return -22; if(moveVector[1] == 0 && moveVector[0] < 0) return 0; if(moveVector[1] > 0 && moveVector[0] < 0) return 22; if(moveVector[1] > 0 && moveVector[0] == 0) return -45; return -22; }
/** * @brief GLimp_CompareModes * @param[in] a * @param[in] b * @return */ static int GLimp_CompareModes(const void *a, const void *b) { const float ASPECT_EPSILON = 0.001f; const SDL_Rect *modeA = (const SDL_Rect *)a; const SDL_Rect *modeB = (const SDL_Rect *)b; float aspectA = modeA->w / (float)modeA->h; float aspectB = modeB->w / (float)modeB->h; int areaA = modeA->w * modeA->h; int areaB = modeB->w * modeB->h; float aspectDiffA = Q_fabs(aspectA - displayAspect); float aspectDiffB = Q_fabs(aspectB - displayAspect); float aspectDiffsDiff = aspectDiffA - aspectDiffB; if (aspectDiffsDiff > ASPECT_EPSILON) { return 1; } else if (aspectDiffsDiff < -ASPECT_EPSILON) { return -1; } else { return areaA - areaB; } }
void CFuncTank::__MAKE_VHOOK(Think)() { pev->avelocity = g_vecZero; TrackTarget(); if (Q_fabs(float_precision(pev->avelocity.x)) > 1 || Q_fabs(float_precision(pev->avelocity.y)) > 1) StartRotSound(); else StopRotSound(); }
/* ====================== UI_MovedirAdjustment ====================== */ static float UI_MovedirAdjustment( playerInfo_t *pi ) { vec3_t relativeAngles; vec3_t moveVector; VectorSubtract( pi->viewAngles, pi->moveAngles, relativeAngles ); AngleVectors( relativeAngles, moveVector, NULL, NULL ); if ( Q_fabs( moveVector[ 0 ] ) < 0.01 ) { moveVector[ 0 ] = 0.0; } if ( Q_fabs( moveVector[ 1 ] ) < 0.01 ) { moveVector[ 1 ] = 0.0; } if ( moveVector[ 1 ] == 0 && moveVector[ 0 ] > 0 ) { return 0; } if ( moveVector[ 1 ] < 0 && moveVector[ 0 ] > 0 ) { return 22; } if ( moveVector[ 1 ] < 0 && moveVector[ 0 ] == 0 ) { return 45; } if ( moveVector[ 1 ] < 0 && moveVector[ 0 ] < 0 ) { return -22; } if ( moveVector[ 1 ] == 0 && moveVector[ 0 ] < 0 ) { return 0; } if ( moveVector[ 1 ] > 0 && moveVector[ 0 ] < 0 ) { return 22; } if ( moveVector[ 1 ] > 0 && moveVector[ 0 ] == 0 ) { return -45; } return -22; }
float RadiusFromBounds( const vector3 *mins, const vector3 *maxs ) { int i; vector3 corner; float a, b; for ( i = 0; i<3; i++ ) { a = Q_fabs( mins->raw[i] ); b = Q_fabs( maxs->raw[i] ); corner.raw[i] = a > b ? a : b; } return VectorLength( &corner ); }
/* ================== CM_PlaneEqual ================== */ int CM_PlaneEqual( patchPlane_t *p, float plane[4], int *flipped ) { float invplane[4]; if ( Q_fabs( p->plane[0] - plane[0] ) < NORMAL_EPSILON && Q_fabs( p->plane[1] - plane[1] ) < NORMAL_EPSILON && Q_fabs( p->plane[2] - plane[2] ) < NORMAL_EPSILON && Q_fabs( p->plane[3] - plane[3] ) < DIST_EPSILON ) { *flipped = qfalse; return qtrue; } VectorNegate( plane, invplane ); invplane[3] = -plane[3]; if ( Q_fabs( p->plane[0] - invplane[0] ) < NORMAL_EPSILON && Q_fabs( p->plane[1] - invplane[1] ) < NORMAL_EPSILON && Q_fabs( p->plane[2] - invplane[2] ) < NORMAL_EPSILON && Q_fabs( p->plane[3] - invplane[3] ) < DIST_EPSILON ) { *flipped = qtrue; return qtrue; } return qfalse; }
/* ================= RadiusFromBounds ================= */ vec_t RadiusFromBounds (const vec3_t mins, const vec3_t maxs) { int i; vec3_t corner; vec_t a, b; for (i=0 ; i<3 ; i++) { a = Q_fabs(mins[i]); b = Q_fabs(maxs[i]); corner[i] = a > b ? a : b; } return VectorLength (corner); }
void CL_MouseClamp(int *x, int *y) { float ax = Q_fabs(*x); float ay = Q_fabs(*y); ax = (ax-10)*(3.0f/45.0f) * (ax-10) * (Q_fabs(*x) > 10); ay = (ay-10)*(3.0f/45.0f) * (ay-10) * (Q_fabs(*y) > 10); if (*x < 0) *x = -ax; else *x = ax; if (*y < 0) *y = -ay; else *y = ay; }
bool CHostageImprov::FaceTowards(const Vector &target, float deltaT) { bool bError = false; Vector2D to = (target - GetFeet()).Make2D(); #ifndef PLAY_GAMEDLL to.NormalizeInPlace(); #else // TODO: fix test demo float_precision float_x = target.x - GetFeet().x; float_precision float_y = target.y - GetFeet().y; float_precision flLen = to.Length(); if (flLen <= 0) { to.x = 1; to.y = 0; } else { to.x = float_x / flLen; to.y = float_y / flLen; } #endif float moveAngle = GetMoveAngle(); Vector2D lat(BotCOS(moveAngle), BotSIN(moveAngle)); Vector2D dir(-lat.y, lat.x); float_precision dot = DotProduct(to, dir); if (DotProduct(to, lat) < 0.0f) { if (dot >= 0.0f) dot = 1.0f; else dot = -1.0f; bError = true; } const float maxTurnRate = 0.05f; if (bError || Q_fabs(dot) >= maxTurnRate) { const float tolerance = 300.0f; float moveRatio = dot * deltaT * tolerance + moveAngle; BotCOS(moveRatio); BotSIN(moveRatio); m_moveAngle = moveRatio; m_hostage->pev->angles.y = moveRatio; return false; } return true; }
void CGib::BounceGibTouch(CBaseEntity *pOther) { if (pev->flags & FL_ONGROUND) { pev->velocity = pev->velocity * 0.9; pev->angles.x = 0; pev->angles.z = 0; pev->avelocity.x = 0; pev->avelocity.z = 0; } else { if (g_Language != LANGUAGE_GERMAN && m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED) { TraceResult tr; Vector vecSpot = pev->origin + Vector(0, 0, 8); UTIL_TraceLine(vecSpot, vecSpot + Vector(0, 0, -24), ignore_monsters, ENT(pev), &tr); UTIL_BloodDecalTrace(&tr, m_bloodColor); m_cBloodDecals--; } if (m_material != matNone && !RANDOM_LONG(0, 2)) { float zvel = Q_fabs(pev->velocity.z); float volume = 0.8 * Q_min(1.0f, zvel / 450); CBreakable::MaterialSoundRandom(edict(), (Materials)m_material, volume); } } }
/** * \brief Calculates the muzzle point. * * Calculates the muzzle point. * * @param ent the player * @param fwd the forward vector * @param rt the right vector * @param vup the up vector * @param muzzlePoint the muzzle point * @param projsize projsize */ void G_Weapon_CalcMuzzlePoint ( gentity_t *ent, vec3_t fwd, vec3_t rt, vec3_t vup, vec3_t muzzlePoint, float projsize) { int weapontype; weapontype = ent->s.weapon; VectorCopy( ent->s.pos.trBase, muzzlePoint ); #if 1 if (weapontype > WP_0 && weapontype < WP_NUM_WEAPONS) { /* Use the table to generate the muzzlepoint; */ { /* Crouching. Use the add-to-Z method to adjust vertically. */ VectorMA(muzzlePoint, WP_MuzzlePoint[weapontype][0], fwd, muzzlePoint); VectorMA(muzzlePoint, WP_MuzzlePoint[weapontype][1], rt, muzzlePoint); if ( ent->client->ps.eFlags & EF_FULL_ROTATE && Q_fabs( ent->client->ps.viewangles[PITCH] > 89.0f ) ) { muzzlePoint[2] -= 20 + WP_MuzzlePoint[weapontype][2]; } else muzzlePoint[2] += ent->client->ps.viewheight + WP_MuzzlePoint[weapontype][2]; /* VectorMA(muzzlePoint, ent->client->ps.viewheight + WP_MuzzlePoint[weapontype][2], vup, muzzlePoint);*/ } } #else /* Test code */ muzzlePoint[2] += ent->client->ps.viewheight;/* By eyes */ muzzlePoint[2] += g_debugUp.value; VectorMA( muzzlePoint, g_debugForward.value, fwd, muzzlePoint); VectorMA( muzzlePoint, g_debugRight.value, rt, muzzlePoint); #endif CorrectForwardVector(ent, fwd, muzzlePoint, projsize); SnapVector( muzzlePoint ); }
int CG_LimboPanel_RenderCounter_RollTimeForButton(panel_button_t *button) { float diff; switch (button->data[0]) { case 0: // class counts case 1: // team counts return 100.f; case 4: // skills return 1000.f; case 6: // stats diff = Q_fabs(button->data[3] - CG_LimboPanel_RenderCounter_ValueForButton(button)); if (diff < 5) { return 200.f / diff; } return 50.f; case 5: // clock case 3: // respawn time case 2: // xp return 50.f; } return 1000.f; }
/* ================ CM_CalcTraceBounds ================ */ static void CM_CalcTraceBounds(traceWork_t *tw, qboolean expand) { int i; if (tw->sphere.use) { for (i = 0; i < 3; i++) { if (tw->start[i] < tw->end[i]) { tw->bounds[0][i] = tw->start[i] - Q_fabs(tw->sphere.offset[i]) - tw->sphere.radius; tw->bounds[1][i] = tw->start[i] + tw->trace.fraction * tw->dir[i] + Q_fabs(tw->sphere.offset[i]) + tw->sphere.radius; } else { tw->bounds[0][i] = tw->start[i] + tw->trace.fraction * tw->dir[i] - Q_fabs(tw->sphere.offset[i]) - tw->sphere.radius; tw->bounds[1][i] = tw->start[i] + Q_fabs(tw->sphere.offset[i]) + tw->sphere.radius; } } } else { for (i = 0; i < 3; i++) { if (tw->start[i] < tw->end[i]) { tw->bounds[0][i] = tw->start[i] + tw->size[0][i]; tw->bounds[1][i] = tw->start[i] + tw->trace.fraction * tw->dir[i] + tw->size[1][i]; } else { tw->bounds[0][i] = tw->start[i] + tw->trace.fraction * tw->dir[i] + tw->size[0][i]; tw->bounds[1][i] = tw->start[i] + tw->size[1][i]; } } } if (expand) { // expand for epsilon for (i = 0; i < 3; i++) { tw->bounds[0][i] -= 1.0f; tw->bounds[1][i] += 1.0f; } } }
/* ================== CM_SnapVector ================== */ void CM_SnapVector( vec3_t normal ) { int i; for ( i = 0 ; i < 3 ; i++ ) { if ( Q_fabs( normal[i] - 1 ) < NORMAL_EPSILON ) { VectorClear( normal ); normal[i] = 1; break; } if ( Q_fabs( normal[i] - -1 ) < NORMAL_EPSILON ) { VectorClear( normal ); normal[i] = -1; break; } } }
/* ======================================================================================================================================= BaseWindingForPlane ======================================================================================================================================= */ winding_t *BaseWindingForPlane(vec3_t normal, vec_t dist) { int i, x = -1; vec_t max = -MAX_MAP_BOUNDS, v; vec3_t org, vright, vup; winding_t *w; // find the major axis for (i = 0; i < 3; i++) { v = Q_fabs(normal[i]); if (v > max) { x = i; max = v; } } if (x == -1) { Com_Error(ERR_DROP, "BaseWindingForPlane: no axis found"); } VectorCopy(vec3_origin, vup); switch (x) { case 0: case 1: vup[2] = 1; break; case 2: vup[0] = 1; break; } v = DotProduct(vup, normal); VectorMA(vup, -v, normal, vup); vec3_norm2(vup, vup); VectorScale(normal, dist, org); vec3_cross(vup, normal, vright); VectorScale(vup, MAX_MAP_BOUNDS, vup); VectorScale(vright, MAX_MAP_BOUNDS, vright); // project a really big axis aligned box onto the plane w = AllocWinding(4); VectorSubtract(org, vright, w->p[0]); VectorAdd(w->p[0], vup, w->p[0]); VectorAdd(org, vright, w->p[1]); VectorAdd(w->p[1], vup, w->p[1]); VectorAdd(org, vright, w->p[2]); VectorSubtract(w->p[2], vup, w->p[2]); VectorSubtract(org, vright, w->p[3]); VectorSubtract(w->p[3], vup, w->p[3]); w->numpoints = 4; return w; }
static float UI_MovedirAdjustment( playerInfo_t *pi ) { vector3 relativeAngles; vector3 moveVector; VectorSubtract( &pi->viewAngles, &pi->moveAngles, &relativeAngles ); AngleVectors( &relativeAngles, &moveVector, NULL, NULL ); if ( Q_fabs( moveVector.x ) < 0.01f ) moveVector.x = 0.0f; if ( Q_fabs( moveVector.y ) < 0.01f ) moveVector.y = 0.0f; if ( moveVector.y == 0 && moveVector.x > 0 ) return 0; if ( moveVector.y < 0 && moveVector.x > 0 ) return 22; if ( moveVector.y < 0 && moveVector.x == 0 ) return 45; if ( moveVector.y < 0 && moveVector.x < 0 ) return -22; if ( moveVector.y == 0 && moveVector.x < 0 ) return 0; if ( moveVector.y > 0 && moveVector.x < 0 ) return 22; if ( moveVector.y > 0 && moveVector.x == 0 ) return -45; return -22; }
/* ================ CM_BoxDistanceFromPlane ================ */ static float CM_BoxDistanceFromPlane(vec3_t center, vec3_t extents, cplane_t *plane) { float d1, d2; d1 = DotProduct(center, plane->normal) - plane->dist; d2 = Q_fabs(extents[0] * plane->normal[0]) + Q_fabs(extents[1] * plane->normal[1]) + Q_fabs(extents[2] * plane->normal[2]); if (d1 - d2 > 0.0f) { return d1 - d2; } if (d1 + d2 < 0.0f) { return d1 + d2; } return 0.0f; }
void BotDirectionToUsercmd( gentity_t *self, vec3_t dir, usercmd_t *cmd ) { vec3_t forward; vec3_t right; float forwardmove; float rightmove; signed char speed = BotGetMaxMoveSpeed( self ); AngleVectors( self->client->ps.viewangles, forward, right, nullptr ); forward[2] = 0; VectorNormalize( forward ); right[2] = 0; VectorNormalize( right ); // get direction and non-optimal magnitude forwardmove = speed * DotProduct( forward, dir ); rightmove = speed * DotProduct( right, dir ); // find optimal magnitude to make speed as high as possible if ( Q_fabs( forwardmove ) > Q_fabs( rightmove ) ) { float highestforward = forwardmove < 0 ? -speed : speed; float highestright = highestforward * rightmove / forwardmove; cmd->forwardmove = ClampChar( highestforward ); cmd->rightmove = ClampChar( highestright ); } else { float highestright = rightmove < 0 ? -speed : speed; float highestforward = highestright * forwardmove / rightmove; cmd->forwardmove = ClampChar( highestforward ); cmd->rightmove = ClampChar( highestright ); } }
//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 ); } }
//Returns qtrue if the fade is complete, don't draw shadows etc // qfalse if it has either partially faded, or not at all. qboolean CG_FadeColor2( vector4 *color, int startMsec, int totalMsec ) { float dt = cg.time - startMsec; if ( dt > totalMsec ) { color->a = 0.0f; return qtrue; } //RAZTODO: else if ( dt < 0 ) else { dt = Q_fabs( dt ); color->a = 1.0f - dt / totalMsec; return qfalse; } }
static float RB_ProjectRadius(float r, vec3_t location) { float pr; float dist; float c; vec3_t p; float projected[4]; c = DotProduct(backEnd.viewParms.orientation.axis[0], backEnd.viewParms.orientation.origin); dist = DotProduct(backEnd.viewParms.orientation.axis[0], location) - c; if (dist <= 0) { return 0; } p[0] = 0; p[1] = Q_fabs(r); p[2] = -dist; projected[0] = p[0] * backEnd.viewParms.projectionMatrix[0] + p[1] * backEnd.viewParms.projectionMatrix[4] + p[2] * backEnd.viewParms.projectionMatrix[8] + backEnd.viewParms.projectionMatrix[12]; projected[1] = p[0] * backEnd.viewParms.projectionMatrix[1] + p[1] * backEnd.viewParms.projectionMatrix[5] + p[2] * backEnd.viewParms.projectionMatrix[9] + backEnd.viewParms.projectionMatrix[13]; projected[2] = p[0] * backEnd.viewParms.projectionMatrix[2] + p[1] * backEnd.viewParms.projectionMatrix[6] + p[2] * backEnd.viewParms.projectionMatrix[10] + backEnd.viewParms.projectionMatrix[14]; projected[3] = p[0] * backEnd.viewParms.projectionMatrix[3] + p[1] * backEnd.viewParms.projectionMatrix[7] + p[2] * backEnd.viewParms.projectionMatrix[11] + backEnd.viewParms.projectionMatrix[15]; pr = projected[1] / projected[3]; if (pr > 1.0f) { pr = 1.0f; } return pr; }
void ProjectPointOnPlane( vector3 *dst, const vector3 *p, const vector3 *normal ) { float d; vector3 n; float inv_denom; inv_denom = DotProduct( normal, normal ); assert( Q_fabs( inv_denom ) != 0.0f ); inv_denom = 1.0f / inv_denom; d = DotProduct( normal, p ) * inv_denom; n.x = normal->x * inv_denom; n.y = normal->y * inv_denom; n.z = normal->z * inv_denom; dst->x = p->x - d * n.x; dst->y = p->y - d * n.y; dst->z = p->z - d * n.z; }
float ProjectRadius( float r, vec3_t location ) { float pr; float dist; float c; vec3_t p; float width; float depth; c = DotProduct( tr.viewParms.or.axis[0], tr.viewParms.or.origin ); dist = DotProduct( tr.viewParms.or.axis[0], location ) - c; if ( dist <= 0 ) return 0; p[0] = 0; p[1] = Q_fabs( r ); p[2] = -dist; width = p[0] * tr.viewParms.projectionMatrix[1] + p[1] * tr.viewParms.projectionMatrix[5] + p[2] * tr.viewParms.projectionMatrix[9] + tr.viewParms.projectionMatrix[13]; depth = p[0] * tr.viewParms.projectionMatrix[3] + p[1] * tr.viewParms.projectionMatrix[7] + p[2] * tr.viewParms.projectionMatrix[11] + tr.viewParms.projectionMatrix[15]; pr = width / depth; #if defined (_XBOX) pr = -pr; #endif if ( pr > 1.0f ) pr = 1.0f; return pr; }
static void ProjectDlightTexture_scalar( void ) { int i, l; vec3_t origin; float *texCoords; byte *colors; byte clipBits[SHADER_MAX_VERTEXES]; float texCoordsArray[SHADER_MAX_VERTEXES][2]; byte colorArray[SHADER_MAX_VERTEXES][4]; glIndex_t hitIndexes[SHADER_MAX_INDEXES]; int numIndexes; float scale; float radius; vec3_t floatColor; float modulate = 0.0f; if ( !backEnd.refdef.num_dlights ) { return; } for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { dlight_t *dl; if ( !( tess.dlightBits & ( 1 << l ) ) ) { continue; // this surface definately doesn't have any of this light } texCoords = texCoordsArray[0]; colors = colorArray[0]; dl = &backEnd.refdef.dlights[l]; VectorCopy( dl->transformed, origin ); radius = dl->radius; scale = 1.0f / radius; if(r_greyscale->integer) { float luminance; luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f; floatColor[0] = floatColor[1] = floatColor[2] = luminance; } else if(r_greyscale->value) { float luminance; luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f; floatColor[0] = LERP(dl->color[0] * 255.0f, luminance, r_greyscale->value); floatColor[1] = LERP(dl->color[1] * 255.0f, luminance, r_greyscale->value); floatColor[2] = LERP(dl->color[2] * 255.0f, luminance, r_greyscale->value); } else { floatColor[0] = dl->color[0] * 255.0f; floatColor[1] = dl->color[1] * 255.0f; floatColor[2] = dl->color[2] * 255.0f; } for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) { int clip = 0; vec3_t dist; VectorSubtract( origin, tess.xyz[i], dist ); backEnd.pc.c_dlightVertexes++; texCoords[0] = 0.5f + dist[0] * scale; texCoords[1] = 0.5f + dist[1] * scale; if( !r_dlightBacks->integer && // dist . tess.normal[i] ( dist[0] * tess.normal[i][0] + dist[1] * tess.normal[i][1] + dist[2] * tess.normal[i][2] ) < 0.0f ) { clip = 63; } else { if ( texCoords[0] < 0.0f ) { clip |= 1; } else if ( texCoords[0] > 1.0f ) { clip |= 2; } if ( texCoords[1] < 0.0f ) { clip |= 4; } else if ( texCoords[1] > 1.0f ) { clip |= 8; } texCoords[0] = texCoords[0]; texCoords[1] = texCoords[1]; // modulate the strength based on the height and color if ( dist[2] > radius ) { clip |= 16; modulate = 0.0f; } else if ( dist[2] < -radius ) { clip |= 32; modulate = 0.0f; } else { dist[2] = Q_fabs(dist[2]); if ( dist[2] < radius * 0.5f ) { modulate = 1.0f; } else { modulate = 2.0f * (radius - dist[2]) * scale; } } } clipBits[i] = clip; colors[0] = ri.ftol(floatColor[0] * modulate); colors[1] = ri.ftol(floatColor[1] * modulate); colors[2] = ri.ftol(floatColor[2] * modulate); colors[3] = 255; } // build a list of triangles that need light numIndexes = 0; for ( i = 0 ; i < tess.numIndexes ; i += 3 ) { int a, b, c; a = tess.indexes[i]; b = tess.indexes[i+1]; c = tess.indexes[i+2]; if ( clipBits[a] & clipBits[b] & clipBits[c] ) { continue; // not lighted } hitIndexes[numIndexes] = a; hitIndexes[numIndexes+1] = b; hitIndexes[numIndexes+2] = c; numIndexes += 3; } if ( !numIndexes ) { continue; } qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] ); qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); GL_Bind( tr.dlightImage ); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered if ( dl->additive ) { GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); } else { GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); } R_DrawElements( numIndexes, hitIndexes ); backEnd.pc.c_totalIndexes += numIndexes; backEnd.pc.c_dlightIndexes += numIndexes; } }
static void ProjectDlightTexture_altivec( void ) { int i, l; vec_t origin0, origin1, origin2; float texCoords0, texCoords1; vector float floatColorVec0, floatColorVec1; vector float modulateVec, colorVec, zero; vector short colorShort; vector signed int colorInt; vector unsigned char floatColorVecPerm, modulatePerm, colorChar; vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff); float *texCoords; byte *colors; byte clipBits[SHADER_MAX_VERTEXES]; float texCoordsArray[SHADER_MAX_VERTEXES][2]; byte colorArray[SHADER_MAX_VERTEXES][4]; unsigned hitIndexes[SHADER_MAX_INDEXES]; int numIndexes; float scale; float radius; vec3_t floatColor; float modulate = 0.0f; if ( !backEnd.refdef.num_dlights ) { return; } // There has to be a better way to do this so that floatColor // and/or modulate are already 16-byte aligned. floatColorVecPerm = vec_lvsl(0,(float *)floatColor); modulatePerm = vec_lvsl(0,(float *)&modulate); modulatePerm = (vector unsigned char)vec_splat((vector unsigned int)modulatePerm,0); zero = (vector float)vec_splat_s8(0); for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { dlight_t *dl; if ( !( tess.dlightBits & ( 1 << l ) ) ) { continue; // this surface definately doesn't have any of this light } texCoords = texCoordsArray[0]; colors = colorArray[0]; dl = &backEnd.refdef.dlights[l]; origin0 = dl->transformed[0]; origin1 = dl->transformed[1]; origin2 = dl->transformed[2]; radius = dl->radius; scale = 1.0f / radius; if(r_greyscale->integer) { float luminance; luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f; floatColor[0] = floatColor[1] = floatColor[2] = luminance; } else if(r_greyscale->value) { float luminance; luminance = LUMA(dl->color[0], dl->color[1], dl->color[2]) * 255.0f; floatColor[0] = LERP(dl->color[0] * 255.0f, luminance, r_greyscale->value); floatColor[1] = LERP(dl->color[1] * 255.0f, luminance, r_greyscale->value); floatColor[2] = LERP(dl->color[2] * 255.0f, luminance, r_greyscale->value); } else { floatColor[0] = dl->color[0] * 255.0f; floatColor[1] = dl->color[1] * 255.0f; floatColor[2] = dl->color[2] * 255.0f; } floatColorVec0 = vec_ld(0, floatColor); floatColorVec1 = vec_ld(11, floatColor); floatColorVec0 = vec_perm(floatColorVec0,floatColorVec0,floatColorVecPerm); for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) { int clip = 0; vec_t dist0, dist1, dist2; dist0 = origin0 - tess.xyz[i][0]; dist1 = origin1 - tess.xyz[i][1]; dist2 = origin2 - tess.xyz[i][2]; backEnd.pc.c_dlightVertexes++; texCoords0 = 0.5f + dist0 * scale; texCoords1 = 0.5f + dist1 * scale; if( !r_dlightBacks->integer && // dist . tess.normal[i] ( dist0 * tess.normal[i][0] + dist1 * tess.normal[i][1] + dist2 * tess.normal[i][2] ) < 0.0f ) { clip = 63; } else { if ( texCoords0 < 0.0f ) { clip |= 1; } else if ( texCoords0 > 1.0f ) { clip |= 2; } if ( texCoords1 < 0.0f ) { clip |= 4; } else if ( texCoords1 > 1.0f ) { clip |= 8; } texCoords[0] = texCoords0; texCoords[1] = texCoords1; // modulate the strength based on the height and color if ( dist2 > radius ) { clip |= 16; modulate = 0.0f; } else if ( dist2 < -radius ) { clip |= 32; modulate = 0.0f; } else { dist2 = Q_fabs(dist2); if ( dist2 < radius * 0.5f ) { modulate = 1.0f; } else { modulate = 2.0f * (radius - dist2) * scale; } } } clipBits[i] = clip; modulateVec = vec_ld(0,(float *)&modulate); modulateVec = vec_perm(modulateVec,modulateVec,modulatePerm); colorVec = vec_madd(floatColorVec0,modulateVec,zero); colorInt = vec_cts(colorVec,0); // RGBx colorShort = vec_pack(colorInt,colorInt); // RGBxRGBx colorChar = vec_packsu(colorShort,colorShort); // RGBxRGBxRGBxRGBx colorChar = vec_sel(colorChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255 vec_ste((vector unsigned int)colorChar,0,(unsigned int *)colors); // store color } // build a list of triangles that need light numIndexes = 0; for ( i = 0 ; i < tess.numIndexes ; i += 3 ) { int a, b, c; a = tess.indexes[i]; b = tess.indexes[i+1]; c = tess.indexes[i+2]; if ( clipBits[a] & clipBits[b] & clipBits[c] ) { continue; // not lighted } hitIndexes[numIndexes] = a; hitIndexes[numIndexes+1] = b; hitIndexes[numIndexes+2] = c; numIndexes += 3; } if ( !numIndexes ) { continue; } qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] ); qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); GL_Bind( tr.dlightImage ); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered if ( dl->additive ) { GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); } else { GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); } R_DrawElements( numIndexes, hitIndexes ); backEnd.pc.c_totalIndexes += numIndexes; backEnd.pc.c_dlightIndexes += numIndexes; } }
/* ================== CM_Trace ================== */ static void CM_Trace(trace_t *results, const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, clipHandle_t model, const vec3_t origin, int brushmask, int capsule, sphere_t *sphere) { int i; traceWork_t tw; vec3_t offset; cmodel_t *cmod; qboolean positionTest; cmod = CM_ClipHandleToModel(model); cm.checkcount++; // for multi-check avoidance c_traces++; // for statistics, may be zeroed // fill in a default trace memset(&tw, 0, sizeof(tw)); tw.trace.fraction = 1.0f; // assume it goes the entire distance until shown otherwise VectorCopy(origin, tw.modelOrigin); if (!cm.numNodes) { *results = tw.trace; return; // map not loaded, shouldn't happen } // allow NULL to be passed in for 0,0,0 if (!mins) { mins = vec3_origin; } if (!maxs) { maxs = vec3_origin; } // set basic parms tw.contents = brushmask; // adjust so that mins and maxs are always symetric, which // avoids some complications with plane expanding of rotated // bmodels for (i = 0 ; i < 3 ; i++) { offset[i] = (mins[i] + maxs[i]) * 0.5; tw.size[0][i] = mins[i] - offset[i]; tw.size[1][i] = maxs[i] - offset[i]; tw.start[i] = start[i] + offset[i]; tw.end[i] = end[i] + offset[i]; } // if a sphere is already specified if (sphere) { tw.sphere = *sphere; } else { tw.sphere.use = capsule; tw.sphere.radius = (tw.size[1][0] > tw.size[1][2]) ? tw.size[1][2] : tw.size[1][0]; tw.sphere.halfheight = tw.size[1][2]; VectorSet(tw.sphere.offset, 0, 0, tw.size[1][2] - tw.sphere.radius); } positionTest = (start[0] == end[0] && start[1] == end[1] && start[2] == end[2]); tw.maxOffset = tw.size[1][0] + tw.size[1][1] + tw.size[1][2]; // tw.offsets[signbits] = vector to apropriate corner from origin tw.offsets[0][0] = tw.size[0][0]; tw.offsets[0][1] = tw.size[0][1]; tw.offsets[0][2] = tw.size[0][2]; tw.offsets[1][0] = tw.size[1][0]; tw.offsets[1][1] = tw.size[0][1]; tw.offsets[1][2] = tw.size[0][2]; tw.offsets[2][0] = tw.size[0][0]; tw.offsets[2][1] = tw.size[1][1]; tw.offsets[2][2] = tw.size[0][2]; tw.offsets[3][0] = tw.size[1][0]; tw.offsets[3][1] = tw.size[1][1]; tw.offsets[3][2] = tw.size[0][2]; tw.offsets[4][0] = tw.size[0][0]; tw.offsets[4][1] = tw.size[0][1]; tw.offsets[4][2] = tw.size[1][2]; tw.offsets[5][0] = tw.size[1][0]; tw.offsets[5][1] = tw.size[0][1]; tw.offsets[5][2] = tw.size[1][2]; tw.offsets[6][0] = tw.size[0][0]; tw.offsets[6][1] = tw.size[1][1]; tw.offsets[6][2] = tw.size[1][2]; tw.offsets[7][0] = tw.size[1][0]; tw.offsets[7][1] = tw.size[1][1]; tw.offsets[7][2] = tw.size[1][2]; // check for point special case if (tw.size[0][0] == 0.0f && tw.size[0][1] == 0.0f && tw.size[0][2] == 0.0f) { tw.isPoint = qtrue; VectorClear(tw.extents); } else { tw.isPoint = qfalse; tw.extents[0] = tw.size[1][0]; tw.extents[1] = tw.size[1][1]; tw.extents[2] = tw.size[1][2]; } if (positionTest) { CM_CalcTraceBounds(&tw, qfalse); } else { vec3_t dir; VectorSubtract(tw.end, tw.start, dir); VectorCopy(dir, tw.dir); VectorNormalize(dir); MakeNormalVectors(dir, tw.tracePlane1.normal, tw.tracePlane2.normal); tw.tracePlane1.dist = DotProduct(tw.tracePlane1.normal, tw.start); tw.tracePlane2.dist = DotProduct(tw.tracePlane2.normal, tw.start); if (tw.isPoint) { tw.traceDist1 = tw.traceDist2 = 1.0f; } else { float dist; tw.traceDist1 = tw.traceDist2 = 0.0f; for (i = 0; i < 8; i++) { dist = Q_fabs(DotProduct(tw.tracePlane1.normal, tw.offsets[i]) - tw.tracePlane1.dist); if (dist > tw.traceDist1) { tw.traceDist1 = dist; } dist = Q_fabs(DotProduct(tw.tracePlane2.normal, tw.offsets[i]) - tw.tracePlane2.dist); if (dist > tw.traceDist2) { tw.traceDist2 = dist; } } // expand for epsilon tw.traceDist1 += 1.0f; tw.traceDist2 += 1.0f; } CM_CalcTraceBounds(&tw, qtrue); } // check for position test special case if (positionTest) { if (model) { #ifdef ALWAYS_BBOX_VS_BBOX if (model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) { tw.sphere.use = qfalse; CM_TestInLeaf(&tw, &cmod->leaf); } else #elif defined(ALWAYS_CAPSULE_VS_CAPSULE) if (model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) { CM_TestCapsuleInCapsule(&tw, model); } else #else // this is dead code when ALWAYS_BBOX_VS_BBOX or ALWAYS_CAPSULE_VS_CAPSULE are active if (model == CAPSULE_MODEL_HANDLE) { if (tw.sphere.use) { CM_TestCapsuleInCapsule(&tw, model); } else { CM_TestBoundingBoxInCapsule(&tw, model); } } else #endif { CM_TestInLeaf(&tw, &cmod->leaf); } } else { CM_PositionTest(&tw); } } else { // general sweeping through world if (model) { #ifdef ALWAYS_BBOX_VS_BBOX if (model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) { tw.sphere.use = qfalse; CM_TraceThroughLeaf(&tw, &cmod->leaf); } else #elif defined(ALWAYS_CAPSULE_VS_CAPSULE) if (model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) { CM_TraceCapsuleThroughCapsule(&tw, model); } else #else // this is dead code when ALWAYS_BBOX_VS_BBOX or ALWAYS_CAPSULE_VS_CAPSULE are active if (model == CAPSULE_MODEL_HANDLE) { if (tw.sphere.use) { CM_TraceCapsuleThroughCapsule(&tw, model); } else { CM_TraceBoundingBoxThroughCapsule(&tw, model); } } else #endif { CM_TraceThroughLeaf(&tw, &cmod->leaf); } } else { CM_TraceThroughTree(&tw, 0, 0, 1, tw.start, tw.end); } } // generate endpos from the original, unmodified start/end if (tw.trace.fraction == 1) { VectorCopy(end, tw.trace.endpos); } else { for (i = 0 ; i < 3 ; i++) { tw.trace.endpos[i] = start[i] + tw.trace.fraction * (end[i] - start[i]); } } *results = tw.trace; }
/* ======================== RB_CalcDeformVertexes ======================== */ void RB_CalcDeformVertexes( deformStage_t *ds ) { int i; vec3_t offset; float scale; float *xyz = ( float * ) tess.xyz; float *normal = ( float * ) tess.normal; float *table; // Ridah if ( ds->deformationWave.frequency < 0 ) { qboolean inverse = qfalse; vec3_t worldUp; //static vec3_t up = {0,0,1}; if ( VectorCompare( backEnd.currentEntity->e.fireRiseDir, vec3_origin ) ) { VectorSet( backEnd.currentEntity->e.fireRiseDir, 0, 0, 1 ); } // get the world up vector in local coordinates if ( backEnd.currentEntity->e.hModel ) { // world surfaces don't have an axis VectorRotate( backEnd.currentEntity->e.fireRiseDir, backEnd.currentEntity->e.axis, worldUp ); } else { VectorCopy( backEnd.currentEntity->e.fireRiseDir, worldUp ); } // don't go so far if sideways, since they must be moving VectorScale( worldUp, 0.4 + 0.6 * Q_fabs( backEnd.currentEntity->e.fireRiseDir[ 2 ] ), worldUp ); ds->deformationWave.frequency *= -1; if ( ds->deformationWave.frequency > 999 ) { // hack for negative Z deformation (ack) inverse = qtrue; ds->deformationWave.frequency -= 999; } table = TableForFunc( ds->deformationWave.func ); for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { float off = ( xyz[ 0 ] + xyz[ 1 ] + xyz[ 2 ] ) * ds->deformationSpread; float dot; scale = WAVEVALUE( table, ds->deformationWave.base, ds->deformationWave.amplitude, ds->deformationWave.phase + off, ds->deformationWave.frequency ); dot = DotProduct( worldUp, normal ); if ( dot * scale > 0 ) { if ( inverse ) { scale *= -1; } VectorMA( xyz, dot * scale, worldUp, xyz ); } } if ( inverse ) { ds->deformationWave.frequency += 999; } ds->deformationWave.frequency *= -1; } // done. else if ( ds->deformationWave.frequency == 0 ) { scale = EvalWaveForm( &ds->deformationWave ); for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { VectorScale( normal, scale, offset ); xyz[ 0 ] += offset[ 0 ]; xyz[ 1 ] += offset[ 1 ]; xyz[ 2 ] += offset[ 2 ]; } } else { table = TableForFunc( ds->deformationWave.func ); for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { float off = ( xyz[ 0 ] + xyz[ 1 ] + xyz[ 2 ] ) * ds->deformationSpread; scale = WAVEVALUE( table, ds->deformationWave.base, ds->deformationWave.amplitude, ds->deformationWave.phase + off, ds->deformationWave.frequency ); VectorScale( normal, scale, offset ); xyz[ 0 ] += offset[ 0 ]; xyz[ 1 ] += offset[ 1 ]; xyz[ 2 ] += offset[ 2 ]; } } }
void CM_DrawDebugSurface( void ( *drawPoly )( int color, int numPoints, float *points ) ) { static cvar_t *cv; #ifndef BSPC static cvar_t *cv2; #endif const patchCollide_t *pc; facet_t *facet; winding_t *w; int i, j, k, n; int curplanenum, planenum, curinward, inward; float plane[4]; vec3_t mins = {-15, -15, -28}, maxs = {15, 15, 28}; //vec3_t mins = {0, 0, 0}, maxs = {0, 0, 0}; vec3_t v1, v2; #ifndef BSPC if ( !cv2 ) { cv2 = Cvar_Get( "r_debugSurface", "0", 0 ); } if ( cv2->integer != 1 ) { BotDrawDebugPolygons( drawPoly, cv2->integer ); return; } #endif if ( !debugPatchCollide ) { return; } #ifndef BSPC if ( !cv ) { cv = Cvar_Get( "cm_debugSize", "2", 0 ); } #endif pc = debugPatchCollide; for ( i = 0, facet = pc->facets ; i < pc->numFacets ; i++, facet++ ) { for ( k = 0 ; k < facet->numBorders + 1; k++ ) { // if ( k < facet->numBorders ) { planenum = facet->borderPlanes[k]; inward = facet->borderInward[k]; } else { planenum = facet->surfacePlane; inward = qfalse; //continue; } Vector4Copy( pc->planes[ planenum ].plane, plane ); //planenum = facet->surfacePlane; if ( inward ) { VectorSubtract( vec3_origin, plane, plane ); plane[3] = -plane[3]; } plane[3] += cv->value; //* for ( n = 0; n < 3; n++ ) { if ( plane[n] > 0 ) { v1[n] = maxs[n]; } else { v1[n] = mins[n];} } //end for VectorNegate( plane, v2 ); plane[3] += Q_fabs( DotProduct( v1, v2 ) ); //*/ w = BaseWindingForPlane( plane, plane[3] ); for ( j = 0 ; j < facet->numBorders + 1 && w; j++ ) { // if ( j < facet->numBorders ) { curplanenum = facet->borderPlanes[j]; curinward = facet->borderInward[j]; } else { curplanenum = facet->surfacePlane; curinward = qfalse; //continue; } // if ( curplanenum == planenum ) { continue; } Vector4Copy( pc->planes[ curplanenum ].plane, plane ); if ( !curinward ) { VectorSubtract( vec3_origin, plane, plane ); plane[3] = -plane[3]; } // if ( !facet->borderNoAdjust[j] ) { plane[3] -= cv->value; // } for ( n = 0; n < 3; n++ ) { if ( plane[n] > 0 ) { v1[n] = maxs[n]; } else { v1[n] = mins[n];} } //end for VectorNegate( plane, v2 ); plane[3] -= Q_fabs( DotProduct( v1, v2 ) ); ChopWindingInPlace( &w, plane, plane[3], 0.1f ); } if ( w ) { if ( facet == debugFacet ) { drawPoly( 4, w->numpoints, w->p[0] ); //Com_Printf("blue facet has %d border planes\n", facet->numBorders); } else { drawPoly( 1, w->numpoints, w->p[0] ); } FreeWinding( w ); } else { Com_Printf( "winding chopped away by border planes\n" ); } } } // draw the debug block { vec3_t v[3]; VectorCopy( debugBlockPoints[0], v[0] ); VectorCopy( debugBlockPoints[1], v[1] ); VectorCopy( debugBlockPoints[2], v[2] ); drawPoly( 2, 3, v[0] ); VectorCopy( debugBlockPoints[2], v[0] ); VectorCopy( debugBlockPoints[3], v[1] ); VectorCopy( debugBlockPoints[0], v[2] ); drawPoly( 2, 3, v[0] ); } #if 0 vec3_t v[4]; v[0][0] = pc->bounds[1][0]; v[0][1] = pc->bounds[1][1]; v[0][2] = pc->bounds[1][2]; v[1][0] = pc->bounds[1][0]; v[1][1] = pc->bounds[0][1]; v[1][2] = pc->bounds[1][2]; v[2][0] = pc->bounds[0][0]; v[2][1] = pc->bounds[0][1]; v[2][2] = pc->bounds[1][2]; v[3][0] = pc->bounds[0][0]; v[3][1] = pc->bounds[1][1]; v[3][2] = pc->bounds[1][2]; drawPoly( 4, v[0] ); #endif }