]> git.mxchange.org Git - flightgear.git/commitdiff
Moved object information into a new subclass of FGNewMat, and changed
authordavid <david>
Sat, 20 Jul 2002 01:51:27 +0000 (01:51 +0000)
committerdavid <david>
Sat, 20 Jul 2002 01:51:27 +0000 (01:51 +0000)
the property name from coverage to coverage_m2.

src/Objects/newmat.cxx
src/Objects/newmat.hxx
src/Objects/obj.cxx

index 919039293735621ebecdb781e1187af8f3d70837..8a3da39e40c663147b5ef54b98802dd71896ab1a 100644 (file)
@@ -90,6 +90,83 @@ local_file_exists( const string& path ) {
 }
 
 
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGNewMat::Object.
+////////////////////////////////////////////////////////////////////////
+
+FGNewMat::Object::Object (const SGPropertyNode * node)
+  : _path(node->getStringValue("path")),
+    _model(0),
+    _coverage_m2(node->getDoubleValue("coverage-m2", 100000)),
+    _range_m(node->getDoubleValue("range-m", 2000))
+{
+  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.");
+  }
+}
+
+FGNewMat::Object::~Object ()
+{
+  _model->deRef();
+}
+
+const string &
+FGNewMat::Object::get_path () const
+{
+  return _path;
+}
+
+ssgEntity *
+FGNewMat::Object::get_model () const
+{
+                               // Load model only on demand
+  if (_model == 0) {
+    SGPath path = globals->get_fg_root();
+    path.append(_path);
+    ssgTexturePath((char *)path.dir().c_str());
+    ssgEntity * entity = load_object((char *)path.c_str());
+    if (entity != 0) {
+      float ranges[] = {0, _range_m};
+      _model = new ssgRangeSelector;
+      ((ssgRangeSelector *)_model)->setRanges(ranges, 2);
+      if (_heading_type == HEADING_BILLBOARD) {
+       ssgCutout * cutout = new ssgCutout(false);
+       cutout->addKid(entity);
+       ((ssgBranch *)_model)->addKid(cutout);
+      } else {
+       ((ssgBranch *)_model)->addKid(entity);
+      }
+      _model->ref();
+    } else {
+      SG_LOG(SG_INPUT, SG_ALERT, "Failed to load object " << path.str());
+    }
+  }
+  return _model;
+}
+
+double
+FGNewMat::Object::get_coverage_m2 () const
+{
+  return _coverage_m2;
+}
+
+double
+FGNewMat::Object::get_range_m () const
+{
+  return _range_m;
+}
+
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // Constructors and destructor.
@@ -118,8 +195,10 @@ FGNewMat::FGNewMat (ssgSimpleState * s)
 
 FGNewMat::~FGNewMat (void)
 {
-  for (unsigned int i = 0; i < objects.size(); i++)
-    objects[i].model->deRef();
+  for (unsigned int i = 0; i < objects.size(); i++) {
+    delete objects[i];
+    objects[i] = 0;
+  }
 }
 
 
@@ -174,33 +253,10 @@ FGNewMat::read_properties (const SGPropertyNode * props)
     ((SGPropertyNode *)props)->getChildren("object");
   for (unsigned int i = 0; i < object_nodes.size(); i++) {
     const SGPropertyNode * object_node = object_nodes[i];
-    if (object_node->hasChild("path")) {
-      Object object;
-      SGPath path = globals->get_fg_root();
-      path.append(object_node->getStringValue("path"));
-      ssgTexturePath((char *)path.dir().c_str());
-      ssgEntity * model = load_object((char *)path.c_str());
-      if (model != 0) {
-       float ranges[] = {0, object_node->getDoubleValue("range-m", 2000)};
-       object.model = new ssgRangeSelector;
-       ((ssgRangeSelector *)object.model)->setRanges(ranges, 2);
-       if (object_node->getBoolValue("billboard", false)) {
-         ssgCutout * cutout = new ssgCutout(false);
-         cutout->addKid(model);
-         ((ssgBranch *)object.model)->addKid(cutout);
-       } else {
-         ((ssgBranch *)object.model)->addKid(model);
-       }
-       object.model->ref();
-       object.coverage = object_node->getDoubleValue("coverage", 100000);
-       object.lod = object_node->getDoubleValue("range-m", 2000);
-       objects.push_back(object);
-      } else {
-       SG_LOG(SG_INPUT, SG_ALERT, "Failed to load object " << path.str());
-      }
-    } else {
+    if (object_node->hasChild("path"))
+      objects.push_back(new Object(object_node));
+    else
       SG_LOG(SG_INPUT, SG_ALERT, "No path supplied for object");
-    }
   }
 }
 
