1
0
Fork 0
flightgear/src/Objects/newmat.hxx

320 lines
7.4 KiB
C++
Raw Normal View History

// newmat.hxx -- a material in the scene graph.
// TODO: this class needs to be renamed.
//
// Written by Curtis Olson, started May 1998.
// Overhauled by David Megginson, December 2001
//
// Copyright (C) 1998 - 2000 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 _NEWMAT_HXX
#define _NEWMAT_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/compiler.h>
#include <simgear/misc/props.hxx>
#include <GL/glut.h>
#include STL_STRING // Standard C++ string library
2001-03-23 22:59:18 +00:00
SG_USING_STD(string);
/**
* A material in the scene graph.
*
* A material represents information about a single surface type
* in the 3D scene graph, including texture, colour, lighting,
* tiling, and so on; most of the materials in FlightGear are
* defined in the $FG_ROOT/materials.xml file, and can be changed
* at runtime.
*/
class FGNewMat {
public:
//////////////////////////////////////////////////////////////////////
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
// Inner classes.
//////////////////////////////////////////////////////////////////////
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
class ObjectGroup;
/**
* A randomly-placeable object.
*/
class Object
{
public:
enum HeadingType {
HEADING_FIXED,
HEADING_BILLBOARD,
HEADING_RANDOM
};
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
int get_model_count () const;
ssgEntity * get_model (int index) const;
ssgEntity * get_random_model () const;
double get_coverage_m2 () const;
HeadingType get_heading_type () const;
protected:
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
friend class ObjectGroup;
Object (const SGPropertyNode * node, double range_m);
virtual ~Object ();
private:
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
void load_models () const;
vector<string> _paths;
mutable vector<ssgEntity *> _models;
mutable bool _models_loaded;
double _coverage_m2;
double _range_m;
HeadingType _heading_type;
};
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
/**
* A collection of related objects with the same visual range.
*/
class ObjectGroup
{
public:
virtual ~ObjectGroup ();
double get_range_m () const;
int get_object_count () const;
Object * get_object (int index) const;
protected:
friend class FGNewMat;
ObjectGroup (SGPropertyNode * node);
private:
double _range_m;
vector<Object *> _objects;
};
////////////////////////////////////////////////////////////////////
// Public Constructors.
////////////////////////////////////////////////////////////////////
/**
* Construct a material from a set of properties.
*
* @param props A property node containing subnodes with the
* state information for the material. This node is usually
* loaded from the $FG_ROOT/materials.xml file.
*/
FGNewMat (const SGPropertyNode * props);
/**
* Construct a material from an absolute texture path.
*
* @param texture_path A string containing an absolute path
* to a texture file (usually RGB).
*/
2002-03-12 05:37:55 +00:00
FGNewMat (const string &texpath);
/**
* Construct a material around an existing SSG state.
*
* This constructor allows the application to create a custom,
* low-level state for the scene graph and wrap a material around
* it. Note: the pointer ownership is transferred to the material.
*
* @param s The SSG state for this material.
*/
FGNewMat (ssgSimpleState * s);
/**
* Destructor.
*/
virtual ~FGNewMat ( void );
////////////////////////////////////////////////////////////////////
// Public methods.
////////////////////////////////////////////////////////////////////
/**
* Force the texture to load if it hasn't already.
*
* @return true if the texture loaded, false if it was loaded
* already.
*/
virtual bool load_texture ();
/**
* Get the textured state.
*/
virtual inline ssgSimpleState *get_textured () { return textured; }
/**
* Get the xsize of the texture, in meters.
*/
virtual inline double get_xsize() const { return xsize; }
/**
* Get the ysize of the texture, in meters.
*/
virtual inline double get_ysize() const { return ysize; }
/**
* Get the light coverage.
*
* A smaller number means more generated night lighting.
*
* @return The area (m^2?) covered by each light.
*/
virtual inline double get_light_coverage () const { return light_coverage; }
/**
* Get the number of randomly-placed objects defined for this material.
*/
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
virtual int get_object_group_count () const { return object_groups.size(); }
/**
* Get a randomly-placed object for this material.
*/
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
virtual ObjectGroup * get_object_group (int index) const {
return object_groups[index];
}
/**
* Get the current state.
*/
virtual inline ssgStateSelector *get_state () const { return state; }
/**
* Increment the reference count for this material.
*
* A material with 0 references may be deleted by the
* material library.
*/
virtual inline void ref () { refcount++; }
/**
* Decrement the reference count for this material.
*/
virtual inline void deRef () { refcount--; }
/**
* Get the reference count for this material.
*
* @return The number of references (0 if none).
*/
virtual inline int getRef () const { return refcount; }
2001-12-29 13:19:09 +00:00
protected:
////////////////////////////////////////////////////////////////////
// Protected methods.
////////////////////////////////////////////////////////////////////
/**
* Initialization method, invoked by all public constructors.
*/
virtual void init();
private:
////////////////////////////////////////////////////////////////////
// Internal state.
////////////////////////////////////////////////////////////////////
// names
string texture_path;
// pointers to ssg states
ssgStateSelector *state;
ssgSimpleState *textured;
ssgSimpleState *nontextured;
// texture size
double xsize, ysize;
// wrap texture?
bool wrapu, wrapv;
// use mipmapping?
int mipmap;
// coverage of night lighting.
double light_coverage;
// material properties
sgVec4 ambient, diffuse, specular, emission;
// true if texture loading deferred, and not yet loaded
bool texture_loaded;
Randomly-place object overhaul and enhancements ----------------------------------------------- Fixed a segfault on exit. Changed the radius of the dummy bounding sphere from 10m to 1000m to ensure that FOV culling doesn't leave anything out. Allow an object to have more than one variant model, which will be chosen randomly. Simply repeat the <path>...</path> property. Removed the <billboard> property and replaced it with <heading-type>, which can be set to "fixed" (leave the model oriented as it is), "random" (give the model a random heading between 0 and 359 deg), or "billboard" (always turn the model to face the camera). The default is "fixed". Models look much better when they are not all facing the same direction. Allow the user to group models with the same visual range, so that there can be *many* fewer nodes in the scene graph when the models are not visible. This causes an XML-format change, so that instead of <object> <range-m>...</range-m> ... </object> <object> <range-m>...</range-m> ... </object> ... we now have <object-group> <range-m>...</range-m> <object> ... </object> <object> ... </object> ... </object-group> Every object in a group can still have its own model(s), coverage, and heading-type, but they all share the same range selector. This change should already help users with tight memory constraints, but it will matter much more when we add more object types -- for example, we can now add dozens of different urban building types without bloating the scene graph or slowing down the LOD tests for tris that are out of range (i.e. most of them).
2002-07-20 14:56:37 +00:00
vector<ObjectGroup *> object_groups;
// ref count so we can properly delete if we have multiple
// pointers to this record
int refcount;
////////////////////////////////////////////////////////////////////
// Internal constructors and methods.
////////////////////////////////////////////////////////////////////
FGNewMat (const FGNewMat &mat); // unimplemented
void read_properties (const SGPropertyNode * props);
void build_ssg_state(bool defer_tex_load = false);
void set_ssg_state( ssgSimpleState *s );
};
#endif // _NEWMAT_HXX