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