]> git.mxchange.org Git - flightgear.git/blob - src/Objects/newmat.hxx
This is step "1" of probably "many" in the process of separating out the
[flightgear.git] / src / Objects / newmat.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
42 SG_USING_STD(string);
43
44
45 /**
46  * A material in the scene graph.
47  *
48  * A material represents information about a single surface type
49  * in the 3D scene graph, including texture, colour, lighting,
50  * tiling, and so on; most of the materials in FlightGear are
51  * defined in the $FG_ROOT/materials.xml file, and can be changed
52  * at runtime.
53  */
54 class FGNewMat {
55
56 public:
57
58 \f
59   //////////////////////////////////////////////////////////////////////
60   // Inner classes.
61   //////////////////////////////////////////////////////////////////////
62
63   class ObjectGroup;
64
65   /**
66    * A randomly-placeable object.
67    *
68    * FGNewMat uses this class to keep track of the model(s) and
69    * parameters for a single instance of a randomly-placeable object.
70    * The object can have more than one variant model (i.e. slightly
71    * different shapes of trees), but they are considered equivalent
72    * and interchangeable.
73    */
74   class Object
75   {
76   public:
77
78     /**
79      * The heading type for a randomly-placed object.
80      */
81     enum HeadingType {
82       HEADING_FIXED,
83       HEADING_BILLBOARD,
84       HEADING_RANDOM
85     };
86
87
88     /**
89      * Get the number of variant models available for the object.
90      *
91      * @return The number of variant models.
92      */
93     int get_model_count () const;
94
95
96     /**
97      * Get a specific variant model for the object.
98      *
99      * @param index The index of the model.
100      * @return The model.
101      */
102     ssgEntity * get_model (int index) const;
103
104
105     /**
106      * Get a randomly-selected variant model for the object.
107      *
108      * @return A randomly select model from the variants.
109      */
110     ssgEntity * get_random_model () const;
111
112
113     /**
114      * Get the average number of meters^2 occupied by each instance.
115      *
116      * @return The coverage in meters^2.
117      */
118     double get_coverage_m2 () const;
119
120
121     /**
122      * Get the heading type for the object.
123      *
124      * @return The heading type.
125      */
126     HeadingType get_heading_type () const;
127
128   protected:
129
130     friend class ObjectGroup;
131
132     Object (const SGPropertyNode * node, double range_m);
133
134     virtual ~Object ();
135
136   private:
137
138     /**
139      * Actually load the models.
140      *
141      * This class uses lazy loading so that models won't be held
142      * in memory for materials that are never referenced.
143      */
144     void load_models () const;
145
146     vector<string> _paths;
147     mutable vector<ssgEntity *> _models;
148     mutable bool _models_loaded;
149     double _coverage_m2;
150     double _range_m;
151     HeadingType _heading_type;
152   };
153
154
155   /**
156    * A collection of related objects with the same visual range.
157    *
158    * Grouping objects with the same range together significantly
159    * reduces the memory requirements of randomly-placed objects.
160    * Each FGNewMat instance keeps a (possibly-empty) list of
161    * object groups for placing randomly on the scenery.
162    */
163   class ObjectGroup
164   {
165   public:
166     virtual ~ObjectGroup ();
167
168
169     /**
170      * Get the visual range of the object in meters.
171      *
172      * @return The visual range.
173      */
174     double get_range_m () const;
175
176
177     /**
178      * Get the number of objects in the group.
179      *
180      * @return The number of objects.
181      */
182     int get_object_count () const;
183
184
185     /**
186      * Get a specific object.
187      *
188      * @param index The object's index, zero-based.
189      * @return The object selected.
190      */
191     Object * get_object (int index) const;
192
193   protected:
194
195     friend class FGNewMat;
196
197     ObjectGroup (SGPropertyNode * node);
198
199   private:
200
201     double _range_m;
202     vector<Object *> _objects;
203
204   };
205
206
207
208 \f
209   ////////////////////////////////////////////////////////////////////
210   // Public Constructors.
211   ////////////////////////////////////////////////////////////////////
212
213   /**
214    * Construct a material from a set of properties.
215    *
216    * @param props A property node containing subnodes with the
217    * state information for the material.  This node is usually
218    * loaded from the $FG_ROOT/materials.xml file.
219    */
220   FGNewMat (const SGPropertyNode * props);
221
222
223   /**
224    * Construct a material from an absolute texture path.
225    *
226    * @param texture_path A string containing an absolute path
227    * to a texture file (usually RGB).
228    */
229   FGNewMat (const string &texpath);
230
231
232   /**
233    * Construct a material around an existing SSG state.
234    *
235    * This constructor allows the application to create a custom,
236    * low-level state for the scene graph and wrap a material around
237    * it.  Note: the pointer ownership is transferred to the material.
238    *
239    * @param s The SSG state for this material.
240    */
241   FGNewMat (ssgSimpleState * s);
242
243   /**
244    * Destructor.
245    */
246   virtual ~FGNewMat ( void );
247
248
249 \f
250   ////////////////////////////////////////////////////////////////////
251   // Public methods.
252   ////////////////////////////////////////////////////////////////////
253
254   /**
255    * Force the texture to load if it hasn't already.
256    *
257    * @return true if the texture loaded, false if it was loaded
258    * already.
259    */
260   virtual bool load_texture ();
261
262
263   /**
264    * Get the textured state.
265    */
266   virtual inline ssgSimpleState *get_textured () { return textured; }
267
268
269   /**
270    * Get the xsize of the texture, in meters.
271    */
272   virtual inline double get_xsize() const { return xsize; }
273
274
275   /**
276    * Get the ysize of the texture, in meters.
277    */
278   virtual inline double get_ysize() const { return ysize; }
279
280
281   /**
282    * Get the light coverage.
283    *
284    * A smaller number means more generated night lighting.
285    *
286    * @return The area (m^2?) covered by each light.
287    */
288   virtual inline double get_light_coverage () const { return light_coverage; }
289
290
291   /**
292    * Get the number of randomly-placed objects defined for this material.
293    */
294   virtual int get_object_group_count () const { return object_groups.size(); }
295
296
297   /**
298    * Get a randomly-placed object for this material.
299    */
300   virtual ObjectGroup * get_object_group (int index) const {
301     return object_groups[index];
302   }
303
304
305   /**
306    * Get the current state.
307    */
308   virtual inline ssgStateSelector *get_state () const { return state; }
309
310
311   /**
312    * Increment the reference count for this material.
313    *
314    * A material with 0 references may be deleted by the
315    * material library.
316    */
317   virtual inline void ref () { refcount++; }
318
319
320   /**
321    * Decrement the reference count for this material.
322    */
323   virtual inline void deRef () { refcount--; }
324
325
326   /**
327    * Get the reference count for this material.
328    *
329    * @return The number of references (0 if none).
330    */
331   virtual inline int getRef () const { return refcount; }
332
333 protected:
334
335 \f
336   ////////////////////////////////////////////////////////////////////
337   // Protected methods.
338   ////////////////////////////////////////////////////////////////////
339
340   /**
341    * Initialization method, invoked by all public constructors.
342    */
343   virtual void init();
344
345
346 private:
347
348 \f
349   ////////////////////////////////////////////////////////////////////
350   // Internal state.
351   ////////////////////////////////////////////////////////////////////
352
353   // names
354   string texture_path;
355
356   // pointers to ssg states
357   ssgStateSelector *state;
358   ssgSimpleState *textured;
359   ssgSimpleState *nontextured;
360
361   // texture size
362   double xsize, ysize;
363
364   // wrap texture?
365   bool wrapu, wrapv;
366
367   // use mipmapping?
368   int mipmap;
369
370   // coverage of night lighting.
371   double light_coverage;
372
373   // material properties
374   sgVec4 ambient, diffuse, specular, emission;
375   double shininess;
376
377   // true if texture loading deferred, and not yet loaded
378   bool texture_loaded;
379
380   vector<ObjectGroup *> object_groups;
381
382   // ref count so we can properly delete if we have multiple
383   // pointers to this record
384   int refcount;
385
386
387 \f
388   ////////////////////////////////////////////////////////////////////
389   // Internal constructors and methods.
390   ////////////////////////////////////////////////////////////////////
391
392   FGNewMat (const FGNewMat &mat); // unimplemented
393
394   void read_properties (const SGPropertyNode * props);
395   void build_ssg_state(bool defer_tex_load = false);
396   void set_ssg_state( ssgSimpleState *s );
397
398
399 };
400
401 #endif // _NEWMAT_HXX