1
0
Fork 0

Moved some of the low level scene graph construction code over to simgear.

This commit is contained in:
curt 2003-05-14 19:22:24 +00:00
parent e1f96243ec
commit 8dcf08c965
9 changed files with 27 additions and 1173 deletions

View file

@ -88,9 +88,9 @@ fgfs_LDADD = \
$(top_builddir)/src/Systems/libSystems.a \ $(top_builddir)/src/Systems/libSystems.a \
$(top_builddir)/src/Time/libTime.a \ $(top_builddir)/src/Time/libTime.a \
$(WEATHER_LIBS) \ $(WEATHER_LIBS) \
-lsgroute -lsgsky -lsgephem -lsgmaterial -lsgmodel -lsgtiming -lsgio \ -lsgroute -lsgsky -lsgephem -lsgmaterial -lsgtgdb -lsgmodel -lsgtiming \
-lsgscreen -lsgmath -lsgbucket -lsgprops -lsgdebug -lsgmagvar -lsgmisc \ -lsgio -lsgscreen -lsgmath -lsgbucket -lsgprops -lsgdebug -lsgmagvar \
-lsgxml -lsgsound -lsgserial \ -lsgmisc -lsgxml -lsgsound -lsgserial \
$(THREAD_LIBS) \ $(THREAD_LIBS) \
-lplibpu -lplibfnt -lplibjs -lplibnet -lplibssg -lplibsg -lplibul \ -lplibpu -lplibfnt -lplibjs -lplibnet -lplibssg -lplibsg -lplibul \
$(PSL_LIBS) \ $(PSL_LIBS) \

View file

@ -1,8 +1,6 @@
noinst_LIBRARIES = libObjects.a noinst_LIBRARIES = libObjects.a
libObjects_a_SOURCES = \ libObjects_a_SOURCES = \
apt_signs.cxx apt_signs.hxx \ obj.cxx obj.hxx
obj.cxx obj.hxx \
pt_lights.cxx pt_lights.hxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src

View file

@ -1,167 +0,0 @@
// apt_signs.cxx -- build airport signs on the fly
//
// Written by Curtis Olson, started July 2001.
//
// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_types.hxx>
#include "apt_signs.hxx"
#include "obj.hxx"
ssgBranch *gen_taxi_sign( SGMaterialLib *matlib,
const string path, const string content )
{
// for demo purposes we assume each element (letter) is 1x1 meter.
// Sign is placed 0.25 meters above the ground
ssgBranch *object = new ssgBranch();
object->setName( (char *)content.c_str() );
double offset = content.length() / 2.0;
for ( unsigned int i = 0; i < content.length(); ++i ) {
string material;
char item = content[i];
if ( item == '<' ) {
material = "ArrowL.rgb";
} else if ( item == '>' ) {
material = "ArrowR.rgb";
} else if ( item >= 'A' && item <= 'Z' ) {
material = "Letter";
material += item;
material += ".rgb";
} else if ( item >= 'a' && item <= 'z' ) {
int tmp = item - 'a';
char c = 'A' + tmp;
material = "Black";
material += c;
material += ".rgb";
} else {
SG_LOG( SG_TERRAIN, SG_ALERT,
"Unknown taxi sign code = '" << item << "' !!!!" );
return NULL;
}
point_list nodes; nodes.clear();
point_list normals; normals.clear();
point_list texcoords; texcoords.clear();
int_list vertex_index; vertex_index.clear();
int_list normal_index; normal_index.clear();
int_list tex_index; tex_index.clear();
nodes.push_back( Point3D( -offset + i, 0, 0.25 ) );
nodes.push_back( Point3D( -offset + i + 1, 0, 0.25 ) );
nodes.push_back( Point3D( -offset + i, 0, 1.25 ) );
nodes.push_back( Point3D( -offset + i + 1, 0, 1.25 ) );
normals.push_back( Point3D( 0, -1, 0 ) );
texcoords.push_back( Point3D( 0, 0, 0 ) );
texcoords.push_back( Point3D( 1, 0, 0 ) );
texcoords.push_back( Point3D( 0, 1, 0 ) );
texcoords.push_back( Point3D( 1, 1, 0 ) );
vertex_index.push_back( 0 );
vertex_index.push_back( 1 );
vertex_index.push_back( 2 );
vertex_index.push_back( 3 );
normal_index.push_back( 0 );
normal_index.push_back( 0 );
normal_index.push_back( 0 );
normal_index.push_back( 0 );
tex_index.push_back( 0 );
tex_index.push_back( 1 );
tex_index.push_back( 2 );
tex_index.push_back( 3 );
ssgLeaf *leaf = gen_leaf( path, GL_TRIANGLE_STRIP, matlib, material,
nodes, normals, texcoords,
vertex_index, normal_index, tex_index,
false, NULL );
object->addKid( leaf );
}
return object;
}
ssgBranch *gen_runway_sign( SGMaterialLib *matlib,
const string path, const string name )
{
// for demo purposes we assume each element (letter) is 1x1 meter.
// Sign is placed 0.25 meters above the ground
ssgBranch *object = new ssgBranch();
object->setName( (char *)name.c_str() );
double width = name.length() / 3.0;
string material = name + ".rgb";
point_list nodes; nodes.clear();
point_list normals; normals.clear();
point_list texcoords; texcoords.clear();
int_list vertex_index; vertex_index.clear();
int_list normal_index; normal_index.clear();
int_list tex_index; tex_index.clear();
nodes.push_back( Point3D( -width, 0, 0.25 ) );
nodes.push_back( Point3D( width + 1, 0, 0.25 ) );
nodes.push_back( Point3D( -width, 0, 1.25 ) );
nodes.push_back( Point3D( width + 1, 0, 1.25 ) );
normals.push_back( Point3D( 0, -1, 0 ) );
texcoords.push_back( Point3D( 0, 0, 0 ) );
texcoords.push_back( Point3D( 1, 0, 0 ) );
texcoords.push_back( Point3D( 0, 1, 0 ) );
texcoords.push_back( Point3D( 1, 1, 0 ) );
vertex_index.push_back( 0 );
vertex_index.push_back( 1 );
vertex_index.push_back( 2 );
vertex_index.push_back( 3 );
normal_index.push_back( 0 );
normal_index.push_back( 0 );
normal_index.push_back( 0 );
normal_index.push_back( 0 );
tex_index.push_back( 0 );
tex_index.push_back( 1 );
tex_index.push_back( 2 );
tex_index.push_back( 3 );
ssgLeaf *leaf = gen_leaf( path, GL_TRIANGLE_STRIP, matlib, material,
nodes, normals, texcoords,
vertex_index, normal_index, tex_index,
false, NULL );
object->addKid( leaf );
return object;
}

