void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir, float orientation, float red, float green, float blue, float alpha, bool alphaFade, float radius, bool temporary ) { vec3_t axis[ 3 ]; float texCoordScale; vec3_t originalPoints[ 4 ]; byte colors[ 4 ]; int i, j; int numFragments; markFragment_t markFragments[ MAX_MARK_FRAGMENTS ], *mf; vec3_t markPoints[ MAX_MARK_POINTS ]; vec3_t projection; if ( !cg_addMarks.integer ) { return; } if( temporary ) { if( CG_CullPointAndRadius( origin, M_SQRT2 * radius ) ) { return; } } if ( radius <= 0 ) { Com_Error(errorParm_t::ERR_DROP, "CG_ImpactMark called with <= 0 radius" ); } //if ( markTotal >= MAX_MARK_POLYS ) { // return; //} // create the texture axis VectorNormalize2( dir, axis[ 0 ] ); PerpendicularVector( axis[ 1 ], axis[ 0 ] ); RotatePointAroundVector( axis[ 2 ], axis[ 0 ], axis[ 1 ], orientation ); CrossProduct( axis[ 0 ], axis[ 2 ], axis[ 1 ] ); texCoordScale = 0.5 * 1.0 / radius; // create the full polygon for ( i = 0; i < 3; i++ ) { originalPoints[ 0 ][ i ] = origin[ i ] - radius * axis[ 1 ][ i ] - radius * axis[ 2 ][ i ]; originalPoints[ 1 ][ i ] = origin[ i ] + radius * axis[ 1 ][ i ] - radius * axis[ 2 ][ i ]; originalPoints[ 2 ][ i ] = origin[ i ] + radius * axis[ 1 ][ i ] + radius * axis[ 2 ][ i ]; originalPoints[ 3 ][ i ] = origin[ i ] - radius * axis[ 1 ][ i ] + radius * axis[ 2 ][ i ]; } // get the fragments VectorScale( dir, -20, projection ); numFragments = trap_CM_MarkFragments( 4, ( const vec3_t * ) originalPoints, projection, MAX_MARK_POINTS, markPoints[ 0 ], MAX_MARK_FRAGMENTS, markFragments ); colors[ 0 ] = red * 255; colors[ 1 ] = green * 255; colors[ 2 ] = blue * 255; colors[ 3 ] = alpha * 255; for ( i = 0, mf = markFragments; i < numFragments; i++, mf++ ) { polyVert_t *v; polyVert_t verts[ MAX_VERTS_ON_POLY ]; markPoly_t *mark; // we have an upper limit on the complexity of polygons // that we store persistently if ( mf->numPoints > MAX_VERTS_ON_POLY ) { mf->numPoints = MAX_VERTS_ON_POLY; } for ( j = 0, v = verts; j < mf->numPoints; j++, v++ ) { vec3_t delta; VectorCopy( markPoints[ mf->firstPoint + j ], v->xyz ); VectorSubtract( v->xyz, origin, delta ); v->st[ 0 ] = 0.5 + DotProduct( delta, axis[ 1 ] ) * texCoordScale; v->st[ 1 ] = 0.5 + DotProduct( delta, axis[ 2 ] ) * texCoordScale; * ( int * ) v->modulate = * ( int * ) colors; } // if it is a temporary (shadow) mark, add it immediately and forget about it if ( temporary ) { trap_R_AddPolyToScene( markShader, mf->numPoints, verts ); continue; } // otherwise save it persistently mark = CG_AllocMark(); mark->time = cg.time; mark->alphaFade = alphaFade; mark->markShader = markShader; mark->poly.numVerts = mf->numPoints; mark->color[ 0 ] = red; mark->color[ 1 ] = green; mark->color[ 2 ] = blue; mark->color[ 3 ] = alpha; memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[ 0 ] ) ); markTotal++; } }
void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir, float orientation, float red, float green, float blue, float alpha, qboolean alphaFade, float radius, qboolean temporary ) { vec3_t axis[3]; float texCoordScale; vec3_t originalPoints[4]; byte colors[4]; int i, j; int numFragments; markFragment_t markFragments[MAX_MARK_FRAGMENTS], *mf; vec3_t markPoints[MAX_MARK_POINTS]; vec3_t projection; markPoly_t *mp, *next; vec3_t delta; if ( !cg_addMarks.integer ) { return; } if ( radius <= 0 ) { CG_Error( "CG_ImpactMark called with <= 0 radius" ); } //if ( markTotal >= MAX_MARK_POLYS ) { // return; //} // HERBY: Bubble G overdraw fix mp = cg_activeMarkPolys.nextMark; for ( ; mp != &cg_activeMarkPolys; mp = next ) { next = mp->nextMark; if(temporary) break; // keep all marks if the new one is just the shadow if(mp->markShader == cgs.media.SchaumShader) continue;//die slick-ents einfach übergehen VectorSubtract( mp->origin, origin, delta ); if ( radius <= mp->radius + 4 && VectorLength( delta ) < ( radius + mp->radius ) * MIN_MARK_DISTANCE ) { CG_FreeMarkPoly( mp ); } } // create the texture axis VectorNormalize2( dir, axis[0] ); PerpendicularVector( axis[1], axis[0] ); RotatePointAroundVector( axis[2], axis[0], axis[1], orientation ); CrossProduct( axis[0], axis[2], axis[1] ); texCoordScale = 0.5 * 1.0 / radius; // create the full polygon for ( i = 0 ; i < 3 ; ++i ) { originalPoints[0][i] = origin[i] - radius * axis[1][i] - radius * axis[2][i]; originalPoints[1][i] = origin[i] + radius * axis[1][i] - radius * axis[2][i]; originalPoints[2][i] = origin[i] + radius * axis[1][i] + radius * axis[2][i]; originalPoints[3][i] = origin[i] - radius * axis[1][i] + radius * axis[2][i]; } // get the fragments VectorScale( dir, -20, projection ); numFragments = trap_CM_MarkFragments( 4, (void *)originalPoints, projection, MAX_MARK_POINTS, markPoints[0], MAX_MARK_FRAGMENTS, markFragments ); if(!numFragments && markShader == cgs.media.SchaumShader) { numFragments = 1; markFragments->firstPoint = 0; markFragments->numPoints = 4; for(i=0;i<4;++i) VectorCopy(originalPoints[i],markPoints[i]); } colors[0] = red * 255; colors[1] = green * 255; colors[2] = blue * 255; colors[3] = alpha * 255; for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ ) { polyVert_t *v; polyVert_t verts[MAX_VERTS_ON_POLY]; markPoly_t *mark; // we have an upper limit on the complexity of polygons // that we store persistantly if ( mf->numPoints > MAX_VERTS_ON_POLY ) { mf->numPoints = MAX_VERTS_ON_POLY; } for ( j = 0, v = verts ; j < mf->numPoints ; j++, v++ ) { vec3_t delta; VectorCopy( markPoints[mf->firstPoint + j], v->xyz ); VectorSubtract( v->xyz, origin, delta ); v->st[0] = 0.5 + DotProduct( delta, axis[1] ) * texCoordScale; v->st[1] = 0.5 + DotProduct( delta, axis[2] ) * texCoordScale; *(int *)v->modulate = *(int *)colors; } // if it is a temporary (shadow) mark, add it immediately and forget about it if ( temporary ) { trap_R_AddPolyToScene( markShader, mf->numPoints, verts ); continue; } // otherwise save it persistantly mark = CG_AllocMark(); mark->time = cg.time; mark->alphaFade = alphaFade; mark->markShader = markShader; mark->poly.numVerts = mf->numPoints; mark->color[0] = red; mark->color[1] = green; mark->color[2] = blue; mark->color[3] = alpha; mark->radius = radius; VectorCopy( origin, mark->origin ); memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) ); markTotal++; } }
void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir, float orientation, float red, float green, float blue, float alpha, qboolean alphaFade, float radius, qboolean temporary, int duration ) { vec3_t axis[3]; float texCoordScale; vec3_t originalPoints[4]; byte colors[4]; int i, j; int numFragments; markFragment_t markFragments[MAX_MARK_FRAGMENTS], *mf; vec5_t markPoints[MAX_MARK_POINTS]; // Ridah, made it vec5_t so it includes S/T vec3_t projection; int multMaxFragments=1; if ( !cg_markTime.integer ) { return; } if ( radius <= 0 ) { CG_Error( "CG_ImpactMark called with <= 0 radius" ); } // Ridah, if no duration, use the default if (duration < 0) { if (duration == -2) { multMaxFragments = -1; // use original mapping } // duration = MARK_TOTAL_TIME; duration = cg_markTime.integer; } // create the texture axis VectorNormalize2( dir, axis[0] ); PerpendicularVector( axis[1], axis[0] ); RotatePointAroundVector( axis[2], axis[0], axis[1], orientation ); CrossProduct( axis[0], axis[2], axis[1] ); texCoordScale = 0.5 * 1.0 / radius; // create the full polygon for ( i = 0 ; i < 3 ; i++ ) { originalPoints[0][i] = origin[i] - radius * axis[1][i] - radius * axis[2][i]; originalPoints[1][i] = origin[i] + radius * axis[1][i] - radius * axis[2][i]; originalPoints[2][i] = origin[i] + radius * axis[1][i] + radius * axis[2][i]; originalPoints[3][i] = origin[i] - radius * axis[1][i] + radius * axis[2][i]; } // get the fragments //VectorScale( dir, -20, projection ); VectorScale( dir, radius*2, projection ); numFragments = trap_CM_MarkFragments( (int)orientation, (void *)originalPoints, projection, MAX_MARK_POINTS, (float *)&markPoints[0], MAX_MARK_FRAGMENTS*multMaxFragments, markFragments ); colors[0] = red * 255; colors[1] = green * 255; colors[2] = blue * 255; colors[3] = alpha * 255; for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ ) { polyVert_t *v; polyVert_t verts[MAX_VERTS_ON_POLY]; markPoly_t *mark; qboolean hasST; // we have an upper limit on the complexity of polygons // that we store persistantly if ( mf->numPoints > MAX_VERTS_ON_POLY ) { mf->numPoints = MAX_VERTS_ON_POLY; } if (mf->numPoints < 0) { hasST = qtrue; mf->numPoints *= -1; } else { hasST = qfalse; } for ( j = 0, v = verts ; j < mf->numPoints ; j++, v++ ) { vec3_t delta; VectorCopy( markPoints[mf->firstPoint + j], v->xyz ); if (!hasST) { VectorSubtract( v->xyz, origin, delta ); v->st[0] = 0.5 + DotProduct( delta, axis[1] ) * texCoordScale; v->st[1] = 0.5 + DotProduct( delta, axis[2] ) * texCoordScale; } else { v->st[0] = markPoints[mf->firstPoint + j][3]; v->st[1] = markPoints[mf->firstPoint + j][4]; } *(int *)v->modulate = *(int *)colors; } // if it is a temporary (shadow) mark, add it immediately and forget about it if ( temporary ) { trap_R_AddPolyToScene( markShader, mf->numPoints, verts ); continue; } // otherwise save it persistantly mark = CG_AllocMark(cg.time + duration); mark->time = cg.time; mark->alphaFade = alphaFade; mark->markShader = markShader; mark->poly.numVerts = mf->numPoints; mark->color[0] = red; mark->color[1] = green; mark->color[2] = blue; mark->color[3] = alpha; mark->duration = duration; memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) ); } }
void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir, float orientation, float red, float green, float blue, float alpha, qboolean alphaFade, float radius, qboolean temporary ) #endif { vec3_t axis[3]; float texCoordScale; vec3_t originalPoints[4]; byte colors[4]; int i, j; int numFragments; markFragment_t markFragments[MAX_MARK_FRAGMENTS], *mf; vec3_t markPoints[MAX_MARK_POINTS]; vec3_t projection; #ifdef TA_WEAPSYS qboolean addedMark = qfalse; #endif if ( !cg_addMarks.integer ) { #ifdef TA_WEAPSYS return qfalse; #else return; #endif } if ( radius <= 0 ) { CG_Error( "CG_ImpactMark called with <= 0 radius" ); } #ifndef IOQ3ZTM //if ( markTotal >= MAX_MARK_POLYS ) { // return; //} #endif // create the texture axis VectorNormalize2( dir, axis[0] ); PerpendicularVector( axis[1], axis[0] ); RotatePointAroundVector( axis[2], axis[0], axis[1], orientation ); CrossProduct( axis[0], axis[2], axis[1] ); texCoordScale = 0.5 * 1.0 / radius; // create the full polygon for ( i = 0 ; i < 3 ; i++ ) { originalPoints[0][i] = origin[i] - radius * axis[1][i] - radius * axis[2][i]; originalPoints[1][i] = origin[i] + radius * axis[1][i] - radius * axis[2][i]; originalPoints[2][i] = origin[i] + radius * axis[1][i] + radius * axis[2][i]; originalPoints[3][i] = origin[i] - radius * axis[1][i] + radius * axis[2][i]; } // get the fragments VectorScale( dir, -20, projection ); numFragments = trap_CM_MarkFragments( 4, (void *)originalPoints, projection, MAX_MARK_POINTS, markPoints[0], MAX_MARK_FRAGMENTS, markFragments ); colors[0] = red * 255; colors[1] = green * 255; colors[2] = blue * 255; colors[3] = alpha * 255; for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ ) { polyVert_t *v; polyVert_t verts[MAX_VERTS_ON_POLY]; markPoly_t *mark; vec3_t delta; vec3_t localOrigin; // create the texture axis VectorNormalize2( mf->projectionDir, axis[0] ); VectorScale( axis[0], -1, axis[0] ); // ZTM: the dir was scaled to -20 before giving to renderer, turn it back around. :S PerpendicularVector( axis[1], axis[0] ); RotatePointAroundVector( axis[2], axis[0], axis[1], orientation ); CrossProduct( axis[0], axis[2], axis[1] ); if ( mf->bmodelNum ) { // ZTM: TODO?: compensate for scale in the axes if necessary? see R_RotateForEntity // ZTM: FIXME: cgame should be able to get origin and axis from entity ! VectorSubtract( origin, mf->bmodelOrigin, delta ); localOrigin[0] = DotProduct( delta, mf->bmodelAxis[0] ); localOrigin[1] = DotProduct( delta, mf->bmodelAxis[1] ); localOrigin[2] = DotProduct( delta, mf->bmodelAxis[2] ); } else { VectorCopy( origin, localOrigin ); } // we have an upper limit on the complexity of polygons // that we store persistantly if ( mf->numPoints > MAX_VERTS_ON_POLY ) { mf->numPoints = MAX_VERTS_ON_POLY; } for ( j = 0, v = verts ; j < mf->numPoints ; j++, v++ ) { VectorCopy( markPoints[mf->firstPoint + j], v->xyz ); VectorSubtract( v->xyz, localOrigin, delta ); v->st[0] = 0.5 + DotProduct( delta, axis[1] ) * texCoordScale; v->st[1] = 0.5 + DotProduct( delta, axis[2] ) * texCoordScale; *(int *)v->modulate = *(int *)colors; } // if it is a temporary (shadow) mark, add it immediately and forget about it if ( temporary ) { trap_R_AddPolyToScene( markShader, mf->numPoints, verts, mf->bmodelNum, 0 ); continue; } // otherwise save it persistantly mark = CG_AllocMark(); mark->bmodelNum = mf->bmodelNum; mark->time = cg.time; mark->alphaFade = alphaFade; mark->markShader = markShader; mark->numVerts = mf->numPoints; mark->color[0] = red; mark->color[1] = green; mark->color[2] = blue; mark->color[3] = alpha; memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) ); #ifndef IOQ3ZTM markTotal++; #endif #ifdef TA_WEAPSYS addedMark = qtrue; #endif } #ifdef TA_WEAPSYS return addedMark; #endif }