]> git.mxchange.org Git - simgear.git/commitdiff
Rename matobj -> matmodel.
authorcurt <curt>
Thu, 15 May 2003 16:19:56 +0000 (16:19 +0000)
committercurt <curt>
Thu, 15 May 2003 16:19:56 +0000 (16:19 +0000)
simgear/scene/material/Makefile.am
simgear/scene/material/mat.cxx
simgear/scene/material/mat.hxx
simgear/scene/material/matmodel.cxx [new file with mode: 0644]
simgear/scene/material/matmodel.hxx [new file with mode: 0644]
simgear/scene/material/matobj.cxx [deleted file]
simgear/scene/material/matobj.hxx [deleted file]

index f781c0016a74497801ec273bf3dd47214ad54d42..fc0059c313871d214c765f9a8175522ea5833746 100644 (file)
@@ -7,11 +7,11 @@ noinst_HEADERS =
 include_HEADERS = \
        mat.hxx \
        matlib.hxx \
-       matobj.hxx
+       matmodel.hxx
 
 libsgmaterial_a_SOURCES = \
        mat.cxx \
        matlib.cxx \
-       matobj.cxx
+       matmodel.cxx
 
 INCLUDES = -I$(top_srcdir)
index d81947e75f0ca13df680c38cb507408d55e6ecf5..0e505de5f9d05bbf6cb9595faff059ee4bead355 100644 (file)
@@ -153,7 +153,7 @@ SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props
   vector<SGPropertyNode_ptr> object_group_nodes =
     ((SGPropertyNode *)props)->getChildren("object-group");
   for (unsigned int i = 0; i < object_group_nodes.size(); i++)
-    object_groups.push_back(new SGMatObjectGroup(object_group_nodes[i]));
+    object_groups.push_back(new SGMatModelGroup(object_group_nodes[i]));
 }
 
 
index 12e545452c6f6e9d2ddcee3daa2b0c17236c9f26..98697f0ef8f3fa22c00fde8393fccabb026536e3 100644 (file)
@@ -40,7 +40,7 @@
 #include <simgear/props/props.hxx>
 #include <simgear/scene/model/loader.hxx>
 
-#include "matobj.hxx"
+#include "matmodel.hxx"
 
 SG_USING_STD(string);
 
@@ -150,7 +150,7 @@ public:
   /**
    * Get a randomly-placed object for this material.
    */
