]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/mat.hxx
Random buildings - initial commit.
[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  - http://www.flightgear.org/~curt
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 <string>      // Standard C++ string library
36 #include <vector>
37 #include <map>
38
39 #include <simgear/math/SGMath.hxx>
40 #include "Effect.hxx"
41 #include <simgear/scene/tgdb/SGTexturedTriangleBin.hxx>
42
43 #include <osg/ref_ptr>
44 #include <osg/Texture2D>
45
46 namespace osg
47 {
48 class StateSet;
49 }
50
51 #include <simgear/scene/util/SGReaderWriterOptions.hxx>
52 #include <simgear/props/props.hxx>
53 #include <simgear/structure/SGSharedPtr.hxx>
54 #include <simgear/scene/util/SGSceneFeatures.hxx>
55 #include <simgear/props/condition.hxx>
56
57 #include "matmodel.hxx"
58
59 namespace simgear
60 {
61 class Effect;
62 void reload_shaders();
63 }
64
65 class SGMaterialGlyph;
66
67 /**
68  * A material in the scene graph.
69  *
70  * A material represents information about a single surface type
71  * in the 3D scene graph, including texture, colour, lighting,
72  * tiling, and so on; most of the materials in FlightGear are
73  * defined in the $FG_ROOT/materials.xml file, and can be changed
74  * at runtime.
75  */
76 class SGMaterial : public SGReferenced {
77
78 public:
79
80 \f
81   ////////////////////////////////////////////////////////////////////
82   // Public Constructors.
83   ////////////////////////////////////////////////////////////////////
84
85   /**
86    * Construct a material from a set of properties.
87    *
88    * @param props A property node containing subnodes with the
89    * state information for the material.  This node is usually
90    * loaded from the $FG_ROOT/materials.xml file.
91    */
92   SGMaterial( const osgDB::Options*, 
93               const SGPropertyNode *props, 
94               SGPropertyNode *prop_root);
95
96   SGMaterial(const simgear::SGReaderWriterOptions*,
97              const SGPropertyNode *props,
98              SGPropertyNode *prop_root);
99   /**
100    * Destructor.
101    */
102   ~SGMaterial( void );
103
104
105 \f
106   ////////////////////////////////////////////////////////////////////
107   // Public methods.
108   ////////////////////////////////////////////////////////////////////
109
110   /**
111    * Get the textured state.
112    */
113   simgear::Effect* get_effect(SGTexturedTriangleBin triangleBin);
114   simgear::Effect* get_effect();
115
116   /**
117    * Get the textured state.
118    */
119   osg::Texture2D* get_object_mask(SGTexturedTriangleBin triangleBin);
120
121
122   /**
123    * Get the number of textures assigned to this material.
124    */
125   inline int get_num() const { return _status.size(); }
126
127
128   /**
129    * Get the xsize of the texture, in meters.
130    */
131   inline double get_xsize() const { return xsize; }
132
133
134   /**
135    * Get the ysize of the texture, in meters.
136    */
137   inline double get_ysize() const { return ysize; }
138
139
140   /**
141    * Get the light coverage.
142    *
143    * A smaller number means more generated night lighting.
144    *
145    * @return The area (m^2) covered by each light.
146    */
147   inline double get_light_coverage () const { return light_coverage; }
148   
149   /**
150    * Get the building coverage.
151    *
152    * A smaller number means more generated buildings.
153    *
154    * @return The area (m^2) covered by each light.
155    */
156   inline double get_building_coverage () const { return building_coverage; }
157
158   /**
159    * Get the building spacing.
160    *
161    * This is the minimum spacing between buildings
162    *
163    * @return The minimum distance between buildings
164    */
165   inline double get_building_spacing () const { return building_spacing; }
166
167   /**
168    * Get the building texture.
169    *
170    * This is the texture used for auto-generated buildings.
171    *
172    * @return The texture for auto-generated buildings.
173    */
174   inline std::string get_building_texture () const { return building_texture; }
175   
176   // Ratio of the 3 random building sizes
177   inline double get_building_small_fraction () const { return building_small_ratio / (building_small_ratio + building_medium_ratio + building_large_ratio); }
178   inline double get_building_medium_fraction () const { return building_medium_ratio / (building_small_ratio + building_medium_ratio + building_large_ratio); }
179   inline double get_building_large_fraction () const { return building_large_ratio / (building_small_ratio + building_medium_ratio + building_large_ratio); }
180   
181   // Proportion of buildings with pitched roofs
182   inline double get_building_small_pitch () const { return building_small_pitch; }
183   inline double get_building_medium_pitch () const { return building_medium_pitch; }
184   inline double get_building_large_pitch () const { return building_large_pitch; }
185
186   // Min/Max number of floors for each size
187   inline int get_building_small_min_floors () const { return  building_small_min_floors; }
188   inline int get_building_small_max_floors () const { return  building_small_max_floors; }
189   inline int get_building_medium_min_floors () const { return building_medium_min_floors; }
190   inline int get_building_medium_max_floors () const { return building_medium_max_floors; }
191   inline int get_building_large_min_floors () const { return building_large_min_floors; }
192   inline int get_building_large_max_floors () const { return building_large_max_floors; }
193   
194   // Minimum width and depth for each size
195   inline double get_building_small_min_width () const { return building_small_min_width; }
196   inline double get_building_small_max_width () const { return building_small_max_width; }
197   inline double get_building_small_min_depth () const { return building_small_min_depth; }
198   inline double get_building_small_max_depth () const { return building_small_max_depth; }
199   
200   inline double get_building_medium_min_width () const { return building_medium_min_width; }
201   inline double get_building_medium_max_width () const { return building_medium_max_width; }
202   inline double get_building_medium_min_depth () const { return building_medium_min_depth; }
203   inline double get_building_medium_max_depth () const { return building_medium_max_depth; }
204   
205   inline double get_building_large_min_width () const { return building_large_min_width; }
206   inline double get_building_large_max_width () const { return building_large_max_width; }
207   inline double get_building_large_min_depth () const { return building_large_min_depth; }
208   inline double get_building_large_max_depth () const { return building_large_max_depth; }
209
210   /**
211    * Get the wood coverage.
212    *
213    * A smaller number means more generated woods within the forest.
214    *
215    * @return The area (m^2) covered by each wood.
216    */
217   inline double get_wood_coverage () const { return wood_coverage; }
218   
219   /**
220    * Get the tree height.
221    *
222    * @return The average height of the trees.
223    */
224   inline double get_tree_height () const { return tree_height; }
225
226   /**
227    * Get the tree width.
228    *
229    * @return The average width of the trees.
230    */
231   inline double get_tree_width () const { return tree_width; }
232
233   /**
234    * Get the forest LoD range.
235    *
236    * @return The LoD range for the trees.
237    */
238   inline double get_tree_range () const { return tree_range; }
239   
240   /**
241    * Get the number of tree varieties available
242    *
243    * @return the number of different trees defined in the texture strip
244    */
245   inline int get_tree_varieties () const { return tree_varieties; }
246   
247   /**
248    * Get the texture strip to use for trees
249    *
250    * @return the texture to use for trees.
251    */
252   inline std::string get_tree_texture () const { return  tree_texture; }
253   
254   /**
255    * Return if the surface material is solid, if it is not solid, a fluid
256    * can be assumed, that is usually water.
257    */
258   bool get_solid () const { return solid; }
259
260   /**
261    * Get the friction factor for that material
262    */
263   double get_friction_factor () const { return friction_factor; }
264
265   /**
266    * Get the rolling friction for that material
267    */
268   double get_rolling_friction () const { return rolling_friction; }
269
270   /**
271    * Get the bumpines for that material
272    */
273   double get_bumpiness () const { return bumpiness; }
274
275   /**
276    * Get the load resistance
277    */
278   double get_load_resistance () const { return load_resistance; }
279
280   /**
281    * Get the list of names for this material
282    */
283   const std::vector<std::string>& get_names() const { return _names; }
284
285   /**
286    * add the given name to the list of names this material is known
287    */
288   void add_name(const std::string& name) { _names.push_back(name); }
289
290   /**
291    * Get the number of randomly-placed objects defined for this material.
292    */
293   int get_object_group_count () const { return object_groups.size(); }
294
295   /**
296    * Get a randomly-placed object for this material.
297    */
298   SGMatModelGroup * get_object_group (int index) const {
299     return object_groups[index];
300   }
301   
302   /**
303    * Evaluate whether this material is valid given the current global
304    * property state.
305    */
306    bool valid() { 
307      if (condition) {
308        return condition->test();       
309      } else {
310        return true;
311      }
312    }
313
314   /**
315    * Return pointer to glyph class, or 0 if it doesn't exist.
316    */
317   SGMaterialGlyph * get_glyph (const std::string& name) const;
318
319   void set_light_color(const SGVec4f& color)
320   { emission = color; }
321   const SGVec4f& get_light_color() const
322   { return emission; }
323
324   SGVec2f get_tex_coord_scale() const
325   {
326     float tex_width = get_xsize();
327     float tex_height = get_ysize();
328
329     return SGVec2f((0 < tex_width) ? 1000.0f/tex_width : 1.0f,
330                    (0 < tex_height) ? 1000.0f/tex_height : 1.0f);
331   }
332
333 protected:
334
335 \f
336   ////////////////////////////////////////////////////////////////////
337   // Protected methods.
338   ////////////////////////////////////////////////////////////////////
339
340   /**
341    * Initialization method, invoked by all public constructors.
342    */
343   void init();
344
345 protected:
346
347   struct _internal_state {
348       _internal_state(simgear::Effect *e, bool l,
349                       const simgear::SGReaderWriterOptions *o);
350       _internal_state(simgear::Effect *e, const std::string &t, bool l,
351                       const simgear::SGReaderWriterOptions *o);
352       void add_texture(const std::string &t, int i);
353       osg::ref_ptr<simgear::Effect> effect;
354       std::vector<std::pair<std::string,int> > texture_paths;
355       bool effect_realized;
356       osg::ref_ptr<const simgear::SGReaderWriterOptions> options;
357   };
358
359 private:
360
361 \f
362   ////////////////////////////////////////////////////////////////////
363   // Internal state.
364   ////////////////////////////////////////////////////////////////////
365
366   // texture status
367   std::vector<_internal_state> _status;
368
369   // texture size
370   double xsize, ysize;
371
372   // wrap texture?
373   bool wrapu, wrapv;
374
375   // use mipmapping?
376   bool mipmap;
377
378   // coverage of night lighting.
379   double light_coverage;
380   
381   // coverage of buildings
382   double building_coverage;
383   
384   // building spacing
385   double building_spacing;
386   
387   // building texture
388   std::string building_texture;
389
390   // Ratio of the 3 random building sizes
391   double building_small_ratio;
392   double building_medium_ratio;
393   double building_large_ratio;
394   
395   // Proportion of buildings with pitched roofs
396   double building_small_pitch;
397   double building_medium_pitch;
398   double building_large_pitch;
399
400   // Min/Max number of floors for each size
401   int building_small_min_floors; 
402   int building_small_max_floors;
403   int building_medium_min_floors;
404   int building_medium_max_floors;
405   int building_large_min_floors;
406   int building_large_max_floors;
407   
408   // Minimum width and depth for each size
409   double building_small_min_width;
410   double building_small_max_width;
411   double building_small_min_depth;
412   double building_small_max_depth;
413   
414   double building_medium_min_width;
415   double building_medium_max_width;
416   double building_medium_min_depth;
417   double building_medium_max_depth;
418   
419   double building_large_min_width;
420   double building_large_max_width;
421   double building_large_min_depth;
422   double building_large_max_depth;
423   
424   // coverage of woods
425   double wood_coverage;
426
427   // Range at which trees become visible
428   double tree_range;
429
430   // Height of the tree
431   double tree_height;
432
433   // Width of the tree
434   double tree_width;
435
436   // Number of varieties of tree texture
437   int tree_varieties;
438
439   // True if the material is solid, false if it is a fluid
440   bool solid;
441
442   // the friction factor of that surface material
443   double friction_factor;
444
445   // the rolling friction of that surface material
446   double rolling_friction;
447
448   // the bumpiness of that surface material
449   double bumpiness;
450
451   // the load resistance of that surface material
452   double load_resistance;
453
454   // material properties
455   SGVec4f ambient, diffuse, specular, emission;
456   double shininess;
457
458   // effect for this material
459   std::string effect;
460
461   // the list of names for this material. May be empty.
462   std::vector<std::string> _names;
463
464   std::vector<SGSharedPtr<SGMatModelGroup> > object_groups;
465
466   // taxiway-/runway-sign texture elements
467   std::map<std::string, SGSharedPtr<SGMaterialGlyph> > glyphs;
468   
469   // Tree texture, typically a strip of applicable tree textures
470   std::string tree_texture;
471   
472   // Object mask, a simple RGB texture used as a mask when placing
473   // random vegetation, objects and buildings
474   std::vector<osg::Texture2D*> _masks;
475   
476   // Condition, indicating when this material is active
477   SGSharedPtr<const SGCondition> condition;
478
479   ////////////////////////////////////////////////////////////////////
480   // Internal constructors and methods.
481   ////////////////////////////////////////////////////////////////////
482
483   void read_properties(const simgear::SGReaderWriterOptions* options,
484                         const SGPropertyNode *props,
485                         SGPropertyNode *prop_root);
486   void buildEffectProperties(const simgear::SGReaderWriterOptions* options);
487   simgear::Effect* get_effect(int i);
488 };
489
490
491 class SGMaterialGlyph : public SGReferenced {
492 public:
493   SGMaterialGlyph(SGPropertyNode *);
494   inline double get_left() const { return _left; }
495   inline double get_right() const { return _right; }
496   inline double get_width() const { return _right - _left; }
497
498 protected:
499   double _left;
500   double _right;
501 };
502
503 class SGMaterialUserData : public osg::Referenced {
504 public:
505   SGMaterialUserData(const SGMaterial* material) :
506     mMaterial(material)
507   {}
508   const SGMaterial* getMaterial() const
509   { return mMaterial; }
510 private:
511   // this cannot be an SGSharedPtr since that would create a cicrular reference
512   // making it impossible to ever free the space needed by SGMaterial
513   const SGMaterial* mMaterial;
514 };
515
516 void
517 SGSetTextureFilter( int max);
518
519 int
520 SGGetTextureFilter();
521
522 #endif // _SG_MAT_HXX