View file

@ -1,54 +0,0 @@
// apt_signs.hxx -- build airport signs on the fly
//
// Written by Curtis Olson, started July 2001.
//
// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _APT_SIGNS_HXX
#define _APT_SIGNS_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include STL_STRING
#include <plib/ssg.h> // plib include
class SGMaterialLib; // forward declaration
SG_USING_STD(string);
// Generate a taxi sign
ssgBranch *gen_taxi_sign( SGMaterialLib *matlib,
const string path, const string content );
// Generate a runway sign
ssgBranch *gen_runway_sign( SGMaterialLib *matlib,
const string path, const string name );
#endif // _APT_SIGNS_HXX

View file

@ -54,12 +54,14 @@
#include <simgear/misc/texcoord.hxx> #include <simgear/misc/texcoord.hxx>
#include <simgear/scene/material/mat.hxx> #include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx> #include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/tgdb/leaf.hxx>
#include <simgear/scene/tgdb/pt_lights.hxx>
#include <Main/globals.hxx> #include <Main/globals.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
#include <Time/light.hxx> #include <Time/light.hxx>
#include "pt_lights.hxx"
#include "obj.hxx" #include "obj.hxx"
SG_USING_STD(string); SG_USING_STD(string);
@ -229,48 +231,6 @@ static void random_pt_inside_tri( float *res,
} }
static void gen_random_surface_points( ssgLeaf *leaf, ssgVertexArray *lights,
double factor ) {
int tris = leaf->getNumTriangles();
if ( tris > 0 ) {
short int n1, n2, n3;
float *p1, *p2, *p3;
sgVec3 result;
// generate a repeatable random seed
p1 = leaf->getVertex( 0 );
unsigned int seed = (unsigned int)(fabs(p1[0]*100));
sg_srandom( seed );
for ( int i = 0; i < tris; ++i ) {
leaf->getTriangle( i, &n1, &n2, &n3 );
p1 = leaf->getVertex(n1);
p2 = leaf->getVertex(n2);
p3 = leaf->getVertex(n3);
double area = sgTriArea( p1, p2, p3 );
double num = area / factor;
// generate a light point for each unit of area
while ( num > 1.0 ) {
random_pt_inside_tri( result, p1, p2, p3 );
lights->add( result );
num -= 1.0;
}
// for partial units of area, use a zombie door method to
// create the proper random chance of a light being created
// for this triangle
if ( num > 0.0 ) {
if ( sg_random() <= num ) {
// a zombie made it through our door
random_pt_inside_tri( result, p1, p2, p3 );
lights->add( result );
}
}
}
}
}
/** /**
* User data for populating leaves when they come in range. * User data for populating leaves when they come in range.
*/ */
@ -719,152 +679,6 @@ gen_random_surface_objects (ssgLeaf *leaf,
// Scenery loaders. // Scenery loaders.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
ssgLeaf *gen_leaf( const string& path,
const GLenum ty,
SGMaterialLib *matlib, const string& material,
const point_list& nodes, const point_list& normals,
const point_list& texcoords,
const int_list& node_index,
const int_list& normal_index,
const int_list& tex_index,
const bool calc_lights, ssgVertexArray *lights )
{
double tex_width = 1000.0, tex_height = 1000.0;
ssgSimpleState *state = NULL;
float coverage = -1;
SGMaterial *mat = matlib->find( material );
if ( mat == NULL ) {
// see if this is an on the fly texture
string file = path;
string::size_type pos = file.rfind( "/" );
file = file.substr( 0, pos );
// cout << "current file = " << file << endl;
file += "/";
file += material;
// cout << "current file = " << file << endl;
if ( ! matlib->add_item( file ) ) {
SG_LOG( SG_TERRAIN, SG_ALERT,
"Ack! unknown usemtl name = " << material
<< " in " << path );
} else {
// locate our newly created material
mat = matlib->find( material );
if ( mat == NULL ) {
SG_LOG( SG_TERRAIN, SG_ALERT,
"Ack! bad on the fly material create = "
<< material << " in " << path );
}
}
}
if ( mat != NULL ) {
// set the texture width and height values for this
// material
tex_width = mat->get_xsize();
tex_height = mat->get_ysize();
state = mat->get_state();
coverage = mat->get_light_coverage();
// cout << "(w) = " << tex_width << " (h) = "
// << tex_width << endl;
} else {
coverage = -1;
}
sgVec2 tmp2;
sgVec3 tmp3;
sgVec4 tmp4;
int i;
// vertices
int size = node_index.size();
if ( size < 1 ) {
SG_LOG( SG_TERRAIN, SG_ALERT, "Woh! node list size < 1" );
exit(-1);
}
ssgVertexArray *vl = new ssgVertexArray( size );
Point3D node;
for ( i = 0; i < size; ++i ) {
node = nodes[ node_index[i] ];
sgSetVec3( tmp3, node[0], node[1], node[2] );
vl -> add( tmp3 );
}
// normals
Point3D normal;
ssgNormalArray *nl = new ssgNormalArray( size );
if ( normal_index.size() ) {
// object file specifies normal indices (i.e. normal indices
// aren't 'implied'
for ( i = 0; i < size; ++i ) {
normal = normals[ normal_index[i] ];
sgSetVec3( tmp3, normal[0], normal[1], normal[2] );
nl -> add( tmp3 );
}
} else {
// use implied normal indices. normal index = vertex index.
for ( i = 0; i < size; ++i ) {
normal = normals[ node_index[i] ];
sgSetVec3( tmp3, normal[0], normal[1], normal[2] );
nl -> add( tmp3 );
}
}
// colors
ssgColourArray *cl = new ssgColourArray( 1 );
sgSetVec4( tmp4, 1.0, 1.0, 1.0, 1.0 );
cl->add( tmp4 );
// texture coordinates
size = tex_index.size();
Point3D texcoord;
ssgTexCoordArray *tl = new ssgTexCoordArray( size );
if ( size == 1 ) {
texcoord = texcoords[ tex_index[0] ];
sgSetVec2( tmp2, texcoord[0], texcoord[1] );
sgSetVec2( tmp2, texcoord[0], texcoord[1] );
if ( tex_width > 0 ) {
tmp2[0] *= (1000.0 / tex_width);
}
if ( tex_height > 0 ) {
tmp2[1] *= (1000.0 / tex_height);
}
tl -> add( tmp2 );
} else if ( size > 1 ) {
for ( i = 0; i < size; ++i ) {
texcoord = texcoords[ tex_index[i] ];
sgSetVec2( tmp2, texcoord[0], texcoord[1] );
if ( tex_width > 0 ) {
tmp2[0] *= (1000.0 / tex_width);
}
if ( tex_height > 0 ) {
tmp2[1] *= (1000.0 / tex_height);
}
tl -> add( tmp2 );
}
}
ssgLeaf *leaf = new ssgVtxTable ( ty, vl, nl, tl, cl );
// lookup the state record
leaf->setState( state );
if ( calc_lights ) {
if ( coverage > 0.0 ) {
if ( coverage < 10000.0 ) {
SG_LOG(SG_INPUT, SG_ALERT, "Light coverage is "
<< coverage << ", pushing up to 10000");
coverage = 10000;
}
gen_random_surface_points(leaf, lights, coverage);
}
}
return leaf;
}
// Load an Binary obj file // Load an Binary obj file
bool fgBinObjLoad( const string& path, const bool is_base, bool fgBinObjLoad( const string& path, const bool is_base,
Point3D *center, Point3D *center,
@ -925,10 +739,10 @@ bool fgBinObjLoad( const string& path, const bool is_base,
} else { } else {
material = pt_materials[i]; material = pt_materials[i];
tex_index.clear(); tex_index.clear();
ssgLeaf *leaf = gen_leaf( path, GL_POINTS, matlib, material, ssgLeaf *leaf = sgMakeLeaf( path, GL_POINTS, matlib, material,
nodes, normals, texcoords, nodes, normals, texcoords,
pts_v[i], pts_n[i], tex_index, pts_v[i], pts_n[i], tex_index,
false, ground_lights ); false, ground_lights );
geometry->addKid( leaf ); geometry->addKid( leaf );
} }
} }
@ -952,10 +766,11 @@ bool fgBinObjLoad( const string& path, const bool is_base,
group_list const& tris_n = obj.get_tris_n(); group_list const& tris_n = obj.get_tris_n();
group_list const& tris_tc = obj.get_tris_tc(); group_list const& tris_tc = obj.get_tris_tc();
for ( i = 0; i < tris_v.size(); ++i ) { for ( i = 0; i < tris_v.size(); ++i ) {
ssgLeaf *leaf = gen_leaf( path, GL_TRIANGLES, matlib, tri_materials[i], ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLES, matlib,
nodes, normals, texcoords, tri_materials[i],
tris_v[i], tris_n[i], tris_tc[i], nodes, normals, texcoords,
is_base, ground_lights ); tris_v[i], tris_n[i], tris_tc[i],
is_base, ground_lights );
if ( use_random_objects ) { if ( use_random_objects ) {
SGMaterial *mat = matlib->find( tri_materials[i] ); SGMaterial *mat = matlib->find( tri_materials[i] );
@ -976,11 +791,11 @@ bool fgBinObjLoad( const string& path, const bool is_base,
group_list const& strips_n = obj.get_strips_n(); group_list const& strips_n = obj.get_strips_n();
group_list const& strips_tc = obj.get_strips_tc(); group_list const& strips_tc = obj.get_strips_tc();
for ( i = 0; i < strips_v.size(); ++i ) { for ( i = 0; i < strips_v.size(); ++i ) {
ssgLeaf *leaf = gen_leaf( path, GL_TRIANGLE_STRIP, ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_STRIP,
matlib, strip_materials[i], matlib, strip_materials[i],
nodes, normals, texcoords, nodes, normals, texcoords,
strips_v[i], strips_n[i], strips_tc[i], strips_v[i], strips_n[i], strips_tc[i],
is_base, ground_lights ); is_base, ground_lights );
if ( use_random_objects ) { if ( use_random_objects ) {
SGMaterial *mat = matlib->find( strip_materials[i] ); SGMaterial *mat = matlib->find( strip_materials[i] );
@ -1001,11 +816,11 @@ bool fgBinObjLoad( const string& path, const bool is_base,
group_list const& fans_n = obj.get_fans_n(); group_list const& fans_n = obj.get_fans_n();
group_list const& fans_tc = obj.get_fans_tc(); group_list const& fans_tc = obj.get_fans_tc();
for ( i = 0; i < fans_v.size(); ++i ) { for ( i = 0; i < fans_v.size(); ++i ) {
ssgLeaf *leaf = gen_leaf( path, GL_TRIANGLE_FAN, ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_FAN,
matlib, fan_materials[i], matlib, fan_materials[i],
nodes, normals, texcoords, nodes, normals, texcoords,
fans_v[i], fans_n[i], fans_tc[i], fans_v[i], fans_n[i], fans_tc[i],
is_base, ground_lights ); is_base, ground_lights );
if ( use_random_objects ) { if ( use_random_objects ) {
SGMaterial *mat = matlib->find( fan_materials[i] ); SGMaterial *mat = matlib->find( fan_materials[i] );
if ( mat == NULL ) { if ( mat == NULL ) {

View file

@ -64,16 +64,4 @@ bool fgGenTile( const string& path, SGBucket b,
SGMaterialLib *matlib, ssgBranch* geometry ); SGMaterialLib *matlib, ssgBranch* geometry );
// Create a ssg leaf
ssgLeaf *gen_leaf( const string& path,
const GLenum ty,
SGMaterialLib *matlib, const string& material,
const point_list& nodes, const point_list& normals,
const point_list& texcoords,
const int_list& node_index,
const int_list& normal_index,
const int_list& tex_index,
const bool calc_lights, ssgVertexArray *lights );
#endif // _OBJ_HXX #endif // _OBJ_HXX

View file

@ -1,619 +0,0 @@
// pt_lights.cxx -- build a 'directional' light on the fly
//
// Written by Curtis Olson, started March 2002.
//
// Copyright (C) 2002 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#include <plib/sg.h>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>
#include "pt_lights.hxx"
// strobe pre-draw (we want a larger point size)
static int StrobePreDraw( ssgEntity *e ) {
glPushAttrib( GL_POINT_BIT );
glPointSize(4.0);
glEnable(GL_POINT_SMOOTH);
return true;
}
// strobe post-draw (we want a larger point size)
static int StrobePostDraw( ssgEntity *e ) {
glPopAttrib();
return true;
}
// Generate a directional light
ssgLeaf *gen_directional_light( sgVec3 pt, sgVec3 dir, sgVec3 up,
const SGMaterial *mat ) {
// calculate a vector perpendicular to dir and up
sgVec3 perp;
sgVectorProductVec3( perp, dir, up );
ssgVertexArray *vl = new ssgVertexArray( 3 );
ssgNormalArray *nl = new ssgNormalArray( 3 );
ssgColourArray *cl = new ssgColourArray( 3 );
// front face
sgVec3 tmp3;
sgCopyVec3( tmp3, pt );
vl->add( tmp3 );
sgAddVec3( tmp3, up );
vl->add( tmp3 );
sgAddVec3( tmp3, perp );
vl->add( tmp3 );
// sgSubVec3( tmp3, up );
// vl->add( tmp3 );
nl->add( dir );
nl->add( dir );
nl->add( dir );
// nl->add( dir );
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
cl->add( color );
cl->add( color );
// cl->add( color );
/*
// temporarily do back face
sgCopyVec3( tmp3, pt );
vl->add( tmp3 );
sgAddVec3( tmp3, up );
vl->add( tmp3 );
sgAddVec3( tmp3, perp );
vl->add( tmp3 );
sgNegateVec3( dir );
nl->add( dir );
nl->add( dir );
nl->add( dir );
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
cl->add( color );
cl->add( color );
*/
/* ssgTexCoordArray *tl = new ssgTexCoordArray( 4 );
sgVec2 tmp2;
sgSetVec2( tmp2, 0.0, 0.0 );
tl->add( tmp2 );
sgSetVec2( tmp2, 1.0, 0.0 );
tl->add( tmp2 );
sgSetVec2( tmp2, 1.0, 1.0 );
tl->add( tmp2 );
sgSetVec2( tmp2, 0.0, 1.0 );
tl->add( tmp2 ); */
ssgLeaf *leaf =
new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
if ( mat != NULL ) {
leaf->setState( mat->get_state() );
} else {
SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: mat = NULL" );
}
return leaf;
}
static void calc_center_point( const point_list &nodes,
const int_list &pnt_i,
sgVec3 result ) {
sgVec3 pt;
sgSetVec3( pt, nodes[pnt_i[0]][0], nodes[pnt_i[0]][1], nodes[pnt_i[0]][2] );
double minx = pt[0];
double maxx = pt[0];
double miny = pt[1];
double maxy = pt[1];
double minz = pt[2];
double maxz = pt[2];
for ( unsigned int i = 0; i < pnt_i.size(); ++i ) {
sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
nodes[pnt_i[i]][2] );
if ( pt[0] < minx ) { minx = pt[0]; }
if ( pt[0] > maxx ) { minx = pt[0]; }
if ( pt[1] < miny ) { miny = pt[1]; }
if ( pt[1] > maxy ) { miny = pt[1]; }
if ( pt[2] < minz ) { minz = pt[2]; }
if ( pt[2] > maxz ) { minz = pt[2]; }
}
sgSetVec3( result, (minx + maxx) / 2.0, (miny + maxy) / 2.0,
(minz + maxz) / 2.0 );
}
static ssgTransform *gen_dir_light_group( const point_list &nodes,
const point_list &normals,
const int_list &pnt_i,
const int_list &nml_i,
const SGMaterial *mat,
sgVec3 up, bool vertical = false )
{
sgVec3 center;
calc_center_point( nodes, pnt_i, center );
// cout << center[0] << "," << center[1] << "," << center[2] << endl;
// find a vector perpendicular to the normal.
sgVec3 perp1;
if ( !vertical ) {
// normal isn't vertical so we can use up as our first vector
sgNormalizeVec3( perp1, up );
} else {
// normal is vertical so we have to work a bit harder to
// determine our first vector
sgVec3 pt1, pt2;
sgSetVec3( pt1, nodes[pnt_i[0]][0], nodes[pnt_i[0]][1],
nodes[pnt_i[0]][2] );
sgSetVec3( pt2, nodes[pnt_i[1]][0], nodes[pnt_i[1]][1],
nodes[pnt_i[1]][2] );
sgSubVec3( perp1, pt2, pt1 );
sgNormalizeVec3( perp1 );
}
ssgVertexArray *vl = new ssgVertexArray( 3 * pnt_i.size() );
ssgNormalArray *nl = new ssgNormalArray( 3 * pnt_i.size() );
ssgColourArray *cl = new ssgColourArray( 3 * pnt_i.size() );
unsigned int i;
sgVec3 pt, normal;
for ( i = 0; i < pnt_i.size(); ++i ) {
sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
nodes[pnt_i[i]][2] );
sgSubVec3( pt, center );
sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1],
normals[nml_i[i]][2] );
// calculate a vector perpendicular to dir and up
sgVec3 perp2;
sgVectorProductVec3( perp2, normal, perp1 );
// front face
sgVec3 tmp3;
sgCopyVec3( tmp3, pt );
vl->add( tmp3 );
sgAddVec3( tmp3, perp1 );
vl->add( tmp3 );
sgAddVec3( tmp3, perp2 );
vl->add( tmp3 );
// sgSubVec3( tmp3, perp1 );
// vl->add( tmp3 );
nl->add( normal );
nl->add( normal );
nl->add( normal );
// nl->add( normal );
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
cl->add( color );
cl->add( color );
// cl->add( color );
}
ssgLeaf *leaf =
new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
if ( mat != NULL ) {
leaf->setState( mat->get_state() );
} else {
SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: material = NULL" );
}
// put an LOD on each lighting component
ssgRangeSelector *lod = new ssgRangeSelector;
lod->setRange( 0, SG_ZERO );
lod->setRange( 1, 20000 );
lod->addKid( leaf );
// create the transformation.
sgCoord coord;
sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 );
ssgTransform *trans = new ssgTransform;
trans->setTransform( &coord );
trans->addKid( lod );
return trans;
}
static ssgTransform *gen_reil_lights( const point_list &nodes,
const point_list &normals,
const int_list &pnt_i,
const int_list &nml_i,
SGMaterialLib *matlib,
sgVec3 up )
{
sgVec3 center;
calc_center_point( nodes, pnt_i, center );
// cout << center[0] << "," << center[1] << "," << center[2] << endl;
sgVec3 nup;
sgNormalizeVec3( nup, up );
ssgVertexArray *vl = new ssgVertexArray( 3 * pnt_i.size() );
ssgNormalArray *nl = new ssgNormalArray( 3 * pnt_i.size() );
ssgColourArray *cl = new ssgColourArray( 3 * pnt_i.size() );
unsigned int i;
sgVec3 pt, normal;
for ( i = 0; i < pnt_i.size(); ++i ) {
sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
nodes[pnt_i[i]][2] );
sgSubVec3( pt, center );
sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1],
normals[nml_i[i]][2] );
// calculate a vector perpendicular to dir and up
sgVec3 perp;
sgVectorProductVec3( perp, normal, nup );
// front face
sgVec3 tmp3;
sgCopyVec3( tmp3, pt );
vl->add( tmp3 );
sgAddVec3( tmp3, nup );
vl->add( tmp3 );
sgAddVec3( tmp3, perp );
vl->add( tmp3 );
// sgSubVec3( tmp3, nup );
// vl->add( tmp3 );
nl->add( normal );
nl->add( normal );
nl->add( normal );
// nl->add( normal );
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
cl->add( color );
cl->add( color );
// cl->add( color );
}
ssgLeaf *leaf =
new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
SGMaterial *mat = matlib->find( "RWY_WHITE_LIGHTS" );
if ( mat != NULL ) {
leaf->setState( mat->get_state() );
} else {
SG_LOG( SG_TERRAIN, SG_ALERT,
"Warning: can't find material = RWY_WHITE_LIGHTS" );
}
leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw );
leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw );
ssgTimedSelector *reil = new ssgTimedSelector;
// need to add this twice to work around an ssg bug
reil->addKid( leaf );
reil->addKid( leaf );
reil->setDuration( 60 );
reil->setLimits( 0, 2 );
reil->setMode( SSG_ANIM_SHUTTLE );
reil->control( SSG_ANIM_START );
// put an LOD on each lighting component
ssgRangeSelector *lod = new ssgRangeSelector;
lod->setRange( 0, SG_ZERO );
lod->setRange( 1, 12000 );
lod->addKid( reil );
// create the transformation.
sgCoord coord;
sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 );
ssgTransform *trans = new ssgTransform;
trans->setTransform( &coord );
trans->addKid( lod );
return trans;
}
static ssgTransform *gen_odals_lights( const point_list &nodes,
const point_list &normals,
const int_list &pnt_i,
const int_list &nml_i,
SGMaterialLib *matlib,
sgVec3 up )
{
sgVec3 center;
calc_center_point( nodes, pnt_i, center );
// cout << center[0] << "," << center[1] << "," << center[2] << endl;
ssgTimedSelector *odals = new ssgTimedSelector;
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
// we don't want directional lights here
SGMaterial *mat = matlib->find( "GROUND_LIGHTS" );
if ( mat == NULL ) {
SG_LOG( SG_TERRAIN, SG_ALERT,
"Warning: can't material = GROUND_LIGHTS" );
}
// center line strobes
int i;
sgVec3 pt;
for ( i = (int)pnt_i.size() - 1; i >= 2; --i ) {
ssgVertexArray *vl = new ssgVertexArray( 1 );
ssgColourArray *cl = new ssgColourArray( 1 );
sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
nodes[pnt_i[i]][2] );
sgSubVec3( pt, center );
vl->add( pt );
cl->add( color );
ssgLeaf *leaf =
new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl );
leaf->setState( mat->get_state() );
leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw );
leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw );
odals->addKid( leaf );
}
// runway end strobes
ssgVertexArray *vl = new ssgVertexArray( 2 );
ssgColourArray *cl = new ssgColourArray( 2 );
sgSetVec3( pt, nodes[pnt_i[0]][0], nodes[pnt_i[0]][1],
nodes[pnt_i[0]][2] );
sgSubVec3( pt, center );
vl->add( pt );
cl->add( color );
sgSetVec3( pt, nodes[pnt_i[1]][0], nodes[pnt_i[1]][1],
nodes[pnt_i[1]][2] );
sgSubVec3( pt, center );
vl->add( pt );
cl->add( color );
ssgLeaf *leaf =
new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl );
leaf->setState( mat->get_state() );
leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw );
leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw );
odals->addKid( leaf );
// setup animition
odals->setDuration( 10 );
odals->setLimits( 0, pnt_i.size() - 1 );
odals->setMode( SSG_ANIM_SHUTTLE );
odals->control( SSG_ANIM_START );
// put an LOD on each lighting component
ssgRangeSelector *lod = new ssgRangeSelector;
lod->setRange( 0, SG_ZERO );
lod->setRange( 1, 12000 );
lod->addKid( odals );
// create the transformation.
sgCoord coord;
sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 );
ssgTransform *trans = new ssgTransform;
trans->setTransform( &coord );
trans->addKid( lod );
return trans;
}
static ssgTransform *gen_rabbit_lights( const point_list &nodes,
const point_list &normals,
const int_list &pnt_i,
const int_list &nml_i,
SGMaterialLib *matlib,
sgVec3 up )
{
sgVec3 center;
calc_center_point( nodes, pnt_i, center );
// cout << center[0] << "," << center[1] << "," << center[2] << endl;
sgVec3 nup;
sgNormalizeVec3( nup, up );
ssgTimedSelector *rabbit = new ssgTimedSelector;
SGMaterial *mat = matlib->find( "RWY_WHITE_LIGHTS" );
if ( mat == NULL ) {
SG_LOG( SG_TERRAIN, SG_ALERT,
"Warning: can't material = RWY_WHITE_LIGHTS" );
}
int i;
sgVec3 pt, normal;
for ( i = (int)pnt_i.size() - 1; i >= 0; --i ) {
ssgVertexArray *vl = new ssgVertexArray( 3 );
ssgNormalArray *nl = new ssgNormalArray( 3 );
ssgColourArray *cl = new ssgColourArray( 3 );
sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
nodes[pnt_i[i]][2] );
sgSubVec3( pt, center );
sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1],
normals[nml_i[i]][2] );
// calculate a vector perpendicular to dir and up
sgVec3 perp;
sgVectorProductVec3( perp, normal, nup );
// front face
sgVec3 tmp3;
sgCopyVec3( tmp3, pt );
vl->add( tmp3 );
sgAddVec3( tmp3, nup );
vl->add( tmp3 );
sgAddVec3( tmp3, perp );
vl->add( tmp3 );
// sgSubVec3( tmp3, nup );
// vl->add( tmp3 );
nl->add( normal );
nl->add( normal );
nl->add( normal );
// nl->add( normal );
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
cl->add( color );
cl->add( color );
// cl->add( color );
ssgLeaf *leaf =
new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
leaf->setState( mat->get_state() );
leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw );
leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw );
rabbit->addKid( leaf );
}
rabbit->setDuration( 10 );
rabbit->setLimits( 0, pnt_i.size() - 1 );
rabbit->setMode( SSG_ANIM_SHUTTLE );
rabbit->control( SSG_ANIM_START );
// put an LOD on each lighting component
ssgRangeSelector *lod = new ssgRangeSelector;
lod->setRange( 0, SG_ZERO );
lod->setRange( 1, 12000 );
lod->addKid( rabbit );
// create the transformation.
sgCoord coord;
sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 );
ssgTransform *trans = new ssgTransform;
trans->setTransform( &coord );
trans->addKid( lod );
return trans;
}
#if 0 // debugging infrastructure
// Generate a normal line
static ssgLeaf *gen_normal_line( SGMaterialLib *matlib,
sgVec3 pt, sgVec3 dir, sgVec3 up ) {
ssgVertexArray *vl = new ssgVertexArray( 3 );
ssgColourArray *cl = new ssgColourArray( 3 );
sgVec3 tmp3;
sgCopyVec3( tmp3, pt );
vl->add( tmp3 );
sgAddVec3( tmp3, dir );
vl->add( tmp3 );
sgVec4 color;
sgSetVec4( color, 1.0, 0.0, 0.0, 1.0 );
cl->add( color );
cl->add( color );
ssgLeaf *leaf =
new ssgVtxTable ( GL_LINES, vl, NULL, NULL, cl );
SGMaterial *mat = matlib->find( "GROUND_LIGHTS" );
leaf->setState( mat->get_state() );
return leaf;
}
#endif
ssgBranch *gen_directional_lights( const point_list &nodes,
const point_list &normals,
const int_list &pnt_i,
const int_list &nml_i,
SGMaterialLib *matlib,
const string &material,
sgVec3 up )
{
sgVec3 nup;
sgNormalizeVec3( nup, up );
SGMaterial *mat = matlib->find( material );
if ( material == "RWY_REIL_LIGHTS" ) {
// cout << "found a reil" << endl;
ssgTransform *reil = gen_reil_lights( nodes, normals, pnt_i, nml_i,
matlib, up );
return reil;
} else if ( material == "RWY_ODALS_LIGHTS" ) {
// cout << "found a odals" << endl;
ssgTransform *odals = gen_odals_lights( nodes, normals, pnt_i, nml_i,
matlib, up );
return odals;
} else if ( material == "RWY_SEQUENCED_LIGHTS" ) {
// cout << "found a rabbit" << endl;
ssgTransform *rabbit = gen_rabbit_lights( nodes, normals,
pnt_i, nml_i,
matlib, up );
return rabbit;
} else if ( material == "RWY_BLUE_TAXIWAY_LIGHTS" ) {
ssgTransform *light_group = gen_dir_light_group( nodes, normals, pnt_i,
nml_i, mat, up,
true );
return light_group;
} else {
ssgTransform *light_group = gen_dir_light_group( nodes, normals, pnt_i,
nml_i, mat, up );
return light_group;
}
return NULL;
}

