]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/tgdb/SGOceanTile.cxx
Crash fix: use cache to find materials.
[simgear.git] / simgear / scene / tgdb / SGOceanTile.cxx
index 337a3103e0b2de1025440200a23615e1744f27ad..f990f946ae02a991f88a4d7239ba532481785e01 100644 (file)
@@ -41,8 +41,9 @@
 #include <simgear/scene/material/EffectGeode.hxx>
 #include <simgear/scene/material/mat.hxx>
 #include <simgear/scene/material/matlib.hxx>
-
+#include <simgear/scene/util/OsgMath.hxx>
 #include <simgear/scene/util/VectorArrayAdapter.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 using namespace simgear;
 // Ocean tile with curvature and apron to hide cracks. The cracks are
@@ -60,12 +61,11 @@ using namespace simgear;
 // it may be superfluous for such a small mesh.
 namespace
 {
-const int lonPoints = 5;
-const int latPoints = 5;
-
 class OceanMesh {
 public:
-    OceanMesh():
+    OceanMesh(int latP, int lonP):
+        latPoints(latP),
+        lonPoints(lonP),
         geoPoints(latPoints * lonPoints + 2 * (lonPoints + latPoints)),
         geod_nodes(latPoints * lonPoints),
         vl(new osg::Vec3Array(geoPoints)),
@@ -75,13 +75,26 @@ public:
         nlArray(*nl, lonPoints + 2, lonPoints, 1),
         tlArray(*tl, lonPoints + 2, lonPoints, 1)
     {
+        int numPoints = latPoints * lonPoints;
+        geod = new SGGeod[numPoints];
+        normals = new SGVec3f[numPoints];
+        rel = new SGVec3d[numPoints];
+    }
+    
+    ~OceanMesh()
+    {
+        delete[] geod;
+        delete[] normals;
+        delete[] rel;
     }
+    
+    const int latPoints, lonPoints;
     const int geoPoints;
-    SGGeod geod[latPoints][lonPoints];
-    SGVec3f normals[latPoints][lonPoints];
-    SGVec3d rel[latPoints][lonPoints];
+    SGGeod* geod;
+    SGVec3f* normals;
+    SGVec3d* rel;
 
-    point_list geod_nodes;
+    std::vector<SGGeod> geod_nodes;
 
     osg::Vec3Array* vl;
     osg::Vec3Array* nl;
@@ -114,35 +127,42 @@ void OceanMesh::calcMesh(const SGVec3d& cartCenter, const SGQuatd& orient,
     for (int j = 0; j < latPoints; j++) {
         double lat = startLat + j * latInc;
         for (int i = 0; i < lonPoints; i++) {
-            geod[j][i] = SGGeod::fromDeg(startLon + i * longInc, lat);
-            SGVec3d cart = SGVec3d::fromGeod(geod[j][i]);
-            rel[j][i] = orient.transform(cart - cartCenter);
-            normals[j][i] = toVec3f(orient.transform(normalize(cart)));
+            int index = (j * lonPoints) + i;
+            geod[index] = SGGeod::fromDeg(startLon + i * longInc, lat);
+            SGVec3d cart = SGVec3d::fromGeod(geod[index]);
+            rel[index] = orient.transform(cart - cartCenter);
+            normals[index] = toVec3f(orient.transform(normalize(cart)));
         }
     }
     
     // Calculate texture coordinates
-    point_list geod_nodes(latPoints * lonPoints);
-    VectorArrayAdapter<point_list> geodNodesArray(geod_nodes, lonPoints);
+    typedef std::vector<SGGeod> GeodVector;
+    
+    GeodVector geod_nodes(latPoints * lonPoints);
+    VectorArrayAdapter<GeodVector> geodNodesArray(geod_nodes, lonPoints);
     int_list rectangle(latPoints * lonPoints);
     VectorArrayAdapter<int_list> rectArray(rectangle, lonPoints);
     for (int j = 0; j < latPoints; j++) {
         for (int i = 0; i < lonPoints; i++) {
-            geodNodesArray(j, i) = Point3D(geod[j][i].getLongitudeDeg(),
-                                           geod[j][i].getLatitudeDeg(),
-                                           geod[j][i].getElevationM());
-            rectArray(j, i) = j * 5 + i;
+            int index = (j * lonPoints) + i;
+            geodNodesArray(j, i) = geod[index];
+            rectArray(j, i) = index;
         }
     }
-    point_list texs = sgCalcTexCoords( clat, geod_nodes, rectangle, 
+    
+    typedef std::vector<SGVec2f> Vec2Array;
+    Vec2Array texs = sgCalcTexCoords( clat, geod_nodes, rectangle, 
                                        1000.0 / tex_width );
-    VectorArrayAdapter<point_list> texsArray(texs, lonPoints);
+                                
+                                       
+    VectorArrayAdapter<Vec2Array> texsArray(texs, lonPoints);
   
     for (int j = 0; j < latPoints; j++) {
         for (int i = 0; i < lonPoints; ++i) {
-            vlArray(j, i) = toOsg(rel[j][i]);
-            nlArray(j, i) = toOsg(normals[j][i]);
-            tlArray(j, i) = toOsg(texsArray(j, i).toSGVec2f());
+            int index = (j * lonPoints) + i;
+            vlArray(j, i) = toOsg(rel[index]);
+            nlArray(j, i) = toOsg(normals[index]);
+            tlArray(j, i) = toOsg(texsArray(j, i));
         }
     }
 
@@ -255,14 +275,14 @@ void fillDrawElementsWithApron(short height, short width,
 }
 }
 
-osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
+osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib, int latPoints, int lonPoints)
 {
     Effect *effect = 0;
 
     double tex_width = 1000.0;
   
     // find Ocean material in the properties list
-    SGMaterial *mat = matlib->find( "Ocean" );
+    SGMaterial *mat = matlib->findCached( "Ocean" );
     if ( mat != NULL ) {
         // set the texture width and height values for this
         // material
@@ -273,11 +293,11 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
     } else {
         SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown use material name = Ocean");
     }
-    OceanMesh grid;
+    OceanMesh grid(latPoints, lonPoints);
     // Calculate center point
     SGVec3d cartCenter = SGVec3d::fromGeod(b.get_center());
     SGGeod geodPos = SGGeod::fromCart(cartCenter);
-    SGQuatd hlOr = SGQuatd::fromLonLat(geodPos);
+    SGQuatd hlOr = SGQuatd::fromLonLat(geodPos)*SGQuatd::fromEulerDeg(0, 0, 180);
 
     double clon = b.get_center_lon();
     double clat = b.get_center_lat();
@@ -291,6 +311,7 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
     cl->push_back(osg::Vec4(1, 1, 1, 1));
   
     osg::Geometry* geometry = new osg::Geometry;
+    geometry->setDataVariance(osg::Object::STATIC);
     geometry->setVertexArray(grid.vl);
     geometry->setNormalArray(grid.nl);
     geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
@@ -317,6 +338,7 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
     transform->setMatrix(osg::Matrix::rotate(toOsg(hlOr))*
                          osg::Matrix::translate(toOsg(cartCenter)));
     transform->addChild(geode);
-  
+    transform->setNodeMask( ~simgear::MODELLIGHT_BIT );
+
     return transform;
 }