#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;
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;
- const char *newmat = "BlackSign";
+ string newmat = "BlackSign";
vector<element_info *> elements;
element_info *close = 0;
int size = -1;
char oldtype = 0, newtype = 0;
- ssgBranch *object = new ssgBranch();
- object->setName((char *)content.c_str());
-
- SGMaterial *material;
- ssgSimpleState *lighted_state;
- ssgSimpleState *unlighted_state;
+ osg::Group* object = new osg::Group;
+ object->setName(content);
// Part I: parse & measure
for (const char *s = content.data(); *s; s++) {
}
}
- if (newmat) {
- material = matlib->find(newmat);
- if (!material) {
- SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << newmat << '\'');
- continue;
- }
- // set material states (lighted & unlighted)
- lighted_state = material->get_state();
- string u = string(newmat) + ".unlighted";
-
- SGMaterial *m = matlib->find(u);
- if (m) {
- unlighted_state = (ssgSimpleState *)m->get_state()->clone(SSG_CLONE_STATE);
- unlighted_state->setTexture(lighted_state->getTexture());
- } else {
- SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << u << '\'');
- unlighted_state = lighted_state;
- }
- newmat = 0;
+ if (newmat.size() == 0 )
+ continue;
+
+ SGMaterial *material = matlib->find(newmat);
+ if (!material) {
+ SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << newmat << '\'');
+ continue;
+ }
+
+
+ // set material states (lighted & unlighted)
+ Effect *lighted_state = material->get_effect();
+ Effect *unlighted_state;
+ string u = newmat + ".unlighted";
+
+ SGMaterial *m = matlib->find(u);
+ if (m) {
+ unlighted_state = m->get_effect();
+ } else {
+ SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << u << '\'');
+ unlighted_state = lighted_state;
}
+ newmat = "";
SGMaterialGlyph *glyph = material->get_glyph(name);
if (!glyph) {
}
// 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) {
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];
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::Vec3Array* nl = new osg::Vec3Array;
+ nl->push_back(osg::Vec3(0, 1, 0));
+
+ osg::Geometry* geometry = new osg::Geometry;
+ geometry->setVertexArray(vl);
+ geometry->setNormalArray(nl);
+ geometry->setNormalBinding(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;
}