diff --git a/src/osgPlugins/geo/Makefile b/src/osgPlugins/geo/Makefile index 25f672591..362ea3b08 100644 --- a/src/osgPlugins/geo/Makefile +++ b/src/osgPlugins/geo/Makefile @@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs CXXFILES =\ ReaderWriterGEO.cpp -LIBS += $(OSG_LIBS) $(OTHER_LIBS) +LIBS += -losgText $(OSG_LIBS) $(OTHER_LIBS) TARGET_BASENAME = geo include $(TOPDIR)/Make/cygwin_plugin_def diff --git a/src/osgPlugins/geo/ReaderWriterGEO.cpp b/src/osgPlugins/geo/ReaderWriterGEO.cpp index 01f5bbc42..7ea24e428 100644 --- a/src/osgPlugins/geo/ReaderWriterGEO.cpp +++ b/src/osgPlugins/geo/ReaderWriterGEO.cpp @@ -33,6 +33,7 @@ #include "geoUnits.h" #include "osgGeoAnimation.h" #include "osgGeoStructs.h" +#include // needed for text nodes using namespace osg; using namespace osgDB; @@ -52,16 +53,37 @@ public: private: }; -class geoArithBehaviour { +class geoMathBehaviour { // base class for math functions where var out = f(var in) public: - geoArithBehaviour() { constant=0; oper=UNKNOWN; in=out=NULL; varop=NULL;} + geoMathBehaviour() { in=out=NULL; } + virtual ~geoMathBehaviour() { } + virtual void setInVar(const double *indvar) {in=indvar;} + virtual void setOutVar(double *outdvar) {out=outdvar;} + virtual void doaction(osg::Node*) const + { // do math operation + } +protected: + const double *in; + double *out; +}; + + +class geoVisibBehaviour : public geoMathBehaviour { +public: + geoVisibBehaviour() { } + virtual ~geoVisibBehaviour() { } + void doaction(osg::Node*) const + { // do visibility operation + } +private: +}; +class geoArithBehaviour : public geoMathBehaviour { +public: + geoArithBehaviour() { constant=0; oper=UNKNOWN; varop=NULL;} ~geoArithBehaviour() { } enum optype{UNKNOWN, ADD, SUBTR, MULT, DIVIDE}; - void setConstant(const float v) { constant=v;} - void setInVar(const double *indvar) {in=indvar;} - void setOutVar(double *outdvar) {out=outdvar;} - void setType(uint iop) - { +// void setConstant(const float v) { constant=v;} + void setType(uint iop) { switch (iop) { case 1: oper=ADD; break; case 2: oper=SUBTR; break; @@ -70,36 +92,154 @@ public: } } void setVariable(const double *varvar) { varop=varvar;} - void doaction(osg::Node*) const - { // do math operation + + void doaction(osg::Node* /*node*/) const { // do math operation if (in && out) { - double mult=varop? *varop : constant; + double var2=varop? *varop : constant; switch (oper) { - case ADD: *out = *in+mult;break; - case SUBTR: *out = *in-mult;break; - case MULT: *out = *in*mult;break; - case DIVIDE: *out = *in/mult;break; - case UNKNOWN: break; // do nothing. + case ADD: *out = *in+var2;break; + case SUBTR: *out = *in-var2;break; + case MULT: *out = *in*var2;break; + case DIVIDE: *out = *in/var2;break; + case UNKNOWN: break; } } } + bool makeBehave(const georecord *grec, geoHeader *theHeader) { + bool ok=false; + const geoField *gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_INPUT_VAR); + if (gfd) { + unsigned fid= gfd->getUInt(); // field identifier + in=theHeader->getVar(fid); // returns address of input var with fid + if (in) { + gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OUTPUT_VAR); + if (gfd) { + fid= gfd->getUInt(); // field identifier + out=theHeader->getVar(fid); // returns address of output var with fid + gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OP_TYPE); + uint iop=gfd?gfd->getUInt():1; + setType(iop); // default add? + gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OPERAND_VALUE); + if (gfd) { + constant= gfd->getFloat(); // field identifier + ok=true; + } + gfd=grec->getField(GEO_DB_ARITHMETIC_ACTION_OPERAND_VAR); + if (gfd) { + unsigned fid= gfd->getUInt(); // field identifier + varop=theHeader->getVar(fid); + ok=varop != NULL; + } + } + } + } + return ok; + } private: float constant; optype oper; - const double *in; - double *out; const double *varop; // if null use constant value in maths; else }; -class geoMatBehaviour { +class geoRangeBehaviour :public geoMathBehaviour { + // output = outmin + frac*(outmax-min) where frac = (in-min)/(max-min) public: - geoMatBehaviour() { var=NULL; type=0;axis.set(0,0,1); centre.set(0,0,0);} - ~geoMatBehaviour() { + geoRangeBehaviour() { inmin=outmin=(float)-1.e32; inmax=outmax=(float)1.e32; in=out=NULL;} + ~geoRangeBehaviour() { } + void setInMax(const double v) { inmax=v;} + void setInMin(const double v) { inmin=v;} + void setOutMax(const double v) { outmax=v;} + void setOutMin(const double v) { outmin=v;} + void doaction(osg::Node*) const { // do math operation + if (in && out) { + float v=*in; + if (vinmax) v=inmax; + v=(v-inmin)/(inmax-inmin); + *out = outmin+v*(outmax-outmin); + } + } + bool makeBehave(const georecord *grec, geoHeader *theHeader) { + bool ok=false; + const geoField *gfd=grec->getField(GEO_DB_RANGE_ACTION_INPUT_VAR); + if (gfd) { + unsigned fid= gfd->getUInt(); // field identifier + in=theHeader->getVar(fid); // returns address of input var with fid + if (in) { + gfd=grec->getField(GEO_DB_RANGE_ACTION_OUTPUT_VAR); + if (gfd) { + fid= gfd->getUInt(); // field identifier + out=theHeader->getVar(fid); // returns address of output var with fid + gfd=grec->getField(GEO_DB_RANGE_ACTION_IN_MIN_VAL); + inmin=gfd?gfd->getFloat():-1.e32; + gfd=grec->getField(GEO_DB_RANGE_ACTION_IN_MAX_VAL); + inmax= gfd?gfd->getFloat() : 1.e32; // field identifier + gfd=grec->getField(GEO_DB_RANGE_ACTION_OUT_MIN_VAL); + outmin=gfd?gfd->getFloat():-1.e32; + gfd=grec->getField(GEO_DB_RANGE_ACTION_OUT_MAX_VAL); + outmax= gfd?gfd->getFloat() : 1.e32; // field identifier + ok=true; + } + } + } + return ok; + } +private: + float inmin,inmax; + float outmin,outmax; +}; +class geoClampBehaviour :public geoMathBehaviour { +public: + geoClampBehaviour() { min=(float)-1.e32; max=(float)1.e32; in=out=NULL;} + ~geoClampBehaviour() { } + void setMax(const double v) { max=v;} + void setMin(const double v) { min=v;} + void doaction(osg::Node *) const { // do math operation + if (in && out) { + float v=*in; + if (vmax) v=max; + *out = v; + } + } + bool makeBehave(const georecord *grec, geoHeader *theHeader) { + bool ok=false; + const geoField *gfd=grec->getField(GEO_DB_CLAMP_ACTION_INPUT_VAR); + if (gfd) { + unsigned fid= gfd->getUInt(); // field identifier + in=theHeader->getVar(fid); // returns address of input var with fid + if (in) { + gfd=grec->getField(GEO_DB_CLAMP_ACTION_OUTPUT_VAR); + if (gfd) { + fid= gfd->getUInt(); // field identifier + out=theHeader->getVar(fid); // returns address of output var with fid + gfd=grec->getField(GEO_DB_CLAMP_ACTION_MIN_VAL); + min=gfd?gfd->getFloat():-1.e32; + gfd=grec->getField(GEO_DB_CLAMP_ACTION_MAX_VAL); + max= gfd?gfd->getFloat() : 1.e32; // field identifier + ok=true; + } + } + } + return ok; + } +private: + float min,max; +}; + +class geoMoveBehaviour { +public: + geoMoveBehaviour() { var=NULL; type=0;axis.set(0,0,1); centre.set(0,0,0);} + ~geoMoveBehaviour() { var=NULL;} void setType(const unsigned int t) { type=t; } void setVar(const double *v) { var=v;} void setCentre(const Vec3 v) { centre=v;} void setAxis(const Vec3 v) { axis=v;} + inline unsigned int getType(void) const { return type;} + inline const double *getVar(void) { return var;} + inline double getValue(void) { return *var;} + inline double DEG2RAD(const double var) const { return var*0.0174532925199432957692369076848861; } void doaction(osg::Node *node) const { if (var) { MatrixTransform *mtr=dynamic_cast (node); @@ -109,12 +249,57 @@ public: break; case DB_DSK_ROTATE_ACTION: mtr->preMult( osg::Matrix::translate(-centre)* - osg::Matrix::rotate((*var),axis)* + osg::Matrix::rotate(DEG2RAD(*var),axis)* osg::Matrix::translate(centre)); break; } } } + + bool makeBehave(const georecord *grec, geoHeader *theHeader, const uint act) { + bool ok=false; + setType(act); + if (act==DB_DSK_ROTATE_ACTION) { + const geoField *gfd=grec->getField(GEO_DB_ROTATE_ACTION_INPUT_VAR); + if (gfd) { + unsigned fid= gfd->getUInt(); // field identifier + var=theHeader->getVar(fid); // returns address of var with fid + if (var) { + gfd=grec->getField(GEO_DB_ROTATE_ACTION_VECTOR); + if (gfd) { + float *ax= gfd->getVec3Arr(); // field identifier + setAxis(osg::Vec3(ax[0],ax[1],ax[2])); + } + gfd=grec->getField(GEO_DB_ROTATE_ACTION_ORIGIN); + if (gfd) { + float *ct= gfd->getVec3Arr(); // field identifier + setCentre(osg::Vec3(ct[0],ct[1],ct[2])); + } + ok=true; + } + } + } else if (act==DB_DSK_TRANSLATE_ACTION) { + const geoField *gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_INPUT_VAR); + if (gfd) { + unsigned fid= gfd->getUInt(); // field identifier + var=theHeader->getVar(fid); // returns address of var with fid + if (var) { + gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_VECTOR); + if (gfd) { + float *ax= gfd->getVec3Arr(); // field identifier + setAxis(osg::Vec3(ax[0],ax[1],ax[2])); + } + gfd=grec->getField(GEO_DB_TRANSLATE_ACTION_ORIGIN); + if (gfd) { + float *ct= gfd->getVec3Arr(); // field identifier + setCentre(osg::Vec3(ct[0],ct[1],ct[2])); + } + ok=true; + } + } + } + return ok; + } private: // for fast transform behaviours unsigned int type; // eg GEO_DB_ROTATE_ACTION_INPUT_VAR, translate etc @@ -122,36 +307,185 @@ private: osg::Vec3 axis; // axis of rotation osg::Vec3 centre; // centre of rotation }; + +class geoStrContentBehaviour : public geoMoveBehaviour { + // sets content of a string... +public: + geoStrContentBehaviour() {format=NULL;PADDING_TYPE=0; + PAD_FOR_SIGN=0; vt=UNKNOWN; } + virtual ~geoStrContentBehaviour() { delete [] format;} + void doaction(osg::Drawable *node) { // do new text + osgText::Text *txt=dynamic_cast(node); + char content[32]; + switch (vt) { + case INT: + sprintf(content, format, (int)getValue()); + break; + case FLOAT: + sprintf(content, format, (float)getValue()); + break; + case DOUBLE: + sprintf(content, format, getValue()); + break; + case CHAR: + sprintf(content, format, (char *)getVar()); + break; + default: + sprintf(content, format, (char *)getVar()); + } + txt->setText(std::string(content)); + } + bool makeBehave(const georecord *grec, geoHeader *theHeader) { + bool ok=false; + const geoField *gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_INPUT_VAR); + if (gfd) { + unsigned fid= gfd->getUInt(); // field identifier + setVar(theHeader->getVar(fid)); // returns address of input var with fid + if (getVar()) { + gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_FORMAT); + if (gfd) { + char *ch=gfd->getChar(); + format=new char[strlen(ch)+1]; + strcpy(format, ch); + { + char *ctmp=format; + while (*ctmp) { + if (*ctmp=='d') vt=INT; + if (*ctmp=='f' && vt!=DOUBLE) vt=FLOAT; + if (*ctmp=='l') vt=DOUBLE; + ctmp++; + } + } + gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_PADDING_TYPE); + // inmin=gfd?gfd->getFloat():-1.e32; + gfd=grec->getField(GEO_DB_STRING_CONTENT_ACTION_PADDING_TYPE); + ok=true; + } + } + } + return ok; + } + virtual void operator() (osg::Node *node, osg::NodeVisitor*) + { // update the string content + if (getVar()) { + osgText::Text *txt=dynamic_cast(node); + switch (getType()) { + case DB_DSK_STRING_CONTENT_ACTION: + { + char content[32]; + sprintf(content,"%f", getValue()); + txt->setText(std::string(content)); + } + break; + default: + break; + } + } + } + enum valuetype {UNKNOWN, INT, FLOAT, DOUBLE, CHAR}; +private: + char *format; + uint PADDING_TYPE; + uint PAD_FOR_SIGN; + valuetype vt; +}; + class geoBehaviourCB: public osg::NodeCallback { public: geoBehaviourCB() { } ~geoBehaviourCB() { } - void addBehaviour(geoMatBehaviour *gb) {gblist.push_back(*gb);} - void addBehaviour(geoArithBehaviour *gb) {galist.push_back(*gb);} + void addBehaviour(geoMoveBehaviour *gb) {gblist.push_back(gb);} + void addBehaviour(geoClampBehaviour *gb) {galist.push_back(gb);} + void addBehaviour(geoArithBehaviour *gb) {galist.push_back(gb);} + void addBehaviour(geoRangeBehaviour *gb) {galist.push_back(gb);} virtual void operator() (osg::Node *node, osg::NodeVisitor* nv) { // update the transform // std::cout<<"geoBehaviourCB callback - "<< var << " " << (*var) < (node); mtr->setMatrix(Matrix::identity()); { - for (std::vector::const_iterator itr=galist.begin(); + for (std::vector::iterator itr=galist.begin(); itrdoaction(node); + itr++) { // perform the arithmetic lists + geoArithBehaviour *ab=dynamic_cast(*itr); + if (ab) ab->doaction(node); + geoClampBehaviour *cb=dynamic_cast(*itr); + if (cb) cb->doaction(node); + geoRangeBehaviour *cr=dynamic_cast(*itr); + if (cr) cr->doaction(node); } } { - for (std::vector::const_iterator itr=gblist.begin(); + for (std::vector::const_iterator itr=gblist.begin(); itrdoaction(node); + itr++) { // motion behaviour + (*itr)->doaction(node); } } traverse(node,nv); } private: - std::vector gblist; - std::vector galist; + std::vector gblist; + std::vector galist; +}; +class geoBehaviourDrawableCB: public osg::Drawable::AppCallback { +public: + geoBehaviourDrawableCB() { } + ~geoBehaviourDrawableCB() { } + void addBehaviour(geoStrContentBehaviour *gb) {gblist.push_back(gb);} + void addBehaviour(geoClampBehaviour *gb) {galist.push_back(gb);} + void addBehaviour(geoArithBehaviour *gb) {galist.push_back(gb);} + void addBehaviour(geoRangeBehaviour *gb) {galist.push_back(gb);} + void app(osg::NodeVisitor *,osg::Drawable *dr) { + //osgText::Text *mtr=dynamic_cast (dr); + { + for (std::vector::iterator itr=galist.begin(); + itr(*itr); + // if (ab) ab->doaction(dr); + // geoClampBehaviour *cb=dynamic_cast(*itr); + // if (cb) cb->doaction(dr); + // geoRangeBehaviour *cr=dynamic_cast(*itr); + // if (cr) cr->doaction(dr); + } + } + { + for (std::vector::const_iterator itr=gblist.begin(); + itrdoaction(dr); + } + } + } +/* virtual void operator() (osg::Node *node, osg::NodeVisitor* nv) + { // update the transform + // std::cout<<"geoBehaviourCB callback - "<< var << " " << (*var) < (node); + { + for (std::vector::iterator itr=galist.begin(); + itr(*itr); + if (ab) ab->doaction(node); + geoClampBehaviour *cb=dynamic_cast(*itr); + if (cb) cb->doaction(node); + geoRangeBehaviour *cr=dynamic_cast(*itr); + if (cr) cr->doaction(node); + } + } + { + for (std::vector::const_iterator itr=gblist.begin(); + itrdoaction(node); + } + } + // traverse(node,nv); + } */ +private: + std::vector gblist; + std::vector galist; }; class pack_colour { @@ -237,10 +571,6 @@ public: blue=col[2]*frac/255.0f; alpha=1.0; // col[3]*frac/255.0f; } else { - // unsigned char *cp=gfd->getUCh4Arr(); - // frac = (float)(cp[3])/255.0f; - // maxcol=cp[2]; - // color_palette[maxcol].get(col); red=cdef[0]/255.0f; // convert to range {0-1} green=cdef[1]/255.0f; blue=cdef[2]/255.0f; @@ -323,11 +653,10 @@ class ReaderWriterGEO : public ReaderWriter fin.close(); // now sort the reocrds so that any record followed by a PUSh has a child set = next record, etc std::vector sorted=sort(recs); // tree-list of sorted record pointers - osgDB::Output fout("georex.txt"); //, std::ios_base::out ); - fout << "Debug file " << std::endl; - // output(fout,sorted); // print details of the sorted tree, with records indented. - nodeList=makeosg(sorted, fout); // make a list of osg nodes - fout.close(); + // osgDB::Output fout("georex.txt"); //, std::ios_base::out ); + // fout << "Debug file " << fileName << std::endl; + nodeList=makeosg(sorted); // make a list of osg nodes + // fout.close(); recs.erase(recs.begin(),recs.end()); color_palette.erase(color_palette.begin(),color_palette.end()); @@ -384,13 +713,13 @@ class ReaderWriterGEO : public ReaderWriter if (curparent) curparent=curparent->getparent(); break; case DB_DSK_HEADER: // attach to previous - curparent= itr; + curparent= &(*itr); sorted.push_back(itr); break; case DB_DSK_INTERNAL_VARS: // attach to parent case DB_DSK_LOCAL_VARS: case DB_DSK_EXTERNAL_VARS: - (curparent)->addBehaviour((itr)); + (curparent)->addBehaviourRecord((itr)); break; case DB_DSK_FLOAT_VAR: // attach to parent case DB_DSK_INT_VAR: @@ -401,7 +730,7 @@ class ReaderWriterGEO : public ReaderWriter case DB_DSK_FLOAT3_VAR: case DB_DSK_FLOAT4_VAR: // else if ((*itr).isVar(): - (curparent)->addBehaviour((itr)); + (curparent)->addBehaviourRecord((itr)); break; case DB_DSK_TEXTURE: // attach to parent geotxlist.push_back(itr); @@ -415,8 +744,8 @@ class ReaderWriterGEO : public ReaderWriter gfd=itr->getField(GEO_DB_COORD_POOL_VALUES); { float *crds= (gfd) ? (gfd->getVec3Arr()):NULL; - int nm=gfd->getNum(); - for (int i=0; igetNum(); + for (uint i=0; igetField(GEO_DB_NORMAL_POOL_VALUES); { float *nrms= (gfd) ? (gfd->getVec3Arr()):NULL; - int nm=gfd->getNum(); - for (int i=0; igetNum(); + for (uint i=0; igetField(GEO_DB_COLOR_PALETTE_HIGHEST_INTENSITIES); if (gfd) { unsigned char *cpal=gfd->getstore(0); - for (int i=1; igetNum(); i++) { + for (uint i=1; igetNum(); i++) { color_palette.push_back(cpal); cpal+=4; } @@ -466,7 +795,7 @@ class ReaderWriterGEO : public ReaderWriter case DB_DSK_ABS_ACTION: case DB_DSK_IF_THEN_ELSE_ACTION: case DB_DSK_DCS_ACTION: - (curparent->getLastChild())->addBehaviour((itr)); + (curparent->getLastChild())->addBehaviourRecord((itr)); break; default: if (curparent) { @@ -478,7 +807,7 @@ class ReaderWriterGEO : public ReaderWriter } return sorted; } - void outputPrim(const georecord *grec, osgDB::Output &fout) { + void outputPrim(const georecord *grec, osgDB::Output &fout) { // output to file for debug const std::vector gr=grec->getchildren(); if (gr.size()>0) { for (std::vector::const_iterator itr=gr.begin(); @@ -488,6 +817,53 @@ class ReaderWriterGEO : public ReaderWriter } } } + osg::Geometry *makeNewGeometry(const georecord *grec, const vertexInfo &vinf, int txidx, uint imat, + int shademodel, Vec4Array *polycols) { + osg::Geometry *nug; + nug=new osg::Geometry; + nug->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + nug->setVertexArray(vinf.getCoords()); + nug->setNormalArray(vinf.getNorms()); + StateSet *dstate=new StateSet; + if (txidx>=0 && (unsigned int)txidxsetTextureAttribute(0, txenvlist[txidx] ); + dstate->setTextureAttributeAndModes(0,txlist[txidx],osg::StateAttribute::ON); + } + if (imat>0 && imatsetColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + dstate->setAttribute(matlist[imat]); + } else { + matlist[0]->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + dstate->setAttribute(matlist[0]); + } + dstate->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::ON); + if (shademodel==GEO_POLY_SHADEMODEL_LIT || + shademodel==GEO_POLY_SHADEMODEL_LIT_GOURAUD) dstate->setMode( GL_LIGHTING, osg::StateAttribute::ON ); + else + dstate->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + { // reclaim the colours + const geoField *gfd=grec->getField(GEO_DB_POLY_USE_MATERIAL_DIFFUSE); // true: use material... + bool usemat= gfd ? gfd->getBool() : false; + if (!usemat) { // get the per vertex colours OR per face colours. + gfd=grec->getField(GEO_DB_POLY_USE_VERTEX_COLORS); // true: use material... + bool usevert=gfd ? gfd->getBool() : true; + if (usevert) { + Vec4Array *cls=vinf.getColors(); + if (cls) { + nug->setColorArray(cls); + nug->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + } + } else { + if (polycols->size() > 0) { + nug->setColorArray(polycols); + nug->setColorBinding(osg::Geometry::BIND_PER_VERTEX); //PRIMITIVE); + } + } + } + } + nug->setStateSet( dstate ); + return nug; + } int getprim(const georecord *grec,vertexInfo &vinf) { // fills vinf with txcoords = texture coordinates, txindex=txindex etc int nv=0; @@ -522,22 +898,114 @@ class ReaderWriterGEO : public ReaderWriter } return nv; } - void outputGeode(georecord grec, osgDB::Output &fout) { + void outputGeode(georecord grec) { // , osgDB::Output &fout const std::vector gr=grec.getchildren(); if (gr.size()>0) { + // fout.moveIn(); for (std::vector::const_iterator itr=gr.begin(); itr!=gr.end(); ++itr) { - fout << *(*itr) << std::endl; + //fout.indent() << *(*itr) << std::endl; if ((*itr)->getType()==DB_DSK_POLYGON) { - outputPrim((*itr), fout); + //outputPrim((*itr),fout); + } + } + // fout.moveOut(); + } + } + osg::MatrixTransform *makeText(georecord *gr) { // make transform, geode & text + std::string ttfPath("fonts/times.ttf"); + int gFontSize1=2; + osgText::PolygonFont* polygonFont= osgNew osgText::PolygonFont(ttfPath, + gFontSize1, + 3); + osgText::Text *text= osgNew osgText::Text(polygonFont); + const geoField *gfd=gr->getField(GEO_DB_TEXT_NAME); + //const char *name=gfd ? gfd->getChar() : "a text"; + gfd=gr->getField(GEO_DB_TEXT_STRING); + const char *content=gfd ? gfd->getChar() : " "; + text->setText(std::string(content)); + gfd=gr->getField(GEO_DB_TEXT_SCALE_X); + //const float scx=gfd ? gfd->getFloat() : 1.0f; + gfd=gr->getField(GEO_DB_TEXT_SCALE_Y); + //const float scy=gfd ? gfd->getFloat() : 1.0f; + gfd=gr->getField(GEO_DB_TEXT_JUSTIFICATION); // GEO_DB_TEXT_DIRECTION); + int tjus=gfd? gfd->getInt() : GEO_TEXT_LEFT_JUSTIFY; + switch(tjus) { + case GEO_TEXT_LEFT_JUSTIFY: text->setAlignment(osgText::Text::LEFT_BOTTOM); break; + case GEO_TEXT_CENTER_JUSTIFY: text->setAlignment(osgText::Text::CENTER_BOTTOM); break; + case GEO_TEXT_RIGHT_JUSTIFY: text->setAlignment(osgText::Text::RIGHT_BOTTOM); break; + } + gfd=gr->getField(GEO_DB_TEXT_PACKED_COLOR); + if (gfd) { + unsigned char *cp=gfd->getUCh4Arr(); + float red=(float)cp[0]*255.0f; + float green=(float)cp[1]*255.0f; + float blue=(float)cp[2]*255.0f; + text->setColor(osg::Vec4(red,green,blue,1.0f)); + } else { // lok for a colour index (exclusive!) + gfd=gr->getField(GEO_DB_TEXT_COLOR_INDEX); + if (gfd) { + int icp=gfd->getInt(); + float red=1.0f; // convert to range {0-1} + float green=1.0f; + float blue=1.0f; + float alpha=1.0f; + uint maxcol=(icp)/128; // the maximum intensity, 0-127 in bank 0, 128-255 =b2 + float frac = (float)(icp-maxcol*128)/128.0f; + unsigned char col[4]; + if (maxcol < color_palette.size()) { + color_palette[maxcol].get(col); + red=col[0]*frac/255.0f; // convert to range {0-1} + green=col[1]*frac/255.0f; + blue=col[2]*frac/255.0f; + alpha=1.0; // col[3]*frac/255.0f; + } else { + red=1.0f; // default colour range {0-1} + green=1.0f; + blue=1.0f; + alpha=1.0; // col[3]*frac/255.0f; + } + text->setColor(osg::Vec4(red,green,blue,1.0)); + } + } + osg::MatrixTransform *numt=new osg::MatrixTransform; + osg::Geode *geod=new osg::Geode; + gfd=gr->getField(GEO_DB_TEXT_MATRIX); + if (gfd) { + float *fmat=gfd->getMat44Arr(); + // text->setPosition(osg::Vec3(fmat[12],fmat[13],fmat[14])); + numt->setMatrix(Matrix(fmat)); + } + numt->addChild(geod); + geod->addDrawable(text); + { + std::vector< georecord *>bhv=gr->getBehaviour(); + if (!bhv.empty()) { // then check for a string content/colour.. action + bool ok=false; + geoBehaviourDrawableCB *gcb=new geoBehaviourDrawableCB; + text->setAppCallback(gcb); + for (std::vector< georecord *>::const_iterator rcitr=bhv.begin(); + rcitr!=bhv.end(); + ++rcitr) + { + if ((*rcitr)->getType()==DB_DSK_STRING_CONTENT_ACTION) { + geoStrContentBehaviour *cb=new geoStrContentBehaviour; + gfd=(*rcitr)->getField(GEO_DB_STRING_CONTENT_ACTION_INPUT_VAR); + if (gfd) { + ok=cb->makeBehave((*rcitr), theHeader); + if (ok) gcb->addBehaviour(cb); + else delete cb; + ok=false; + } + } } } } + return numt; } - std::vectormakeGeometry(georecord grec, const unsigned int imat) - { - // makegeometry returns a set of Geometrys to attach to current parent (Geode) + void makeGeometry(georecord grec, const unsigned int imat,Geode *nug) + { // makegeometry returns a set of Geometrys attached to current parent (Geode nug) const std::vector gr=grec.getchildren(); std::vector geom; if (gr.size()>0) { @@ -566,7 +1034,6 @@ class ReaderWriterGEO : public ReaderWriter gfd=(*itr)->getField(GEO_DB_POLY_PACKED_COLOR); // the colour if (gfd) { unsigned char *cls=gfd->getUCh4Arr(); - //polycols->push_back(osg::Vec4((float)cls[0],(float)cls[2],(float)cls[3],(float)cls[4])); float red=cls[0]/255.0f; float green=cls[1]/255.0f; float blue=cls[2]/255.0f; @@ -594,51 +1061,10 @@ class ReaderWriterGEO : public ReaderWriter igidx++; } int nv=getprim((*itr),vinf); - if (igeom<0) { - osg::Geometry *nug; - nug=new osg::Geometry; - nug->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - nug->setVertexArray(vinf.getCoords()); - nug->setNormalArray(vinf.getNorms()); - StateSet *dstate=new StateSet; - if (txidx>=0 && (unsigned int)txidxsetTextureAttribute(0, txenvlist[txidx] ); - dstate->setTextureAttributeAndModes(0,txlist[txidx],osg::StateAttribute::ON); - } - if (imat>0 && imatsetColorMode(osg::Material::AMBIENT_AND_DIFFUSE); - dstate->setAttribute(matlist[imat]); - } else { - matlist[0]->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); - dstate->setAttribute(matlist[0]); - } - dstate->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::ON); - if (shademodel==GEO_POLY_SHADEMODEL_LIT || - shademodel==GEO_POLY_SHADEMODEL_LIT_GOURAUD) dstate->setMode( GL_LIGHTING, osg::StateAttribute::ON ); - else - dstate->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); - { // reclaim the colours - gfd=(*itr)->getField(GEO_DB_POLY_USE_MATERIAL_DIFFUSE); // true: use material... - bool usemat= gfd ? gfd->getBool() : false; - if (!usemat) { // get the per vertex colours OR per face colours. - gfd=(*itr)->getField(GEO_DB_POLY_USE_VERTEX_COLORS); // true: use material... - bool usevert=gfd ? gfd->getBool() : true; - if (usevert) { - Vec4Array *cls=vinf.getColors(); - if (cls) { - nug->setColorArray(cls); - nug->setColorBinding(osg::Geometry::BIND_PER_VERTEX); - } - } else { - if (polycols->size() > 0) { - nug->setColorArray(polycols); - nug->setColorBinding(osg::Geometry::BIND_PER_VERTEX); //PRIMITIVE); - } - } - } - } - nug->setStateSet( dstate ); - geom.push_back(nug); + if (igeom<0) { // we need a new geometry for this due to new texture/material combo + osg::Geometry *nugeom=makeNewGeometry((*itr), vinf, txidx, imat,shademodel, polycols); + geom.push_back(nugeom); + nug->addDrawable(nugeom); igeom=ia.size(); ia.push_back(txidx); // look up table for which texture corresponds to which geom } @@ -658,25 +1084,61 @@ class ReaderWriterGEO : public ReaderWriter } // osg::notify(osg::WARN) << vinf; } - return geom; + return; } - Geode *makeGeode(const georecord *gr, osgDB::Output &fout) - { - Geode *nug=new Geode; + void makeTexts(georecord grec, unsigned int /*imat*/,Group *nug) + { // makegeometry returns a set of Geometrys attached to current parent (Geode nug) + const std::vector gr=grec.getchildren(); + std::vector geom; + if (gr.size()>0) { + //Vec4Array *polycols= new osg::Vec4Array; // polygon colours + std::vector ia; // list of texture indices found in this geode; sort into new + //int nstart=0; // start of list + for (std::vector::const_iterator itr=gr.begin(); + itr!=gr.end(); + ++itr) { + if ((*itr)->getType()==DB_DSK_TEXT) { + osg::MatrixTransform *text=makeText((*itr)); + if (text) nug->addChild(text); + } + } + // osg::notify(osg::WARN) << vinf; + } + return; + } + Group *makeTextGeode(const georecord *gr) + { // in geo text is defined with a matrix included in the geo.geode (gr is this geo.geode) + // - we need to create this tree to render text + Group *nug=new Group; const geoField *gfd=gr->getField(GEO_DB_RENDERGROUP_MAT); const unsigned int imat=gfd ? gfd->getInt():0; gfd=gr->getField(GEO_DB_RENDERGROUP_NAME); if (gfd) { nug->setName(gfd->getChar()); } - std::vectorgeom=makeGeometry((*gr),imat); - outputGeode((*gr), fout); - for (std::vector::iterator itg=geom.begin(); - itg!=geom.end(); - ++itg) - { - nug->addDrawable((*itg)); + makeTexts((*gr),imat,nug); + return nug; + } + Geode *makeGeode(const georecord *gr) + { + const geoField *gfd=gr->getField(GEO_DB_RENDERGROUP_MAT); + const unsigned int imat=gfd ? gfd->getInt():0; + gfd=gr->getField(GEO_DB_RENDERGROUP_IS_BILLBOARD); + bool isbillb = gfd ? gfd->getBool() : false; + Geode *nug; + if (isbillb) { + Billboard *bilb= new Billboard ; + bilb->setAxis(Vec3(0,0,1)); + bilb->setNormal(Vec3(0,1,0)); + nug=bilb; + } else { + nug=new Geode; } + gfd=gr->getField(GEO_DB_RENDERGROUP_NAME); + if (gfd) { + nug->setName(gfd->getChar()); + } + makeGeometry((*gr),imat,nug); return nug; } osg::Group *makePage(const georecord *gr) @@ -877,6 +1339,7 @@ class ReaderWriterGEO : public ReaderWriter MatrixTransform *makeBehave(const georecord *gr) { MatrixTransform *mtr=NULL; + bool ok=false; // true if the matrix transform is a matrix transform std::vector< georecord *>bhv=gr->getBehaviour(); if (!bhv.empty()) { // then add a DCS/matrix_transform mtr=new MatrixTransform; @@ -894,110 +1357,73 @@ class ReaderWriterGEO : public ReaderWriter } } if ((*rcitr)->getType()==DB_DSK_ROTATE_ACTION) { - const geoField *gfd=(*rcitr)->getField(GEO_DB_ROTATE_ACTION_INPUT_VAR); - if (gfd) { - unsigned fid= gfd->getUInt(); // field identifier - const double *dvar=theHeader->getVar(fid); // returns address of var with fid - if (dvar) { - geoMatBehaviour *cb=new geoMatBehaviour; - cb->setVar(dvar); - cb->setType(DB_DSK_ROTATE_ACTION); - gfd=(*rcitr)->getField(GEO_DB_ROTATE_ACTION_VECTOR); - if (gfd) { - float *ax= gfd->getVec3Arr(); // field identifier - cb->setAxis(osg::Vec3(ax[0],ax[1],ax[2])); - } - gfd=(*rcitr)->getField(GEO_DB_ROTATE_ACTION_ORIGIN); - if (gfd) { - float *ct= gfd->getVec3Arr(); // field identifier - cb->setCentre(osg::Vec3(ct[0],ct[1],ct[2])); - } - gcb->addBehaviour(cb); - } - } + geoMoveBehaviour *cb= new geoMoveBehaviour; + ok=cb->makeBehave((*rcitr), theHeader,DB_DSK_ROTATE_ACTION); + if (ok) gcb->addBehaviour(cb); + else delete cb; } if ((*rcitr)->getType()==DB_DSK_TRANSLATE_ACTION) { - const geoField *gfd=(*rcitr)->getField(GEO_DB_TRANSLATE_ACTION_INPUT_VAR); - if (gfd) { - unsigned fid= gfd->getUInt(); // field identifier - const double *dvar=theHeader->getVar(fid); // returns address of var with fid - if (dvar) { - geoMatBehaviour *cb=new geoMatBehaviour; - cb->setVar(dvar); - cb->setType(DB_DSK_TRANSLATE_ACTION); - gfd=(*rcitr)->getField(GEO_DB_TRANSLATE_ACTION_VECTOR); - if (gfd) { - float *ax= gfd->getVec3Arr(); // field identifier - cb->setAxis(osg::Vec3(ax[0],ax[1],ax[2])); - } - gfd=(*rcitr)->getField(GEO_DB_TRANSLATE_ACTION_ORIGIN); - if (gfd) { - float *ct= gfd->getVec3Arr(); // field identifier - cb->setCentre(osg::Vec3(ct[0],ct[1],ct[2])); - } - gcb->addBehaviour(cb); - } - } + geoMoveBehaviour *cb= new geoMoveBehaviour; + ok=cb->makeBehave((*rcitr), theHeader,DB_DSK_TRANSLATE_ACTION); + if (ok) gcb->addBehaviour(cb); + else delete cb; } if ((*rcitr)->getType()==DB_DSK_ARITHMETIC_ACTION) { - const geoField *gfd=(*rcitr)->getField(GEO_DB_ARITHMETIC_ACTION_INPUT_VAR); - if (gfd) { - unsigned fid= gfd->getUInt(); // field identifier - const double *indvar=theHeader->getVar(fid); // returns address of input var with fid - if (indvar) { - gfd=(*rcitr)->getField(GEO_DB_ARITHMETIC_ACTION_OUTPUT_VAR); - if (gfd) { - fid= gfd->getUInt(); // field identifier - double *outdvar=theHeader->getVar(fid); // returns address of output var with fid - geoArithBehaviour *cb=new geoArithBehaviour; - cb->setInVar(indvar); - cb->setOutVar(outdvar); - gfd=(*rcitr)->getField(GEO_DB_ARITHMETIC_ACTION_OP_TYPE); - uint iop=gfd?gfd->getUInt():1; - cb->setType(iop); // default add? - gfd=(*rcitr)->getField(GEO_DB_ARITHMETIC_ACTION_OPERAND_VALUE); - if (gfd) { - float ax= gfd->getFloat(); // field identifier - cb->setConstant(ax); - } - gfd=(*rcitr)->getField(GEO_DB_ARITHMETIC_ACTION_OPERAND_VAR); - if (gfd) { - unsigned fid= gfd->getUInt(); // field identifier - const double *varvar=theHeader->getVar(fid); - cb->setVariable(varvar); - } - gcb->addBehaviour(cb); - } - } - } + geoArithBehaviour *cb=new geoArithBehaviour; + ok=cb->makeBehave((*rcitr), theHeader); + if (ok) gcb->addBehaviour(cb); + else delete cb; + } + if ((*rcitr)->getType()==DB_DSK_CLAMP_ACTION) { + geoClampBehaviour *cb=new geoClampBehaviour; + ok=cb->makeBehave((*rcitr), theHeader); + if (ok) gcb->addBehaviour(cb); + else delete cb; + } + if ((*rcitr)->getType()==DB_DSK_RANGE_ACTION) { + geoRangeBehaviour *cb=new geoRangeBehaviour; + ok=cb->makeBehave((*rcitr), theHeader); + if (ok) gcb->addBehaviour(cb); + else delete cb; + } + if ((*rcitr)->getType()==DB_DSK_STRING_CONTENT_ACTION) { + ok=false; } } } + if (!ok) { + mtr=NULL; + } return mtr; } - std::vector makeosg(const std::vector gr, osgDB::Output &fout) { + std::vector makeosg(const std::vector gr) { // recursive traversal of records and extract osg::Nodes equivalent Group *geodeholder=NULL; std::vector nodelist; - fout.moveIn(); // increase indent + // fout.moveIn(); // increase indent if (gr.size()>0) { for (std::vector::const_iterator itr=gr.begin(); itr!=gr.end(); ++itr) { const georecord *gr=*itr; MatrixTransform *mtr=makeBehave(gr); - fout.indent() << (*gr) << std::endl; + //fout.indent() << (*gr) << std::endl; if (gr->getType()== DB_DSK_GEODE) { // geodes can require >1 geometry for example if polygons have different texture indices. - Geode *geode=makeGeode(gr, fout); + Geode *geode=makeGeode(gr); // geode of geometrys + Group *textgeode=makeTextGeode(gr); // group of matrices & texts + outputGeode((*gr)); + if (mtr) { - mtr->addChild(geode); + if (geode) mtr->addChild(geode); + if (textgeode) mtr->addChild(textgeode); nodelist.push_back(mtr); mtr=NULL; } else { - if (!geodeholder) { + if (!geodeholder && (geode || textgeode)) { geodeholder=new osg::Group; } - geodeholder->addChild(geode); + if (geode) geodeholder->addChild(geode); + if (textgeode) geodeholder->addChild(textgeode); } } else { Group *holder=NULL; @@ -1005,13 +1431,13 @@ class ReaderWriterGEO : public ReaderWriter switch (gr->getType()) { case DB_DSK_HEADER: holder=makeHeader(gr); - { + /*{ for (std::vector::const_iterator itr=color_palette.begin(); itr!=color_palette.end(); ++itr) { fout << (*itr) << std::endl; } - } + } */ break; case DB_DSK_MATERIAL: { @@ -1085,14 +1511,14 @@ class ReaderWriterGEO : public ReaderWriter case DB_DSK_FLOAT2_VAR: case DB_DSK_FLOAT3_VAR: case DB_DSK_FLOAT4_VAR: - fout.indent() << "AVars " << gr->getType() << std::endl; - fout.indent() << (*gr) << std::endl; + // fout.indent() << "AVars " << gr->getType() << std::endl; + // fout.indent() << (*gr) << std::endl; break; case DB_DSK_INTERNAL_VARS: case DB_DSK_LOCAL_VARS: case DB_DSK_EXTERNAL_VARS: - fout.indent() << "==Vars " << gr->getType() << std::endl; - fout.indent() << (*gr) << std::endl; + // fout.indent() << "==Vars " << gr->getType() << std::endl; + // fout.indent() << (*gr) << std::endl; break; case DB_DSK_CLAMP_ACTION: case DB_DSK_RANGE_ACTION: @@ -1107,8 +1533,8 @@ class ReaderWriterGEO : public ReaderWriter case DB_DSK_VISIBILITY_ACTION: case DB_DSK_STRING_CONTENT_ACTION: holder=new Group; - fout.indent() << "==Poorly handled option " << gr->getType() << std::endl; - fout.indent() << (*gr) << std::endl; + // fout.indent() << "==Poorly handled option " << gr->getType() << std::endl; + // fout.indent() << (*gr) << std::endl; break; default: { osg::Group *gp=new Group; @@ -1119,7 +1545,7 @@ class ReaderWriterGEO : public ReaderWriter // fout.indent() << (*gr) << std::endl; if (holder) nodelist.push_back(holder); - std::vector child=makeosg((*itr)->getchildren(),fout); + std::vector child=makeosg((*itr)->getchildren()); for (std::vector::iterator itr=child.begin(); itr!=child.end(); ++itr) { @@ -1129,7 +1555,7 @@ class ReaderWriterGEO : public ReaderWriter } } if (geodeholder) nodelist.push_back(geodeholder); - fout.moveOut(); // decrease indent + //fout.moveOut(); // decrease indent return nodelist; } void output(osgDB::Output &fout,std::vector gr) @@ -1209,7 +1635,7 @@ void userVars::addUserVar(const georecord &gr) { } } gfd= gr.getField(GEO_DB_FLOAT_VAR_STEP); - //float fstp=gfd ? gfd->getFloat():0.0f; + //float fstp=gfd ? gfd->getFloat():0; vars.push_back(*nm); } } @@ -1224,7 +1650,7 @@ void internalVars::update(osg::Timer &_timer,osg::FrameStamp &_frameStamp) { unsigned int typ=itr->getToken(); switch (typ) { case GEO_DB_INTERNAL_VAR_FRAMECOUNT: - vars[iord].setVal(_frameTick); + vars[iord].setVal((float)_frameStamp.getFrameNumber()); break; case GEO_DB_INTERNAL_VAR_CURRENT_TIME: vars[iord].setVal(_timer.delta_s(0,_frameTick)); @@ -1276,4 +1702,3 @@ void internalVars::update(osg::Timer &_timer,osg::FrameStamp &_frameStamp) { // now register with Registry to instantiate the above // reader/writer. osgDB::RegisterReaderWriterProxy gReaderWriter_GEO_Proxy; - diff --git a/src/osgPlugins/geo/osgGeoStructs.h b/src/osgPlugins/geo/osgGeoStructs.h index 0ef37526b..57bddc2c2 100644 --- a/src/osgPlugins/geo/osgGeoStructs.h +++ b/src/osgPlugins/geo/osgGeoStructs.h @@ -205,6 +205,7 @@ public: if (gf.tokenId!=GEO_DB_LAST_FIELD) { output.indent() << " Field:token " << (int)gf.tokenId << " datatype " << (int)gf.TypeId << " num its " << gf.numItems << " size " << gf.storeSize << std::endl; + if (gf.TypeId==DB_CHAR) output.indent(); for (uint i=0; i getchildren(void) const { return children;} void addchild(class georecord *gr) { children.push_back(gr);} georecord *getLastChild(void) const { return children.back();} - void addBehaviour(class georecord *gr) { behaviour.push_back(gr);} + void addBehaviourRecord(class georecord *gr) { behaviour.push_back(gr);} std::vector< georecord *>getBehaviour() const { return behaviour;} const geoFieldList getFields() const { return fields;} inline bool isVar(void) const { @@ -440,60 +442,62 @@ public: } friend inline std::ostream& operator << (osgDB::Output& output, const georecord& gr) { - if (gr.id == DB_DSK_PUSH) output << "Push" << std::endl; - else if (gr.id == DB_DSK_POP) output << "Pop" << std::endl; - else if (gr.id == DB_DSK_HEADER) output << "Header" << std::endl; - else if (gr.id == DB_DSK_GROUP) output << "Group" << std::endl; - else if (gr.id == DB_DSK_BILLBOARD) output << "Billboard" << std::endl; - else if (gr.id == DB_DSK_SEQUENCE) output << "Sequence" << std::endl; - else if (gr.id == DB_DSK_LOD) output << "LOD" << std::endl; - else if (gr.id == DB_DSK_GEODE) output << "Geode" << std::endl; - else if (gr.id == DB_DSK_POLYGON) output << "Polygon" << std::endl; - else if (gr.id == DB_DSK_MESH) output << "Mesh" << std::endl; - else if (gr.id == DB_DSK_CUBE) output << "Cube" << std::endl; - else if (gr.id == DB_DSK_SPHERE) output << "Sphere" << std::endl; - else if (gr.id == DB_DSK_CONE) output << "Cone" << std::endl; - else if (gr.id == DB_DSK_CYLINDER) output << "Cylinder" << std::endl; - else if (gr.id == DB_DSK_VERTEX) output << "Vertex" << std::endl; - else if (gr.id == DB_DSK_TEXTURE) output << "Texture" << std::endl; - else if (gr.id == DB_DSK_MATERIAL) output << "Material" << std::endl; - else if (gr.id == DB_DSK_VIEW) output << "View" << std::endl; - else if (gr.id == DB_DSK_EXTENSION_LIST) output << "Extensions" << std::endl; - else if (gr.id == DB_DSK_COORD_POOL) output << "Coords" << std::endl; - else if (gr.id == DB_DSK_NORMAL_POOL) output << "Normals" << std::endl; - else if (gr.id == DB_DSK_SWITCH) output << "Switch" << std::endl; - else if (gr.id == DB_DSK_TEXT) output << "Text" << std::endl; - else if (gr.id == DB_DSK_BASE_GROUP) output << "Base group" << std::endl; - else if (gr.id == DB_DSK_BASE_SURFACE) output << "Base Surface" << std::endl; - else if (gr.id == DB_DSK_INSTANCE) output << "Instance" << std::endl; - else if (gr.id == DB_DSK_LIGHTPT) output << "Light Point" << std::endl; - else if (gr.id == DB_DSK_EXTERNAL) output << "External" << std::endl; - else if (gr.id == DB_DSK_PAGE) output << "Page" << std::endl; - else if (gr.id == DB_DSK_COLOR_PALETTE) output << "Colour palette" << std::endl; - else if (gr.id == DB_DSK_INTERNAL_VARS) output << "Internal vars" << std::endl; - else if (gr.id == DB_DSK_LOCAL_VARS) output << "Local vars" << std::endl; - else if (gr.id == DB_DSK_EXTERNAL_VARS) output << "External vars" << std::endl; + switch (gr.id) { + case DB_DSK_PUSH: output << "Push" << std::endl; break; + case DB_DSK_POP: output << "Pop" << std::endl; break; + case DB_DSK_HEADER: output << "Header" << std::endl; break; + case DB_DSK_GROUP: output << "Group" << std::endl; break; + case DB_DSK_BILLBOARD: output << "Billboard" << std::endl; break; + case DB_DSK_SEQUENCE: output << "Sequence" << std::endl; break; + case DB_DSK_LOD: output << "LOD" << std::endl; break; + case DB_DSK_GEODE: output << "Geode" << std::endl; break; + case DB_DSK_POLYGON: output << "Polygon" << std::endl; break; + case DB_DSK_MESH: output << "Mesh" << std::endl; break; + case DB_DSK_CUBE: output << "Cube" << std::endl; break; + case DB_DSK_SPHERE: output << "Sphere" << std::endl; break; + case DB_DSK_CONE: output << "Cone" << std::endl; break; + case DB_DSK_CYLINDER: output << "Cylinder" << std::endl; break; + case DB_DSK_VERTEX: output << "Vertex" << std::endl; break; + case DB_DSK_TEXTURE: output << "Texture" << std::endl; break; + case DB_DSK_MATERIAL: output << "Material" << std::endl; break; + case DB_DSK_VIEW: output << "View" << std::endl; break; + case DB_DSK_EXTENSION_LIST: output << "Extensions" << std::endl; break; + case DB_DSK_COORD_POOL: output << "Coords" << std::endl; break; + case DB_DSK_NORMAL_POOL: output << "Normals" << std::endl; break; + case DB_DSK_SWITCH: output << "Switch" << std::endl; break; + case DB_DSK_TEXT: output << "Text" << std::endl; break; + case DB_DSK_BASE_GROUP: output << "Base group" << std::endl; break; + case DB_DSK_BASE_SURFACE: output << "Base Surface" << std::endl; break; + case DB_DSK_INSTANCE: output << "Instance" << std::endl; break; + case DB_DSK_LIGHTPT: output << "Light Point" << std::endl; break; + case DB_DSK_EXTERNAL: output << "External" << std::endl; break; + case DB_DSK_PAGE: output << "Page" << std::endl; break; + case DB_DSK_COLOR_PALETTE: output << "Colour palette" << std::endl; break; + case DB_DSK_INTERNAL_VARS: output << "Internal vars" << std::endl; break; + case DB_DSK_LOCAL_VARS: output << "Local vars" << std::endl; break; + case DB_DSK_EXTERNAL_VARS: output << "External vars" << std::endl; break; // behaviours - else if (gr.id == DB_DSK_BEHAVIOR) output << "Behaviour" << std::endl; - else if (gr.id == DB_DSK_CLAMP_ACTION) output << "clamp action" << std::endl; - else if (gr.id == DB_DSK_RANGE_ACTION) output << "range action" << std::endl; - else if (gr.id == DB_DSK_ROTATE_ACTION) output << "rotate action" << std::endl; - else if (gr.id == DB_DSK_TRANSLATE_ACTION) output << "translate action" << std::endl; - else if (gr.id == DB_DSK_SCALE_ACTION) output << "scale action" << std::endl; - else if (gr.id == DB_DSK_ARITHMETIC_ACTION) output << "arithmetic action" << std::endl; - else if (gr.id == DB_DSK_LOGIC_ACTION) output << "logic action" << std::endl; - else if (gr.id == DB_DSK_CONDITIONAL_ACTION) output << "conditional action" << std::endl; - else if (gr.id == DB_DSK_LOOPING_ACTION) output << "looping action" << std::endl; - else if (gr.id == DB_DSK_COMPARE_ACTION) output << "compare action" << std::endl; - else if (gr.id == DB_DSK_VISIBILITY_ACTION) output << "visibility action" << std::endl; - else if (gr.id == DB_DSK_STRING_CONTENT_ACTION) output << "string content action" << std::endl; + case DB_DSK_BEHAVIOR: output << "Behaviour" << std::endl; break; + case DB_DSK_CLAMP_ACTION: output << "clamp action" << std::endl; break; + case DB_DSK_RANGE_ACTION: output << "range action" << std::endl; break; + case DB_DSK_ROTATE_ACTION: output << "rotate action" << std::endl; break; + case DB_DSK_TRANSLATE_ACTION: output << "translate action" << std::endl; break; + case DB_DSK_SCALE_ACTION: output << "scale action" << std::endl; break; + case DB_DSK_ARITHMETIC_ACTION: output << "arithmetic action" << std::endl; break; + case DB_DSK_LOGIC_ACTION: output << "logic action" << std::endl; break; + case DB_DSK_CONDITIONAL_ACTION: output << "conditional action" << std::endl; break; + case DB_DSK_LOOPING_ACTION: output << "looping action" << std::endl; break; + case DB_DSK_COMPARE_ACTION: output << "compare action" << std::endl; break; + case DB_DSK_VISIBILITY_ACTION: output << "visibility action" << std::endl; break; + case DB_DSK_STRING_CONTENT_ACTION: output << "string content action" << std::endl; break; // var types - else if (gr.id == DB_DSK_FLOAT_VAR) output << "Float var" << std::endl; - else if (gr.id == DB_DSK_INT_VAR) output << "Int var" << std::endl; - else if (gr.id == DB_DSK_LONG_VAR) output << "Long var" << std::endl; - else if (gr.id == DB_DSK_DOUBLE_VAR) output << "Double var" << std::endl; - else if (gr.id == DB_DSK_BOOL_VAR) output << "Bool var" << std::endl; - else output << " inp record " << gr.id << std::endl; + case DB_DSK_FLOAT_VAR: output << "Float var" << std::endl; break; + case DB_DSK_INT_VAR: output << "Int var" << std::endl; break; + case DB_DSK_LONG_VAR: output << "Long var" << std::endl; break; + case DB_DSK_DOUBLE_VAR: output << "Double var" << std::endl; break; + case DB_DSK_BOOL_VAR: output << "Bool var" << std::endl; break; + default: output << " inp record " << gr.id << std::endl; break; + } for (geoFieldList::const_iterator itr=gr.fields.begin(); itr!=gr.fields.end();