/* ================ CG_DrawRangeMarker ================ */ void CG_DrawRangeMarker( int rmType, const vec3_t origin, const float *angles, float range, qboolean drawSurface, qboolean drawIntersection, qboolean drawFrontline, const vec3_t rgb, float surfaceOpacity, float lineOpacity, float lineThickness ) { if ( drawSurface ) { qhandle_t pcsh; vec4_t rgba; pcsh = cgs.media.plainColorShader; VectorCopy( rgb, rgba ); rgba[ 3 ] = surfaceOpacity; if ( rmType == 0 ) { CG_DrawSphere( origin, range, pcsh, rgba ); } else if ( rmType == 1 ) { CG_DrawSphericalCone( origin, angles, range, qfalse, pcsh, rgba ); } else if ( rmType == 2 ) { CG_DrawSphericalCone( origin, angles, range, qtrue, pcsh, rgba ); } } if ( drawIntersection || drawFrontline ) { const cgMediaBinaryShader_t *mbsh; cgBinaryShaderSetting_t *bshs; int i; if ( cg.numBinaryShadersUsed >= NUM_BINARY_SHADERS ) { return; } mbsh = &cgs.media.binaryShaders[ cg.numBinaryShadersUsed ]; if ( rmType == 0 ) { if ( range > lineThickness / 2 ) { if ( drawIntersection ) { CG_DrawSphere( origin, range - lineThickness / 2, mbsh->b1, NULL ); } CG_DrawSphere( origin, range - lineThickness / 2, mbsh->f2, NULL ); } if ( drawIntersection ) { CG_DrawSphere( origin, range + lineThickness / 2, mbsh->b2, NULL ); } CG_DrawSphere( origin, range + lineThickness / 2, mbsh->f1, NULL ); } else if ( rmType == 1 || rmType == 2 ) { qboolean t2; float f, r; vec3_t forward, tip; t2 = ( rmType == 2 ); f = lineThickness * ( t2 ? 0.26f : 0.8f ); r = f + lineThickness * ( t2 ? 0.23f : 0.43f ); AngleVectors( angles, forward, NULL, NULL ); if ( range > r ) { VectorMA( origin, f, forward, tip ); if ( drawIntersection ) { CG_DrawSphericalCone( tip, angles, range - r, t2, mbsh->b1, NULL ); } CG_DrawSphericalCone( tip, angles, range - r, t2, mbsh->f2, NULL ); } VectorMA( origin, -f, forward, tip ); if ( drawIntersection ) { CG_DrawSphericalCone( tip, angles, range + r, t2, mbsh->b2, NULL ); } CG_DrawSphericalCone( tip, angles, range + r, t2, mbsh->f1, NULL ); } bshs = &cg.binaryShaderSettings[ cg.numBinaryShadersUsed ]; for ( i = 0; i < 3; ++i ) { bshs->color[ i ] = 255 * lineOpacity * rgb[ i ]; } bshs->drawIntersection = drawIntersection; bshs->drawFrontline = drawFrontline; ++cg.numBinaryShadersUsed; } }
/* ================ CG_DrawRangeMarker ================ */ void CG_DrawRangeMarker( rangeMarker_t rmType, const vec3_t origin, float range, const vec3_t angles, vec4_t rgba ) { if ( cg_rangeMarkerDrawSurface.integer ) { qhandle_t pcsh; pcsh = cgs.media.plainColorShader; rgba[ 3 ] *= Com_Clamp( 0.0f, 1.0f, cg_rangeMarkerSurfaceOpacity.value ); switch( rmType ) { case RM_SPHERE: CG_DrawSphere( origin, range, pcsh, rgba ); break; case RM_SPHERICAL_CONE_64: CG_DrawSphericalCone( origin, angles, range, qfalse, pcsh, rgba ); break; case RM_SPHERICAL_CONE_240: CG_DrawSphericalCone( origin, angles, range, qtrue, pcsh, rgba ); break; } } if ( cg_rangeMarkerDrawIntersection.integer || cg_rangeMarkerDrawFrontline.integer ) { float lineOpacity, lineThickness; const cgMediaBinaryShader_t *mbsh; cgBinaryShaderSetting_t *bshs; int i; if ( cg.numBinaryShadersUsed >= NUM_BINARY_SHADERS ) { return; } lineOpacity = Com_Clamp( 0.0f, 1.0f, cg_rangeMarkerLineOpacity.value ); lineThickness = cg_rangeMarkerLineThickness.value; if ( lineThickness < 0.0f ) lineThickness = 0.0f; mbsh = &cgs.media.binaryShaders[ cg.numBinaryShadersUsed ]; if ( rmType == RM_SPHERE ) { if ( range > lineThickness / 2 ) { if ( cg_rangeMarkerDrawIntersection.integer ) { CG_DrawSphere( origin, range - lineThickness / 2, mbsh->b1, NULL ); } CG_DrawSphere( origin, range - lineThickness / 2, mbsh->f2, NULL ); } if ( cg_rangeMarkerDrawIntersection.integer ) { CG_DrawSphere( origin, range + lineThickness / 2, mbsh->b2, NULL ); } CG_DrawSphere( origin, range + lineThickness / 2, mbsh->f1, NULL ); } else { qboolean t2; float f, r; vec3_t forward, tip; t2 = ( rmType == RM_SPHERICAL_CONE_240 ); f = lineThickness * ( t2 ? 0.26f : 0.8f ); r = f + lineThickness * ( t2 ? 0.23f : 0.43f ); AngleVectors( angles, forward, NULL, NULL ); if ( range > r ) { VectorMA( origin, f, forward, tip ); if ( cg_rangeMarkerDrawIntersection.integer ) { CG_DrawSphericalCone( tip, angles, range - r, t2, mbsh->b1, NULL ); } CG_DrawSphericalCone( tip, angles, range - r, t2, mbsh->f2, NULL ); } VectorMA( origin, -f, forward, tip ); if ( cg_rangeMarkerDrawIntersection.integer ) { CG_DrawSphericalCone( tip, angles, range + r, t2, mbsh->b2, NULL ); } CG_DrawSphericalCone( tip, angles, range + r, t2, mbsh->f1, NULL ); } bshs = &cg.binaryShaderSettings[ cg.numBinaryShadersUsed ]; for ( i = 0; i < 3; ++i ) { bshs->color[ i ] = 255 * lineOpacity * rgba[ i ]; } bshs->drawIntersection = !!cg_rangeMarkerDrawIntersection.integer; bshs->drawFrontline = !!cg_rangeMarkerDrawFrontline.integer; ++cg.numBinaryShadersUsed; } }