]> git.mxchange.org Git - flightgear.git/commitdiff
Started functional decomposition for dynamic objects.
authordavid <david>
Tue, 16 Jul 2002 23:39:53 +0000 (23:39 +0000)
committerdavid <david>
Tue, 16 Jul 2002 23:39:53 +0000 (23:39 +0000)
Fixed typo in last patch, where objects were using object_group_lod
rather than object_lod.

src/Objects/obj.cxx

index ff7e5ed72050d1c3191748ecfb493acaa0ec158c..ba81c0efa7f88430953461ce46169b5e5d3ad0a3 100644 (file)
@@ -313,6 +313,83 @@ static void gen_random_surface_points( ssgLeaf *leaf, ssgVertexArray *lights,
 }
 
 
+/**
+ * Add an object to a random location inside a triangle.
+ *
+ * @param p1 The first vertex of the triangle.
+ * @param p2 The second vertex of the triangle.
+ * @param p3 The third vertex of the triangle.
+ * @param center The center of the triangle.
+ * @param ROT The world-up rotation matrix.
+ * @param mat The material object.
+ * @param object_index The index of the dynamically-placed object in
+ *        the material.
+ * @param branch The branch where the object should be added to the
+ *        scene graph.
+ */
+static void
+add_object_to_triangle (sgVec3 p1, sgVec3 p2, sgVec3 p3, sgVec3 center,
+                       sgMat4 ROT, FGNewMat * mat, int object_index,
+                       ssgBranch * branch)
+{
+    sgVec3 result;
+
+    random_pt_inside_tri(result, p1, p2, p3);
+    sgSubVec3(result, center);
+    sgMat4 OBJ_pos, OBJ;
+    sgMakeTransMat4(OBJ_pos, result);
+    sgCopyMat4(OBJ, ROT);
+    sgPostMultMat4(OBJ, OBJ_pos);
+    ssgTransform * pos = new ssgTransform;
+    pos->setTransform(OBJ);
+    float obj_range = mat->get_object_lod(object_index);
+    float range_div = (sg_random() * obj_range);
+    if (range_div < 0.0000001) {
+      // avoid a divide by zero error
+      range_div = 1.0;
+    }
+    float random_range = 160.0 * obj_range / range_div + obj_range;
+    float ranges[] = {0, random_range};
+    ssgRangeSelector *range = new ssgRangeSelector;
+    range->setRanges(ranges, 2);
+    range->addKid(mat->get_object(object_index));
+    pos->addKid(range);
+    branch->addKid(pos);
+}
+
+
+/**
+ * Create a rotation matrix to align an object for the current lat/lon.
+ *
+ * By default, objects are aligned for the north pole.  This code
+ * calculates a matrix to rotate them for the surface of the earth in
+ * the current location.
+ *
+ * TODO: there should be a single version of this method somewhere
+ * for all of SimGear.
+ *
+ * @param ROT The resulting rotation matrix.
+ * @param hdg_deg The object heading in degrees.
+ * @param lon_deg The longitude in degrees.
+ * @param lat_deg The latitude in degrees.
+ */
+static void
+makeWorldUpRotationMatrix (sgMat4 ROT, double hdg_deg,
+                          double lon_deg, double lat_deg)
+{
+    sgVec3 obj_right, obj_up;
+    sgSetVec3(obj_right, 0.0, 1.0, 0.0); // Y axis
+    sgSetVec3(obj_up, 0.0, 0.0, 1.0); // Z axis
+    sgMat4 ROT_lon, ROT_lat, ROT_hdg;
+    sgMakeRotMat4(ROT_lon, lon_deg, obj_up);
+    sgMakeRotMat4(ROT_lat, 90 - lat_deg, obj_right);
+    sgMakeRotMat4(ROT_hdg, hdg_deg, obj_up);
+    sgCopyMat4(ROT, ROT_hdg);
+    sgPostMultMat4(ROT, ROT_lat);
+    sgPostMultMat4(ROT, ROT_lon);
+}
+
+
 static void
 gen_random_surface_objects (ssgLeaf *leaf,
                            ssgBranch *branch,
@@ -330,20 +407,8 @@ gen_random_surface_objects (ssgLeaf *leaf,
     float hdg_deg = 0.0;       // do something here later
 
 
-    // The object will be aligned for the north pole.  This code
-    // calculates a matrix to rotate it to for the surface of the
-    // earth in the current location.
-    sgVec3 obj_right, obj_up;
-    sgSetVec3(obj_right, 0.0, 1.0, 0.0); // Y axis
-    sgSetVec3(obj_up, 0.0, 0.0, 1.0); // Z axis
-    sgMat4 ROT_lon, ROT_lat, ROT_hdg;
-    sgMakeRotMat4(ROT_lon, lon_deg, obj_up);
-    sgMakeRotMat4(ROT_lat, 90 - lat_deg, obj_right);
-    sgMakeRotMat4(ROT_hdg, hdg_deg, obj_up);
     sgMat4 ROT;
-    sgCopyMat4(ROT, ROT_hdg);
-    sgPostMultMat4(ROT, ROT_lat);
-    sgPostMultMat4(ROT, ROT_lon);
+    makeWorldUpRotationMatrix(ROT, hdg_deg, lon_deg, lat_deg);
 
     if ( num > 0 ) {
        short int n1, n2, n3;
@@ -383,27 +448,8 @@ gen_random_surface_objects (ssgLeaf *leaf,
              
              // place an object each unit of area
              while ( num > 1.0 ) {
-               random_pt_inside_tri( result, p1, p2, p3 );
-               sgSubVec3(result, center);
-               sgMat4 OBJ_pos, OBJ;
-               sgMakeTransMat4(OBJ_pos, result);
-               sgCopyMat4(OBJ, ROT);
-               sgPostMultMat4(OBJ, OBJ_pos);
-               ssgTransform * pos = new ssgTransform;
-               pos->setTransform(OBJ);
-                float obj_range = mat->get_object_lod(j);
-                float range_div = (sg_random() * obj_range);
-                if (range_div < 0.0000001) {
-                    // avoid a divide by zero error
-                    range_div = 1.0;
-                }
-                float random_range = 160.0 * obj_range / range_div + obj_range;
-                float ranges[] = {0, random_range};
-                ssgRangeSelector *range = new ssgRangeSelector;
-                range->setRanges(ranges, 2);
-                range->addKid(mat->get_object(j));
-                pos->addKid(range);
-               location->addKid(pos);
+               add_object_to_triangle(p1, p2, p3, center,
+                                      ROT, mat, j, location);
                num -= 1.0;
              }
              // for partial units of area, use a zombie door method to
@@ -412,27 +458,8 @@ gen_random_surface_objects (ssgLeaf *leaf,
              if ( num > 0.0 ) {
                if ( sg_random() <= num ) {
                  // a zombie made it through our door
-                 random_pt_inside_tri( result, p1, p2, p3 );
-                 sgSubVec3(result, center);
-                 sgMat4 OBJ_pos, OBJ;
-                 sgMakeTransMat4(OBJ_pos, result);
-                 sgCopyMat4(OBJ, ROT);
-                 sgPostMultMat4(OBJ, OBJ_pos);
-                 ssgTransform * pos = new ssgTransform;
-                 pos->setTransform(OBJ);
-                  float obj_range = mat->get_object_lod(j);
-                  float range_div = (sg_random() * obj_range);
-                  if (range_div < 0.0000001) {
-                      // avoid a divide by zero error
-                      range_div = 1.0;
-                  }
-                  float random_range = 160.0 * obj_range / range_div + obj_range;
-                  float ranges[] = {0, random_range};
-                  ssgRangeSelector *range = new ssgRangeSelector;
-                  range->setRanges(ranges, 2);
-                  range->addKid(mat->get_object(j));
-                 pos->addKid(range);
-                 location->addKid(pos);
+                 add_object_to_triangle(p1, p2, p3, center,
+                                        ROT, mat, j, location);
                }
              }
            }
@@ -441,6 +468,12 @@ gen_random_surface_objects (ssgLeaf *leaf,
 }
 
 
+\f
+////////////////////////////////////////////////////////////////////////
+// Scenery loaders.
+////////////////////////////////////////////////////////////////////////
+
+
 // Load an Ascii obj file
 ssgBranch *fgAsciiObjLoad( const string& path, FGTileEntry *t,
                           ssgVertexArray *lights, const bool is_base)