]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/mat.hxx
Moved fgfs_src/Object/newmat.[ch]xx and fgfs_src/Object/matlib.[ch]xx into
[simgear.git] / simgear / scene / material / mat.hxx
1 // newmat.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 _NEWMAT_HXX
27 #define _NEWMAT_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 FGNewMat {
56
57 public:
58
59 \f
60   //////////////////////////////////////////////////////////////////////
61   // Inner classes.
62   //////////////////////////////////////////////////////////////////////
63
64   class ObjectGroup;
65
66   /**
67    * A randomly-placeable object.
68    *
69    * FGNewMat 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( FGModelLoader *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                           FGModelLoader *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( FGModelLoader *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( FGModelLoader *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 FGNewMat 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 FGNewMat;
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   FGNewMat( const string &fg_root, const SGPropertyNode *props,
235             bool smooth_shading, bool use_textures );
236
237
238   /**
239    * Construct a material from an absolute texture path.
240    *
241    * @param texture_path A string containing an absolute path
242    * to a texture file (usually RGB).
243    */
244   FGNewMat( const string &texpath, bool smooth_shading, bool use_textures );
245
246
247   /**
248    * Construct a material around an existing SSG state.
249    *
250    * This constructor allows the application to create a custom,
251    * low-level state for the scene graph and wrap a material around
252    * it.  Note: the pointer ownership is transferred to the material.
253    *
254    * @param s The SSG state for this material.
255    */
256   FGNewMat( ssgSimpleState *s, bool smooth_shading, bool use_textures );
257
258   /**
259    * Destructor.
260    */
261   virtual ~FGNewMat( void );
262
263
264 \f
265   ////////////////////////////////////////////////////////////////////
266   // Public methods.
267   ////////////////////////////////////////////////////////////////////
268
269   /**
270    * Force the texture to load if it hasn't already.
271    *
272    * @return true if the texture loaded, false if it was loaded
273    * already.
274    */
275   virtual bool load_texture ();
276
277
278   /**
279    * Get the textured state.
280    */
281   virtual inline ssgSimpleState *get_textured () { return textured; }
282
283
284   /**
285    * Get the xsize of the texture, in meters.
286    */
287   virtual inline double get_xsize() const { return xsize; }
288
289
290   /**
291    * Get the ysize of the texture, in meters.
292    */
293   virtual inline double get_ysize() const { return ysize; }
294
295
296   /**
297    * Get the light coverage.
298    *
299    * A smaller number means more generated night lighting.
300    *
301    * @return The area (m^2?) covered by each light.
302    */
303   virtual inline double get_light_coverage () const { return light_coverage; }
304
305
306   /**
307    * Get the number of randomly-placed objects defined for this material.
308    */
309   virtual int get_object_group_count () const { return object_groups.size(); }
310
311
312   /**
313    * Get a randomly-placed object for this material.
314    */
315   virtual ObjectGroup * get_object_group (int index) const {
316     return object_groups[index];
317   }
318
319
320   /**
321    * Get the current state.
322    */
323   virtual inline ssgStateSelector *get_state () const { return state; }
324
325
326   /**
327    * Increment the reference count for this material.
328    *
329    * A material with 0 references may be deleted by the
330    * material library.
331    */
332   virtual inline void ref () { refcount++; }
333
334
335   /**
336    * Decrement the reference count for this material.
337    */
338   virtual inline void deRef () { refcount--; }
339
340
341   /**
342    * Get the reference count for this material.
343    *
344    * @return The number of references (0 if none).
345    */
346   virtual inline int getRef () const { return refcount; }
347
348 protected:
349
350 \f
351   ////////////////////////////////////////////////////////////////////
352   // Protected methods.
353   ////////////////////////////////////////////////////////////////////
354
355   /**
356    * Initialization method, invoked by all public constructors.
357    */
358   virtual void init();
359
360
361 private:
362
363 \f
364   ////////////////////////////////////////////////////////////////////
365   // Internal state.
366   ////////////////////////////////////////////////////////////////////
367
368   // names
369   string texture_path;
370
371   // pointers to ssg states
372   ssgStateSelector *state;
373   ssgSimpleState *textured;
374   ssgSimpleState *nontextured;
375
376   // texture size
377   double xsize, ysize;
378
379   // wrap texture?
380   bool wrapu, wrapv;
381
382   // use mipmapping?
383   int mipmap;
384
385   // coverage of night lighting.
386   double light_coverage;
387
388   // material properties
389   sgVec4 ambient, diffuse, specular, emission;
390   double shininess;
391
392   // true if texture loading deferred, and not yet loaded
393   bool texture_loaded;
394
395   vector<ObjectGroup *> object_groups;
396
397   // ref count so we can properly delete if we have multiple
398   // pointers to this record
399   int refcount;
400
401
402 \f
403   ////////////////////////////////////////////////////////////////////
404   // Internal constructors and methods.
405   ////////////////////////////////////////////////////////////////////
406
407   FGNewMat( const string &fg_root, const FGNewMat &mat ); // unimplemented
408
409   void read_properties( const string &fg_root, const SGPropertyNode *props );
410   void build_ssg_state( bool defer_tex_load,
411                         bool smooth_shading,
412                         bool use_textures );
413   void set_ssg_state( ssgSimpleState *s,
414                       bool smooth_shading, bool use_textures );
415
416
417 };
418
419 #endif // _NEWMAT_HXX