1 // mat.hxx -- a material in the scene graph.
2 // TODO: this class needs to be renamed.
4 // Written by Curtis Olson, started May 1998.
5 // Overhauled by David Megginson, December 2001
7 // Copyright (C) 1998 - 2000 Curtis L. Olson - curt@flightgear.org
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License as
11 // published by the Free Software Foundation; either version 2 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 # error This library requires C++
33 #include <simgear/compiler.h>
35 #include STL_STRING // Standard C++ string library
40 #include <simgear/props/props.hxx>
41 #include <simgear/scene/model/loader.hxx>
47 * A material in the scene graph.
49 * A material represents information about a single surface type
50 * in the 3D scene graph, including texture, colour, lighting,
51 * tiling, and so on; most of the materials in FlightGear are
52 * defined in the $FG_ROOT/materials.xml file, and can be changed
60 //////////////////////////////////////////////////////////////////////
62 //////////////////////////////////////////////////////////////////////
67 * A randomly-placeable object.
69 * SGMaterial uses this class to keep track of the model(s) and
70 * parameters for a single instance of a randomly-placeable object.
71 * The object can have more than one variant model (i.e. slightly
72 * different shapes of trees), but they are considered equivalent
73 * and interchangeable.
80 * The heading type for a randomly-placed object.
90 * Get the number of variant models available for the object.
92 * @return The number of variant models.
94 int get_model_count( SGModelLoader *loader,
95 const string &fg_root,
96 SGPropertyNode *prop_root,
97 double sim_time_sec );
101 * Get a specific variant model for the object.
103 * @param index The index of the model.
106 ssgEntity *get_model( int index,
107 SGModelLoader *loader,
108 const string &fg_root,
109 SGPropertyNode *prop_root,
110 double sim_time_sec );
114 * Get a randomly-selected variant model for the object.
116 * @return A randomly select model from the variants.
118 ssgEntity *get_random_model( SGModelLoader *loader,
119 const string &fg_root,
120 SGPropertyNode *prop_root,
121 double sim_time_sec );
125 * Get the average number of meters^2 occupied by each instance.
127 * @return The coverage in meters^2.
129 double get_coverage_m2 () const;
133 * Get the heading type for the object.
135 * @return The heading type.
137 HeadingType get_heading_type () const;
141 friend class ObjectGroup;
143 Object (const SGPropertyNode * node, double range_m);
150 * Actually load the models.
152 * This class uses lazy loading so that models won't be held
153 * in memory for materials that are never referenced.
155 void load_models( SGModelLoader *loader,
156 const string &fg_root,
157 SGPropertyNode *prop_root,
158 double sim_time_sec );
160 vector<string> _paths;
161 mutable vector<ssgEntity *> _models;
162 mutable bool _models_loaded;
165 HeadingType _heading_type;
170 * A collection of related objects with the same visual range.
172 * Grouping objects with the same range together significantly
173 * reduces the memory requirements of randomly-placed objects.
174 * Each SGMaterial instance keeps a (possibly-empty) list of
175 * object groups for placing randomly on the scenery.
180 virtual ~ObjectGroup ();
184 * Get the visual range of the object in meters.
186 * @return The visual range.
188 double get_range_m () const;
192 * Get the number of objects in the group.
194 * @return The number of objects.
196 int get_object_count () const;
200 * Get a specific object.
202 * @param index The object's index, zero-based.
203 * @return The object selected.
205 Object * get_object (int index) const;
209 friend class SGMaterial;
211 ObjectGroup (SGPropertyNode * node);
216 vector<Object *> _objects;
223 ////////////////////////////////////////////////////////////////////
224 // Public Constructors.
225 ////////////////////////////////////////////////////////////////////
228 * Construct a material from a set of properties.
230 * @param props A property node containing subnodes with the
231 * state information for the material. This node is usually
232 * loaded from the $FG_ROOT/materials.xml file.
234 SGMaterial( const string &fg_root, const SGPropertyNode *props );
238 * Construct a material from an absolute texture path.
240 * @param texture_path A string containing an absolute path
241 * to a texture file (usually RGB).
243 SGMaterial( const string &texpath );
247 * Construct a material around an existing SSG state.
249 * This constructor allows the application to create a custom,
250 * low-level state for the scene graph and wrap a material around
251 * it. Note: the pointer ownership is transferred to the material.
253 * @param s The SSG state for this material.
255 SGMaterial( ssgSimpleState *s );
260 virtual ~SGMaterial( void );
264 ////////////////////////////////////////////////////////////////////
266 ////////////////////////////////////////////////////////////////////
269 * Force the texture to load if it hasn't already.
271 * @return true if the texture loaded, false if it was loaded
274 virtual bool load_texture ();
278 * Get the textured state.
280 virtual inline ssgSimpleState *get_state () const { return state; }
284 * Get the xsize of the texture, in meters.
286 virtual inline double get_xsize() const { return xsize; }
290 * Get the ysize of the texture, in meters.
292 virtual inline double get_ysize() const { return ysize; }
296 * Get the light coverage.
298 * A smaller number means more generated night lighting.
300 * @return The area (m^2?) covered by each light.
302 virtual inline double get_light_coverage () const { return light_coverage; }
306 * Get the number of randomly-placed objects defined for this material.
308 virtual int get_object_group_count () const { return object_groups.size(); }
312 * Get a randomly-placed object for this material.
314 virtual ObjectGroup * get_object_group (int index) const {
315 return object_groups[index];
320 * Increment the reference count for this material.
322 * A material with 0 references may be deleted by the
325 virtual inline void ref () { refcount++; }
329 * Decrement the reference count for this material.
331 virtual inline void deRef () { refcount--; }
335 * Get the reference count for this material.
337 * @return The number of references (0 if none).
339 virtual inline int getRef () const { return refcount; }
344 ////////////////////////////////////////////////////////////////////
345 // Protected methods.
346 ////////////////////////////////////////////////////////////////////
349 * Initialization method, invoked by all public constructors.
357 ////////////////////////////////////////////////////////////////////
359 ////////////////////////////////////////////////////////////////////
364 // pointers to ssg states
365 ssgSimpleState *state;
376 // coverage of night lighting.
377 double light_coverage;
379 // material properties
380 sgVec4 ambient, diffuse, specular, emission;
383 // true if texture loading deferred, and not yet loaded
386 vector<ObjectGroup *> object_groups;
388 // ref count so we can properly delete if we have multiple
389 // pointers to this record
394 ////////////////////////////////////////////////////////////////////
395 // Internal constructors and methods.
396 ////////////////////////////////////////////////////////////////////
398 SGMaterial( const string &fg_root, const SGMaterial &mat ); // unimplemented
400 void read_properties( const string &fg_root, const SGPropertyNode *props );
401 void build_ssg_state( bool defer_tex_load );
402 void set_ssg_state( ssgSimpleState *s );
407 #endif // _SG_MAT_HXX