-
-
-// definition of a cu cloud, only for testing
-void SGNewCloud::new_cu(void) {
- float s = 150.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 = 475.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
-}
-
-
-
-
-/*
-Public Sub drawContainers()
- Dim N As Integer, i As Integer
- N = UBound(tbSpriteCont())
-
- Call glPolygonMode(faceFrontAndBack, pgmLine)
-
- Call glColor3f(0.9, 0.9, 0.9)
-
- For i = 0 To N - 1
- With tbSpriteCont(i)
- Call glPushMatrix
- Call glTranslatef(.x * c_scale + cloudpos(0), .y * c_scale + cloudpos(1), .z * c_scale + cloudpos(2))
- Call gCtl.Shapes.box(.r * c_scale, .r * c_scale, .r * c_scale)
- Call glPopMatrix
- End With
- Next i
-If 0 Then
- Call glPushMatrix
- Call glTranslatef(ccenter(0), ccenter(1), ccenter(2))
- Call gCtl.Shapes.Sphere(cradius, 8, 8)
- Call glPopMatrix
-End If
-End Sub
-*/
-void SGNewCloud::drawContainers() {
-
-
-}
-
-
-/*
-*/
-
-//bool SGNewCloud::compareSpriteFunction(const spriteDef &a, const spriteDef &b) {
-// return (a.dist > b.dist);
-//}
-
-// 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]);
- }
- 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;*/
-
-
- 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
- // TODO:use cloudfield vis, not hardcoded value
- float t = 1.0f - dist_center / (15000.0f * 2.0 );
- 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();
-
- }
-}
-
-
-// compute rotations so that a quad is facing the camera
-// TODO:change obsolete code because we dont use glrotate anymore
-void SGNewCloud::CalcAngles(sgVec3 refpos, sgVec3 FakeEyePos, float *angleY, float *angleX) {
- sgVec3 upAux, lookAt, objToCamProj, objToCam;
- float angle, angle2;
-
- sgSetVec3(objToCamProj, -FakeEyePos[SG_X] + refpos[SG_X], -FakeEyePos[SG_Z] + refpos[SG_Z], 0.0f);
- sgNormaliseVec3(objToCamProj);
-
- sgSetVec3(lookAt, 0.0f, 1.0f, 0.0f);
- sgVectorProductVec3(upAux, lookAt, objToCamProj);
- angle = sgScalarProductVec3(lookAt, objToCamProj);
- if( (angle < 0.9999f) && (angle > -0.9999f) ) {
- angle = acos(angle) * 180.0f / SG_PI;
- if( upAux[2] < 0.0f )
- angle = -angle;
- } else
- angle = 0.0f;
-
- sgSetVec3(objToCam, -FakeEyePos[SG_X] + refpos[SG_X], -FakeEyePos[SG_Z] + refpos[SG_Z], -FakeEyePos[SG_Y] + refpos[SG_Y]);
- sgNormaliseVec3(objToCam);
-
- angle2 = sgScalarProductVec3(objToCamProj, objToCam);
- if( (angle2 < 0.9999f) && (angle2 > -0.9999f) ) {
- angle2 = -acos(angle2) * 180.0f / SG_PI;
- if( objToCam[2] > 0.0f )
- angle2 = -angle2;
- } else
- angle2 = 0.0f;
-
- angle2 += 90.0f;
-
- *angleY = angle;
- *angleX = angle2;
-}
-
-// draw a cloud but this time we use the impostor texture
-void SGNewCloud::RenderBB(sgVec3 deltaPos, float angleY, float angleX, float dist_center) {
- // TODO:glrotate is not needed
- glPushMatrix();
- glTranslatef(center[SG_X] - deltaPos[SG_X], center[SG_Z] - deltaPos[SG_Z], center[SG_Y] - deltaPos[SG_Y]);
- glRotatef(angleY, 0.0f, 0.0f, 1.0f);
- glRotatef(angleX, 1.0f, 0.0f, 0.0f);
-
- // blend clouds with sky based on distance to limit the contrast of distant cloud
- // TODO:use cloudfield vis, not hardcoded value
- float t = 1.0f - dist_center / (15000.0f * 2.0 );
- // err the alpha value is not good for impostor, debug that
- t *= 1.65;
- if ( t < 0.0f )
- t = 0.0f;
-
- glColor4f(t, t, t, t);
- float r = radius;
- glBegin(GL_QUADS);
- glTexCoord2f(0.0f, 1.0f);
- glVertex2f(-r, r);
- glTexCoord2f(1.0f, 1.0f);
- glVertex2f(r, r);
- glTexCoord2f(1.0f, 0.0f);
- glVertex2f(r, -r);
- glTexCoord2f(0.0f, 0.0f);
- glVertex2f(-r, -r);
- glEnd();
-
-#if 1 // debug only
- int age = cldCache->queryImpostorAge(bbId);
- // draw a red border for the newly generated BBs else draw a white border
- if( age < 200 )
- glColor3f(1, 0, 0);
- else
- glColor3f(1, 1, 1);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glBegin(GL_QUADS);
- glVertex2f(-r, -r);
- glVertex2f(r, -r);
- glVertex2f(r, r);
- glVertex2f(-r, r);
- glEnd();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-