]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/mat.hxx
Removed non-textured and flat shaded support because it really clutters up
[simgear.git] / simgear / scene / material / mat.hxx
1 // mat.hxx -- a material in the scene graph.
2 // TODO: this class needs to be renamed.
3 //
4 // Written by Curtis Olson, started May 1998.
5 // Overhauled by David Megginson, December 2001
6 //
7 // Copyright (C) 1998 - 2000  Curtis L. Olson  - curt@flightgear.org
8 //
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.
13 //
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.
18 //
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.
22 //
23 // $Id$
24
25
26 #ifndef _SG_MAT_HXX
27 #define _SG_MAT_HXX
28
29 #ifndef __cplusplus                                                          
30 # error This library requires C++
31 #endif                                   
32
33 #include <simgear/compiler.h>
34
35 #include STL_STRING      // Standard C++ string library
36
37 #include <plib/sg.h>
38 #include <plib/ssg.h>
39
40 #include <simgear/props/props.hxx>
41 #include <simgear/scene/model/loader.hxx>
42
43 SG_USING_STD(string);
44
45
46 /**
47  * A material in the scene graph.
48  *
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
53  * at runtime.
54  */
55 class SGMaterial {
56
57 public:
58
59 \f
60   //////////////////////////////////////////////////////////////////////
61   // Inner classes.
62   //////////////////////////////////////////////////////////////////////
63
64   class ObjectGroup;
65
66   /**
67    * A randomly-placeable object.
68    *
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.
74    */
75   class Object
76   {
77   public:
78
79     /**
80      * The heading type for a randomly-placed object.
81      */
82     enum HeadingType {
83       HEADING_FIXED,
84       HEADING_BILLBOARD,
85       HEADING_RANDOM
86     };
87
88
89     /**
90      * Get the number of variant models available for the object.
91      *
92      * @return The number of variant models.
93      */
94     int get_model_count( SGModelLoader *loader,
95                          const string &fg_root,
96                          SGPropertyNode *prop_root,
97                          double sim_time_sec );
98
99
100     /**
101      * Get a specific variant model for the object.
102      *
103      * @param index The index of the model.
104      * @return The model.
105      */
106     ssgEntity *get_model( int index,
107                           SGModelLoader *loader,
108                           const string &fg_root,
109                           SGPropertyNode *prop_root,
110                           double sim_time_sec );
111
112
113     /**
114      * Get a randomly-selected variant model for the object.
115      *
116      * @return A randomly select model from the variants.
117      */
118     ssgEntity *get_random_model( SGModelLoader *loader,
119                                  const string &fg_root,
120                                  SGPropertyNode *prop_root,
121                                  double sim_time_sec );
122
123
124     /**
125      * Get the average number of meters^2 occupied by each instance.
126      *
127      * @return The coverage in meters^2.
128      */
129     double get_coverage_m2 () const;
130
131
132     /**
133      * Get the heading type for the object.
134      *
135      * @return The heading type.
136      */
137     HeadingType get_heading_type () const;
138
139   protected:
140
141     friend class ObjectGroup;
142
143     Object (const SGPropertyNode * node, double range_m);
144
145     virtual ~Object ();
146
147   private:
148
149     /**
150      * Actually load the models.
151      *
152      * This class uses lazy loading so that models won't be held
153      * in memory for materials that are never referenced.
154      */
155     void load_models( SGModelLoader *loader,
156                       const string &fg_root,
157                       SGPropertyNode *prop_root,
158                       double sim_time_sec );
159
160     vector<string> _paths;
161     mutable vector<ssgEntity *> _models;
162     mutable bool _models_loaded;
163     double _coverage_m2;
164     double _range_m;
165     HeadingType _heading_type;
166   };
167
168
169   /**
170    * A collection of related objects with the same visual range.
171    *
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.
176    */
177   class ObjectGroup
178   {
179   public:
180     virtual ~ObjectGroup ();
181
182
183     /**
184      * Get the visual range of the object in meters.
185      *
186      * @return The visual range.
187      */
188     double get_range_m () const;
189
190
191     /**
192      * Get the number of objects in the group.
193      *
194      * @return The number of objects.
195      */
196     int get_object_count () const;
197
198
199     /**
200      * Get a specific object.
201      *
202      * @param index The object's index, zero-based.
203      * @return The object selected.
204      */
205     Object * get_object (int index) const;
206
207   protected:
208
209     friend class SGMaterial;
210
211     ObjectGroup (SGPropertyNode * node);
212
213   private:
214
215     double _range_m;
216     vector<Object *> _objects;
217
218   };
219
220
221
222 \f
223   ////////////////////////////////////////////////////////////////////
224   // Public Constructors.
225   ////////////////////////////////////////////////////////////////////
226
227   /**
228    * Construct a material from a set of properties.
229    *
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.
233    */
234   SGMaterial( const string &fg_root, const SGPropertyNode *props );
235
236
237   /**
238    * Construct a material from an absolute texture path.
239    *
240    * @param texture_path A string containing an absolute path
241    * to a texture file (usually RGB).
242    */
243   SGMaterial( const string &texpath );
244
245
246   /**
247    * Construct a material around an existing SSG state.
248    *
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.
252    *
253    * @param s The SSG state for this material.
254    */
255   SGMaterial( ssgSimpleState *s );
256
257   /**
258    * Destructor.
259    */
260   virtual ~SGMaterial( void );
261
262
263 \f
264   ////////////////////////////////////////////////////////////////////
265   // Public methods.
266   ////////////////////////////////////////////////////////////////////
267
268   /**
269    * Force the texture to load if it hasn't already.
270    *
271    * @return true if the texture loaded, false if it was loaded
272    * already.
273    */
274   virtual bool load_texture ();
275
276
277   /**
278    * Get the textured state.
279    */
280   virtual inline ssgSimpleState *get_state () const { return state; }
281
282
283   /**
284    * Get the xsize of the texture, in meters.
285    */
286   virtual inline double get_xsize() const { return xsize; }
287
288
289   /**
290    * Get the ysize of the texture, in meters.
291    */
292   virtual inline double get_ysize() const { return ysize; }
293
294
295   /**
296    * Get the light coverage.
297    *
298    * A smaller number means more generated night lighting.
299    *
300    * @return The area (m^2?) covered by each light.
301    */
302   virtual inline double get_light_coverage () const { return light_coverage; }
303
304
305   /**
306    * Get the number of randomly-placed objects defined for this material.
307    */
308   virtual int get_object_group_count () const { return object_groups.size(); }
309
310
311   /**
312    * Get a randomly-placed object for this material.
313    */
314   virtual ObjectGroup * get_object_group (int index) const {
315     return object_groups[index];
316   }
317
318
319   /**
320    * Increment the reference count for this material.
321    *
322    * A material with 0 references may be deleted by the
323    * material library.
324    */
325   virtual inline void ref () { refcount++; }
326
327
328   /**
329    * Decrement the reference count for this material.
330    */
331   virtual inline void deRef () { refcount--; }
332
333
334   /**
335    * Get the reference count for this material.
336    *
337    * @return The number of references (0 if none).
338    */
339   virtual inline int getRef () const { return refcount; }
340
341 protected:
342
343 \f
344   ////////////////////////////////////////////////////////////////////
345   // Protected methods.
346   ////////////////////////////////////////////////////////////////////
347
348   /**
349    * Initialization method, invoked by all public constructors.
350    */
351   virtual void init();
352
353
354 private:
355
356 \f
357   ////////////////////////////////////////////////////////////////////
358   // Internal state.
359   ////////////////////////////////////////////////////////////////////
360
361   // names
362   string texture_path;
363
364   // pointers to ssg states
365   ssgSimpleState *state;
366
367   // texture size
368   double xsize, ysize;
369
370   // wrap texture?
371   bool wrapu, wrapv;
372
373   // use mipmapping?
374   int mipmap;
375
376   // coverage of night lighting.
377   double light_coverage;
378
379   // material properties
380   sgVec4 ambient, diffuse, specular, emission;
381   double shininess;
382
383   // true if texture loading deferred, and not yet loaded
384   bool texture_loaded;
385
386   vector<ObjectGroup *> object_groups;
387
388   // ref count so we can properly delete if we have multiple
389   // pointers to this record
390   int refcount;
391
392
393 \f
394   ////////////////////////////////////////////////////////////////////
395   // Internal constructors and methods.
396   ////////////////////////////////////////////////////////////////////
397
398   SGMaterial( const string &fg_root, const SGMaterial &mat ); // unimplemented
399
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 );
403
404
405 };
406
407 #endif // _SG_MAT_HXX