1 // pt_lights.cxx -- build a 'directional' light on the fly
3 // Written by Curtis Olson, started March 2002.
5 // Copyright (C) 2002 Curtis L. Olson - curt@flightgear.org
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include "pt_lights.hxx"
32 // Generate a directional light
33 ssgLeaf *gen_directional_light( sgVec3 pt, sgVec3 dir, sgVec3 up,
34 const string &material ) {
36 // calculate a vector perpendicular to dir and up
38 sgVectorProductVec3( perp, dir, up );
40 ssgVertexArray *vl = new ssgVertexArray( 3 );
41 ssgNormalArray *nl = new ssgNormalArray( 1 );
42 ssgColourArray *cl = new ssgColourArray( 1 );
46 sgCopyVec3( tmp3, pt );
48 sgAddVec3( tmp3, up );
50 sgAddVec3( tmp3, perp );
52 // sgSubVec3( tmp3, up );
61 sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
63 sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
69 // temporarily do back face
70 sgCopyVec3( tmp3, pt );
72 sgAddVec3( tmp3, up );
74 sgAddVec3( tmp3, perp );
82 sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
84 sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
89 /* ssgTexCoordArray *tl = new ssgTexCoordArray( 4 );
91 sgSetVec2( tmp2, 0.0, 0.0 );
93 sgSetVec2( tmp2, 1.0, 0.0 );
95 sgSetVec2( tmp2, 1.0, 1.0 );
97 sgSetVec2( tmp2, 0.0, 1.0 );
101 new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
103 FGNewMat *newmat = material_lib.find( material );
105 if ( newmat != NULL ) {
106 leaf->setState( newmat->get_state() );
108 SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: can't material = "
116 ssgLeaf *gen_dir_light_group( const point_list &nodes,
117 const point_list &normals,
118 const int_list &pnt_i,
119 const int_list &nml_i,
120 const string &material,
124 sgNormalizeVec3( nup, up );
126 ssgVertexArray *vl = new ssgVertexArray( 3 );
127 ssgNormalArray *nl = new ssgNormalArray( 3 );
128 ssgColourArray *cl = new ssgColourArray( 3 );
132 for ( i = 0; i < pnt_i.size(); ++i ) {
133 sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
134 nodes[pnt_i[i]][2] );
135 sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1],
136 normals[nml_i[i]][2] );
138 // calculate a vector perpendicular to dir and up
140 sgVectorProductVec3( perp, normal, nup );
144 sgCopyVec3( tmp3, pt );
146 sgAddVec3( tmp3, nup );
148 sgAddVec3( tmp3, perp );
150 // sgSubVec3( tmp3, nup );
156 // nl->add( normal );
159 sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
161 sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
168 new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
170 FGNewMat *newmat = material_lib.find( material );
172 if ( newmat != NULL ) {
173 leaf->setState( newmat->get_state() );
175 SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: can't material = "
183 ssgTimedSelector *gen_reil_lights( const point_list &nodes,
184 const point_list &normals,
185 const int_list &pnt_i,
186 const int_list &nml_i,
187 const string &material,
191 sgNormalizeVec3( nup, up );
193 ssgVertexArray *vl = new ssgVertexArray( 6 );
194 ssgNormalArray *nl = new ssgNormalArray( 6 );
195 ssgColourArray *cl = new ssgColourArray( 6 );
199 for ( i = 0; i < pnt_i.size(); ++i ) {
200 sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
201 nodes[pnt_i[i]][2] );
202 sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1],
203 normals[nml_i[i]][2] );
205 // calculate a vector perpendicular to dir and up
207 sgVectorProductVec3( perp, normal, nup );
211 sgCopyVec3( tmp3, pt );
213 sgAddVec3( tmp3, nup );
215 sgAddVec3( tmp3, perp );
217 // sgSubVec3( tmp3, nup );
223 // nl->add( normal );
226 sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
228 sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
235 new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
237 FGNewMat *newmat = material_lib.find( "RWY_WHITE_LIGHTS" );
239 if ( newmat != NULL ) {
240 leaf->setState( newmat->get_state() );
242 SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: can't material = "
246 ssgTimedSelector *reil = new ssgTimedSelector;
248 // need to add this twice to work around an ssg bug
249 reil->addKid( leaf );
250 reil->addKid( leaf );
252 reil->setDuration( 60 );
253 reil->setLimits( 0, 2 );
254 reil->setMode( SSG_ANIM_SHUTTLE );
255 reil->control( SSG_ANIM_START );
261 ssgTimedSelector *gen_rabbit_lights( const point_list &nodes,
262 const point_list &normals,
263 const int_list &pnt_i,
264 const int_list &nml_i,
265 const string &material,
271 sgNormalizeVec3( nup, up );
273 ssgTimedSelector *rabbit = new ssgTimedSelector;
277 for ( i = (int)pnt_i.size() - 1; i >= 0; --i ) {
278 ssgVertexArray *vl = new ssgVertexArray( 3 );
279 ssgNormalArray *nl = new ssgNormalArray( 3 );
280 ssgColourArray *cl = new ssgColourArray( 3 );
282 sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
283 nodes[pnt_i[i]][2] );
284 cout << "nml_i[" << i << "] = " << nml_i[i] << endl;
286 sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1],
287 normals[nml_i[i]][2] );
289 // calculate a vector perpendicular to dir and up
291 sgVectorProductVec3( perp, normal, nup );
295 sgCopyVec3( tmp3, pt );
297 sgAddVec3( tmp3, nup );
299 sgAddVec3( tmp3, perp );
301 // sgSubVec3( tmp3, nup );
307 // nl->add( normal );
310 sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
312 sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
318 new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
320 FGNewMat *newmat = material_lib.find( "RWY_WHITE_LIGHTS" );
322 if ( newmat != NULL ) {
323 leaf->setState( newmat->get_state() );
325 SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: can't material = "
329 rabbit->addKid( leaf );
331 // ssg bug where first entry in animation is ignored.
332 rabbit->addKid( leaf );
337 rabbit->setDuration( 10 );
338 rabbit->setLimits( 0, pnt_i.size() + 1 );
339 rabbit->setMode( SSG_ANIM_SHUTTLE );
340 rabbit->control( SSG_ANIM_START );
346 // Generate a directional light
347 ssgLeaf *gen_normal_line( sgVec3 pt, sgVec3 dir, sgVec3 up ) {
349 ssgVertexArray *vl = new ssgVertexArray( 3 );
350 ssgNormalArray *nl = new ssgNormalArray( 1 );
351 ssgColourArray *cl = new ssgColourArray( 1 );
354 sgCopyVec3( tmp3, pt );
356 sgAddVec3( tmp3, dir );
360 sgSetVec4( color, 1.0, 0.0, 0.0, 1.0 );
365 new ssgVtxTable ( GL_LINES, vl, NULL, NULL, cl );
367 FGNewMat *newmat = material_lib.find( "GROUND_LIGHTS" );
368 leaf->setState( newmat->get_state() );
374 ssgBranch *gen_directional_lights( const point_list &nodes,
375 const point_list &normals,
376 const int_list &pnt_i,
377 const int_list &nml_i,
378 const string &material,
381 ssgBranch *result = new ssgBranch;
384 sgNormalizeVec3( nup, up );
386 if ( material == "RWY_REIL_LIGHTS" ) {
387 cout << "found a reil" << endl;
388 ssgTimedSelector *reil = gen_reil_lights( nodes, normals, pnt_i, nml_i,
390 result->addKid( reil );
391 } else if ( material == "RWY_SEQUENCED_LIGHTS" ) {
392 cout << "found a rabbit" << endl;
393 ssgTimedSelector *rabbit = gen_rabbit_lights( nodes, normals,
396 result->addKid( rabbit );
398 ssgLeaf *light_group = gen_dir_light_group( nodes, normals, pnt_i,
399 nml_i, material, up );
400 result->addKid( light_group );