]> git.mxchange.org Git - simgear.git/blob - simgear/sky/cloud.cxx
Updating cloud code.
[simgear.git] / simgear / sky / cloud.cxx
1 // cloud.cxx -- model a single cloud layer
2 //
3 // Written by Curtis Olson, started June 2000.
4 //
5 // Copyright (C) 2000  Curtis L. Olson  - curt@flightgear.org
6 //
7 // This program is distributed in the hope that it will be useful, but
8 // WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // General Public License for more details.
11 //
12 // You should have received a copy of the GNU General Public License
13 // along with this program; if not, write to the Free Software
14 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 //
16 // $Id$
17
18
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include <stdio.h>
24 #include <iostream>
25
26 #include <plib/ssg.h>
27
28 #include <simgear/constants.h>
29 #include <simgear/math/fg_random.h>
30 #include <simgear/math/point3d.hxx>
31 #include <simgear/math/polar3d.hxx>
32
33 #include "cloud.hxx"
34
35
36 // Constructor
37 SGCloudLayer::SGCloudLayer( void ) {
38 }
39
40
41 // Destructor
42 SGCloudLayer::~SGCloudLayer( void ) {
43 }
44
45
46 // build the moon object
47 void SGCloudLayer::build( FGPath path, double s, double asl, double thickness,
48                           double transition )
49 {
50     scale = 2000.0;
51
52     layer_asl = asl;
53     layer_thickness = thickness;
54     layer_transition = transition;
55
56     size = s;
57     last_lon = last_lat = -999.0f;
58
59     // set up the cloud state
60     path.append( "cloud.rgba" );
61     layer_state = new ssgSimpleState();
62     layer_state->setTexture( (char *)path.c_str() );
63     layer_state->setShadeModel( GL_SMOOTH );
64     layer_state->disable( GL_LIGHTING );
65     layer_state->disable( GL_CULL_FACE );
66     layer_state->enable( GL_TEXTURE_2D );
67     layer_state->enable( GL_COLOR_MATERIAL );
68     layer_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
69     layer_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
70     layer_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
71     layer_state->enable( GL_BLEND );
72     layer_state->enable( GL_ALPHA_TEST );
73     layer_state->setAlphaClamp( 0.01 );
74
75     cl = new ssgColourArray( 4 );
76     vl = new ssgVertexArray( 4 );
77     tl = new ssgTexCoordArray( 4 );
78
79     // build the cloud layer
80     sgVec4 color;
81     sgVec3 vertex;
82     sgVec2 tc;
83     sgSetVec4( color, 1.0f, 1.0f, 1.0f, 1.0f );
84
85     sgSetVec3( vertex, -size, -size, 0.0f );
86     sgVec2 base;
87     sgSetVec2( base, fg_random(), fg_random() );
88     sgSetVec2( tc, base[0], base[1] );
89     cl->add( color );
90     vl->add( vertex );
91     tl->add( tc );
92
93     sgSetVec3( vertex, size, -size, 0.0f );
94     sgSetVec2( tc, base[0] + size / scale, base[1] );
95     cl->add( color );
96     vl->add( vertex );
97     tl->add( tc );
98
99     sgSetVec3( vertex, -size, size, 0.0f );
100     sgSetVec2( tc, base[0], base[1] + size / scale );
101     cl->add( color );
102     vl->add( vertex );
103     tl->add( tc );
104
105     sgSetVec3( vertex, size, size, 0.0f );
106     sgSetVec2( tc, base[0] + size / scale, base[1] + size / scale );
107     cl->add( color );
108     vl->add( vertex );
109     tl->add( tc );
110
111     ssgLeaf *layer = 
112         new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, NULL, tl, cl );
113     layer->setState( layer_state );
114
115     // force a repaint of the moon colors with arbitrary defaults
116     repaint( color );
117
118     // build the ssg scene graph sub tree for the sky and connected
119     // into the provide scene graph branch
120     layer_transform = new ssgTransform;
121
122     // moon_transform->addKid( halo );
123     layer_transform->addKid( layer );
124
125     layer_root = new ssgRoot;
126     layer_root->addKid( layer_transform );
127 }
128
129
130 // repaint the cloud layer colors
131 bool SGCloudLayer::repaint( sgVec3 fog_color ) {
132     float *color;
133
134     for ( int i = 0; i < 4; ++i ) {
135         color = cl->get( i );
136         sgCopyVec4( color, fog_color );
137     }
138
139     return true;
140 }
141
142
143 // reposition the cloud layer at the specified origin and orientation
144 // lon specifies a rotation about the Z axis
145 // lat specifies a rotation about the new Y axis
146 // spin specifies a rotation about the new Z axis (and orients the
147 // sunrise/set effects
148 bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat,
149                                double alt )
150 {
151     sgMat4 T1, LON, LAT;
152     sgVec3 axis;
153
154     // combine p and asl (meters) to get translation offset
155     sgVec3 asl_offset;
156     sgCopyVec3( asl_offset, up );
157     sgNormalizeVec3( asl_offset );
158     if ( alt <= layer_asl ) {
159         sgScaleVec3( asl_offset, layer_asl );
160     } else {
161         sgScaleVec3( asl_offset, layer_asl + layer_thickness );
162     }
163     // cout << "asl_offset = " << asl_offset[0] << "," << asl_offset[1]
164     //      << "," << asl_offset[2] << endl;
165     sgAddVec3( asl_offset, p );
166     // cout << "  asl_offset = " << asl_offset[0] << "," << asl_offset[1]
167     //      << "," << asl_offset[2] << endl;
168
169     // Translate to zero elevation
170     // Point3D zero_elev = current_view.get_cur_zero_elev();
171     // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
172     sgMakeTransMat4( T1, asl_offset );
173
174     // printf("  Translated to %.2f %.2f %.2f\n", 
175     //        zero_elev.x, zero_elev.y, zero_elev.z );
176
177     // Rotate to proper orientation
178     // printf("  lon = %.2f  lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
179     //        FG_Latitude * RAD_TO_DEG);
180     // xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
181     sgSetVec3( axis, 0.0, 0.0, 1.0 );
182     sgMakeRotMat4( LON, lon * RAD_TO_DEG, axis );
183
184     // xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
185     sgSetVec3( axis, 0.0, 1.0, 0.0 );
186     sgMakeRotMat4( LAT, 90.0 - lat * RAD_TO_DEG, axis );
187
188     sgMat4 TRANSFORM;
189
190     sgCopyMat4( TRANSFORM, T1 );
191     sgPreMultMat4( TRANSFORM, LON );
192     sgPreMultMat4( TRANSFORM, LAT );
193
194     sgCoord layerpos;
195     sgSetCoord( &layerpos, TRANSFORM );
196
197     layer_transform->setTransform( &layerpos );
198
199     // now calculate update texture coordinates
200     if ( last_lon < -900 ) {
201         last_lon = lon;
202         last_lat = lat;
203     }
204
205     if ( lon != last_lon || lat != last_lat ) {
206         Point3D start( last_lon, last_lat, 0.0 );
207         Point3D dest( lon, lat, 0.0 );
208         double course, dist;
209         calc_gc_course_dist( dest, start, &course, &dist );
210         // cout << "course = " << course << ", dist = " << dist << endl;
211
212         double xoff = cos( course ) * dist / (2 * scale);
213         double yoff = sin( course ) * dist / (2 * scale);
214
215         // cout << "xoff = " << xoff << ", yoff = " << yoff << endl;
216
217         float *base, *tc;
218         base = tl->get( 0 );
219
220         base[0] += xoff;
221         while ( base[0] > 1.0 ) { base[0] -= 1.0; }
222         while ( base[0] < 0.0 ) { base[0] += 1.0; }
223
224         base[1] += yoff;
225         while ( base[1] > 1.0 ) { base[1] -= 1.0; }
226         while ( base[1] < 0.0 ) { base[1] += 1.0; }
227
228         // cout << "base = " << base[0] << "," << base[1] << endl;
229
230         tc = tl->get( 1 );
231         sgSetVec2( tc, base[0] + size / scale, base[1] );
232  
233         tc = tl->get( 2 );
234         sgSetVec2( tc, base[0], base[1] + size / scale );
235  
236         tc = tl->get( 3 );
237         sgSetVec2( tc, base[0] + size / scale, base[1] + size / scale );
238  
239         last_lon = lon;
240         last_lat = lat;
241     }
242
243     return true;
244 }
245
246
247 void SGCloudLayer::draw() {
248     ssgCullAndDraw( layer_root );
249 }