1 // newmat.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++
44 #include <simgear/compiler.h>
45 #include <simgear/misc/props.hxx>
49 #include STL_STRING // Standard C++ string library
55 * A material in the scene graph.
57 * A material represents information about a single surface type
58 * in the 3D scene graph, including texture, colour, lighting,
59 * tiling, and so on; most of the materials in FlightGear are
60 * defined in the $FG_ROOT/materials.xml file, and can be changed
68 //////////////////////////////////////////////////////////////////////
70 //////////////////////////////////////////////////////////////////////
75 * A randomly-placeable object.
77 * FGNewMat uses this class to keep track of the model(s) and
78 * parameters for a single instance of a randomly-placeable object.
79 * The object can have more than one variant model (i.e. slightly
80 * different shapes of trees), but they are considered equivalent
81 * and interchangeable.
88 * The heading type for a randomly-placed object.
98 * Get the number of variant models available for the object.
100 * @return The number of variant models.
102 int get_model_count () const;
106 * Get a specific variant model for the object.
108 * @param index The index of the model.
111 ssgEntity * get_model (int index) const;
115 * Get a randomly-selected variant model for the object.
117 * @return A randomly select model from the variants.
119 ssgEntity * get_random_model () const;
123 * Get the average number of meters^2 occupied by each instance.
125 * @return The coverage in meters^2.
127 double get_coverage_m2 () const;
131 * Get the heading type for the object.
133 * @return The heading type.
135 HeadingType get_heading_type () const;
139 friend class ObjectGroup;
141 Object (const SGPropertyNode * node, double range_m);
148 * Actually load the models.
150 * This class uses lazy loading so that models won't be held
151 * in memory for materials that are never referenced.
153 void load_models () const;
155 vector<string> _paths;
156 mutable vector<ssgEntity *> _models;
157 mutable bool _models_loaded;
160 HeadingType _heading_type;
165 * A collection of related objects with the same visual range.
167 * Grouping objects with the same range together significantly
168 * reduces the memory requirements of randomly-placed objects.
169 * Each FGNewMat instance keeps a (possibly-empty) list of
170 * object groups for placing randomly on the scenery.
175 virtual ~ObjectGroup ();
179 * Get the visual range of the object in meters.
181 * @return The visual range.
183 double get_range_m () const;
187 * Get the number of objects in the group.
189 * @return The number of objects.
191 int get_object_count () const;
195 * Get a specific object.
197 * @param index The object's index, zero-based.
198 * @return The object selected.
200 Object * get_object (int index) const;
204 friend class FGNewMat;
206 ObjectGroup (SGPropertyNode * node);
211 vector<Object *> _objects;
218 ////////////////////////////////////////////////////////////////////
219 // Public Constructors.
220 ////////////////////////////////////////////////////////////////////
223 * Construct a material from a set of properties.
225 * @param props A property node containing subnodes with the
226 * state information for the material. This node is usually
227 * loaded from the $FG_ROOT/materials.xml file.
229 FGNewMat (const SGPropertyNode * props);
233 * Construct a material from an absolute texture path.
235 * @param texture_path A string containing an absolute path
236 * to a texture file (usually RGB).
238 FGNewMat (const string &texpath);
242 * Construct a material around an existing SSG state.
244 * This constructor allows the application to create a custom,
245 * low-level state for the scene graph and wrap a material around
246 * it. Note: the pointer ownership is transferred to the material.
248 * @param s The SSG state for this material.
250 FGNewMat (ssgSimpleState * s);
255 virtual ~FGNewMat ( void );
259 ////////////////////////////////////////////////////////////////////
261 ////////////////////////////////////////////////////////////////////
264 * Force the texture to load if it hasn't already.
266 * @return true if the texture loaded, false if it was loaded
269 virtual bool load_texture ();
273 * Get the textured state.
275 virtual inline ssgSimpleState *get_textured () { return textured; }
279 * Get the xsize of the texture, in meters.
281 virtual inline double get_xsize() const { return xsize; }
285 * Get the ysize of the texture, in meters.
287 virtual inline double get_ysize() const { return ysize; }
291 * Get the light coverage.
293 * A smaller number means more generated night lighting.
295 * @return The area (m^2?) covered by each light.
297 virtual inline double get_light_coverage () const { return light_coverage; }
301 * Get the number of randomly-placed objects defined for this material.
303 virtual int get_object_group_count () const { return object_groups.size(); }
307 * Get a randomly-placed object for this material.
309 virtual ObjectGroup * get_object_group (int index) const {
310 return object_groups[index];
315 * Get the current state.
317 virtual inline ssgStateSelector *get_state () const { return state; }
321 * Increment the reference count for this material.
323 * A material with 0 references may be deleted by the
326 virtual inline void ref () { refcount++; }
330 * Decrement the reference count for this material.
332 virtual inline void deRef () { refcount--; }
336 * Get the reference count for this material.
338 * @return The number of references (0 if none).
340 virtual inline int getRef () const { return refcount; }
345 ////////////////////////////////////////////////////////////////////
346 // Protected methods.
347 ////////////////////////////////////////////////////////////////////
350 * Initialization method, invoked by all public constructors.
358 ////////////////////////////////////////////////////////////////////
360 ////////////////////////////////////////////////////////////////////
365 // pointers to ssg states
366 ssgStateSelector *state;
367 ssgSimpleState *textured;
368 ssgSimpleState *nontextured;
379 // coverage of night lighting.
380 double light_coverage;
382 // material properties
383 sgVec4 ambient, diffuse, specular, emission;
386 // true if texture loading deferred, and not yet loaded
389 vector<ObjectGroup *> object_groups;
391 // ref count so we can properly delete if we have multiple
392 // pointers to this record
397 ////////////////////////////////////////////////////////////////////
398 // Internal constructors and methods.
399 ////////////////////////////////////////////////////////////////////
401 FGNewMat (const FGNewMat &mat); // unimplemented
403 void read_properties (const SGPropertyNode * props);
404 void build_ssg_state(bool defer_tex_load = false);
405 void set_ssg_state( ssgSimpleState *s );
410 #endif // _NEWMAT_HXX