/** * @brief Check rain particle visibility * @details Check the snowflake is visible and still going, wrapping if necessary. */ static qboolean CG_SnowParticleCheckVisible(cg_atmosphericParticle_t *particle) { float moved; vec2_t distance; if (!particle || particle->active == ACT_NOT) { return qfalse; } // units moved since last frame moved = (cg.time - cg_atmFx.lastRainTime) * 0.001; VectorMA(particle->pos, moved, particle->delta, particle->pos); if (particle->pos[2] < BG_GetSkyGroundHeightAtPoint(particle->pos)) { return CG_SetParticleActive(particle, ACT_NOT); } distance[0] = particle->pos[0] - cg.refdef_current->vieworg[0]; distance[1] = particle->pos[1] - cg.refdef_current->vieworg[1]; if ((distance[0] * distance[0] + distance[1] * distance[1]) > Square(MAX_ATMOSPHERIC_DISTANCE)) { // just nuke this particle, let it respawn return CG_SetParticleActive(particle, ACT_NOT); } return qtrue; }
static qboolean CG_SnowParticleCheckVisible(cg_atmosphericParticle_t *particle) { // Check the snowflake is visible and still going, wrapping if necessary. float moved; vec2_t distance; //int msec = trap_Milliseconds(); //n_checkvisibletime++; if (!particle || particle->active == ACT_NOT) { // checkvisibletime += trap_Milliseconds() - msec; return(qfalse); } moved = (cg.time - cg_atmFx.lastRainTime) * 0.001; // Units moved since last frame VectorMA(particle->pos, moved, particle->delta, particle->pos); if (particle->pos[2] < BG_GetSkyGroundHeightAtPoint(particle->pos)) { //checkvisibletime += trap_Milliseconds() - msec; return CG_SetParticleActive(particle, ACT_NOT); } distance[0] = particle->pos[0] - cg.refdef_current->vieworg[0]; distance[1] = particle->pos[1] - cg.refdef_current->vieworg[1]; if ((distance[0] * distance[0] + distance[1] * distance[1]) > Square(MAX_ATMOSPHERIC_DISTANCE)) { // just nuke this particle, let it respawn return CG_SetParticleActive(particle, ACT_NOT); } //checkvisibletime += trap_Milliseconds() - msec; return(qtrue); }
static qboolean CG_SnowParticleCheckVisible( cg_atmosphericParticle_t *particle ) { // Check the snowflake is visible and still going, wrapping if necessary. float moved; vec2_t distance; // int msec = trap_Milliseconds(); // n_checkvisibletime++; if( !particle || particle->active == ACT_NOT ) { // checkvisibletime += trap_Milliseconds() - msec; return( qfalse ); } moved = (cg.time - cg_atmFx.lastRainTime) * 0.001; // Units moved since last frame VectorMA( particle->pos, moved, particle->delta, particle->pos ); if( particle->pos[2] < BG_GetSkyGroundHeightAtPoint( particle->pos ) ) { // checkvisibletime += trap_Milliseconds() - msec; return CG_SetParticleActive( particle, ACT_NOT ); } distance[0] = particle->pos[0] - cg.refdef_current->vieworg[0]; distance[1] = particle->pos[1] - cg.refdef_current->vieworg[1]; if( (distance[0] * distance[0] + distance[1] * distance[1]) > Square( MAX_ATMOSPHERIC_DISTANCE ) ) { // ydnar: just nuke this particle, let it respawn return CG_SetParticleActive( particle, ACT_NOT ); /* // Attempt to respot the particle at our other side particle->pos[0] -= 1.85f * distance[0]; particle->pos[1] -= 1.85f * distance[1]; // ydnar: place particle in random position between ground and sky groundHeight = BG_GetSkyGroundHeightAtPoint( particle->pos ); skyHeight = BG_GetSkyHeightAtPoint( particle->pos ); if( skyHeight == MAX_ATMOSPHERIC_HEIGHT ) return CG_SetParticleActive( particle, ACT_NOT ); particle->pos[ 2 ] = groundHeight + random() * (skyHeight - groundHeight); // ydnar: valid spot? if( particle->pos[ 2 ] <= groundHeight || particle->pos[ 2 ] >= skyHeight ) return CG_SetParticleActive( particle, ACT_NOT ); */ } // checkvisibletime += trap_Milliseconds() - msec; return( qtrue ); }
static qboolean CG_RainParticleCheckVisible( cg_atmosphericParticle_t *particle ) { // Check the raindrop is visible and still going, wrapping if necessary. float moved; vec2_t distance; // int msec = trap_Milliseconds(); if( !particle || particle->active == ACT_NOT ) { // checkvisibletime += trap_Milliseconds() - msec; return( qfalse ); } moved = (cg.time - cg_atmFx.lastRainTime) * 0.001; // Units moved since last frame VectorMA( particle->pos, moved, particle->delta, particle->pos ); if( particle->pos[2] + particle->height < BG_GetSkyGroundHeightAtPoint( particle->pos ) ) { // checkvisibletime += trap_Milliseconds() - msec; return CG_SetParticleActive( particle, ACT_NOT ); } distance[0] = particle->pos[0] - cg.refdef_current->vieworg[0]; distance[1] = particle->pos[1] - cg.refdef_current->vieworg[1]; if( (distance[0] * distance[0] + distance[1] * distance[1]) > Square( MAX_ATMOSPHERIC_DISTANCE ) ) { // ydnar: just nuke this particle, let it respawn return CG_SetParticleActive( particle, ACT_NOT ); /* // Attempt to respot the particle at our other side particle->pos[0] -= 1.85f * distance[0]; particle->pos[1] -= 1.85f * distance[1]; // Valid spot? pointHeight = BG_GetSkyHeightAtPoint( particle->pos ); if( pointHeight == MAX_ATMOSPHERIC_HEIGHT ) { // checkvisibletime += trap_Milliseconds() - msec; return CG_SetParticleActive( particle, ACT_NOT ); } pointHeight = BG_GetSkyGroundHeightAtPoint( particle->pos ); if( pointHeight == MAX_ATMOSPHERIC_HEIGHT || pointHeight >= particle->pos[2] ) { // checkvisibletime += trap_Milliseconds() - msec; return CG_SetParticleActive( particle, ACT_NOT ); } */ } // checkvisibletime += trap_Milliseconds() - msec; return( qtrue ); }
/** * @brief Generate rain particle * @details Attempt to 'spot' a raindrop somewhere below a sky texture. */ static qboolean CG_RainParticleGenerate(cg_atmosphericParticle_t *particle, vec3_t currvec, float currweight) { float angle = random() * 2 * M_PI, distance = 20 + MAX_ATMOSPHERIC_DISTANCE * random(); float groundHeight, skyHeight; particle->pos[0] = cg.refdef_current->vieworg[0] + sin(angle) * distance; particle->pos[1] = cg.refdef_current->vieworg[1] + cos(angle) * distance; // choose a spawn point randomly between sky and ground skyHeight = BG_GetSkyHeightAtPoint(particle->pos); if (skyHeight >= MAX_ATMOSPHERIC_HEIGHT) { return qfalse; } groundHeight = BG_GetSkyGroundHeightAtPoint(particle->pos); if (groundHeight + particle->height + ATMOSPHERIC_PARTICLE_OFFSET >= skyHeight) { return qfalse; } particle->pos[2] = groundHeight + random() * (skyHeight - groundHeight); // make sure it doesn't fall from too far cause it then will go over our heads ('lower the ceiling') if (cg_atmFx.baseHeightOffset > 0) { if (particle->pos[2] - cg.refdef_current->vieworg[2] > cg_atmFx.baseHeightOffset) { particle->pos[2] = cg.refdef_current->vieworg[2] + cg_atmFx.baseHeightOffset; if (particle->pos[2] < groundHeight) { return qfalse; } } } // rain goes in bursts - allow max raindrops every 10 seconds if (cg_atmFx.oldDropsActive > (0.50 * cg_atmFx.numDrops + 0.001 * cg_atmFx.numDrops * (10000 - (cg.time % 10000)))) { return qfalse; } CG_SetParticleActive(particle, ACT_FALLING); particle->colour[0] = 0.6 + 0.2 * random() * 0xFF; particle->colour[1] = 0.6 + 0.2 * random() * 0xFF; particle->colour[2] = 0.6 + 0.2 * random() * 0xFF; VectorCopy(currvec, particle->delta); particle->delta[2] += crandom() * 100; VectorCopy(particle->delta, particle->deltaNormalized); VectorNormalizeFast(particle->deltaNormalized); particle->height = ATMOSPHERIC_RAIN_HEIGHT + crandom() * 100; particle->weight = currweight; particle->effectshader = &cg_atmFx.effectshaders[0]; //particle->effectshader = &cg_atmFx.effectshaders[ (int) (random() * ( cg_atmFx.numEffectShaders - 1 )) ]; return qtrue; }
static qboolean CG_SnowParticleGenerate( cg_atmosphericParticle_t *particle, vec3_t currvec, float currweight ) { // Attempt to 'spot' a snowflake somewhere below a sky texture. float angle, distance; float groundHeight, skyHeight; // int msec = trap_Milliseconds(); // n_generatetime++; angle = random() * 2 * M_PI; distance = 20 + MAX_ATMOSPHERIC_DISTANCE * random(); particle->pos[0] = cg.refdef.vieworg[0] + sin( angle ) * distance; particle->pos[1] = cg.refdef.vieworg[1] + cos( angle ) * distance; // ydnar: choose a spawn point randomly between sky and ground skyHeight = BG_GetSkyHeightAtPoint( particle->pos ); if ( skyHeight == MAX_ATMOSPHERIC_HEIGHT ) { return qfalse; } groundHeight = BG_GetSkyGroundHeightAtPoint( particle->pos ); if ( groundHeight >= skyHeight ) { return qfalse; } particle->pos[2] = groundHeight + random() * ( skyHeight - groundHeight ); // make sure it doesn't fall from too far cause it then will go over our heads ('lower the ceiling') if ( cg_atmFx.baseHeightOffset > 0 ) { if ( particle->pos[2] - cg.refdef.vieworg[2] > cg_atmFx.baseHeightOffset ) { particle->pos[2] = cg.refdef.vieworg[2] + cg_atmFx.baseHeightOffset; if ( particle->pos[2] < groundHeight ) { return qfalse; } } } CG_SetParticleActive( particle, ACT_FALLING ); VectorCopy( currvec, particle->delta ); particle->delta[2] += crandom() * 25; VectorCopy( particle->delta, particle->deltaNormalized ); VectorNormalizeFast( particle->deltaNormalized ); particle->height = ATMOSPHERIC_SNOW_HEIGHT + random() * 2; particle->weight = particle->height * 0.5f; if (cg_atmFx.numEffectShaders > 1) { particle->effectshader = &cg_atmFx.effectshaders[ rand()%cg_atmFx.numEffectShaders ]; } else { particle->effectshader = &cg_atmFx.effectshaders[0]; } // generatetime += trap_Milliseconds() - msec; return( qtrue ); }
/** * @brief Generate a snowflake * @details Attempt to 'spot' a snowflake somewhere below a sky texture. */ static qboolean CG_SnowParticleGenerate(cg_atmosphericParticle_t *particle, vec3_t currvec, float currweight) { float angle = random() * 2 * M_PI, distance = 20 + MAX_ATMOSPHERIC_DISTANCE * random(); float groundHeight, skyHeight; particle->pos[0] = cg.refdef_current->vieworg[0] + sin(angle) * distance; particle->pos[1] = cg.refdef_current->vieworg[1] + cos(angle) * distance; // choose a spawn point randomly between sky and ground skyHeight = BG_GetSkyHeightAtPoint(particle->pos); if (skyHeight >= MAX_ATMOSPHERIC_HEIGHT) { return qfalse; } groundHeight = BG_GetSkyGroundHeightAtPoint(particle->pos); if (groundHeight + particle->height + ATMOSPHERIC_PARTICLE_OFFSET >= skyHeight) { return qfalse; } particle->pos[2] = groundHeight + random() * (skyHeight - groundHeight); // make sure it doesn't fall from too far cause it then will go over our heads ('lower the ceiling') if (cg_atmFx.baseHeightOffset > 0) { if (particle->pos[2] - cg.refdef_current->vieworg[2] > cg_atmFx.baseHeightOffset) { particle->pos[2] = cg.refdef_current->vieworg[2] + cg_atmFx.baseHeightOffset; if (particle->pos[2] < groundHeight) { return qfalse; } } } CG_SetParticleActive(particle, ACT_FALLING); VectorCopy(currvec, particle->delta); particle->delta[2] += crandom() * 25; VectorCopy(particle->delta, particle->deltaNormalized); VectorNormalizeFast(particle->deltaNormalized); particle->height = ATMOSPHERIC_SNOW_HEIGHT + random() * 2; particle->weight = particle->height * 0.5f; particle->effectshader = &cg_atmFx.effectshaders[0]; //particle->effectshader = &cg_atmFx.effectshaders[ (int) (random() * ( cg_atmFx.numEffectShaders - 1 )) ]; return qtrue; }
static qboolean CG_RainParticleGenerate( cg_atmosphericParticle_t *particle, vec3_t currvec, float currweight ) { // Attempt to 'spot' a raindrop somewhere below a sky texture. float angle, distance; float groundHeight, skyHeight; // int msec = trap_Milliseconds(); // n_generatetime++; angle = random() * 2*M_PI; distance = 20 + MAX_ATMOSPHERIC_DISTANCE * random(); particle->pos[0] = cg.refdef_current->vieworg[0] + sin(angle) * distance; particle->pos[1] = cg.refdef_current->vieworg[1] + cos(angle) * distance; // ydnar: choose a spawn point randomly between sky and ground skyHeight = BG_GetSkyHeightAtPoint( particle->pos ); if( skyHeight == MAX_ATMOSPHERIC_HEIGHT ) return qfalse; groundHeight = BG_GetSkyGroundHeightAtPoint( particle->pos ); if( groundHeight >= skyHeight ) return qfalse; particle->pos[2] = groundHeight + random() * (skyHeight - groundHeight); // make sure it doesn't fall from too far cause it then will go over our heads ('lower the ceiling') if( cg_atmFx.baseHeightOffset > 0 ) { if( particle->pos[2] - cg.refdef_current->vieworg[2] > cg_atmFx.baseHeightOffset ) { particle->pos[2] = cg.refdef_current->vieworg[2] + cg_atmFx.baseHeightOffset; if( particle->pos[2] < groundHeight ) { return qfalse; } } } // ydnar: rain goes in bursts { float maxActiveDrops; // every 10 seconds allow max raindrops maxActiveDrops = 0.50 * cg_atmFx.numDrops + 0.001 * cg_atmFx.numDrops * (10000 - (cg.time % 10000)); if( cg_atmFx.oldDropsActive > maxActiveDrops ) return qfalse; } CG_SetParticleActive( particle, ACT_FALLING ); particle->colour[0] = 0.6 + 0.2 * random() * 0xFF; particle->colour[1] = 0.6 + 0.2 * random() * 0xFF; particle->colour[2] = 0.6 + 0.2 * random() * 0xFF; VectorCopy( currvec, particle->delta ); particle->delta[2] += crandom() * 100; VectorCopy( particle->delta, particle->deltaNormalized ); VectorNormalizeFast( particle->deltaNormalized ); particle->height = ATMOSPHERIC_RAIN_HEIGHT + crandom() * 100; particle->weight = currweight; particle->effectshader = &cg_atmFx.effectshaders[0]; // particle->effectshader = &cg_atmFx.effectshaders[ (int) (random() * ( cg_atmFx.numEffectShaders - 1 )) ]; // generatetime += trap_Milliseconds() - msec; return( qtrue ); }