index 3e9f05a661b4735fb8648428b569c00de29d0932..5060517889a74b1103e30c333c2746b06523931b 100644 (file)
@@ -64,6 +64,43 @@ class FGNewMat {
 
 public:
 
+\f
+  //////////////////////////////////////////////////////////////////////
+  // Inner class.
+  //////////////////////////////////////////////////////////////////////
+
+
+  /**
+   * A randomly-placeable object.
+   */
+  class Object
+  {
+  public:
+
+    enum HeadingType {
+      HEADING_FIXED,
+      HEADING_BILLBOARD,
+      HEADING_RANDOM
+    };
+
+    const string &get_path () const;
+    ssgEntity * get_model () const;
+    double get_coverage_m2 () const;
+    double get_range_m () const;
+    HeadingType get_heading_type () const;
+  protected:
+    friend class FGNewMat;
+    Object (const SGPropertyNode * node);
+    virtual ~Object ();
+  private:
+    string _path;
+    mutable ssgEntity * _model;
+    double _coverage_m2;
+    double _range_m;
+    HeadingType _heading_type;
+  };
+
+
 \f
   ////////////////////////////////////////////////////////////////////
   // Public Constructors.
@@ -148,31 +185,15 @@ public:
 
 
   /**
-   * Get the number of dynamic objects defined for this material.
+   * Get the number of randomly-placed objects defined for this material.
    */
   virtual int get_object_count () const { return objects.size(); }
 
 
   /**
-   * Get a dynamic object for this material.
+   * Get a randomly-placed object for this material.
    */
-  virtual ssgEntity * get_object (int i) const { return objects[i].model; }
-
-
-  /**
-   * Get the average space for a dynamic object for this material.
-   */
-  virtual double get_object_coverage (int i) const {
-    return objects[i].coverage;
-  }
-
-
-  /**
-   * Get the target LOD range for a dynamic object for this material.
-   */
-  virtual double get_object_lod (int i) const {
-    return objects[i].lod;
-  }
+  virtual Object * get_object (int index) const { return objects[index]; }
 
 
   /**
@@ -249,14 +270,7 @@ private:
   // true if texture loading deferred, and not yet loaded
   bool texture_loaded;
 
-  struct Object
-  {
-    ssgEntity * model;
-    double coverage;
-    double lod;
-  };
-
-  vector<Object> objects;
+  vector<Object *> objects;
 
   // ref count so we can properly delete if we have multiple
   // pointers to this record
@@ -274,6 +288,7 @@ private:
   void build_ssg_state(bool defer_tex_load = false);
   void set_ssg_state( ssgSimpleState *s );
 
+
 };
 
 #endif // _NEWMAT_HXX 
index 40302f92bb6a8d47da37682881c018b0253fab57..f0b2e6e24a97a7b1b82f8d6294398fd9547779c3 100644 (file)
@@ -329,7 +329,7 @@ static void gen_random_surface_points( ssgLeaf *leaf, ssgVertexArray *lights,
  */
 static void
 add_object_to_triangle (sgVec3 p1, sgVec3 p2, sgVec3 p3, sgVec3 center,
-                       sgMat4 ROT, FGNewMat * mat, int object_index,
+                       sgMat4 ROT, FGNewMat::Object * object,
                        ssgBranch * branch)
 {
     sgVec3 result;
@@ -342,7 +342,7 @@ add_object_to_triangle (sgVec3 p1, sgVec3 p2, sgVec3 p3, sgVec3 center,
     sgPostMultMat4(OBJ, OBJ_pos);
     ssgTransform * pos = new ssgTransform;
     pos->setTransform(OBJ);
-    pos->addKid(mat->get_object(object_index));
+    pos->addKid(object->get_model());
     branch->addKid(pos);
 }
 
@@ -353,8 +353,7 @@ public:
   float * p1;
   float * p2;
   float * p3;
-  FGNewMat * mat;
-  int object_index;
+  FGNewMat::Object * object;
   ssgBranch * branch;
   sgMat4 ROT;
 };
@@ -376,8 +375,8 @@ public:
  *        surface.
  */
 static void
-fill_in_triangle (float * p1, float * p2, float * p3, FGNewMat * mat,
-                 int object_index, ssgBranch * branch, sgMat4 ROT)
+fill_in_triangle (float * p1, float * p2, float * p3,
+                 FGNewMat::Object *object, ssgBranch * branch, sgMat4 ROT)
 {
     sgVec3 center;
     sgSetVec3(center,
@@ -385,12 +384,11 @@ fill_in_triangle (float * p1, float * p2, float * p3, FGNewMat * mat,
              (p1[1] + p2[1] + p3[1]) / 3.0,
              (p1[2] + p2[2] + p3[2]) / 3.0);
     double area = sgTriArea(p1, p2, p3);
-    double num = area / mat->get_object_coverage(object_index);
+    double num = area / object->get_coverage_m2();
 
     // place an object each unit of area
     while ( num > 1.0 ) {
-      add_object_to_triangle(p1, p2, p3, center,
-                            ROT, mat, object_index, branch);
+      add_object_to_triangle(p1, p2, p3, center, ROT, object, branch);
       num -= 1.0;
     }
     // for partial units of area, use a zombie door method to
@@ -399,8 +397,7 @@ fill_in_triangle (float * p1, float * p2, float * p3, FGNewMat * mat,
     if ( num > 0.0 ) {
       if ( sg_random() <= num ) {
        // a zombie made it through our door
-       add_object_to_triangle(p1, p2, p3, center,
-                              ROT, mat, object_index, branch);
+       add_object_to_triangle(p1, p2, p3, center, ROT, object, branch);
       }
     }
 }
@@ -423,8 +420,8 @@ in_range_callback (ssgEntity * entity, int mask)
 {
   RandomObjectUserData * data = (RandomObjectUserData *)entity->getUserData();
   if (!data->is_filled_in) {
-    fill_in_triangle(data->p1, data->p2, data->p3, data->mat,
-                    data->object_index, data->branch, data->ROT);
+    fill_in_triangle(data->p1, data->p2, data->p3, data->object,
+                    data->branch, data->ROT);
     data->is_filled_in = true;
   }
   return 1;
@@ -540,7 +537,7 @@ get_bounding_radius (sgVec3 center, float *p1, float *p2, float *p3)
  */
 static void
 setup_triangle (float * p1, float * p2, float * p3,
-                  FGNewMat * mat, ssgBranch * branch, sgMat4 ROT)
+               FGNewMat * mat, ssgBranch * branch, sgMat4 ROT)
 {
                                // Set up a single center point for LOD
     sgVec3 center;
@@ -564,13 +561,15 @@ setup_triangle (float * p1, float * p2, float * p3,
                                // Iterate through all the object types.
     int num_objects = mat->get_object_count();
     for (int i = 0; i < num_objects; i++) {
+                               // Look up the random object.
+        FGNewMat::Object * object = mat->get_object(i);
 
                                // Set up the range selector for the entire
                                // triangle; note that we use the object
                                // range plus the bounding radius here, to
                                // allow for objects far from the center.
        float ranges[] = {0,
-                         mat->get_object_lod(i) + bounding_radius,
+                         object->get_range_m() + bounding_radius,
                           500000};
        ssgRangeSelector * lod = new ssgRangeSelector;
        lod->setRanges(ranges, 3);
@@ -589,8 +588,7 @@ setup_triangle (float * p1, float * p2, float * p3,
        data->p1 = p1;
        data->p2 = p2;
        data->p3 = p3;
-       data->mat = mat;
-       data->object_index = i;
+       data->object = object;
        data->branch = in_range;
        sgCopyMat4(data->ROT, ROT);