- return n * (-0.5f + sg_random());
-}
-
-// generate all sprite with defined boxes
-void SGNewCloud::genSprites( void ) {
- float x, y, z, r;
- int N, sc;
- N = list_spriteContainer.size();
- for(int i = 0 ; i < N ; i++ ) {
- spriteContainer *thisBox = & list_spriteContainer[i];
- // the type defines how the sprites can be positioned inside the box, their size, etc
- switch(thisBox->cont_type) {
- case CLbox_sc:
- for( sc = 0 ; sc <= 4 ; sc ++ ) {
- r = thisBox->r + Rnd(0.2f);
- x = thisBox->pos[SG_X] + Rnd(thisBox->r);
- y = thisBox->pos[SG_Y] + Rnd(thisBox->r * 0.2f);
- z = thisBox->pos[SG_Z] + Rnd(thisBox->r);
- addSprite(x, y, z, r, thisBox->cont_type, i);
- }
- break;
- case CLbox_stratus:
- sc = 1;
- r = thisBox->r;
- x = thisBox->pos[SG_X];
- y = thisBox->pos[SG_Y];
- z = thisBox->pos[SG_Z];
- addSprite(x, y, z, r, thisBox->cont_type, i);
- break;
- case CLbox_cumulus:
- for( sc = 0 ; sc <= 4 ; sc ++ ) {
- r = thisBox->r + Rnd(0.2f);
- x = thisBox->pos[SG_X] + Rnd(thisBox->r * 0.75f);
- y = thisBox->pos[SG_Y] + Rnd(thisBox->r * 0.5f);
- z = thisBox->pos[SG_Z] + Rnd(thisBox->r * 0.75f);
- if ( y < thisBox->pos[SG_Y] - thisBox->r / 10.0f )
- y = thisBox->pos[SG_Y] - thisBox->r / 10.0f;
- addSprite(x, y, z, r, thisBox->cont_type, i);
- }
- break;
- default:
- for( sc = 0 ; sc <= 4 ; sc ++ ) {
- r = thisBox->r + Rnd(0.2f);
- x = thisBox->pos[SG_X] + Rnd(thisBox->r);
- y = thisBox->pos[SG_Y] + Rnd(thisBox->r);
- z = thisBox->pos[SG_Z] + Rnd(thisBox->r);
- addSprite(x, y, z, r, thisBox->cont_type, i);
- }
- break;
- }
- sgScaleVec3(thisBox->center, 1.0f / sc);
- }
-
- radius = maxx - minx;
- if ( (maxy - miny) > radius )
- radius = (maxy - miny);
- if ( (maxz - minz) > radius )
- radius = (maxz - minz);
- radius /= 2.0f;
- sgSetVec3( center, (maxx + minx) / 2.0f, (maxy + miny) / 2.0f, (maxz + minz) / 2.0f );
-
-/* fadingrank = 0
-' fadingrank = UBound(tbSpriteDef()) * 10
- fadingdir = 0*/
- // TODO : compute initial sprite normals for lighting function
-}
-
-
-// definition of a cu cloud, only for testing
-void SGNewCloud::new_cu(void) {
- float s = 250.0f;
- float r = Rnd(1.0) + 0.5;
- if( r < 0.5f ) {
- addContainer(0.0f, 0.0f, 0.0f, s, CLbox_cumulus);
- addContainer(s, 0, 0, s, CLbox_cumulus);
- addContainer(0, 0, 2 * s, s, CLbox_cumulus);
- addContainer(s, 0, 2 * s, s, CLbox_cumulus);
-
- addContainer(-1.2f * s, 0.2f * s, s, s * 1.4f, CLbox_cumulus);
- addContainer(0.2f * s, 0.2f * s, s, s * 1.4f, CLbox_cumulus);
- addContainer(1.6f * s, 0.2f * s, s, s * 1.4f, CLbox_cumulus);
- } else if ( r < 0.90f ) {
- addContainer(0, 0, 0, s * 1.2, CLbox_cumulus);
- addContainer(s, 0, 0, s, CLbox_cumulus);
- addContainer(0, 0, s, s, CLbox_cumulus);
- addContainer(s * 1.1, 0, s, s * 1.2, CLbox_cumulus);
-
- addContainer(-1.2 * s, 1 + 0.2 * s, s * 0.5, s * 1.4, CLbox_standard);
- addContainer(0.2 * s, 1 + 0.25 * s, s * 0.5, s * 1.5, CLbox_standard);
- addContainer(1.6 * s, 1 + 0.2 * s, s * 0.5, s * 1.4, CLbox_standard);
-
- } else {
- // cb
- s = 675.0f;
- addContainer(0, 0, 0, s, CLbox_cumulus);
- addContainer(0, 0, s, s, CLbox_cumulus);
- addContainer(s, 0, s, s, CLbox_cumulus);
- addContainer(s, 0, 0, s, CLbox_cumulus);
-
- addContainer(s / 2, s, s / 2, s * 1.5, CLbox_standard);
-
- addContainer(0, 2 * s, 0, s, CLbox_standard);
- addContainer(0, 2 * s, s, s, CLbox_standard);
- addContainer(s, 2 * s, s, s, CLbox_standard);
- addContainer(s, 2 * s, 0, s, CLbox_standard);
-
- }
- genSprites();
-}
-
-
-// define the new position of the cloud (inside the cloud field, not on sphere)
-void SGNewCloud::SetPos(sgVec3 newPos) {
- int N = list_spriteDef.size();
- sgVec3 deltaPos;
- sgSubVec3( deltaPos, newPos, cloudpos );
-
- // for each particle
- for(int i = 0 ; i < N ; i ++) {
- sgAddVec3( list_spriteDef[i].pos, deltaPos );
- }
- sgAddVec3( center, deltaPos );
- sgSetVec3( cloudpos, newPos[SG_X], newPos[SG_Y], newPos[SG_Z]);
- // TODO : recompute sprite normal so we don't have to redo that each frame
-}
-
-
-
-
-void SGNewCloud::drawContainers() {
-
-
-}
-
-
-
-// sort on distance to eye because of transparency
-void SGNewCloud::sortSprite( sgVec3 eye ) {
- list_of_spriteDef::iterator iSprite;
-
- // compute distance from sprite to eye
- for( iSprite = list_spriteDef.begin() ; iSprite != list_spriteDef.end() ; iSprite++ ) {
- sgVec3 dist;
- sgSubVec3( dist, iSprite->pos, eye );
- iSprite->dist = -(dist[0]*dist[0] + dist[1]*dist[1] + dist[2]*dist[2]);
- }
- std::sort( list_spriteDef.begin(), list_spriteDef.end() );
-}
-
-// render the cloud on screen or on the RTT texture to build the impostor
-void SGNewCloud::Render3Dcloud( bool drawBB, sgVec3 FakeEyePos, sgVec3 deltaPos, float dist_center ) {
-
-/* int clrank = fadingrank / 10;
- int clfadeinrank = fadingrank - clrank * 10;*/
- float CloudVisFade = 1.0 / (1.5 * SGCloudField::get_CloudVis());
-
- computeSimpleLight( FakeEyePos );
-
- // view point sort, we sort because of transparency
- sortSprite( FakeEyePos );
-
- GLint previousTexture = -1, thisTexture;
- list_of_spriteDef::iterator iSprite;
- for( iSprite = list_spriteDef.begin() ; iSprite != list_spriteDef.end() ; iSprite++ ) {
- // choose texture to use depending on sprite type
- switch(iSprite->sprite_type) {
- case CLbox_stratus:
- thisTexture = CLTexture_stratus;
- break;
- default:
- thisTexture = CLTexture_cumulus;
- break;
- }
- // in practice there is no texture switch (atm)
- if( previousTexture != thisTexture ) {
- previousTexture = thisTexture;
- glBindTexture(GL_TEXTURE_2D, cloudTextures[thisTexture]->getHandle());
- }
-
- sgVec3 translate;
- if( drawBB ) {
- sgCopyVec3( translate, iSprite->pos);
- sgSubVec3( translate, iSprite->pos, deltaPos );
- }
- else
- sgSubVec3( translate, iSprite->pos, deltaPos);
-
-
- // flipx and flipy are random texture flip flags, this gives more random clouds
- float flipx = (float) ( iSprite->rank & 1 );
- float flipy = (float) ( (iSprite->rank >> 1) & 1 );
- // cu texture have a flat bottom so we can't do a vertical flip
- if( iSprite->sprite_type == CLbox_cumulus || iSprite->sprite_type == CLbox_stratus )
- flipy = 0.0f;
- if( iSprite->sprite_type == CLbox_stratus )
- flipx = 0.0f;
- // adjust colors depending on cloud type
- // TODO : rewrite that later, still experimental
- switch(iSprite->sprite_type) {
- case CLbox_cumulus:
- // dark bottom
- sgScaleVec3(iSprite->l0, 0.6f);
- sgScaleVec3(iSprite->l1, 0.6f);
- break;
- case CLbox_stratus:
- // usually dark grey
- sgScaleVec3(iSprite->l0, 0.8f);
- sgScaleVec3(iSprite->l1, 0.8f);
- sgScaleVec3(iSprite->l2, 0.8f);
- sgScaleVec3(iSprite->l3, 0.8f);
- break;
- default:
- // darker bottom than top
- sgScaleVec3(iSprite->l0, 0.8f);
- sgScaleVec3(iSprite->l1, 0.8f);
- break;
- }
- float r = iSprite->r * 0.5f;
-
- sgVec4 l0, l1, l2, l3;
- sgCopyVec4 ( l0, iSprite->l0 );
- sgCopyVec4 ( l1, iSprite->l1 );
- sgCopyVec4 ( l2, iSprite->l2 );
- sgCopyVec4 ( l3, iSprite->l3 );
- if( ! drawBB ) {
- // blend clouds with sky based on distance to limit the contrast of distant cloud
- float t = 1.0f - dist_center * CloudVisFade;
- if ( t < 0.0f )
- t = 0.0f; // no, it should have been culled
- // now clouds at the far plane are half blended
- sgScaleVec4( l0, t );
- sgScaleVec4( l1, t );
- sgScaleVec4( l2, t );
- sgScaleVec4( l3, t );
- }
- // compute the rotations so that the quad is facing the camera
- sgVec3 pos;
- sgSetVec3( pos, translate[SG_X], translate[SG_Z], translate[SG_Y] );
- sgCopyVec3( translate, pos );
- sgNormaliseVec3( translate );
- sgVec3 x, y, up = {0.0f, 0.0f, 1.0f};
- sgVectorProductVec3(x, translate, up);
- sgNormaliseVec3(x);
- sgScaleVec3(x, r);
- sgVectorProductVec3(y, x, translate);
- sgNormaliseVec3(y);
- sgScaleVec3(y, r);
-
- sgVec3 left, right;
- if( drawBB )
- sgSetVec3( left, iSprite->pos[SG_X], iSprite->pos[SG_Z], iSprite->pos[SG_Y]);
- else
- sgCopyVec3( left, pos );
- sgSubVec3 (left, y);
- sgAddVec3 (right, left, x);
- sgSubVec3 (left, x);
-
- glBegin(GL_QUADS);
- glColor4fv(l0);
- glTexCoord2f(flipx, 1.0f - flipy);
- glVertex3fv(left);
- glColor4fv(l1);
- glTexCoord2f(1.0f - flipx, 1.0f - flipy);
- glVertex3fv(right);
- sgScaleVec3( y, 2.0 );
- sgAddVec3( left, y);
- sgAddVec3( right, y);
- glColor4fv(l2);
- glTexCoord2f(1.0f - flipx, flipy);
- glVertex3fv(right);
- glColor4fv(l3);
- glTexCoord2f(flipx, flipy);
- glVertex3fv(left);
-
- glEnd();
-
- }