]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/tgdb/apt_signs.cxx
Merge branch 'jmt/ref_ptr-conv'
[simgear.git] / simgear / scene / tgdb / apt_signs.cxx
index 3bda05cb4a3e4984b614c054f4bc6a83d2fe91fd..d76622a6c397f9fec1752e9d666fca12a325da99 100644 (file)
 
 #include <vector>
 
+#include <osg/StateSet>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Group>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/sg_types.hxx>
-#include <simgear/scene/tgdb/leaf.hxx>
+#include <simgear/scene/material/Effect.hxx>
+#include <simgear/scene/material/EffectGeode.hxx>
 #include <simgear/scene/material/mat.hxx>
 #include <simgear/scene/material/matlib.hxx>
 
 #define SIGN "OBJECT_SIGN: "
 #define RWY "OBJECT_RUNWAY_SIGN: "
 
-SG_USING_STD(vector);
+using std::vector;
+using namespace simgear;
 
 // for temporary storage of sign elements
 struct element_info {
-    element_info(SGMaterial *m, ssgSimpleState *s, SGMaterialGlyph *g, double h)
+    element_info(SGMaterial *m, Effect *s, SGMaterialGlyph *g, double h)
         : material(m), state(s), glyph(g), height(h)
     {
         scale = h * m->get_xsize()
                 / (m->get_ysize() < 0.001 ? 1.0 : m->get_ysize());
     }
     SGMaterial *material;
-    ssgSimpleState *state;
+    Effect *state;
     SGMaterialGlyph *glyph;
     double height;
     double scale;
@@ -64,25 +71,26 @@ struct pair {
     const char *keyword;
     const char *glyph_name;
 } cmds[] = {
-    {"@u",       "up"},
-    {"@d",       "down"},
-    {"@l",       "left"},
-    {"@lu",      "left-up"},
-    {"@ul",      "left-up"},
-    {"@ld",      "left-down"},
-    {"@dl",      "left-down"},
-    {"@r",       "right"},
-    {"@ru",      "right-up"},
-    {"@ur",      "right-up"},
-    {"@rd",      "right-down"},
-    {"@dr",      "right-down"},
+    {"@u",       "^u"},
+    {"@d",       "^d"},
+    {"@l",       "^l"},
+    {"@lu",      "^lu"},
+    {"@ul",      "^lu"},
+    {"@ld",      "^ld"},
+    {"@dl",      "^ld"},
+    {"@r",       "^r"},
+    {"@ru",      "^ru"},
+    {"@ur",      "^ru"},
+    {"@rd",      "^rd"},
+    {"@dr",      "^rd"},
     {0, 0},
 };
 
 
 // see $FG_ROOT/Docs/README.scenery
 //
-ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string content)
+osg::Node*
+SGMakeSign(SGMaterialLib *matlib, const string& path, const string& content)
 {
     double sign_height = 1.0;  // meter
     bool lighted = true;
@@ -95,12 +103,12 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
     int size = -1;
     char oldtype = 0, newtype = 0;
 
-    ssgBranch *object = new ssgBranch();
-    object->setName((char *)content.c_str());
+    osg::Group* object = new osg::Group;
+    object->setName(content);
 
-    SGMaterial *material;
-    ssgSimpleState *lighted_state;
-    ssgSimpleState *unlighted_state;
+    SGMaterial *material = 0;
+    Effect *lighted_state = 0;
+    Effect *unlighted_state = 0;
 
     // Part I: parse & measure
     for (const char *s = content.data(); *s; s++) {
@@ -212,26 +220,31 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
         }
 
         if (newmat.size()) {
-            material = matlib->find(newmat);
-            if (!material) {
+            SGMaterial *m = matlib->find(newmat);
+            if (!m) {
+                // log error, but keep using previous material to at least show something
                 SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << newmat << '\'');
-                continue;
-            }
-
-            // set material states (lighted & unlighted)
-            lighted_state = material->get_state();
-            string u = newmat + ".unlighted";
-
-            SGMaterial *m = matlib->find(u);
-            if (m) {
-                unlighted_state = m->get_state();
             } else {
-                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << u << '\'');
-                unlighted_state = lighted_state;
+                material = m;
+                // set material states (lighted & unlighted)
+                lighted_state = material->get_effect();
+                newmat.append(".unlighted");
+
+                m = matlib->find(newmat);
+                if (m) {
+                    unlighted_state = m->get_effect();
+                } else {
+                    SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << newmat << '\'');
+                    unlighted_state = lighted_state;
+                }
             }