View file

@ -1,107 +0,0 @@
// pt_lights.hxx -- build a 'directional' light on the fly
//
// Written by Curtis Olson, started March 2002.
//
// Copyright (C) 2002 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _PT_LIGHTS_HXX
#define _PT_LIGHTS_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include STL_STRING
#include <vector> // STL
#include <plib/sg.h>
#include <plib/ssg.h> // plib include
#include <simgear/math/sg_types.hxx>
SG_USING_STD(string);
SG_USING_STD(vector);
typedef vector < int > int_list;
typedef int_list::iterator int_list_iterator;
typedef int_list::const_iterator int_point_list_iterator;
// Define the various supported light types
typedef enum {
FG_RWYLIGHT_TAXI = 0,
FG_RWYLIGHT_VASI,
FG_RWYLIGHT_EDGE,
FG_RWYLIGHT_TOUCHDOWN,
FG_RWYLIGHT_THRESHOLD,
FG_RWYLIGHT_WHITE,
FG_RWYLIGHT_RED,
FG_RWYLIGHT_GREEN,
FG_RWYLIGHT_YELLOW
} fgRunwayLightType;
// Generate a directional light. This routines creates a
// 'directional' light that can only be viewed from within 90 degrees
// of the specified dir vector.
// To accomplish this, he routine creates a triangle with the 1st
// point coincident with the specified pt and the 2nd and 3rd points
// extending upward. The 1st point is created with an 'alpha' value
// of 1 while the 2nd and 3rd points are created with an 'alpha' of
// 0.0.
// If the triangle is drawn in glPolygonMode(GL_FRONT, GL_POINT) mode,
// then two important things happen:
// 1) Only the 3 vertex points are drawn, the 2nd two with an alpha of
// 0 so actually only the desired point is rendered.
// 2) since we are drawing a triangle, back face culling takes care of
// eliminating this poing when the view angle relative to dir is
// greater than 90 degrees.
// The final piece of this puzzle is that if we now use environment
// mapping on this point, via an appropriate texture we can then
// control the intensity and color of the point based on the view
// angle relative to 'dir' the optimal view direction of the light
// (i.e. the direction the light is pointing.)
// Yes this get's to be long and convoluted. If you can suggest a
// simpler way, please do! :-)
ssgLeaf *gen_directional_light( sgVec3 pt, sgVec3 dir, sgVec3 up );
ssgBranch *gen_directional_lights( const point_list &nodes,
const point_list &normals,
const int_list &pnt_i,
const int_list &nml_i,
SGMaterialLib *matlib,
const string &material,
sgVec3 up );
#endif // _PT_LIGHTS_HXX

View file

@ -36,6 +36,7 @@
#include <simgear/misc/sgstream.hxx> #include <simgear/misc/sgstream.hxx>
#include <simgear/scene/material/mat.hxx> #include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx> #include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/tgdb/apt_signs.hxx>
#include <Aircraft/aircraft.hxx> #include <Aircraft/aircraft.hxx>
#include <Include/general.hxx> #include <Include/general.hxx>
@ -43,7 +44,6 @@
#include <Main/viewer.hxx> #include <Main/viewer.hxx>
#include <Scenery/scenery.hxx> #include <Scenery/scenery.hxx>
#include <Time/light.hxx> #include <Time/light.hxx>
#include <Objects/apt_signs.hxx>
#include <Objects/obj.hxx> #include <Objects/obj.hxx>
#include "tileentry.hxx" #include "tileentry.hxx"