// //================= //CG_SpawnPolygon //================= // cpoly_t *CG_SpawnPolygon( float r, float g, float b, float a, float die, float fadetime, qboolean fadealpha, struct shader_s *shader ) { cpoly_t *pl; float dietime, fadefreq; // clamp and scale colors if( r < 0 ) r = 0; else if( r > 1 ) r = 255; else r *= 255; if( g < 0 ) g = 0; else if( g > 1 ) g = 255; else g *= 255; if( b < 0 ) b = 0; else if( b > 1 ) b = 255; else b *= 255; if( a < 0 ) a = 0; else if( a > 1 ) a = 255; else a *= 255; dietime = cg.time + die * 1000; fadefreq = 0.001f / min( fadetime, die ); fadetime = cg.time + (die - min( fadetime, die )) * 1000; // allocate poly pl = CG_AllocPoly (); pl->die = dietime; pl->fadetime = fadetime; pl->fadefreq = fadefreq; pl->fadealpha = fadealpha; pl->shader = shader; pl->color[0] = r; pl->color[1] = g; pl->color[2] = b; pl->color[3] = a; return pl; } // //================= //CG_OrientPolygon //================= // void CG_OrientPolygon( vec3_t origin, vec3_t angles, poly_t *poly ) { int i, j; //poly_t *poly; vec3_t center; vec3_t perp; //poly = cgpolygon->poly; #if 0 //rotate around polygon's center //find polygon's center VectorClear( center ); for( i = 0; i < poly->numverts ; i++ ) { for( j = 0; j < 3; j++ ) { center[j] += poly->verts[i][j]; } } for( j = 0; j < 3; j++ ) center[j] /= poly->numverts; #endif //rotate the polygon around it's default origin (0,0,0) VectorClear(center); //axis_identity[0] = ROLL //axis_identity[1] = PITCH //axis_identity[2] = YAW //FIXME: needs optimization for( i = 0; i < poly->numverts ; i++ ) { VectorSubtract( poly->verts[i], center, perp ); RotatePointAroundVector( poly->verts[i], axis_identity[0], perp, angles[ROLL] ); VectorSubtract( poly->verts[i], center, perp ); RotatePointAroundVector( poly->verts[i], axis_identity[1], perp, angles[PITCH] ); VectorSubtract( poly->verts[i], center, perp ); RotatePointAroundVector( poly->verts[i], axis_identity[2], perp, angles[YAW] ); } //move to the desired origin for( i = 0; i < poly->numverts ; i++ ) { for( j = 0; j < 3; j++ ) poly->verts[i][j] += origin[j]; } } // //================= //CG_ElectroBeamSprite2 //================= // void CG_ElectroBeamSprite2( vec3_t start, vec3_t end ) { cpoly_t *cgpoly; poly_t *poly; //struct shader_s *shader = trap_R_RegisterPic( "gfx/misc/testpoly2" ); struct shader_s *shader = trap_R_RegisterPic("gfx/misc/electro"); vec3_t angles, dir; int vcolor, i; float xmin, ymin, xmax, ymax; float imagelength = 64; float stx = 1.0, sty = 1.0; //find out electrobeam polygon sizes VectorSubtract( end, start, dir ); VecToAngles( dir, angles ); xmin = 0; xmax = VectorNormalize( dir ); ymin = -10; ymax = 10; if( xmax > imagelength ) { stx = xmax/imagelength; } cgpoly = CG_SpawnPolygon( 1.0, 1.0, 1.0, 1.0, 10, 1, qtrue, shader ); VectorCopy( angles, cgpoly->angles ); VectorCopy( start, cgpoly->origin ); cgpoly->effects = CGPOLY_EF_AUTOSPRITE_ROLL; //create the polygon inside the cgpolygon poly = cgpoly->poly; poly->shader = cgpoly->shader; vcolor = COLOR_RGBA( (int)(cgpoly->color[0] * 255), (int)(cgpoly->color[1] * 255), (int)(cgpoly->color[2] * 255), (int)(cgpoly->color[3] * 255) ); poly->numverts = 0; //A VectorSet( poly->verts[poly->numverts], xmin, 0, ymin ); poly->stcoords[poly->numverts][0] = 0; poly->stcoords[poly->numverts][1] = 0; *(int *)poly->colors[poly->numverts] = vcolor; poly->numverts++; //D VectorSet( poly->verts[poly->numverts], xmax, 0, ymin ); poly->stcoords[poly->numverts][0] = stx; poly->stcoords[poly->numverts][1] = 0; *(int *)poly->colors[poly->numverts] = vcolor; poly->numverts++; //C VectorSet( poly->verts[poly->numverts], xmax, 0, ymax ); poly->stcoords[poly->numverts][0] = stx; poly->stcoords[poly->numverts][1] = sty; *(int *)poly->colors[poly->numverts] = vcolor; poly->numverts++; //B VectorSet( poly->verts[poly->numverts], xmin, 0, ymax ); poly->stcoords[poly->numverts][0] = 0; poly->stcoords[poly->numverts][1] = sty; *(int *)poly->colors[poly->numverts] = vcolor; poly->numverts++; //the verts data is stored inside cgpoly, cause it can be moved later for( i = 0; i < poly->numverts; i++ ) VectorCopy( poly->verts[i], cgpoly->verts[i] ); } // //================= //CG_Addpolys //================= // void CG_AddPolys( void ) { int i; float fade; cpoly_t *cgpoly, *next, *hnode; poly_t *poly; static byte_vec4_t color; static vec3_t angles; // add polys in first-spawed - first-drawn order hnode = &cg_polys_headnode; for( cgpoly = hnode->prev; cgpoly != hnode; cgpoly = next ) { next = cgpoly->prev; // it's time to DIE if( cgpoly->die <= cg.time ) { CG_FreePoly( cgpoly ); continue; } poly = cgpoly->poly; //jal[start] composite the poly with cgpoly's data if( !(cgpoly->effects & CGPOLY_EF_NOORIENT) ) { for( i=0; inumverts; i++ ) VectorCopy( cgpoly->verts[i], poly->verts[i] ); VectorCopy( cgpoly->angles, angles ); if( cgpoly->effects & CGPOLY_EF_AUTOSPRITE_PITCH ) { } if( cgpoly->effects & CGPOLY_EF_AUTOSPRITE_YAW ) { } if( cgpoly->effects & CGPOLY_EF_AUTOSPRITE_ROLL ) { // vec3_t dir, angles2; // VectorSubtract( cg.refdef.vieworg, cgpoly->origin, dir ); // VecToAngles( dir, angles2 ); } CG_OrientPolygon( cgpoly->origin, angles, poly ); } //jal[end] // fade out if( cgpoly->fadetime < cg.time ) { fade = (cgpoly->die - cg.time) * cgpoly->fadefreq; if( cgpoly->fadealpha ) { color[0] = ( qbyte )( cgpoly->color[0] ); color[1] = ( qbyte )( cgpoly->color[1] ); color[2] = ( qbyte )( cgpoly->color[2] ); color[3] = ( qbyte )( cgpoly->color[3]*fade ); } else { color[0] = ( qbyte )( cgpoly->color[0]*fade ); color[1] = ( qbyte )( cgpoly->color[1]*fade ); color[2] = ( qbyte )( cgpoly->color[2]*fade ); color[3] = ( qbyte )( cgpoly->color[3] ); } for( i = 0; i < poly->numverts; i++ ) *( int * )poly->colors[i] = *( int * )color; } trap_R_AddPolyToScene( poly ); } }