-  virtual SGMatObjectGroup * get_object_group (int index) const {
+  virtual SGMatModelGroup * get_object_group (int index) const {
     return object_groups[index];
   }
 
@@ -222,7 +222,7 @@ private:
   // true if texture loading deferred, and not yet loaded
   bool texture_loaded;
 
-  vector<SGMatObjectGroup *> object_groups;
+  vector<SGMatModelGroup *> object_groups;
 
   // ref count so we can properly delete if we have multiple
   // pointers to this record
diff --git a/simgear/scene/material/matmodel.cxx b/simgear/scene/material/matmodel.cxx
new file mode 100644 (file)
index 0000000..24f8c86
--- /dev/null
@@ -0,0 +1,250 @@
+// matmodel.cxx -- class to handle models tied to a material property
+//
+// Written by Curtis Olson, started May 1998.
+//
+// Copyright (C) 1998 - 2003  Curtis L. Olson  - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifdef HAVE_CONFIG_H
+#  include <simgear_config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include <map>
+SG_USING_STD(map);
+
+#include <simgear/compiler.h>
+
+#ifdef SG_MATH_EXCEPTION_CLASH
+#  include <math.h>
+#endif
+
+#include <simgear/debug/logstream.hxx>
+#include <simgear/math/sg_random.h>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/misc/sgstream.hxx>
+#include <simgear/scene/model/loader.hxx>
+
+#include "matmodel.hxx"
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Local static functions.
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * Internal method to test whether a file exists.
+ *
+ * TODO: this should be moved to a SimGear library of local file
+ * functions.
+ */
+static inline bool
+local_file_exists( const string& path ) {
+    sg_gzifstream in( path );
+    if ( ! in.is_open() ) {
+       return false;
+    } else {
+       return true;
+    }
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGMatModel.
+////////////////////////////////////////////////////////////////////////
+
+SGMatModel::SGMatModel (const SGPropertyNode * node, double range_m)
+  : _models_loaded(false),
+    _coverage_m2(node->getDoubleValue("coverage-m2", 1000000)),
+    _range_m(range_m)
+{
+                               // Sanity check
+  if (_coverage_m2 < 1000) {
+    SG_LOG(SG_INPUT, SG_ALERT, "Random object coverage " << _coverage_m2
+          << " is too small, forcing, to 1000");
+    _coverage_m2 = 1000;
+  }
+
+                               // Note all the model paths
+  vector <SGPropertyNode_ptr> path_nodes = node->getChildren("path");
+  for (unsigned int i = 0; i < path_nodes.size(); i++)
+    _paths.push_back(path_nodes[i]->getStringValue());
+
+                               // Note the heading type
+  string hdg = node->getStringValue("heading-type", "fixed");
+  if (hdg == "fixed") {
+    _heading_type = HEADING_FIXED;
+  } else if (hdg == "billboard") {
+    _heading_type = HEADING_BILLBOARD;
+  } else if (hdg == "random") {
+    _heading_type = HEADING_RANDOM;
+  } else {
+    _heading_type = HEADING_FIXED;
+    SG_LOG(SG_INPUT, SG_ALERT, "Unknown heading type: " << hdg
+          << "; using 'fixed' instead.");
+  }
+
+  // uncomment to preload models
+  // load_models();
+}
+
+SGMatModel::~SGMatModel ()
+{
+  for (unsigned int i = 0; i < _models.size(); i++) {
+    if (_models[i] != 0) {
+      _models[i]->deRef();
+      _models[i] = 0;
+    }
+  }
+}
+
+int
+SGMatModel::get_model_count( SGModelLoader *loader,
+                                   const string &fg_root,
+                                   SGPropertyNode *prop_root,
+                                   double sim_time_sec )
+{
+  load_models( loader, fg_root, prop_root, sim_time_sec );
+  return _models.size();
+}
+
+inline void
+SGMatModel::load_models ( SGModelLoader *loader,
+                                const string &fg_root,
+                                SGPropertyNode *prop_root,
+                                double sim_time_sec )
+{
+                               // Load model only on demand
+  if (!_models_loaded) {
+    for (unsigned int i = 0; i < _paths.size(); i++) {
+      ssgEntity *entity = loader->load_model( fg_root, _paths[i],
+                                              prop_root, sim_time_sec );
+      if (entity != 0) {
+                                // FIXME: this stuff can be handled
+                                // in the XML wrapper as well (at least,
+                                // the billboarding should be handled
+                                // there).
+       float ranges[] = {0, _range_m};
+       ssgRangeSelector * lod = new ssgRangeSelector;
+        lod->ref();
+        lod->setRanges(ranges, 2);
+       if (_heading_type == HEADING_BILLBOARD) {
+         ssgCutout * cutout = new ssgCutout(false);
+         cutout->addKid(entity);
+         lod->addKid(cutout);
+       } else {
+         lod->addKid(entity);
+       }
+       _models.push_back(lod);
+      } else {
+       SG_LOG(SG_INPUT, SG_ALERT, "Failed to load object " << _paths[i]);
+      }
+    }
+  }
+  _models_loaded = true;
+}
+
+ssgEntity *
+SGMatModel::get_model( int index,
+                               SGModelLoader *loader,
+                               const string &fg_root,
+                               SGPropertyNode *prop_root,
+                               double sim_time_sec )
+{
+  load_models( loader, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
+  return _models[index];
+}
+
+ssgEntity *
+SGMatModel::get_random_model( SGModelLoader *loader,
+                                      const string &fg_root,
+                                      SGPropertyNode *prop_root,
+                                      double sim_time_sec )
+{
+  load_models( loader, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
+  int nModels = _models.size();
+  int index = int(sg_random() * nModels);
+  if (index >= nModels)
+    index = 0;
+  return _models[index];
+}
+
+double
+SGMatModel::get_coverage_m2 () const
+{
+  return _coverage_m2;
+}
+
+SGMatModel::HeadingType
+SGMatModel::get_heading_type () const
+{
+  return _heading_type;
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of SGMatModelGroup.
+////////////////////////////////////////////////////////////////////////
+
+SGMatModelGroup::SGMatModelGroup (SGPropertyNode * node)
+  : _range_m(node->getDoubleValue("range-m", 2000))
+{
+                               // Load the object subnodes
+  vector<SGPropertyNode_ptr> object_nodes =
+    ((SGPropertyNode *)node)->getChildren("object");
+  for (unsigned int i = 0; i < object_nodes.size(); i++) {
+    const SGPropertyNode * object_node = object_nodes[i];
+    if (object_node->hasChild("path"))
+      _objects.push_back(new SGMatModel(object_node, _range_m));
+    else
+      SG_LOG(SG_INPUT, SG_ALERT, "No path supplied for object");
+  }
+}
+
+SGMatModelGroup::~SGMatModelGroup ()
+{
+  for (unsigned int i = 0; i < _objects.size(); i++) {
+    delete _objects[i];
+    _objects[i] = 0;
+  }
+}
+
+double
+SGMatModelGroup::get_range_m () const
+{
+  return _range_m;
+}
+
+int
+SGMatModelGroup::get_object_count () const
+{
+  return _objects.size();
+}
+
+SGMatModel *
+SGMatModelGroup::get_object (int index) const
+{
+  return _objects[index];
+}
+
+
+// end of matmodel.cxx
diff --git a/simgear/scene/material/matmodel.hxx b/simgear/scene/material/matmodel.hxx
new file mode 100644 (file)
index 0000000..33d769e
--- /dev/null
@@ -0,0 +1,202 @@
+// matmodel.hxx -- class to handle models tied to a material property
+//
+// Written by David Megginson, December 2001
+//
+// Copyright (C) 1998 - 2003  Curtis L. Olson  - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifndef _SG_MAT_MODEL_HXX
+#define _SG_MAT_MODEL_HXX
+
+#ifndef __cplusplus                                                          
+# error This library requires C++
+#endif                                   
+
+#include <simgear/compiler.h>
+
+#include STL_STRING      // Standard C++ string library
+
+#include <plib/sg.h>
+#include <plib/ssg.h>
+
+#include <simgear/props/props.hxx>
+#include <simgear/scene/model/loader.hxx>
+
+SG_USING_STD(string);
+
+
+class SGMatModelGroup;
+
+
+/**
+ * A randomly-placeable object.
+ *
+ * SGMaterial uses this class to keep track of the model(s) and
+ * parameters for a single instance of a randomly-placeable object.
+ * The object can have more than one variant model (i.e. slightly
+ * different shapes of trees), but they are considered equivalent
+ * and interchangeable.
+ */
+class SGMatModel {
+
+public:
+
+    /**
+     * The heading type for a randomly-placed object.
+     */
+    enum HeadingType {
+        HEADING_FIXED,
+        HEADING_BILLBOARD,
+        HEADING_RANDOM
+    };
+
+    /**
+     * Get the number of variant models available for the object.
+     *
+     * @return The number of variant models.
+     */
+    int get_model_count( SGModelLoader *loader,
+                         const string &fg_root,
+                         SGPropertyNode *prop_root,
+                         double sim_time_sec );
+
+
+    /**
+     * Get a specific variant model for the object.
+     *
+     * @param index The index of the model.
+     * @return The model.
+     */
+    ssgEntity *get_model( int index,
+                          SGModelLoader *loader,
+                          const string &fg_root,
+                          SGPropertyNode *prop_root,
+                          double sim_time_sec );
+
+
+    /**
+     * Get a randomly-selected variant model for the object.
+     *
+     * @return A randomly select model from the variants.
+     */
+    ssgEntity *get_random_model( SGModelLoader *loader,
+                                 const string &fg_root,
+                                 SGPropertyNode *prop_root,
+                                 double sim_time_sec );
+
+
+    /**
+     * Get the average number of meters^2 occupied by each instance.
+     *
+     * @return The coverage in meters^2.
+     */
+    double get_coverage_m2 () const;
+
+
+    /**
+     * Get the heading type for the object.
+     *
+     * @return The heading type.
+     */
+    HeadingType get_heading_type () const;
+
+protected:
+
+    friend class SGMatModelGroup;
+
+    SGMatModel (const SGPropertyNode * node, double range_m);
+
+    virtual ~SGMatModel ();
+
+private:
+
+    /**
+     * Actually load the models.
+     *
+     * This class uses lazy loading so that models won't be held
+     * in memory for materials that are never referenced.
+     */
+    void load_models( SGModelLoader *loader,
+                      const string &fg_root,
+                      SGPropertyNode *prop_root,
+                      double sim_time_sec );
+
+    vector<string> _paths;
+    mutable vector<ssgEntity *> _models;
+    mutable bool _models_loaded;
+    double _coverage_m2;
+    double _range_m;
+    HeadingType _heading_type;
+};
+
+
+/**
+ * A collection of related objects with the same visual range.
+ *
+ * Grouping objects with the same range together significantly
+ * reduces the memory requirements of randomly-placed objects.
+ * Each SGMaterial instance keeps a (possibly-empty) list of
+ * object groups for placing randomly on the scenery.
+ */
+class SGMatModelGroup {
+
+public:
+
+    virtual ~SGMatModelGroup ();
+
+
+    /**
+     * Get the visual range of the object in meters.
+     *
+     * @return The visual range.
+     */
+    double get_range_m () const;
+
+
+    /**
+     * Get the number of objects in the group.
+     *
+     * @return The number of objects.
+     */
+    int get_object_count () const;
+
+
+    /**
+     * Get a specific object.
+     *
+     * @param index The object's index, zero-based.
+     * @return The object selected.
+     */
+    SGMatModel * get_object (int index) const;
+
+protected:
+
+    friend class SGMaterial;
+
+    SGMatModelGroup (SGPropertyNode * node);
+
+private:
+
+    double _range_m;
+    vector<SGMatModel *> _objects;
+
+};
+
+
+#endif // _SG_MAT_MODEL_HXX 
diff --git a/simgear/scene/material/matobj.cxx b/simgear/scene/material/matobj.cxx
deleted file mode 100644 (file)
index 9f581d6..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-// matobj.cxx -- class to handle material properties
-//
-// Written by Curtis Olson, started May 1998.
-//
-// Copyright (C) 1998 - 2003  Curtis L. Olson  - curt@flightgear.org
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-
-
-#ifdef HAVE_CONFIG_H
-#  include <simgear_config.h>
-#endif
-
-#include <simgear/compiler.h>
-
-#include <map>
-SG_USING_STD(map);
-
-#include <simgear/compiler.h>
-
-#ifdef SG_MATH_EXCEPTION_CLASH
-#  include <math.h>
-#endif
-
-#include <simgear/debug/logstream.hxx>
-#include <simgear/math/sg_random.h>
-#include <simgear/misc/sg_path.hxx>
-#include <simgear/misc/sgstream.hxx>
-#include <simgear/scene/model/loader.hxx>
-
-#include "matobj.hxx"
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Local static functions.
-////////////////////////////////////////////////////////////////////////
-
-/**
- * Internal method to test whether a file exists.
- *
- * TODO: this should be moved to a SimGear library of local file
- * functions.
- */
-static inline bool
-local_file_exists( const string& path ) {
-    sg_gzifstream in( path );
-    if ( ! in.is_open() ) {
-       return false;
-    } else {
-       return true;
-    }
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of SGMatObject.
-////////////////////////////////////////////////////////////////////////
-
-SGMatObject::SGMatObject (const SGPropertyNode * node, double range_m)
-  : _models_loaded(false),
-    _coverage_m2(node->getDoubleValue("coverage-m2", 1000000)),
-    _range_m(range_m)
-{
-                               // Sanity check
-  if (_coverage_m2 < 1000) {
-    SG_LOG(SG_INPUT, SG_ALERT, "Random object coverage " << _coverage_m2
-          << " is too small, forcing, to 1000");
-    _coverage_m2 = 1000;
-  }
-
-                               // Note all the model paths
-  vector <SGPropertyNode_ptr> path_nodes = node->getChildren("path");
-  for (unsigned int i = 0; i < path_nodes.size(); i++)
-    _paths.push_back(path_nodes[i]->getStringValue());
-
-                               // Note the heading type
-  string hdg = node->getStringValue("heading-type", "fixed");
-  if (hdg == "fixed") {
-    _heading_type = HEADING_FIXED;
-  } else if (hdg == "billboard") {
-    _heading_type = HEADING_BILLBOARD;
-  } else if (hdg == "random") {
-    _heading_type = HEADING_RANDOM;
-  } else {
-    _heading_type = HEADING_FIXED;
-    SG_LOG(SG_INPUT, SG_ALERT, "Unknown heading type: " << hdg
-          << "; using 'fixed' instead.");
-  }
-
-  // uncomment to preload models
-  // load_models();
-}
-
-SGMatObject::~SGMatObject ()
-{
-  for (unsigned int i = 0; i < _models.size(); i++) {
-    if (_models[i] != 0) {
-      _models[i]->deRef();
-      _models[i] = 0;
-    }
-  }
-}
-
-int
-SGMatObject::get_model_count( SGModelLoader *loader,
-                                   const string &fg_root,
-                                   SGPropertyNode *prop_root,
-                                   double sim_time_sec )
-{
-  load_models( loader, fg_root, prop_root, sim_time_sec );
-  return _models.size();
-}
-
-inline void
-SGMatObject::load_models ( SGModelLoader *loader,
-                                const string &fg_root,
-                                SGPropertyNode *prop_root,
-                                double sim_time_sec )
-{
-                               // Load model only on demand
-  if (!_models_loaded) {
-    for (unsigned int i = 0; i < _paths.size(); i++) {
-      ssgEntity *entity = loader->load_model( fg_root, _paths[i],
-                                              prop_root, sim_time_sec );
-      if (entity != 0) {
-                                // FIXME: this stuff can be handled
-                                // in the XML wrapper as well (at least,
-                                // the billboarding should be handled
-                                // there).
-       float ranges[] = {0, _range_m};
-       ssgRangeSelector * lod = new ssgRangeSelector;
-        lod->ref();
-        lod->setRanges(ranges, 2);
-       if (_heading_type == HEADING_BILLBOARD) {
-         ssgCutout * cutout = new ssgCutout(false);
-         cutout->addKid(entity);
-         lod->addKid(cutout);
-       } else {
-         lod->addKid(entity);
-       }
-       _models.push_back(lod);
-      } else {
-       SG_LOG(SG_INPUT, SG_ALERT, "Failed to load object " << _paths[i]);
-      }
-    }
-  }
-  _models_loaded = true;
-}
-
-ssgEntity *
-SGMatObject::get_model( int index,
-                               SGModelLoader *loader,
-                               const string &fg_root,
-                               SGPropertyNode *prop_root,
-                               double sim_time_sec )
-{
-  load_models( loader, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
-  return _models[index];
-}
-
-ssgEntity *
-SGMatObject::get_random_model( SGModelLoader *loader,
-                                      const string &fg_root,
-                                      SGPropertyNode *prop_root,
-                                      double sim_time_sec )
-{
-  load_models( loader, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
-  int nModels = _models.size();
-  int index = int(sg_random() * nModels);
-  if (index >= nModels)
-    index = 0;
-  return _models[index];
-}
-
-double
-SGMatObject::get_coverage_m2 () const
-{
-  return _coverage_m2;
-}
-
-SGMatObject::HeadingType
-SGMatObject::get_heading_type () const
-{
-  return _heading_type;
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of SGMatObjectGroup.
-////////////////////////////////////////////////////////////////////////
-
-SGMatObjectGroup::SGMatObjectGroup (SGPropertyNode * node)
-  : _range_m(node->getDoubleValue("range-m", 2000))
-{
-                               // Load the object subnodes
-  vector<SGPropertyNode_ptr> object_nodes =
-    ((SGPropertyNode *)node)->getChildren("object");
-  for (unsigned int i = 0; i < object_nodes.size(); i++) {
-    const SGPropertyNode * object_node = object_nodes[i];
-    if (object_node->hasChild("path"))
-      _objects.push_back(new SGMatObject(object_node, _range_m));
-    else
-      SG_LOG(SG_INPUT, SG_ALERT, "No path supplied for object");
-  }
-}
-
-SGMatObjectGroup::~SGMatObjectGroup ()
-{
-  for (unsigned int i = 0; i < _objects.size(); i++) {
-    delete _objects[i];
-    _objects[i] = 0;
-  }
-}
-
-double
-SGMatObjectGroup::get_range_m () const
-{
-  return _range_m;
-}
-
-int
-SGMatObjectGroup::get_object_count () const
-{
-  return _objects.size();
-}
-
-SGMatObject *
-SGMatObjectGroup::get_object (int index) const
-{
-  return _objects[index];
-}
-
-
-// end of matobj.cxx
diff --git a/simgear/scene/material/matobj.hxx b/simgear/scene/material/matobj.hxx
deleted file mode 100644 (file)
index 8d92b5f..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-// matobj.hxx -- a material in the scene graph.
-// TODO: this class needs to be renamed.
-//
-// Written by Curtis Olson, started May 1998.
-// Overhauled by David Megginson, December 2001
-//
-// Copyright (C) 1998 - 2003  Curtis L. Olson  - curt@flightgear.org
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-
-
-#ifndef _SG_MAT_OBJ_HXX
-#define _SG_MAT_OBJ_HXX
-
-#ifndef __cplusplus                                                          
-# error This library requires C++
-#endif                                   
-
-#include <simgear/compiler.h>
-
-#include STL_STRING      // Standard C++ string library
-
-#include <plib/sg.h>
-#include <plib/ssg.h>
-
-#include <simgear/props/props.hxx>
-#include <simgear/scene/model/loader.hxx>
-
-SG_USING_STD(string);
-
-
-class SGMatObjectGroup;
-
-
-/**
- * A randomly-placeable object.
- *
- * SGMaterial uses this class to keep track of the model(s) and
- * parameters for a single instance of a randomly-placeable object.
- * The object can have more than one variant model (i.e. slightly
- * different shapes of trees), but they are considered equivalent
- * and interchangeable.
- */
-class SGMatObject {
-
-public:
-
-    /**
-     * The heading type for a randomly-placed object.
-     */
-    enum HeadingType {
-        HEADING_FIXED,
-        HEADING_BILLBOARD,
-        HEADING_RANDOM
-    };
-
-    /**
-     * Get the number of variant models available for the object.
-     *
-     * @return The number of variant models.
-     */
-    int get_model_count( SGModelLoader *loader,
-                         const string &fg_root,
-                         SGPropertyNode *prop_root,
-                         double sim_time_sec );
-
-
-    /**
-     * Get a specific variant model for the object.
-     *
-     * @param index The index of the model.
-     * @return The model.
-     */
-    ssgEntity *get_model( int index,
-                          SGModelLoader *loader,
-                          const string &fg_root,
-                          SGPropertyNode *prop_root,
-                          double sim_time_sec );
-
-
-    /**
-     * Get a randomly-selected variant model for the object.
-     *
-     * @return A randomly select model from the variants.
-     */
-    ssgEntity *get_random_model( SGModelLoader *loader,
-                                 const string &fg_root,
-                                 SGPropertyNode *prop_root,
-                                 double sim_time_sec );
-
-
-    /**
-     * Get the average number of meters^2 occupied by each instance.
-     *
-     * @return The coverage in meters^2.
-     */
-    double get_coverage_m2 () const;
-
-
-    /**
-     * Get the heading type for the object.
-     *
-     * @return The heading type.
-     */
-    HeadingType get_heading_type () const;
-
-protected:
-
-    friend class SGMatObjectGroup;
-
-    SGMatObject (const SGPropertyNode * node, double range_m);
-
-    virtual ~SGMatObject ();
-
-private:
-
-    /**
-     * Actually load the models.
-     *
-     * This class uses lazy loading so that models won't be held
-     * in memory for materials that are never referenced.
-     */
-    void load_models( SGModelLoader *loader,
-                      const string &fg_root,
-                      SGPropertyNode *prop_root,
-                      double sim_time_sec );
-
-    vector<string> _paths;
-    mutable vector<ssgEntity *> _models;
-    mutable bool _models_loaded;
-    double _coverage_m2;
-    double _range_m;
-    HeadingType _heading_type;
-};
-
-
-/**
- * A collection of related objects with the same visual range.
- *
- * Grouping objects with the same range together significantly
- * reduces the memory requirements of randomly-placed objects.
- * Each SGMaterial instance keeps a (possibly-empty) list of
- * object groups for placing randomly on the scenery.
- */
-class SGMatObjectGroup {
-
-public:
-
-    virtual ~SGMatObjectGroup ();
-
-
-    /**
-     * Get the visual range of the object in meters.
-     *
-     * @return The visual range.
-     */
-    double get_range_m () const;
-
-
-    /**
-     * Get the number of objects in the group.
-     *
-     * @return The number of objects.
-     */
-    int get_object_count () const;
-
-
-    /**
-     * Get a specific object.
-     *
-     * @param index The object's index, zero-based.
-     * @return The object selected.
-     */
-    SGMatObject * get_object (int index) const;
-
-protected:
-
-    friend class SGMaterial;
-
-    SGMatObjectGroup (SGPropertyNode * node);
-
-private:
-
-    double _range_m;
-    vector<SGMatObject *> _objects;
-
-};
-
-
-
-#endif // _SG_MAT_OBJ_HXX