-            newmat = "";
+            newmat.clear();
         }
 
+        // This can only happen if the default material is missing.
+        // Error has been already logged in the block above.
+        if (!material) continue;
         SGMaterialGlyph *glyph = material->get_glyph(name);
         if (!glyph) {
             SG_LOG( SG_TERRAIN, SG_ALERT, SIGN "unsupported glyph `" << *s << '\'');
@@ -239,7 +252,7 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
         }
 
         // in managed mode push frame stop and frame start first
-        ssgSimpleState *state = lighted ? lighted_state : unlighted_state;
+        Effect *state = lighted ? lighted_state : unlighted_state;
         element_info *e;
         if (newtype && newtype != oldtype) {
             if (close) {
@@ -276,12 +289,6 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
     double hpos = -total_width / 2;
     const double dist = 0.25;        // hard-code distance from surface for now
 
-    sgVec3 normal;
-    sgSetVec3(normal, 0, -1, 0);
-
-    sgVec4 color;
-    sgSetVec4(color, 1.0, 1.0, 1.0, 1.0);
-
     for (unsigned int i = 0; i < elements.size(); i++) {
         element_info *element = elements[i];
 
@@ -291,112 +298,96 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
         double abswidth = width * element->scale;
 
         // vertices
-        ssgVertexArray *vl = new ssgVertexArray(4);
-        vl->add(0, hpos,            dist);
-        vl->add(0, hpos + abswidth, dist);
-        vl->add(0, hpos,            dist + height);
-        vl->add(0, hpos + abswidth, dist + height);
+        osg::Vec3Array* vl = new osg::Vec3Array;
+        vl->push_back(osg::Vec3(0, hpos,            dist));
+        vl->push_back(osg::Vec3(0, hpos + abswidth, dist));
+        vl->push_back(osg::Vec3(0, hpos,            dist + height));
+        vl->push_back(osg::Vec3(0, hpos + abswidth, dist + height));
 
         // texture coordinates
-        ssgTexCoordArray *tl = new ssgTexCoordArray(4);
-        tl->add(xoffset,         0);
-        tl->add(xoffset + width, 0);
-        tl->add(xoffset,         1);
-        tl->add(xoffset + width, 1);
+        osg::Vec2Array* tl = new osg::Vec2Array;
+        tl->push_back(osg::Vec2(xoffset,         0));
+        tl->push_back(osg::Vec2(xoffset + width, 0));
+        tl->push_back(osg::Vec2(xoffset,         1));
+        tl->push_back(osg::Vec2(xoffset + width, 1));
 
         // normals
-        ssgNormalArray *nl = new ssgNormalArray(1);
-        nl->add(normal);
+        osg::Vec3Array* nl = new osg::Vec3Array;
+        nl->push_back(osg::Vec3(0, -1, 0));
 
         // colors
-        ssgColourArray *cl = new ssgColourArray(1);
-        cl->add(color);
-
-        ssgLeaf *leaf = new ssgVtxTable(GL_TRIANGLE_STRIP, vl, nl, tl, cl);
-        leaf->setState(element->state);
-
-        object->addKid(leaf);
+        osg::Vec4Array* cl = new osg::Vec4Array;
+        cl->push_back(osg::Vec4(1, 1, 1, 1));
+
+        osg::Geometry* geometry = new osg::Geometry;
+        geometry->setVertexArray(vl);
+        geometry->setNormalArray(nl);
+        geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
+        geometry->setColorArray(cl);
+        geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+        geometry->setTexCoordArray(0, tl);
+        geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
+        EffectGeode* geode = new EffectGeode;
+        geode->addDrawable(geometry);
+        geode->setEffect(element->state);
+
+        object->addChild(geode);
         hpos += abswidth;
         delete element;
     }
 
 
     // minimalistic backside
-    ssgVertexArray *vl = new ssgVertexArray(4);
-    vl->add(0, hpos,               dist);
-    vl->add(0, hpos - total_width, dist);
-    vl->add(0, hpos,               dist + sign_height);
-    vl->add(0, hpos - total_width, dist + sign_height);
-
-    ssgNormalArray *nl = new ssgNormalArray(1);
-    nl->add(0, 1, 0);
-
-    ssgLeaf *leaf = new ssgVtxTable(GL_TRIANGLE_STRIP, vl, nl, 0, 0);
+    osg::Vec3Array* vl = new osg::Vec3Array;
+    vl->push_back(osg::Vec3(0, hpos,               dist));
+    vl->push_back(osg::Vec3(0, hpos - total_width, dist));
+    vl->push_back(osg::Vec3(0, hpos,               dist + sign_height));
+    vl->push_back(osg::Vec3(0, hpos - total_width, dist + sign_height));
+
+    osg::Vec2Array* tl = new osg::Vec2Array;
+    for (int i = 0; i < 4; ++i)
+        tl->push_back(osg::Vec2(0.0, 0.0));
+    osg::Vec3Array* nl = new osg::Vec3Array;
+    nl->push_back(osg::Vec3(0, 1, 0));
+    osg::Vec4Array* cl = new osg::Vec4Array;
+    cl->push_back(osg::Vec4(0.0, 0.0, 0.0, 1.0));
+    osg::Geometry* geometry = new osg::Geometry;
+    geometry->setVertexArray(vl);
+    geometry->setNormalArray(nl);
+    geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
+    geometry->setTexCoordArray(0, tl);
+    geometry->setColorArray(cl);
+    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+    geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
+    EffectGeode* geode = new EffectGeode;
+    geode->addDrawable(geometry);
     SGMaterial *mat = matlib->find("BlackSign");
     if (mat)
-        leaf->setState(mat->get_state());
-    object->addKid(leaf);
+      geode->setEffect(mat->get_effect());
+    object->addChild(geode);
 
     return object;
 }
 
-
-
-
-
-ssgBranch *sgMakeRunwaySign( SGMaterialLib *matlib,
-                             const string path, const string name )
+osg::Node*
+SGMakeRunwaySign(SGMaterialLib *matlib, const string& path, const string& name)
 {
     // for demo purposes we assume each element (letter) is 1x1 meter.
     // Sign is placed 0.25 meters above the ground
 
-    ssgBranch *object = new ssgBranch();
-    object->setName( (char *)name.c_str() );
-
-    double width = name.length() / 3.0;
-
-    string material = name;
-
-    point_list nodes;
-    point_list normals;
-    point_list texcoords;
-    int_list vertex_index;
-    int_list normal_index;
-    int_list tex_index;
-
-    nodes.push_back( Point3D( -width, 0, 0.25 ) );
-    nodes.push_back( Point3D( width + 1, 0, 0.25 ) );
-    nodes.push_back( Point3D( -width, 0, 1.25 ) );
-    nodes.push_back( Point3D( width + 1, 0, 1.25 ) );
-
-    normals.push_back( Point3D( 0, -1, 0 ) );
-
-    texcoords.push_back( Point3D( 0, 0, 0 ) );
-    texcoords.push_back( Point3D( 1, 0, 0 ) );
-    texcoords.push_back( Point3D( 0, 1, 0 ) );
-    texcoords.push_back( Point3D( 1, 1, 0 ) );
-
-    vertex_index.push_back( 0 );
-    vertex_index.push_back( 1 );
-    vertex_index.push_back( 2 );
-    vertex_index.push_back( 3 );
-
-    normal_index.push_back( 0 );
-    normal_index.push_back( 0 );
-    normal_index.push_back( 0 );
-    normal_index.push_back( 0 );
-
-    tex_index.push_back( 0 );
-    tex_index.push_back( 1 );
-    tex_index.push_back( 2 );
-    tex_index.push_back( 3 );
-
-    ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_STRIP, matlib, material,
-                                nodes, normals, texcoords,
-                                vertex_index, normal_index, tex_index,
-                                false, NULL );
-
-    object->addKid( leaf );
+    float width = name.length() / 3.0;
+
+    osg::Vec3 corner(-width, 0, 0.25f);
+    osg::Vec3 widthVec(2*width + 1, 0, 0);
+    osg::Vec3 heightVec(0, 0, 1);
+    osg::Geometry* geometry;
+    geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec);
+    EffectGeode* geode = new EffectGeode;
+    geode->setName(name);
+    geode->addDrawable(geometry);
+    SGMaterial *mat = matlib->find(name);
+    if (mat)
+      geode->setEffect(mat->get_effect());
 
-    return object;
+    return geode;
 }