diff --git a/VisualStudio/osgUtil/osgUtil.dsp b/VisualStudio/osgUtil/osgUtil.dsp index 1e483969b..2673bf5ea 100755 --- a/VisualStudio/osgUtil/osgUtil.dsp +++ b/VisualStudio/osgUtil/osgUtil.dsp @@ -185,6 +185,10 @@ SOURCE=..\..\src\osgUtil\Tesselator.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgUtil\TransformCallback.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgUtil\TrackballManipulator.cpp # End Source File # Begin Source File @@ -313,6 +317,10 @@ SOURCE=..\..\include\osgUtil\Tesselator # End Source File # Begin Source File +SOURCE=..\..\include\osgUtil\TransformCallback +# End Source File +# Begin Source File + SOURCE=..\..\include\osgUtil\TrackballManipulator # End Source File # Begin Source File diff --git a/include/osg/Math b/include/osg/Math index 8114eec39..03bb3e800 100644 --- a/include/osg/Math +++ b/include/osg/Math @@ -71,26 +71,32 @@ namespace osg { #ifdef USE_DEGREES_INTERNALLY -inline double inDegrees(double angle) { return angle; } -inline double inRadians(double angle) { return angle*180.0/M_PI; } + inline double inDegrees(double angle) { return angle; } + inline double inRadians(double angle) { return angle*180.0/M_PI; } #else -inline double inDegrees(double angle) { return angle*M_PI/180.0; } -inline double inRadians(double angle) { return angle; } + inline double inDegrees(double angle) { return angle*M_PI/180.0; } + inline double inRadians(double angle) { return angle; } #endif inline double DegreesToRadians(double angle) { return angle*M_PI/180.0; } inline double RadiansToDegrees(double angle) { return angle*180.0/M_PI; } #ifdef WIN32 -inline bool isNaN(float v) { return ::_isnan(v)!=0; } -inline bool isNaN(double v) { return ::_isnan(v)!=0; } -inline bool isInfinite(float v) { return !::_finite(v); } -inline bool isInfinite(double v) { return !::_finite(v); } + inline bool isNaN(float v) { return ::_isnan(v)!=0; } + inline bool isNaN(double v) { return ::_isnan(v)!=0; } + inline bool isInfinite(float v) { return !::_finite(v); } + inline bool isInfinite(double v) { return !::_finite(v); } +#elseif __sgi + inline bool isNaN(float v) { return ::isnan(v); } + inline bool isNaN(double v) { return ::isnan(v); } + // can't find a function to test for infiniting on sgi yet.. + inline bool isInfinite(float v) { return false; } + inline bool isInfinite(double v) { return false; } #else -inline bool isNaN(float v) { return ::isnan(v); } -inline bool isNaN(double v) { return ::isnan(v); } -inline bool isInfinite(float v) { return ::isinf(v); } -inline bool isInfinite(double v) { return ::isinf(v); } + inline bool isNaN(float v) { return ::isnan(v); } + inline bool isNaN(double v) { return ::isnan(v); } + inline bool isInfinite(float v) { return ::isinf(v); } + inline bool isInfinite(double v) { return ::isinf(v); } #endif }; diff --git a/include/osg/Matrix b/include/osg/Matrix index 2f8b23bd5..e4d850813 100644 --- a/include/osg/Matrix +++ b/include/osg/Matrix @@ -17,7 +17,7 @@ using namespace std; #endif // temporary #define to keep backwards compatibility. -#define USE_DEPRECATED_MATRIX_METHODS +//#define USE_DEPRECATED_MATRIX_METHODS namespace osg { diff --git a/include/osg/Transform b/include/osg/Transform index 8683066d3..f014ae579 100644 --- a/include/osg/Transform +++ b/include/osg/Transform @@ -41,15 +41,34 @@ class SG_EXPORT Transform : public Group /** Get the Transform Type.*/ inline const Type getType() const { return _type; } - void setMatrix(const Matrix& mat ); inline Matrix& getMatrix() { return *_matrix; } inline const Matrix& getMatrix() const { return *_matrix; } - void preMult( const Matrix& mat ); + inline void setMatrix(const Matrix& mat ) + { + (*_matrix) = mat; + dirtyBound(); + } + + /** preMult trasforms relative to the childrens coordinate system.*/ + inline void preMult( const Matrix& mat ) + { + (*_matrix) = mat * (*_matrix); + dirtyBound(); + } + + /** postMult trasforms relative to the parents coordinate system.*/ + inline void postMult( const Matrix& mat ) + { + (*_matrix) = (*_matrix) * mat; + dirtyBound(); + } + +#ifdef USE_DEPRECATED_MATRIX_METHODS void preScale( const float sx, const float sy, const float sz ); void preTranslate( const float tx, const float ty, const float tz ); void preRotate( const float deg, const float x, const float y, const float z ); - +#endif protected : diff --git a/include/osgDB/ReaderWriter b/include/osgDB/ReaderWriter index 03e53591a..f6916c088 100644 --- a/include/osgDB/ReaderWriter +++ b/include/osgDB/ReaderWriter @@ -45,14 +45,14 @@ class OSGDB_EXPORT ReaderWriter : public osg::Referenced { public: - enum Status + enum ReadStatus { FILE_NOT_HANDLED, FILE_LOADED, ERROR_IN_READING_FILE }; - ReadResult(Status status=FILE_NOT_HANDLED):_status(status) {} + ReadResult(ReadStatus status=FILE_NOT_HANDLED):_status(status) {} ReadResult(const std::string& m):_status(ERROR_IN_READING_FILE),_message(m) {} ReadResult(osg::Object* obj):_status(FILE_LOADED),_object(obj) {} @@ -73,14 +73,14 @@ class OSGDB_EXPORT ReaderWriter : public osg::Referenced const std::string& message() const { return _message; } - const Status status() const { return _status; } + const ReadStatus status() const { return _status; } const bool success() const { return _status==FILE_LOADED; } const bool error() const { return _status==ERROR_IN_READING_FILE; } const bool notHandled() const { return _status==FILE_NOT_HANDLED; } protected: - Status _status; + ReadStatus _status; std::string _message; osg::ref_ptr _object; }; @@ -89,14 +89,14 @@ class OSGDB_EXPORT ReaderWriter : public osg::Referenced { public: - enum Status + enum WriteStatus { FILE_NOT_HANDLED, FILE_SAVED, ERROR_IN_WRITING_FILE }; - WriteResult(Status status=FILE_NOT_HANDLED):_status(status) {} + WriteResult(WriteStatus status=FILE_NOT_HANDLED):_status(status) {} WriteResult(const std::string& m):_status(ERROR_IN_WRITING_FILE),_message(m) {} WriteResult(const WriteResult& rr):_status(rr._status),_message(rr._message) {} @@ -104,14 +104,14 @@ class OSGDB_EXPORT ReaderWriter : public osg::Referenced const std::string& message() const { return _message; } - const Status status() const { return _status; } + const WriteStatus status() const { return _status; } const bool success() const { return _status==FILE_SAVED; } const bool error() const { return _status==ERROR_IN_WRITING_FILE; } const bool notHandled() const { return _status==FILE_NOT_HANDLED; } protected: - Status _status; + WriteStatus _status; std::string _message; }; diff --git a/include/osgText/Paragraph b/include/osgText/Paragraph index ff2b20223..2b2803a20 100644 --- a/include/osgText/Paragraph +++ b/include/osgText/Paragraph @@ -37,9 +37,10 @@ class OSGTEXT_EXPORT Paragraph : public osg::Geode void setAlignment(int alignment); int getAlignment() { return _alignment; } - float getHeight() const; + static bool createFormatedText(unsigned int noCharsPerLine,const std::string& str,std::vector& formatedText); + protected: virtual ~Paragraph() {} diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index bf09a99fc..7c1fd57ee 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -84,9 +84,9 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced /** Get the background color.*/ const osg::Vec4& getBackgroundColor() const { return _backgroundColor; } - void setGlobalState(osg::StateSet* state) { _globalState = state; } - osg::StateSet* getGlobalState() { return _globalState.get(); } - const osg::StateSet* getGlobalState() const { return _globalState.get(); } + void setGlobalStateSet(osg::StateSet* state) { _globalState = state; } + osg::StateSet* getGlobalStateSet() { return _globalState.get(); } + const osg::StateSet* getGlobalStateSet() const { return _globalState.get(); } enum LightingMode { HEADLIGHT, // default diff --git a/src/Demos/osgcube/osgcube.cpp b/src/Demos/osgcube/osgcube.cpp index 29dd3499f..0bf3b39c6 100644 --- a/src/Demos/osgcube/osgcube.cpp +++ b/src/Demos/osgcube/osgcube.cpp @@ -18,11 +18,11 @@ // Global variables - this is basically the stuff which will be animated // ---------------------------------------------------------------------- -class TransformCallback : public osg::NodeCallback{ +class MyTransformCallback : public osg::NodeCallback{ public: - TransformCallback(osg::Transform* node,float angularVelocity) + MyTransformCallback(osg::Transform* node,float angularVelocity) { _nodeToOperateOn = node; _angular_velocity = angularVelocity; @@ -169,7 +169,7 @@ int main( int argc, char **argv ) myTransform->addChild( createCube() ); // move node in a circle at 90 degrees a sec. - myTransform->setAppCallback(new TransformCallback(myTransform,osg::inDegrees(90.0f))); + myTransform->setAppCallback(new MyTransformCallback(myTransform,osg::inDegrees(90.0f))); // create the viewer and the model to it. osgGLUT::Viewer viewer; diff --git a/src/Demos/osgreflect/osgreflect.cpp b/src/Demos/osgreflect/osgreflect.cpp index f596338f8..dd6ae1c1a 100644 --- a/src/Demos/osgreflect/osgreflect.cpp +++ b/src/Demos/osgreflect/osgreflect.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -41,65 +42,6 @@ // we apply them. -class TransformCallback : public osg::NodeCallback{ - - public: - - TransformCallback(osg::Transform* node,float angularVelocity) - { - _nodeToOperateOn = node; - if (node) - { - _pivotPoint = node->getBound().center(); - } - - _angular_velocity = angularVelocity; - _previousTraversalNumber = -1; - _previous_t = _timer.tick(); - } - - virtual void operator() (osg::Node* node, osg::NodeVisitor* nv) - { - if (nv) - { - if (_nodeToOperateOn && node==_nodeToOperateOn) - { - // ensure that we do not operate on this node more than - // once during this traversal. This is an issue since node - // can be shared between multiple parents. - if (nv->getTraversalNumber()!=_previousTraversalNumber) - { - osg::Timer_t new_t = _timer.tick(); - float delta_angle = _angular_velocity*_timer.delta_s(_previous_t,new_t); - _previous_t = new_t; - - // update the specified dcs. - _nodeToOperateOn->preTranslate(_pivotPoint[0],_pivotPoint[1],_pivotPoint[2]); - _nodeToOperateOn->preRotate(delta_angle,0.0f,0.0f,1.0f); - _nodeToOperateOn->preTranslate(-_pivotPoint[0],-_pivotPoint[1],-_pivotPoint[2]); - - _previousTraversalNumber = nv->getTraversalNumber(); - } - } - } - - // must continue subgraph traversal. - traverse(node,nv); - - } - - protected: - - osg::Transform* _nodeToOperateOn; - float _angular_velocity; - osg::Vec3 _pivotPoint; - - int _previousTraversalNumber; - osg::Timer _timer; - osg::Timer_t _previous_t; - -}; - /* * Function to read several files (typically one) as specified on the command * line, and return them in an osg::Node @@ -425,9 +367,9 @@ int main( int argc, char **argv ) osg::Transform* dcs = new osg::Transform; dcs->setStateSet(dstate); - dcs->preTranslate(0.0f,0.0f,z); - dcs->preScale(1.0f,1.0f,-1.0f); - dcs->preTranslate(0.0f,0.0f,-z); + dcs->preMult(osg::Matrix::trans(0.0f,0.0f,-z)* + osg::Matrix::scale(1.0f,1.0f,-1.0f)* + osg::Matrix::trans(0.0f,0.0f,z)); dcs->addChild(loadedModelTransform); @@ -472,7 +414,8 @@ int main( int argc, char **argv ) osgGLUT::Viewer viewer; viewer.addViewport( rootNode ); - loadedModelTransform->setAppCallback(new TransformCallback(loadedModelTransform,osg::inDegrees(45.0f))); + osg::NodeCallback* nc = new osgUtil::TransformCallback(loadedModelTransform->getBound().center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(45.0f)); + loadedModelTransform->setAppCallback(nc); // register trackball, flight and drive. viewer.registerCameraManipulator(new osgUtil::TrackballManipulator); diff --git a/src/Demos/osgtext/main.cpp b/src/Demos/osgtext/main.cpp index 7040c926f..7d7650278 100644 --- a/src/Demos/osgtext/main.cpp +++ b/src/Demos/osgtext/main.cpp @@ -416,7 +416,7 @@ public: virtual float app(unsigned int viewport) { float ret; - ret=Viewer::app(viewport); + ret=osgGLUT::Viewer::app(viewport); if(_hudSceneView.valid() && viewport>=_viewportList.size()-1) { _hudSceneView->app(); @@ -427,7 +427,7 @@ public: virtual float cull(unsigned int viewport) { float ret; - ret=Viewer::cull(viewport); + ret=osgGLUT::Viewer::cull(viewport); if(_hudSceneView.valid() && viewport>=_viewportList.size()-1) _hudSceneView->cull(); return ret; @@ -436,7 +436,7 @@ public: virtual float draw(unsigned int viewport) { float ret; - ret=Viewer::draw(viewport); + ret=osgGLUT::Viewer::draw(viewport); if(_hudSceneView.valid() && viewport>=_viewportList.size()-1) _hudSceneView->draw(); return ret; @@ -452,7 +452,7 @@ public: virtual void reshape(GLint w, GLint h) { - Viewer::reshape(w,h); + osgGLUT::Viewer::reshape(w,h); if(_hudSceneView.valid()) { @@ -463,7 +463,7 @@ public: virtual bool open() { - bool ret=Viewer::open(); + bool ret=osgGLUT::Viewer::open(); // set the clear flag / after the visualReq.Visitor if(_hudSceneView.valid()) @@ -536,7 +536,7 @@ protected: } return; default: - Viewer::keyboard(key,x,y); + osgGLUT::Viewer::keyboard(key,x,y); }; } @@ -583,7 +583,7 @@ int main( int argc, char **argv ) // setup the sceneData setScene(textGroup); - textGroup->preRotate(osg::inDegrees(90),1,0,0); + textGroup->preMult(osg::Matrix::rotate(osg::inDegrees(90.0f),1.0f,0.0f,0.0f)); rootNode->addChild(textGroup); // setup the 2dNode diff --git a/src/Demos/osgtexture/osgtexture.cpp b/src/Demos/osgtexture/osgtexture.cpp index c0b64d1a9..949318a27 100644 --- a/src/Demos/osgtexture/osgtexture.cpp +++ b/src/Demos/osgtexture/osgtexture.cpp @@ -115,7 +115,7 @@ osg::Node* createTexturedItem(const osg::Vec3& offset,osg::Texture* texture,osg: // place and also to add individual texture set to it, so that // that state is inherited down to its children. osg::Transform* local_transform = new osg::Transform; - local_transform->preTranslate(offset.x(),offset.y(),offset.z()); + local_transform->postMult(osg::Matrix::trans(offset)); // create the StateSet to store the texture data osg::StateSet* stateset = new osg::StateSet; @@ -140,7 +140,7 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom if (image==NULL) return NULL; osg::Transform* top_transform = new osg::Transform; - top_transform->preTranslate(offset.x(),offset.y(),offset.z()); + top_transform->postMult(osg::Matrix::trans(offset)); osg::Vec3 local_offset(0.0f,0.0f,0.0f); osg::Vec3 local_delta(3.0f,0.0f,0.0f); diff --git a/src/osg/Transform.cpp b/src/osg/Transform.cpp index 95ee61663..6f610cb9f 100644 --- a/src/osg/Transform.cpp +++ b/src/osg/Transform.cpp @@ -21,20 +21,7 @@ Transform::~Transform() { } - -void Transform::setMatrix(const Matrix& mat ) -{ - (*_matrix) = mat; - dirtyBound(); -} - - -void Transform::preMult( const Matrix& mat ) -{ - (*_matrix) = mat * (*_matrix); - dirtyBound(); -} - +#ifdef USE_DEPRECATED_MATRIX_METHODS void Transform::preScale( const float sx, const float sy, const float sz ) { (*_matrix) = Matrix::scale( sx, sy, sz ) * (*_matrix); @@ -53,7 +40,7 @@ void Transform::preRotate( const float deg, const float x, const float y, const (*_matrix) = Matrix::rotate( deg, x, y, z ) * (*_matrix); dirtyBound(); } - +#endif const bool Transform::computeBound() const { if (!Group::computeBound()) return false; diff --git a/src/osgGLUT/Viewer.cpp b/src/osgGLUT/Viewer.cpp index f52d5a17f..58cd61153 100644 --- a/src/osgGLUT/Viewer.cpp +++ b/src/osgGLUT/Viewer.cpp @@ -954,18 +954,18 @@ void Viewer::keyboard(unsigned char key, int x, int y) backface = 1 - backface; if( backface ) - sceneView->getGlobalState()->setMode(GL_CULL_FACE,osg::StateAttribute::ON); + sceneView->getGlobalStateSet()->setMode(GL_CULL_FACE,osg::StateAttribute::ON); else - sceneView->getGlobalState()->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE_OFF); + sceneView->getGlobalStateSet()->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE_OFF); break; case 'l' : lighting = 1 - lighting ; if( lighting ) - sceneView->getGlobalState()->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_ON); + sceneView->getGlobalStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_ON); else - sceneView->getGlobalState()->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_OFF); + sceneView->getGlobalStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_OFF); break; case 'L' : @@ -984,8 +984,8 @@ void Viewer::keyboard(unsigned char key, int x, int y) texture = 1 - texture; if (texture) { - sceneView->getGlobalState()->setModeToInherit(GL_TEXTURE_2D); -// sceneView->getGlobalState()->setAttributeToInherit(osg::StateAttribute::TEXTURE); + sceneView->getGlobalStateSet()->setModeToInherit(GL_TEXTURE_2D); +// sceneView->getGlobalStateSet()->setAttributeToInherit(osg::StateAttribute::TEXTURE); } else { @@ -993,8 +993,8 @@ void Viewer::keyboard(unsigned char key, int x, int y) // thus causing them to all use the same texture attribute, hence // preventing a state attribute change due to unused textures. static osg::ref_ptr blank_texture = new osg::Texture; - sceneView->getGlobalState()->setMode(GL_TEXTURE_2D,osg::StateAttribute::OVERRIDE_OFF); -// sceneView->getGlobalState()->setAttribute(blank_texture.get(),true); + sceneView->getGlobalStateSet()->setMode(GL_TEXTURE_2D,osg::StateAttribute::OVERRIDE_OFF); +// sceneView->getGlobalStateSet()->setAttribute(blank_texture.get(),true); } break; @@ -1007,7 +1007,7 @@ void Viewer::keyboard(unsigned char key, int x, int y) polymode = (polymode+1)%3; osg::PolygonMode* polyModeObj = new osg::PolygonMode; polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,polymodes[polymode]); - sceneView->getGlobalState()->setAttribute(polyModeObj); + sceneView->getGlobalStateSet()->setAttribute(polyModeObj); } break; diff --git a/src/osgPlugins/dw/ReaderWriterDW.cpp b/src/osgPlugins/dw/ReaderWriterDW.cpp index aa5d9fcef..0ad3f809f 100644 --- a/src/osgPlugins/dw/ReaderWriterDW.cpp +++ b/src/osgPlugins/dw/ReaderWriterDW.cpp @@ -39,308 +39,308 @@ int dwfgets(char *clin, int max, FILE *fin); // , end of line= 13 as well as Cre class dwmaterial {// design workshop material, to be translated to OGL public: - typedef enum {Properties,TiledTexture,FullFace, SpotLight,PointLight} mttype; - dwmaterial() { type=Properties; - opacity=1; specular=0; specexp=0; fname="";TextureWidth=1; TextureHeight=1; - ctx=NULL; tx=NULL; id=0; dstate=NULL;colour[0]=colour[1]=colour[2]=colour[3]=1; - bright=halfIn=halfOut=falloff=0;atyp=NONE; - } - ~dwmaterial() { } - void settexture() { - if (!dstate) dstate = new StateSet; - if (isTextured()) { // shares common textures - if (!ctx || !tx) { // new texture needed - if (fname.length()>0) { - ctx=osgDB::readImageFile(fname.c_str()); - if (ctx) { - ctx->setFileName(fname); - tx=new Texture; - tx->setImage(ctx); - tx->setWrap(Texture::WRAP_S, Texture::REPEAT); - tx->setWrap(Texture::WRAP_T, Texture::REPEAT); - } - osg::TexEnv* texenv = new osg::TexEnv; - texenv->setMode(osg::TexEnv::MODULATE); - dstate->setAttribute( texenv ); - } - } - if (ctx && tx) { // texture exists - dstate->setAttributeAndModes(tx,osg::StateAttribute::ON); - dstate->setMode(GL_TEXTURE_2D,StateAttribute::ON); - } - } - } - StateSet *make() { // returns the OSG material - if (!dstate) { // if it does not exist, then make it - dstate = new StateSet; - osg::Material* osgMaterial = new osg::Material; - dstate->setAttribute(osgMaterial); - if (opacity<0.99) { - osgMaterial->setTransparency(Material::FRONT_AND_BACK, opacity); - dstate->setMode(GL_BLEND,StateAttribute::ON); - dstate->setRenderingHint(StateSet::TRANSPARENT_BIN); - colour[3]=opacity; - } - osgMaterial->setAmbient(Material::FRONT_AND_BACK,colour); - osgMaterial->setDiffuse(Material::FRONT_AND_BACK,colour); + typedef enum {Properties,TiledTexture,FullFace, SpotLight,PointLight} mttype; + dwmaterial() { type=Properties; + opacity=1; specular=0; specexp=0; fname="";TextureWidth=1; TextureHeight=1; + ctx=NULL; tx=NULL; id=0; dstate=NULL;colour[0]=colour[1]=colour[2]=colour[3]=1; + bright=halfIn=halfOut=falloff=0;atyp=NONE; + } + ~dwmaterial() { } + void settexture() { + if (!dstate) dstate = new StateSet; + if (isTextured()) { // shares common textures + if (!ctx || !tx) { // new texture needed + if (fname.length()>0) { + ctx=osgDB::readImageFile(fname.c_str()); + if (ctx) { + ctx->setFileName(fname); + tx=new Texture; + tx->setImage(ctx); + tx->setWrap(Texture::WRAP_S, Texture::REPEAT); + tx->setWrap(Texture::WRAP_T, Texture::REPEAT); + } + osg::TexEnv* texenv = new osg::TexEnv; + texenv->setMode(osg::TexEnv::MODULATE); + dstate->setAttribute( texenv ); + } + } + if (ctx && tx) { // texture exists + dstate->setAttributeAndModes(tx,osg::StateAttribute::ON); + dstate->setMode(GL_TEXTURE_2D,StateAttribute::ON); + } + } + } + StateSet *make() { // returns the OSG material + if (!dstate) { // if it does not exist, then make it + dstate = new StateSet; + osg::Material* osgMaterial = new osg::Material; + dstate->setAttribute(osgMaterial); + if (opacity<0.99) { + osgMaterial->setTransparency(Material::FRONT_AND_BACK, opacity); + dstate->setMode(GL_BLEND,StateAttribute::ON); + dstate->setRenderingHint(StateSet::TRANSPARENT_BIN); + colour[3]=opacity; + } + osgMaterial->setAmbient(Material::FRONT_AND_BACK,colour); + osgMaterial->setDiffuse(Material::FRONT_AND_BACK,colour); - Vec4 colspec=colour*specular; - colspec[3]=colour[3]; - osgMaterial->setSpecular(Material::FRONT_AND_BACK,colspec); - osgMaterial->setShininess(Material::FRONT_AND_BACK,specexp); + Vec4 colspec=colour*specular; + colspec[3]=colour[3]; + osgMaterial->setSpecular(Material::FRONT_AND_BACK,colspec); + osgMaterial->setShininess(Material::FRONT_AND_BACK,specexp); - dstate->setMode( GL_LIGHTING, StateAttribute::ON ); - dstate->setMode( GL_CULL_FACE, StateAttribute::ON ); + dstate->setMode( GL_LIGHTING, StateAttribute::ON ); + dstate->setMode( GL_CULL_FACE, StateAttribute::ON ); - osg::CullFace *cf = new osg::CullFace; // to define non-default culling - cf->setMode(osg::CullFace::BACK); - dstate->setAttribute(cf); + osg::CullFace *cf = new osg::CullFace; // to define non-default culling + cf->setMode(osg::CullFace::BACK); + dstate->setAttribute(cf); - dstate->setMode(GL_TEXTURE_2D,StateAttribute::OFF); - settexture(); - } - return dstate; - } - inline int isType(mttype t1) const {return (type==t1 ); } - inline int isTextured() {return (type==TiledTexture || type==FullFace ); } - void setcolour(const float rgb[3]) { - colour[0]=rgb[0]; colour[1]=rgb[1]; colour[2]=rgb[2]; - } - void settxrep(const float repx, const float repy) { - TextureWidth=repx; - TextureHeight=repy; - } - inline float getRepWid() const { return TextureWidth;} - inline float getRepHt() const { return TextureHeight;} - inline int isFullFace() const { return type==FullFace;} - inline int getid() const { return id;} - inline void setid(const int i) { id=i;} - inline void setopacity(float o) { opacity=o;} - inline void setspecular(float o) { specular=o;} - inline void setspecexp(float o) { specexp=o;} - void setType(const char *buff) { - if (strncmp(buff,"Tiled_Texture",13)==0) - type=dwmaterial::TiledTexture; - else if (strncmp(buff,"Spot_Light",11)==0) - type=dwmaterial::SpotLight; - else if (strncmp(buff,"Point_Light",11)==0) - type=dwmaterial::PointLight; - else if (strncmp(buff,"Properties",11)==0) - type=dwmaterial::Properties; - else if (strncmp(buff,"Full_Face_Texture",16)==0) - type=dwmaterial::FullFace; - } - void setfname(const char *buff) { - fname=new char[strlen(buff+13)+5]; - fname= (buff+13); - fname+= ".tga"; - } - LightSource *makeLight(const Vec4 pos) { - Light *lt= new Light; - Vec4 cdef; - cdef[0]=cdef[1]=cdef[2]=0.0f; cdef[3]=0.0f; - lt->setSpecular(colour*bright/2.0f); - lt->setDiffuse(colour*bright/4.0f); - lt->setAmbient(cdef); - lt->on(); - if (atyp==NONE) ; - else if (atyp==INVERSE_DIST) { - lt->setLinearAttenuation(1.0f); - lt->setConstantAttenuation(0.01f); - } - lt->setPosition(pos); - LightSource *ls=new LightSource(); - ls->setLight(lt); - return ls; - } - void setAtten(const char *buff) { - if (strstr(buff,"kQ3AttenuationTypeNone")) atyp=NONE; - else if (strstr(buff,"kQ3AttenuationTypeInverseDistance")) atyp=INVERSE_DIST; - // else if (strstr(buff,"kQ3AttenuationTypeNone")) ; - } - void setBright(const float br) { bright=br;} - void setHalfAngleIn(const float ha) { halfIn=ha;} - void setHalfAngleOut(const float ha) { halfOut=ha;} - void setFallOff(const float fo) { falloff=fo;} - const Vec4 getcolour() { return colour;} + dstate->setMode(GL_TEXTURE_2D,StateAttribute::OFF); + settexture(); + } + return dstate; + } + inline int isType(mttype t1) const {return (type==t1 ); } + inline int isTextured() {return (type==TiledTexture || type==FullFace ); } + void setcolour(const float rgb[3]) { + colour[0]=rgb[0]; colour[1]=rgb[1]; colour[2]=rgb[2]; + } + void settxrep(const float repx, const float repy) { + TextureWidth=repx; + TextureHeight=repy; + } + inline float getRepWid() const { return TextureWidth;} + inline float getRepHt() const { return TextureHeight;} + inline int isFullFace() const { return type==FullFace;} + inline int getid() const { return id;} + inline void setid(const int i) { id=i;} + inline void setopacity(float o) { opacity=o;} + inline void setspecular(float o) { specular=o;} + inline void setspecexp(float o) { specexp=o;} + void setType(const char *buff) { + if (strncmp(buff,"Tiled_Texture",13)==0) + type=dwmaterial::TiledTexture; + else if (strncmp(buff,"Spot_Light",11)==0) + type=dwmaterial::SpotLight; + else if (strncmp(buff,"Point_Light",11)==0) + type=dwmaterial::PointLight; + else if (strncmp(buff,"Properties",11)==0) + type=dwmaterial::Properties; + else if (strncmp(buff,"Full_Face_Texture",16)==0) + type=dwmaterial::FullFace; + } + void setfname(const char *buff) { + fname=new char[strlen(buff+13)+5]; + fname= (buff+13); + fname+= ".tga"; + } + LightSource *makeLight(const Vec4 pos) { + Light *lt= new Light; + Vec4 cdef; + cdef[0]=cdef[1]=cdef[2]=0.0f; cdef[3]=0.0f; + lt->setSpecular(colour*bright/2.0f); + lt->setDiffuse(colour*bright/4.0f); + lt->setAmbient(cdef); + lt->on(); + if (atyp==NONE) ; + else if (atyp==INVERSE_DIST) { + lt->setLinearAttenuation(1.0f); + lt->setConstantAttenuation(0.01f); + } + lt->setPosition(pos); + LightSource *ls=new LightSource(); + ls->setLight(lt); + return ls; + } + void setAtten(const char *buff) { + if (strstr(buff,"kQ3AttenuationTypeNone")) atyp=NONE; + else if (strstr(buff,"kQ3AttenuationTypeInverseDistance")) atyp=INVERSE_DIST; + // else if (strstr(buff,"kQ3AttenuationTypeNone")) ; + } + void setBright(const float br) { bright=br;} + void setHalfAngleIn(const float ha) { halfIn=ha;} + void setHalfAngleOut(const float ha) { halfOut=ha;} + void setFallOff(const float fo) { falloff=fo;} + const Vec4 getcolour() { return colour;} private: - int id; - Vec4 colour; // the ambient/diffuse+alpha colour - mttype type; - float opacity, specular, specexp; // transp, specularity properties - float TextureWidth, TextureHeight; - std::string fname; // picture file - enum atten {NONE, INVERSE_DIST, INVERSE_SQUARE} atyp; - float bright,halfIn,halfOut,falloff; // light brightness - Image *ctx; - Texture *tx; - StateSet *dstate; // used to represent the dw material in OSG + int id; + Vec4 colour; // the ambient/diffuse+alpha colour + mttype type; + float opacity, specular, specexp; // transp, specularity properties + float TextureWidth, TextureHeight; + std::string fname; // picture file + enum atten {NONE, INVERSE_DIST, INVERSE_SQUARE} atyp; + float bright,halfIn,halfOut,falloff; // light brightness + Image *ctx; + Texture *tx; + StateSet *dstate; // used to represent the dw material in OSG }; // structure to use as data for tesselation typedef struct { - double pos[3]; // must be double for the tessellator to detect vertices - Vec2 uv; // texture coordainte - may not be used? - Vec3 nrmv; // surface normal - const dwmaterial *themat; - int idx; // index in the verts[] array + double pos[3]; // must be double for the tessellator to detect vertices + Vec2 uv; // texture coordainte - may not be used? + Vec3 nrmv; // surface normal + const dwmaterial *themat; + int idx; // index in the verts[] array } avertex; class _face { public: - _face() { opening=NULL; idx=NULL; nv=0; nop=0; nset=0; nrm[0]=nrm[1]=nrm[2]=0;} - ~_face() { delete [] idx;} - void setnv(const int n){ nv=n; idx=new int[n];} - void addvtx(const int n){ - if (nset < nv) { - idx[nset]=n; - nset++; - } - } - void addholevtx(const int nvtot) { - if (opening) { - opening[nop-1].addvtx(nvtot); - } - } - void norm(Vec3 &n, const Vec3 side, const Vec3 s2) const { - n=s2^side; // perpendicular - n.normalize(); // unit norm - } - const Vec3 getnorm(void) const { return nrm; } // use the predefined normal - void getside12(Vec3 &s1, Vec3 &s2, const Vec3 verts[]) const { - int ic=1; // counter for later vertices to ensure not coincident - int i1=idx[0]; // first vertex of face - int i2=idx[1]; // second, must be non-coincident - while (i2==i1) { - ic++; - i2=idx[ic]; - } - int i3=idx[ic]; // second, must be non-coincident - while (i3==i2 || i3==i1) { - ic++; - i3=idx[ic]; - } - s1=(verts[i2]-verts[i1]); // side 1 of face - s2=(verts[i3]-verts[i2]); // side 2 of face - } - void getnorm(const Vec3 verts[]) { - Vec3 side, s2; // used in cross product to find normal - getside12(side,s2, verts); - norm(nrm, s2, side); - } - void getsides(float *wid, float *ht, const Vec3 verts[]) const - { - Vec3 side, s2; // used in cross product to find normal - getside12(side,s2, verts); - *wid=side.length(); - *ht=s2.length(); - } - void settrans(Matrix &mx, const Vec3 nrm, const Vec3 verts[], const dwmaterial *mat) const { - // define the matrix perpendcular to normal for mapping textures - float wid=mat->getRepWid(); - float ht=mat->getRepHt(); - Vec3 r1, r2,r3; // 3 rows of rotation matrix - if (mat->isFullFace()) { // set wid, ht from polygon - Vec3 s2; // want transformed u coordinate parallel to 'r1' - getside12(r1,s2, verts); // r1 = edge of first side - getsides(&ht, &wid, verts); // get the lengths of sides for transformation of xyz to uv - r3=nrm; - r1.normalize(); - r2=r3^r1; - } else { - // mat.nrm= (0,0,1) AND mat (0,1,0) => (0,a,b) - // the transformation is unitary - preserves lengths; and - // converts points on a plane into (s,t, constant) coords for use with texturing - // Rinv.(0,0,1) = (nrm) implies R since Rinv=R(transpose) - r3=nrm; // already a unit vector - // mat.(010) = (0ab) -> Minv.(0ab) = (010); and this row DOT nrm=0 - if (r3.z() < 0.99f && r3.z() > -0.99f) { // not face parallel to ground - choose r1 perpendicular to nrm & 001 - r2.set(0,0,1); // therefore r1 is in plane of face. - r1=r2^r3; - r1.normalize(); - } else { // parallel to ground - make perpendicular to edge 1 of face - r1=verts[idx[1]]-verts[idx[0]]; - r1.normalize(); - } - r2=r3^r1; - } - for (int j=0; j<3; j++) { // and create the transpose matrix (inverse of rotation matrix) - mx(0,j)=r1[j]; - mx(1,j)=r2[j]; - mx(2,j)=r3[j]; - } - // mx.postTrans(mx,0.5f,0.5f,0.0f); - mx(0,0)*=1.0f/wid; - mx(1,0)*=1.0f/wid; - mx(0,1)*=1.0f/ht; - mx(1,1)*=1.0f/ht; - if (mat->isFullFace()) { // set offset such that mx*verts[idx[0]] -> uv=(0,0) - Vec3 pos; - pos=mx*verts[idx[0]]; - mx(0,3)=pos.x(); - mx(1,3)=pos.y(); - mx(2,3)=pos.z(); - } else { // scale inversely to the texture preferred repeat size - mx(0,3)=0.5f/wid; - mx(1,3)=0.5f/ht; - } - // mx.postScale(mx,1.0f/themat->TextureWidth, 1.0f/themat->TextureHeight,1); - } - inline int setnvop(const osg::ushort n) { // add a new hole in this face with n vertices - _face *oldop=opening; - opening=new _face[nop+1]; - for (int i=0; iidx=NULL;} - inline int getnv() { return nv;} - inline int getvert(const int j) { return idx[j];} - inline int complete() { return (idx && nv>0 && nset==nv);} // face has all defined - inline int holecomplete() { if (!opening) return 1; // no hole, so it is complete - return opening[nop-1].complete();} // latest opening in face has all vertices defined - int getallverts(void) const { int ntot=nv; - for (int i=0; i 0.0f) { // normals are parallel - reverse order of vertices - opening[i].reverse(); - opening[i].setnorm(verts); - } - } - } - void setposes(avertex &poses, const int j, const Vec3 verts[]) const { - poses.pos[0]=verts[idx[j]].x(); - poses.pos[1]=verts[idx[j]].y(); - poses.pos[2]=verts[idx[j]].z(); - poses.nrmv=nrm; - poses.idx=idx[j]; - } - void tesselate(const Vec3 verts[], const dwmaterial *themat, - GLUtesselator *ts, _dwobj *dwob, const Matrix *tmat) const; - void link(const int idop, const _face *f2, const int idop2,const Vec3 verts[], const dwmaterial *themat) const; // to join up opposed faces of a hole - inline const int getidx(int i) const { return idx[i];} + _face() { opening=NULL; idx=NULL; nv=0; nop=0; nset=0; nrm[0]=nrm[1]=nrm[2]=0;} + ~_face() { delete [] idx;} + void setnv(const int n){ nv=n; idx=new int[n];} + void addvtx(const int n){ + if (nset < nv) { + idx[nset]=n; + nset++; + } + } + void addholevtx(const int nvtot) { + if (opening) { + opening[nop-1].addvtx(nvtot); + } + } + void norm(Vec3 &n, const Vec3 side, const Vec3 s2) const { + n=s2^side; // perpendicular + n.normalize(); // unit norm + } + const Vec3 getnorm(void) const { return nrm; } // use the predefined normal + void getside12(Vec3 &s1, Vec3 &s2, const Vec3 verts[]) const { + int ic=1; // counter for later vertices to ensure not coincident + int i1=idx[0]; // first vertex of face + int i2=idx[1]; // second, must be non-coincident + while (i2==i1) { + ic++; + i2=idx[ic]; + } + int i3=idx[ic]; // second, must be non-coincident + while (i3==i2 || i3==i1) { + ic++; + i3=idx[ic]; + } + s1=(verts[i2]-verts[i1]); // side 1 of face + s2=(verts[i3]-verts[i2]); // side 2 of face + } + void getnorm(const Vec3 verts[]) { + Vec3 side, s2; // used in cross product to find normal + getside12(side,s2, verts); + norm(nrm, s2, side); + } + void getsides(float *wid, float *ht, const Vec3 verts[]) const + { + Vec3 side, s2; // used in cross product to find normal + getside12(side,s2, verts); + *wid=side.length(); + *ht=s2.length(); + } + void settrans(Matrix &mx, const Vec3 nrm, const Vec3 verts[], const dwmaterial *mat) const { + // define the matrix perpendcular to normal for mapping textures + float wid=mat->getRepWid(); + float ht=mat->getRepHt(); + Vec3 r1, r2,r3; // 3 rows of rotation matrix + if (mat->isFullFace()) { // set wid, ht from polygon + Vec3 s2; // want transformed u coordinate parallel to 'r1' + getside12(r1,s2, verts); // r1 = edge of first side + getsides(&ht, &wid, verts); // get the lengths of sides for transformation of xyz to uv + r3=nrm; + r1.normalize(); + r2=r3^r1; + } else { + // mat.nrm= (0,0,1) AND mat (0,1,0) => (0,a,b) + // the transformation is unitary - preserves lengths; and + // converts points on a plane into (s,t, constant) coords for use with texturing + // Rinv.(0,0,1) = (nrm) implies R since Rinv=R(transpose) + r3=nrm; // already a unit vector + // mat.(010) = (0ab) -> Minv.(0ab) = (010); and this row DOT nrm=0 + if (r3.z() < 0.99f && r3.z() > -0.99f) { // not face parallel to ground - choose r1 perpendicular to nrm & 001 + r2.set(0,0,1); // therefore r1 is in plane of face. + r1=r2^r3; + r1.normalize(); + } else { // parallel to ground - make perpendicular to edge 1 of face + r1=verts[idx[1]]-verts[idx[0]]; + r1.normalize(); + } + r2=r3^r1; + } + for (int j=0; j<3; j++) { // and create the transpose matrix (inverse of rotation matrix) + mx(0,j)=r1[j]; + mx(1,j)=r2[j]; + mx(2,j)=r3[j]; + } + // mx.postTrans(mx,0.5f,0.5f,0.0f); + mx(0,0)*=1.0f/wid; + mx(1,0)*=1.0f/wid; + mx(0,1)*=1.0f/ht; + mx(1,1)*=1.0f/ht; + if (mat->isFullFace()) { // set offset such that mx*verts[idx[0]] -> uv=(0,0) + Vec3 pos; + pos=mx*verts[idx[0]]; + mx(0,3)=pos.x(); + mx(1,3)=pos.y(); + mx(2,3)=pos.z(); + } else { // scale inversely to the texture preferred repeat size + mx(0,3)=0.5f/wid; + mx(1,3)=0.5f/ht; + } + // mx.postScale(mx,1.0f/themat->TextureWidth, 1.0f/themat->TextureHeight,1); + } + inline int setnvop(const osg::ushort n) { // add a new hole in this face with n vertices + _face *oldop=opening; + opening=new _face[nop+1]; + for (int i=0; iidx=NULL;} + inline int getnv() { return nv;} + inline int getvert(const int j) { return idx[j];} + inline int complete() { return (idx && nv>0 && nset==nv);} // face has all defined + inline int holecomplete() { if (!opening) return 1; // no hole, so it is complete + return opening[nop-1].complete();} // latest opening in face has all vertices defined + int getallverts(void) const { int ntot=nv; + for (int i=0; i 0.0f) { // normals are parallel - reverse order of vertices + opening[i].reverse(); + opening[i].setnorm(verts); + } + } + } + void setposes(avertex &poses, const int j, const Vec3 verts[]) const { + poses.pos[0]=verts[idx[j]].x(); + poses.pos[1]=verts[idx[j]].y(); + poses.pos[2]=verts[idx[j]].z(); + poses.nrmv=nrm; + poses.idx=idx[j]; + } + void tesselate(const Vec3 verts[], const dwmaterial *themat, + GLUtesselator *ts, _dwobj *dwob, const Matrix *tmat) const; + void link(const int idop, const _face *f2, const int idop2,const Vec3 verts[], const dwmaterial *themat) const; // to join up opposed faces of a hole + inline const int getidx(int i) const { return idx[i];} private: - void linkholes(const Vec3 verts[], const dwmaterial *themat, const _face *f2) const; - void reverse() { // reverse order of the vertices - for (int j=0; jidx; // vertex position index - nrms[nload]=pos->nrmv; - txcoords[nload].set(pos->uv[0],pos->uv[1]); - txidx[nload]=nload; // matrix transformed txc + prims() { nbegin=0; primlengs=NULL;gsidx=NULL;nrmidx=NULL; + txidx=NULL;nrms=NULL;txcoords=NULL; tmat=NULL; + nload=0; nff=0; curmode=0; + } + ~prims() { /*delete [] primlengs; delete [] nrms; + delete [] gsidx; delete [] nrmidx; delete [] txcoords;*/ + } + bool isGLtype() { return nbegtype[nbegin]==curmode;} + void addv(avertex *pos) { // tesselation callback + nrmidx[nload]=nload; // all normals for this face are same, flat shade + gsidx[nload]=pos->idx; // vertex position index + nrms[nload]=pos->nrmv; + txcoords[nload].set(pos->uv[0],pos->uv[1]); + txidx[nload]=nload; // matrix transformed txc - ntesverts[nbegin]++; - nload++; - } - void End() { - if (nbegin<20 && ntesverts[nbegin]>0) { - primlengs[nff+nbegin]=ntesverts[nbegin]; - nbegin++; - } - } - void begin(GLenum op) { // part of a tesselator callback - starts a new primitive of type op - if (nbegin<20) { // reSet counters - nbegtype[nbegin]=op; - ntesverts[nbegin]=0; - } - switch (op) { - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - case GL_QUADS: - case GL_QUAD_STRIP: - case GL_POLYGON: - break; - default: + ntesverts[nbegin]++; + nload++; + } + void End() { + if (nbegin<20 && ntesverts[nbegin]>0) { + primlengs[nff+nbegin]=ntesverts[nbegin]; + nbegin++; + } + } + void begin(GLenum op) { // part of a tesselator callback - starts a new primitive of type op + if (nbegin<20) { // reSet counters + nbegtype[nbegin]=op; + ntesverts[nbegin]=0; + } + switch (op) { + case GL_TRIANGLES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + case GL_QUADS: + case GL_QUAD_STRIP: + case GL_POLYGON: + break; + default: // commenting out since this value is a local and // is not used, RO July 2001. - // int i=0; - break; - } - } - void combine( GLdouble coords[3], avertex *d[4], - GLfloat w[4], avertex **dataOut , _dwobj *dwob); - void linkholes(const Vec3 verts[], const dwmaterial *themat, - const _face *f1, const _face *f2, - const int ipr[2], const int idx[], const int nv) { - gsidx[nload]=f1->getidx(ipr[1]); // vertex position index - gsidx[nload+1]=f1->getidx(ipr[0]); // vertex position index - gsidx[nload+2]=f2->getidx(nv-ipr[0]-1); // vertex position index - gsidx[nload+3]=f2->getidx(nv-ipr[1]-1); // vertex position index - - Matrix mx; // texture matrix transform to plane - Vec3 s1,s2; - Vec3 nrm; - s1=verts[gsidx[nload+1]]-verts[gsidx[nload]]; - s2=verts[gsidx[nload+2]]-verts[gsidx[nload+1]]; - f1->norm(nrm, s2, s1); - f1->settrans(mx, nrm, verts,themat); - for (int j=0; j<4; j++) { - Vec3 uv; - uv=mx*verts[gsidx[nload]]; - txcoords[nload].set(uv[0],uv[1]); - nrmidx[nload]=nload; - txidx[nload]=nload; // matrix transformed txc - nrms[nload]=nrm; // for per vertex normals - nload++; - } - nff++; - } - void setmode(int md, const int nfnvf) { // define the GL primitive type & number of expected vertices - GLenum mode[]= {GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, - GL_QUADS, GL_QUAD_STRIP, GL_POLYGON}; - curmode=mode[md]; - gsidx=new osg::ushort[6*nfnvf]; - nrmidx=new osg::ushort[6*nfnvf]; - txidx=new osg::ushort[6*nfnvf]; - txcoords=new Vec2[6*nfnvf]; // one texture coord per vertex - nrms=new Vec3[6*nfnvf]; // one normal per face or per vertex - primlengs=new int[nfnvf]; // primitive lengths - nff=0; - nload=0; - } - void tesselate(const _face &fc, const Vec3 verts[], const dwmaterial *themat,GLUtesselator* ts, _dwobj *dwob) - { // generates a set of primitives all of one type (eg tris, qstrip trifan...) - nbegin=0; // number of triangle strips etc generated - fc.tesselate(verts, themat, ts, dwob, tmat); - nff+=nbegin; // the number of primitives generated - } - void buildDrawable(Group *grp, Vec3 verts[], dwmaterial *themat, const int nverts) { - if (nload>0 && nff>0) { // there are some strips of this type - Geode *geode = new Geode; - GeoSet *gset = new GeoSet; - osg::ushort *nunrmidx=new osg::ushort[nload]; - osg::ushort *nutxidx = new osg::ushort[nload]; - osg::ushort *nusidx = new osg::ushort[nload]; - Vec3 *nunrms=new Vec3[nload]; // one normal per face (nff) or per vertex (nload) - int *nuprimlengs=new int[nff]; // primitive lengths - Vec2 *nutxc=new Vec2[nload]; - int i; // general counter - for (i=0; iaddDrawable(gset); - grp->addChild( geode ); // add to the world outside - gset->setNumPrims( nff ); - switch (curmode) { - case GL_TRIANGLES: gset->setPrimType( osg::GeoSet::TRIANGLES ); - gset->setNumPrims( nload/3 ); - break; - case GL_TRIANGLE_STRIP: gset->setPrimType( osg::GeoSet::TRIANGLE_STRIP ); - gset->setPrimLengths( nuprimlengs ); - break; - case GL_TRIANGLE_FAN: gset->setPrimType( osg::GeoSet::TRIANGLE_FAN ); - gset->setPrimLengths( nuprimlengs ); - break; - case GL_QUADS: gset->setPrimType( osg::GeoSet::QUADS ); - gset->setNumPrims( nload/4 ); - break; - case GL_QUAD_STRIP: gset->setPrimType( osg::GeoSet::QUAD_STRIP ); - break; - case GL_POLYGON: gset->setPrimType( osg::GeoSet::POLYGON ); - break; - } - gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); //BIND_PERPRIM); // - gset->setNormals(nunrms, nunrmidx); + // int i=0; + break; + } + } + void combine( GLdouble coords[3], avertex *d[4], + GLfloat w[4], avertex **dataOut , _dwobj *dwob); + void linkholes(const Vec3 verts[], const dwmaterial *themat, + const _face *f1, const _face *f2, + const int ipr[2], const int idx[], const int nv) { + gsidx[nload]=f1->getidx(ipr[1]); // vertex position index + gsidx[nload+1]=f1->getidx(ipr[0]); // vertex position index + gsidx[nload+2]=f2->getidx(nv-ipr[0]-1); // vertex position index + gsidx[nload+3]=f2->getidx(nv-ipr[1]-1); // vertex position index + + Matrix mx; // texture matrix transform to plane + Vec3 s1,s2; + Vec3 nrm; + s1=verts[gsidx[nload+1]]-verts[gsidx[nload]]; + s2=verts[gsidx[nload+2]]-verts[gsidx[nload+1]]; + f1->norm(nrm, s2, s1); + f1->settrans(mx, nrm, verts,themat); + for (int j=0; j<4; j++) { + Vec3 uv; + uv=mx*verts[gsidx[nload]]; + txcoords[nload].set(uv[0],uv[1]); + nrmidx[nload]=nload; + txidx[nload]=nload; // matrix transformed txc + nrms[nload]=nrm; // for per vertex normals + nload++; + } + nff++; + } + void setmode(int md, const int nfnvf) { // define the GL primitive type & number of expected vertices + GLenum mode[]= {GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, + GL_QUADS, GL_QUAD_STRIP, GL_POLYGON}; + curmode=mode[md]; + gsidx=new osg::ushort[6*nfnvf]; + nrmidx=new osg::ushort[6*nfnvf]; + txidx=new osg::ushort[6*nfnvf]; + txcoords=new Vec2[6*nfnvf]; // one texture coord per vertex + nrms=new Vec3[6*nfnvf]; // one normal per face or per vertex + primlengs=new int[nfnvf]; // primitive lengths + nff=0; + nload=0; + } + void tesselate(const _face &fc, const Vec3 verts[], const dwmaterial *themat,GLUtesselator* ts, _dwobj *dwob) + { // generates a set of primitives all of one type (eg tris, qstrip trifan...) + nbegin=0; // number of triangle strips etc generated + fc.tesselate(verts, themat, ts, dwob, tmat); + nff+=nbegin; // the number of primitives generated + } + void buildDrawable(Group *grp, Vec3 verts[], dwmaterial *themat, const int nverts) { + if (nload>0 && nff>0) { // there are some strips of this type + Geode *geode = new Geode; + GeoSet *gset = new GeoSet; + osg::ushort *nunrmidx=new osg::ushort[nload]; + osg::ushort *nutxidx = new osg::ushort[nload]; + osg::ushort *nusidx = new osg::ushort[nload]; + Vec3 *nunrms=new Vec3[nload]; // one normal per face (nff) or per vertex (nload) + int *nuprimlengs=new int[nff]; // primitive lengths + Vec2 *nutxc=new Vec2[nload]; + int i; // general counter + for (i=0; iaddDrawable(gset); + grp->addChild( geode ); // add to the world outside + gset->setNumPrims( nff ); + switch (curmode) { + case GL_TRIANGLES: gset->setPrimType( osg::GeoSet::TRIANGLES ); + gset->setNumPrims( nload/3 ); + break; + case GL_TRIANGLE_STRIP: gset->setPrimType( osg::GeoSet::TRIANGLE_STRIP ); + gset->setPrimLengths( nuprimlengs ); + break; + case GL_TRIANGLE_FAN: gset->setPrimType( osg::GeoSet::TRIANGLE_FAN ); + gset->setPrimLengths( nuprimlengs ); + break; + case GL_QUADS: gset->setPrimType( osg::GeoSet::QUADS ); + gset->setNumPrims( nload/4 ); + break; + case GL_QUAD_STRIP: gset->setPrimType( osg::GeoSet::QUAD_STRIP ); + break; + case GL_POLYGON: gset->setPrimType( osg::GeoSet::POLYGON ); + break; + } + gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); //BIND_PERPRIM); // + gset->setNormals(nunrms, nunrmidx); - gset->setTextureCoords(nutxc,nutxidx); - gset->setCoords( verts, nusidx ); - if (themat->isType(dwmaterial::PointLight) || themat->isType(dwmaterial::SpotLight)) { - Vec4 pos; - pos.set(0,0,0,1); - for (int i=0; imakeLight(pos); - grp->addChild(ls); - } else { - StateSet *dstate=themat->make(); - gset->setStateSet( dstate ); - } - } else { - delete [] primlengs; - delete [] nrms; - delete [] gsidx; - delete [] nrmidx; - delete [] txcoords; - delete [] txidx; - primlengs=NULL; gsidx=NULL; nrmidx=NULL; - txidx=NULL; nrms=NULL; txcoords=NULL;; - } - } - void settmat(const Matrix *mx) { - tmat= mx; - } + gset->setTextureCoords(nutxc,nutxidx); + gset->setCoords( verts, nusidx ); + if (themat->isType(dwmaterial::PointLight) || themat->isType(dwmaterial::SpotLight)) { + Vec4 pos; + pos.set(0,0,0,1); + for (int i=0; imakeLight(pos); + grp->addChild(ls); + } else { + StateSet *dstate=themat->make(); + gset->setStateSet( dstate ); + } + } else { + delete [] primlengs; + delete [] nrms; + delete [] gsidx; + delete [] nrmidx; + delete [] txcoords; + delete [] txidx; + primlengs=NULL; gsidx=NULL; nrmidx=NULL; + txidx=NULL; nrms=NULL; txcoords=NULL;; + } + } + void settmat(const Matrix *mx) { + tmat= mx; + } private: - int nbegin; - int ntesverts[20]; // number of vertices in each primitive list - up to 20 restarts - GLenum nbegtype[20]; // up to 20 restarts - GLenum curmode; - int nload; // numebr of vertices loaded into these arrays - int nff; // primitive loaded - int *primlengs; - osg::ushort *gsidx; - osg::ushort *nrmidx; - osg::ushort *txidx; - Vec3 *nrms; // one normal per face - Vec2 *txcoords; // one texture coord per vertex - const Matrix *tmat; // local texture matrix, or may be NULL for default mapping + int nbegin; + int ntesverts[20]; // number of vertices in each primitive list - up to 20 restarts + GLenum nbegtype[20]; // up to 20 restarts + GLenum curmode; + int nload; // numebr of vertices loaded into these arrays + int nff; // primitive loaded + int *primlengs; + osg::ushort *gsidx; + osg::ushort *nrmidx; + osg::ushort *txidx; + Vec3 *nrms; // one normal per face + Vec2 *txcoords; // one texture coord per vertex + const Matrix *tmat; // local texture matrix, or may be NULL for default mapping }; static prims prd; // tesselation subroutines void CALLBACK myFaceBegin(GLenum op) {// tess vertex call back - prd.begin(op); - //glBegin(op); + prd.begin(op); + //glBegin(op); } void CALLBACK myFaceEnd() {// tess vertex call back - if ( prd.isGLtype()) { // a prim of type == nvf ending; next counter needed - prd.End(); - } - //glEnd(); + if ( prd.isGLtype()) { // a prim of type == nvf ending; next counter needed + prd.End(); + } + //glEnd(); } void CALLBACK myVertex(void *pv) {// tess vertex call back with texture coord == void *pv1, - // dwob needed if there is a combine callback to add the new vertex to group - if (prd.isGLtype()) { // a prim of type == nvf being created; use this vertex - prd.addv((avertex *)pv); - } + // dwob needed if there is a combine callback to add the new vertex to group + if (prd.isGLtype()) { // a prim of type == nvf being created; use this vertex + prd.addv((avertex *)pv); + } } void CALLBACK combineCallback( GLdouble coords[3], avertex *d[4], GLfloat w[4], avertex **dataOut , _dwobj *dwob) { - prd.combine(coords, d, w, dataOut,dwob); + prd.combine(coords, d, w, dataOut,dwob); } void CALLBACK error (GLenum errno) { // tess error code - const unsigned char *errm=gluErrorString(errno); - printf("tesselator error %d %s\n", errno,errm);//, errm + const unsigned char *errm=gluErrorString(errno); + printf("tesselator error %d %s\n", errno,errm);//, errm } - //========== + //========== void _face::linkholes(const Vec3 verts[], const dwmaterial *themat, const _face *f2) const { - int ipr[2]; - ipr[0]=nv-1; - for (int i=0; iopening[idop2]); + opening[idop].linkholes(verts, themat, &f2->opening[idop2]); } //======== Edges link 2 vertices; indicate where a sharp crease can be found ========== class _dwedge { public: - _dwedge(){;} - ~_dwedge(){;} - void set(int i, int j) { e1=i; e2=j; } + _dwedge(){;} + ~_dwedge(){;} + void set(int i, int j) { e1=i; e2=j; } private: - int e1,e2; // ends of the edge - it joins verts[e1] to verts[e2] + int e1,e2; // ends of the edge - it joins verts[e1] to verts[e2] }; //=================== class _dwobj { // class for design workshop read of a single object public: - _dwobj() {oldv=verts=NULL; nverts=nfaces=0; openings=NULL;faces=NULL; tmat=NULL; edges=NULL; - nopens=nfaceverts=0; fc1=fc2=NULL; colour[0]=colour[1]=colour[2]=colour[3]=1; - } - ~_dwobj() {/*delete verts; delete faces;delete openings;*/ - delete fc1;delete fc2; - } - int readOpenings(FILE *fp, const int nexpected) - { // read up to nexpected openings, each opening may have a number of vertices + _dwobj() {oldv=verts=NULL; nverts=nfaces=0; openings=NULL;faces=NULL; tmat=NULL; edges=NULL; + nopens=nfaceverts=0; fc1=fc2=NULL; colour[0]=colour[1]=colour[2]=colour[3]=1; + } + ~_dwobj() {/*delete verts; delete faces;delete openings;*/ + delete fc1;delete fc2; + } + int readOpenings(FILE *fp, const int nexpected) + { // read up to nexpected openings, each opening may have a number of vertices char buff[256]; - openings=new int[nexpected*2]; - fc1=new osg::ushort[nexpected]; - fc2=new osg::ushort[nexpected]; - nopens=0; - int nvop=0; // current number of vertices in hole in object - while (nopenssetmx(&mx); // may be used by combine callback to define txcoord - gluTessBeginPolygon(ts, dwob); - gluTessBeginContour(ts); /**/ - for (int j=0; jsetmx(&mx); // may be used by combine callback to define txcoord + gluTessBeginPolygon(ts, dwob); + gluTessBeginContour(ts); /**/ + for (int j=0; jpos[0] = coords[0]; - newv->pos[1] = coords[1]; - newv->pos[2] = coords[2]; - newv->uv[0] = newv->uv[1] =0; - newv->nrmv[0] = newv->nrmv[1] = newv->nrmv[2] =0; - for (int i=0; i<4; i++) { - if (d[i]) { - newv->uv[0] = w[i]*d[i]->uv[0]; - newv->uv[1] = w[i]*d[i]->uv[1]; - newv->nrmv[0] = w[i]*d[i]->nrmv[0]; - newv->nrmv[1] = w[i]*d[i]->nrmv[1]; - newv->nrmv[2] = w[i]*d[i]->nrmv[2]; - newv->themat=d[i]->themat; - } - } - dwob->makeuv(newv->uv, newv->pos); - newv->idx=dwob->addvtx(coords[0], coords[1], coords[2]); - *dataOut = newv; - } else { - *dataOut = NULL; - } + GLfloat w[4], avertex **dataOut , _dwobj *dwob) { + if (nbegin<20 && isGLtype()) { // a prim of type == nvf being created; use this vertex + avertex *newv = new avertex(); // (avertex *)calloc(1, sizeof(avertex)); + newv->pos[0] = coords[0]; + newv->pos[1] = coords[1]; + newv->pos[2] = coords[2]; + newv->uv[0] = newv->uv[1] =0; + newv->nrmv[0] = newv->nrmv[1] = newv->nrmv[2] =0; + for (int i=0; i<4; i++) { + if (d[i]) { + newv->uv[0] = w[i]*d[i]->uv[0]; + newv->uv[1] = w[i]*d[i]->uv[1]; + newv->nrmv[0] = w[i]*d[i]->nrmv[0]; + newv->nrmv[1] = w[i]*d[i]->nrmv[1]; + newv->nrmv[2] = w[i]*d[i]->nrmv[2]; + newv->themat=d[i]->themat; + } + } + dwob->makeuv(newv->uv, newv->pos); + newv->idx=dwob->addvtx(coords[0], coords[1], coords[2]); + *dataOut = newv; + } else { + *dataOut = NULL; + } } void _dwobj::buildDrawable(Group *grp) { // current DWobject complete; make a drawable, and add it to a osg::Group - if (nfaces>0) { - int nvf; - int nfnvf=0; // number of vertices for faces plus holes - int i; // a general counter - for (i=0; i0) { + int nvf; + int nfnvf=0; // number of vertices for faces plus holes + int i; // a general counter + for (i=0; i0) obj.readOpenings(fp, nexpected); - } else if( strncmp(buff,"UVW:",4)==0) { // texture application matrix - Matrix mx; - sscanf(buff+4,"%f %f %f%f %f %f%f %f %f", - &mx(0,0), &mx(0,1), &mx(0,2), - &mx(1,0), &mx(1,1), &mx(1,2), - &mx(2,0), &mx(2,1), &mx(2,2)); - obj.settmat(&mx); - } - } + if( buff[0] == '#' ) + continue; + else if( strncmp(buff,"numMaterials:",13)==0) { // No of materials + nmn=atoi(buff+14); + matpalet=new dwmaterial[nmn]; + } else if( strncmp(buff,"Material:",9)==0) { // No of materials + dwfgets(buff, sizeof( buff ), fp ); + nmat++; + rdg=MATERIAL; + int id=atoi(buff); + matpalet[nmat].setid(id); // current material to be modified + + } else if (strncmp(buff, "Phase:",6)==0) { + } else if (strncmp(buff, "CurrPhase:",10)==0) { + } else if (strncmp(buff, "numPhases:",10)==0) { + } else if (strncmp(buff, "Opacity:",8)==0) { + float opacity=atof(buff+8); + matpalet[nmat].setopacity(opacity); + } else if (strncmp(buff, "FallOff:",8)==0) { + float fo=atof(buff+8); + matpalet[nmat].setFallOff(fo); + } else if (strncmp(buff, "InnerHalfAngle:",15)==0) { + float ha=atof(buff+15); + matpalet[nmat].setHalfAngleIn(ha); + } else if (strncmp(buff, "OuterHalfAngle:",15)==0) { + float ha=atof(buff+15); + matpalet[nmat].setHalfAngleOut(ha); + } else if (strncmp(buff, "Brightness:",11)==0) { + float br=atof(buff+11); + matpalet[nmat].setBright(br); + } else if (strncmp(buff, "Attentuation:",13)==0) { // oops - they can't spell + matpalet[nmat].setAtten(buff+13); + } else if (strncmp(buff, "MaterialType:",13)==0) { + matpalet[nmat].setType(buff+14); + } else if (strncmp(buff, "SpecularReflectivity:",21)==0) { + float spec=atof(buff+21); + matpalet[nmat].setspecular(spec); + } else if (strncmp(buff, "SmoothnessExponent:",19)==0) { + float spec=atof(buff+19); + matpalet[nmat].setspecexp(spec/100.0f); // convert to 0-1 from percent + } else if (strncmp(buff, "TextureWidthAndHeight:",22)==0) { + char *ct=strchr(buff+22,','); + float repx=atof(buff+23), repy=atof(ct+1); + matpalet[nmat].settxrep(repx, repy); + } else if (strncmp(buff, "PictureFile:",12)==0) { + char *end=strchr(buff,'\n'); // end of line + if (end) *end='\0'; // removed + matpalet[nmat].setfname(buff); + } else if( strncmp(buff,"Extrusion:",10)==0 || + strncmp(buff,"Cube:",5)==0 || + strncmp(buff,"Polyline:",9)==0 || + strncmp(buff,"Polyhedron:",11)==0) { + rdg=OBJECT; + obj.buildDrawable(grp); + obj.reset(); + } else if( strncmp(buff,"Mat:",4)==0) { + int mt=atoi(buff+4); + for (int j=0; j0) obj.readOpenings(fp, nexpected); + } else if( strncmp(buff,"UVW:",4)==0) { // texture application matrix + Matrix mx; + sscanf(buff+4,"%f %f %f%f %f %f%f %f %f", + &mx(0,0), &mx(0,1), &mx(0,2), + &mx(1,0), &mx(1,1), &mx(1,2), + &mx(2,0), &mx(2,1), &mx(2,2)); + obj.settmat(&mx); + } + } } fclose( fp ); - obj.buildDrawable(grp); // tidy up any remaining objects + obj.buildDrawable(grp); // tidy up any remaining objects return grp; @@ -1021,18 +1020,18 @@ private: int dwfgets(char *clin, int max, FILE *fin) { // replace fgets to detect EOL = char 13 as well as Creturn=10 GWM 111100 - // Macintosh produced files (such as those obtainable - //from the great buildings site at www.Artifice.com) use 13 format, PC models use 10. - int nread=0; - char c1=1; - do { - if (!feof( fin )) { - clin[nread]=c1=fgetc(fin); - nread++; - } - } while (nread0) clin[nread-1]='\0'; // null terminate and remove training blank - return nread; + // Macintosh produced files (such as those obtainable + //from the great buildings site at www.Artifice.com) use 13 format, PC models use 10. + int nread=0; + char c1=1; + do { + if (!feof( fin )) { + clin[nread]=c1=fgetc(fin); + nread++; + } + } while (nread0) clin[nread-1]='\0'; // null terminate and remove training blank + return nread; } // now register with osg::Registry to instantiate the above diff --git a/src/osgPlugins/obj/ReaderWriterOBJ.cpp b/src/osgPlugins/obj/ReaderWriterOBJ.cpp index 8aadde108..8350bd708 100644 --- a/src/osgPlugins/obj/ReaderWriterOBJ.cpp +++ b/src/osgPlugins/obj/ReaderWriterOBJ.cpp @@ -157,7 +157,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(const std::string& fil // note obj_x -> osg_x, // obj_y -> osg_z, // obj_z -> osg_y, - xform->preTranslate(obj->position[0], obj->position[2], obj->position[1]); + xform->setMatrix(osg::Matrix::trans(obj->position[0], obj->position[2], obj->position[1])); osg_top = xform; } else diff --git a/src/osgPlugins/pfb/ReaderWriterPFB.cpp b/src/osgPlugins/pfb/ReaderWriterPFB.cpp index 6ef8c88bd..f6ef367b2 100644 --- a/src/osgPlugins/pfb/ReaderWriterPFB.cpp +++ b/src/osgPlugins/pfb/ReaderWriterPFB.cpp @@ -170,11 +170,11 @@ class ReaderWriterPFB : public osgDB::ReaderWriter if (root) { if (pfdStoreFile(root,fileName.c_str())!=0) return WriteResult::FILE_SAVED; - else return "Unable to write file from performer."; + else return std::string("Unable to write file from performer."); } else { - return "Unable to convert scene to performer, cannot write file."; + return std::string("Unable to convert scene to performer, cannot write file."); } } diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index eb8a67043..aaf0f0696 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -1,11 +1,11 @@ /* -------------------------------------------------------------------------- * - * openscenegraph textLib / FTGL + * openscenegraph textLib / FTGL * * -------------------------------------------------------------------------- - * - * prog: max rheiner;mrn@paus.ch - * date: 4/25/2001 (m/d/y) + * + * prog: max rheiner;mrn@paus.ch + * date: 4/25/2001 (m/d/y) * * ---------------------------------------------------------------------------- * @@ -61,136 +61,136 @@ std::string findFontFile(const std::string& str) Font:: Font() { - _init=false; - _font=NULL; - _created=false; + _init=false; + _font=NULL; + _created=false; - _pointSize=14; - _res=72; + _pointSize=14; + _res=72; } bool Font:: init(const std::string& font) { - _font=NULL; - _created=false; + _font=NULL; + _created=false; - open(font); + open(font); - if(_font!=NULL) - return true; - else - return false; + if(_font!=NULL) + return true; + else + return false; } Font:: ~Font() { - clear(); + clear(); } bool Font:: open(const std::string& font) { - clear(); + clear(); std::string filename = findFontFile(font); if (filename.empty()) return false; - _font=createFontObj(); - if( _font!=NULL && _font->Open(filename.c_str()) ) - { - _init=true; - _fontName=font; - return true; - } - else - return false; + _font=createFontObj(); + if( _font!=NULL && _font->Open(filename.c_str()) ) + { + _init=true; + _fontName=font; + return true; + } + else + return false; } bool Font:: create(int pointSize,const unsigned int res) { - _pointSize=pointSize; - _res=res; + _pointSize=pointSize; + _res=res; - return create(); + return create(); } bool Font:: create() { - if(_init) - { - if(_font->FaceSize(_pointSize,_res)) - { - _created=true; - return true; - } - else - return false; - } - else - return false; + if(_init) + { + if(_font->FaceSize(_pointSize,_res)) + { + _created=true; + return true; + } + else + return false; + } + else + return false; } void Font:: output(const char* text) { - if(_created) - _font->render(text); - else - create(_pointSize); + if(_created) + _font->render(text); + else + create(_pointSize); } void Font:: clear() { - _init=false; - - if(_font) - { - delete _font; - _font=NULL; - } + _init=false; + + if(_font) + { + delete _font; + _font=NULL; + } - _fontName=""; + _fontName=""; } float Font:: getWidth(const char* text) const { - if(_init && _created) - return _font->Advance(text); - else - return -1; + if(_init && _created) + return _font->Advance(text); + else + return -1; } int Font:: getHeight() const { - if(_init && _created) - return _pointSize; - else - return -1; + if(_init && _created) + return _pointSize; + else + return -1; } int Font:: getDescender() const { - if(_init && _created) - return _font->Descender(); - else - return -1; + if(_init && _created) + return _font->Descender(); + else + return -1; } int Font:: getAscender() const { - if(_init && _created) - return _font->Ascender(); - else - return -1; + if(_init && _created) + return _font->Ascender(); + else + return -1; } @@ -201,22 +201,22 @@ getAscender() const // BitmapFont BitmapFont:: -BitmapFont(const std::string& font, - int point_size): +BitmapFont(const std::string& font, + int point_size): RasterFont() { - if(init(font)) - { - } - _pointSize=point_size; + if(init(font)) + { + } + _pointSize=point_size; } FTFont* BitmapFont:: createFontObj(void) { - return (FTFont*)(new FTGLBitmapFont); + return (FTFont*)(new FTGLBitmapFont); } - + // BitmapFont /////////////////////////////////////////////////////////////////////////////// @@ -224,23 +224,23 @@ createFontObj(void) // PixmapFont PixmapFont:: -PixmapFont(const std::string& font, - int point_size): +PixmapFont(const std::string& font, + int point_size): RasterFont(font) { - if(init(font)) - { - } - _pointSize=point_size; + if(init(font)) + { + } + _pointSize=point_size; } - + FTFont* PixmapFont:: createFontObj(void) { - return (FTFont*)(new FTGLPixmapFont); + return (FTFont*)(new FTGLPixmapFont); } - + // PixmapFont /////////////////////////////////////////////////////////////////////////////// @@ -248,23 +248,23 @@ createFontObj(void) // PixmapFont TextureFont:: -TextureFont(const std::string& font, - int point_size): +TextureFont(const std::string& font, + int point_size): RasterFont(font) { - if(init(font)) - { - } - _pointSize=point_size; + if(init(font)) + { + } + _pointSize=point_size; } - + FTFont* TextureFont:: createFontObj(void) { - return (FTFont*)(new FTGLTextureFont); + return (FTFont*)(new FTGLTextureFont); } - + // PixmapFont /////////////////////////////////////////////////////////////////////////////// @@ -272,25 +272,25 @@ createFontObj(void) // _FTGLOutlineFont OutlineFont:: -OutlineFont(const std::string& font, - int point_size, - double precision): +OutlineFont(const std::string& font, + int point_size, + double precision): VectorFont(font) { - if(init(font)) - { - } - _pointSize=point_size; - _precision=precision; + if(init(font)) + { + } + _pointSize=point_size; + _precision=precision; } - + FTFont* OutlineFont:: createFontObj(void) { - return (FTFont*)(new FTGLOutlineFont); + return (FTFont*)(new FTGLOutlineFont); } - + // _FTGLOutlineFont /////////////////////////////////////////////////////////////////////////////// @@ -298,24 +298,24 @@ createFontObj(void) // PolygonFont PolygonFont:: -PolygonFont(const std::string& font, - int point_size, - double precision): +PolygonFont(const std::string& font, + int point_size, + double precision): VectorFont(font) { - if(init(font)) - { - } - _pointSize=point_size; - _precision=precision; + if(init(font)) + { + } + _pointSize=point_size; + _precision=precision; } - + FTFont* PolygonFont:: createFontObj(void) { - return (FTFont*)(new FTGLPolygonFont); + return (FTFont*)(new FTGLPolygonFont); } - + // PolygonFont /////////////////////////////////////////////////////////////////////////////// diff --git a/src/osgText/Makefile b/src/osgText/Makefile index f4a1983ee..fe2b368eb 100644 --- a/src/osgText/Makefile +++ b/src/osgText/Makefile @@ -42,7 +42,7 @@ TARGET_INCLUDE_FILES = \ osgText/Text\ osgText/Version -C++FLAGS += -I ../../include -I /usr/include/freetype2 -I /usr/local/include/freetype2 +C++FLAGS += -I../../include -I/usr/include/freetype2 -I/usr/local/include/freetype2 include ../../Make/makerules diff --git a/src/osgText/Paragraph.cpp b/src/osgText/Paragraph.cpp index 2d2ea9108..af23889ed 100644 --- a/src/osgText/Paragraph.cpp +++ b/src/osgText/Paragraph.cpp @@ -98,55 +98,15 @@ void Paragraph::createDrawables() typedef vector TextList; TextList formatedText; - - std::string::size_type start = 0; - std::string::size_type last_space = 0; - std::string::size_type current_line_length = 0; - - for(std::string::size_type current=0; - current<_text.size(); - ++current) - { - const char c = _text[current]; - if (c==' ') last_space = current; - - if (c=='\n') - { - formatedText.push_back(std::string(_text,start,current-start)); - start = current+1; - - last_space = start; - current_line_length = 0; - } - else if (current_line_length==_maxCharsPerLine) - { - if (last_space>start) - { - formatedText.push_back(std::string(_text,start,last_space-start)); - start = last_space+1; - } - - else - { - formatedText.push_back(std::string(_text,start,current-start)); - start = current+1; - } - - last_space = start; - current_line_length = 0; - } - else ++current_line_length; - } - if (start<_text.size()) - { - formatedText.push_back(std::string(_text,start,_text.size()-start)); - } + + createFormatedText(_maxCharsPerLine,_text,formatedText); // now create the text drawables from the formate text list. for(TextList::iterator itr=formatedText.begin(); itr!=formatedText.end(); ++itr) { + osgText::Text* textDrawable = new osgText::Text(_font.get()); textDrawable->setAlignment(_alignment); textDrawable->setPosition(pos); @@ -162,3 +122,54 @@ void Paragraph::createDrawables() } } + +bool Paragraph::createFormatedText(unsigned int noCharsPerLine,const std::string& str,std::vector& formatedText) +{ + if (str.empty()) return false; + + std::string::size_type start = 0; + std::string::size_type last_space = 0; + std::string::size_type current_line_length = 0; + + for(std::string::size_type current=0; + currentstart) + { + formatedText.push_back(std::string(str,start,last_space-start)); + start = last_space+1; + current_line_length = current-start; + } + + else + { + formatedText.push_back(std::string(str,start,current-start)); + start = current+1; + current_line_length = 0; + } + + last_space = start; + } + else ++current_line_length; + } + if (startisOk()) - { - _init=true; - _font=font; + if(font && font->isOk()) + { + _init=true; + _font=font; - if(dynamic_cast(_font.get())) - _fontType=POLYGON; - else if(dynamic_cast(_font.get())) - _fontType=BITMAP; - else if(dynamic_cast(_font.get())) - _fontType=PIXMAP; - else if(dynamic_cast(_font.get())) - _fontType=TEXTURE; - else if(dynamic_cast(_font.get())) - _fontType=OUTLINE; + if(dynamic_cast(_font.get())) + _fontType=POLYGON; + else if(dynamic_cast(_font.get())) + _fontType=BITMAP; + else if(dynamic_cast(_font.get())) + _fontType=PIXMAP; + else if(dynamic_cast(_font.get())) + _fontType=TEXTURE; + else if(dynamic_cast(_font.get())) + _fontType=OUTLINE; - } + } } Text:: @@ -71,19 +71,19 @@ void Text::setFont(Font* font) if(font && font->isOk()) { - _init=true; - _font=font; + _init=true; + _font=font; - if(dynamic_cast(_font.get())) - _fontType=POLYGON; - else if(dynamic_cast(_font.get())) - _fontType=BITMAP; - else if(dynamic_cast(_font.get())) - _fontType=PIXMAP; - else if(dynamic_cast(_font.get())) - _fontType=TEXTURE; - else if(dynamic_cast(_font.get())) - _fontType=OUTLINE; + if(dynamic_cast(_font.get())) + _fontType=POLYGON; + else if(dynamic_cast(_font.get())) + _fontType=BITMAP; + else if(dynamic_cast(_font.get())) + _fontType=PIXMAP; + else if(dynamic_cast(_font.get())) + _fontType=TEXTURE; + else if(dynamic_cast(_font.get())) + _fontType=OUTLINE; _initAlignment = false; dirtyBound(); @@ -94,348 +94,348 @@ void Text::setFont(Font* font) void Text:: setDefaults() { - _init=false; - - _pos.set(0,0,0); - _alignmentPos.set(0,0,0); - - _fontType=UNDEF; - _alignment=LEFT_BOTTOM; - _drawMode=DEFAULT; + _init=false; + + _pos.set(0,0,0); + _alignmentPos.set(0,0,0); + + _fontType=UNDEF; + _alignment=LEFT_BOTTOM; + _drawMode=DEFAULT; - _boundingBoxType=GLYPH; - _boundingBoxType=GEOMETRY; + _boundingBoxType=GLYPH; + _boundingBoxType=GEOMETRY; - _initAlignment=false; + _initAlignment=false; - _useDisplayList=false; + _useDisplayList=false; } const bool Text:: computeBound() const { - if(!_init) - { - _bbox_computed=false; - return true; - } + if(!_init) + { + _bbox_computed=false; + return true; + } - // culling - if(_font->isCreated()) - { // ready to get the siz - _bbox.init(); + // culling + if(_font->isCreated()) + { // ready to get the siz + _bbox.init(); - Vec3 min,max; - calcBounds(&min,&max); + Vec3 min,max; + calcBounds(&min,&max); - _bbox.expandBy(min); - _bbox.expandBy(max); + _bbox.expandBy(min); + _bbox.expandBy(max); - _bbox_computed=true; - } - else - { // have to wait for the init. - _bbox.init(); + _bbox_computed=true; + } + else + { // have to wait for the init. + _bbox.init(); - // to be sure that the obj isn't culled -// _bbox.expandBy(_pos); + // to be sure that the obj isn't culled +// _bbox.expandBy(_pos); - _bbox.expandBy(_pos + Vec3(-100,-100,-100)); - _bbox.expandBy(_pos + Vec3(100,100,100)); + _bbox.expandBy(_pos + Vec3(-100,-100,-100)); + _bbox.expandBy(_pos + Vec3(100,100,100)); - /* - _bbox.expandBy(Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX)); - _bbox.expandBy(Vec3(FLT_MAX,FLT_MAX,FLT_MAX)); - */ - _bbox_computed=true; + /* + _bbox.expandBy(Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX)); + _bbox.expandBy(Vec3(FLT_MAX,FLT_MAX,FLT_MAX)); + */ + _bbox_computed=true; - } - return true; + } + return true; } void Text::drawImmediateMode(State& state) { - if(!_init) - return; - - if(!_font->isCreated()) - { - _font->create(); - dirtyBound(); - } + if(!_init) + return; + + if(!_font->isCreated()) + { + _font->create(); + dirtyBound(); + } - if(!_initAlignment) - initAlignment(); - - // draw boundingBox - if(_drawMode & BOUNDINGBOX) - drawBoundingBox(); - // draw alignment - if(_drawMode & ALIGNEMENT) - drawAlignment(); + if(!_initAlignment) + initAlignment(); + + // draw boundingBox + if(_drawMode & BOUNDINGBOX) + drawBoundingBox(); + // draw alignment + if(_drawMode & ALIGNEMENT) + drawAlignment(); - // draw boundingBox - if(_drawMode & TEXT) - { - Vec3 drawPos(_pos+_alignmentPos); - glPushMatrix(); - switch(_fontType) - { - case POLYGON: - glTranslatef(drawPos.x(),drawPos.y(),drawPos.z()); - _font->output(_text.c_str()); - break; - case OUTLINE: - glTranslatef(drawPos.x(),drawPos.y(),drawPos.z()); - _font->output(_text.c_str()); - break; - case BITMAP: - glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z()); - _font->output(_text.c_str()); - break; - case PIXMAP: - glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z()); - _font->output(_text.c_str()); - break; - case TEXTURE: - glTranslatef(drawPos.x(),drawPos.y(),drawPos.z()); - _font->output(_text.c_str()); - break; + // draw boundingBox + if(_drawMode & TEXT) + { + Vec3 drawPos(_pos+_alignmentPos); + glPushMatrix(); + switch(_fontType) + { + case POLYGON: + glTranslatef(drawPos.x(),drawPos.y(),drawPos.z()); + _font->output(_text.c_str()); + break; + case OUTLINE: + glTranslatef(drawPos.x(),drawPos.y(),drawPos.z()); + _font->output(_text.c_str()); + break; + case BITMAP: + glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z()); + _font->output(_text.c_str()); + break; + case PIXMAP: + glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z()); + _font->output(_text.c_str()); + break; + case TEXTURE: + glTranslatef(drawPos.x(),drawPos.y(),drawPos.z()); + _font->output(_text.c_str()); + break; - }; - glPopMatrix(); - } + }; + glPopMatrix(); + } } void Text:: drawBoundingBox(void) { - if(!_init) - return; + if(!_init) + return; - glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT ); - glDisable(GL_TEXTURE_2D); - glColor3f(0,1,0); - glBegin(GL_LINE_LOOP); - glVertex3f(_bbox.xMin(),_bbox.yMin(),_bbox.zMin()); - glVertex3f(_bbox.xMax(),_bbox.yMin(),_bbox.zMin()); - glVertex3f(_bbox.xMax(),_bbox.yMax(),_bbox.zMin()); - glVertex3f(_bbox.xMin(),_bbox.yMax(),_bbox.zMin()); - glEnd(); - glPopAttrib(); + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT ); + glDisable(GL_TEXTURE_2D); + glColor3f(0,1,0); + glBegin(GL_LINE_LOOP); + glVertex3f(_bbox.xMin(),_bbox.yMin(),_bbox.zMin()); + glVertex3f(_bbox.xMax(),_bbox.yMin(),_bbox.zMin()); + glVertex3f(_bbox.xMax(),_bbox.yMax(),_bbox.zMin()); + glVertex3f(_bbox.xMin(),_bbox.yMax(),_bbox.zMin()); + glEnd(); + glPopAttrib(); } void Text:: drawAlignment(void) { - if(!_init) - return; + if(!_init) + return; - double size=_font->getPointSize()/4; + double size=_font->getPointSize()/4; - glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT ); - glDisable(GL_TEXTURE_2D); - glColor3f(1,0,0); - glBegin(GL_LINES); - glVertex3f(_pos.x() - size,_pos.y(),_pos.z()); - glVertex3f(_pos.x() + size,_pos.y(),_pos.z()); - - glVertex3f(_pos.x(),_pos.y() - size,_pos.z()); - glVertex3f(_pos.x(),_pos.y() + size,_pos.z()); + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT ); + glDisable(GL_TEXTURE_2D); + glColor3f(1,0,0); + glBegin(GL_LINES); + glVertex3f(_pos.x() - size,_pos.y(),_pos.z()); + glVertex3f(_pos.x() + size,_pos.y(),_pos.z()); + + glVertex3f(_pos.x(),_pos.y() - size,_pos.z()); + glVertex3f(_pos.x(),_pos.y() + size,_pos.z()); - glEnd(); - glPopAttrib(); + glEnd(); + glPopAttrib(); } - + void Text:: setPosition(const Vec3& pos) { - _pos=pos; + _pos=pos; } void Text:: setPosition(const Vec2& pos) { - setPosition(Vec3(pos.x(),pos.y(),0)); + setPosition(Vec3(pos.x(),pos.y(),0)); } void Text:: calcBounds(Vec3* min,Vec3* max) const { - if(!_init) - return; + if(!_init) + return; - float h=_font->getHeight(); - float w=_font->getWidth(_text.c_str()); - float descender=_font->getDescender(); + float h=_font->getHeight(); + float w=_font->getWidth(_text.c_str()); + float descender=_font->getDescender(); - min->set(0,descender,0); - max->set(w,h + descender ,0); + min->set(0,descender,0); + max->set(w,h + descender ,0); } bool Text:: initAlignment(void) { - if(!_init) - return false; + if(!_init) + return false; - // culling - if(_font->isCreated()) - { // ready to get the siz - _bbox.init(); + // culling + if(_font->isCreated()) + { // ready to get the siz + _bbox.init(); - Vec3 min,max; - initAlignment(&min,&max); + Vec3 min,max; + initAlignment(&min,&max); - _bbox.expandBy(min); - _bbox.expandBy(max); + _bbox.expandBy(min); + _bbox.expandBy(max); - _bbox_computed=true; + _bbox_computed=true; - _initAlignment=true; - } - else - { // have to wait for the init. - _bbox.init(); + _initAlignment=true; + } + else + { // have to wait for the init. + _bbox.init(); - // to be sure that the obj isn't culled - _bbox.expandBy(Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX)); - _bbox.expandBy(Vec3(FLT_MAX,FLT_MAX,FLT_MAX)); + // to be sure that the obj isn't culled + _bbox.expandBy(Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX)); + _bbox.expandBy(Vec3(FLT_MAX,FLT_MAX,FLT_MAX)); - _bbox_computed=true; - } + _bbox_computed=true; + } - return true; + return true; } void Text:: initAlignment(Vec3* min,Vec3* max) { - if(!_init) - return; + if(!_init) + return; - float h=_font->getHeight(); - float w=_font->getWidth(_text.c_str()); - float descender=_font->getDescender(); + float h=_font->getHeight(); + float w=_font->getWidth(_text.c_str()); + float descender=_font->getDescender(); - min->set(0,descender,0); - max->set(w,h + descender ,0); + min->set(0,descender,0); + max->set(w,h + descender ,0); - switch(_boundingBoxType) - { - case GLYPH: - h+=descender; - switch(_alignment) - { - case LEFT_TOP: - _alignmentPos.set(0.0,h,0.0); - break; - case LEFT_CENTER: - _alignmentPos.set(0.0,h/2.0,0.0); - break; - case LEFT_BOTTOM: - _alignmentPos.set(0.0,0.0,0.0); - break; + switch(_boundingBoxType) + { + case GLYPH: + h+=descender; + switch(_alignment) + { + case LEFT_TOP: + _alignmentPos.set(0.0,h,0.0); + break; + case LEFT_CENTER: + _alignmentPos.set(0.0,h/2.0,0.0); + break; + case LEFT_BOTTOM: + _alignmentPos.set(0.0,0.0,0.0); + break; - case CENTER_TOP: - _alignmentPos.set(w/2.0,h,0.0); - break; - case CENTER_CENTER: - _alignmentPos.set(w/2.0,h/2.0,0.0); - break; - case CENTER_BOTTOM: - _alignmentPos.set(w/2.0,0.0,0.0); - break; + case CENTER_TOP: + _alignmentPos.set(w/2.0,h,0.0); + break; + case CENTER_CENTER: + _alignmentPos.set(w/2.0,h/2.0,0.0); + break; + case CENTER_BOTTOM: + _alignmentPos.set(w/2.0,0.0,0.0); + break; - case RIGHT_TOP: - _alignmentPos.set(w,h,0.0); - break; - case RIGHT_CENTER: - _alignmentPos.set(w,h/2.0,0.0); - break; - case RIGHT_BOTTOM: - _alignmentPos.set(w,0.0,0.0); - break; - }; - _alignmentPos=-_alignmentPos; + case RIGHT_TOP: + _alignmentPos.set(w,h,0.0); + break; + case RIGHT_CENTER: + _alignmentPos.set(w,h/2.0,0.0); + break; + case RIGHT_BOTTOM: + _alignmentPos.set(w,0.0,0.0); + break; + }; + _alignmentPos=-_alignmentPos; - *min+=_pos+_alignmentPos; - *max+=_pos+_alignmentPos; - break; + *min+=_pos+_alignmentPos; + *max+=_pos+_alignmentPos; + break; - case GEOMETRY: - switch(_alignment) - { - case LEFT_TOP: - _alignmentPos.set(0.0,h + descender,0.0); - break; - case LEFT_CENTER: - _alignmentPos.set(0.0,(max->y()-min->y()) /2.0 + descender,0.0); - break; - case LEFT_BOTTOM: - _alignmentPos.set(0.0,descender,0.0); - break; + case GEOMETRY: + switch(_alignment) + { + case LEFT_TOP: + _alignmentPos.set(0.0,h + descender,0.0); + break; + case LEFT_CENTER: + _alignmentPos.set(0.0,(max->y()-min->y()) /2.0 + descender,0.0); + break; + case LEFT_BOTTOM: + _alignmentPos.set(0.0,descender,0.0); + break; - case CENTER_TOP: - _alignmentPos.set(w/2.0,h + descender,0.0); - break; - case CENTER_CENTER: - _alignmentPos.set(w/2.0,(max->y()-min->y()) /2.0 + descender,0.0); - break; - case CENTER_BOTTOM: - _alignmentPos.set(w/2.0,descender,0.0); - break; + case CENTER_TOP: + _alignmentPos.set(w/2.0,h + descender,0.0); + break; + case CENTER_CENTER: + _alignmentPos.set(w/2.0,(max->y()-min->y()) /2.0 + descender,0.0); + break; + case CENTER_BOTTOM: + _alignmentPos.set(w/2.0,descender,0.0); + break; - case RIGHT_TOP: - _alignmentPos.set(w,h + descender,0.0); - break; - case RIGHT_CENTER: - _alignmentPos.set(w,(max->y()-min->y()) /2.0 + descender,0.0); - break; - case RIGHT_BOTTOM: - _alignmentPos.set(w,descender,0.0); - break; - }; - _alignmentPos=-_alignmentPos; + case RIGHT_TOP: + _alignmentPos.set(w,h + descender,0.0); + break; + case RIGHT_CENTER: + _alignmentPos.set(w,(max->y()-min->y()) /2.0 + descender,0.0); + break; + case RIGHT_BOTTOM: + _alignmentPos.set(w,descender,0.0); + break; + }; + _alignmentPos=-_alignmentPos; - *min+=_pos+_alignmentPos; - *max+=_pos+_alignmentPos; - break; - }; + *min+=_pos+_alignmentPos; + *max+=_pos+_alignmentPos; + break; + }; - + - switch(_fontType) - { - case BITMAP: - break; - case PIXMAP: - break; + switch(_fontType) + { + case BITMAP: + break; + case PIXMAP: + break; - }; + }; } void Text:: setAlignment(int alignment) { - _alignment=alignment; - - if(!_init || !_font->isCreated()) - return; + _alignment=alignment; + + if(!_init || !_font->isCreated()) + return; - initAlignment(); + initAlignment(); } void Text:: setBoundingBox(int mode) { - _boundingBoxType=mode; - - if(!_init || !_font->isCreated()) - return; + _boundingBoxType=mode; + + if(!_init || !_font->isCreated()) + return; - initAlignment(); + initAlignment(); } // Text diff --git a/src/osgUtil/Makefile b/src/osgUtil/Makefile index ca0edd40c..cf81ac32d 100644 --- a/src/osgUtil/Makefile +++ b/src/osgUtil/Makefile @@ -26,6 +26,7 @@ C++FILES = \ StateSetManipulator.cpp\ Tesselator.cpp\ TrackballManipulator.cpp\ + TransformCallback.cpp\ TriStripVisitor.cpp\ Version.cpp\ VisualsRequirementsVisitor.cpp\ @@ -68,6 +69,7 @@ TARGET_INCLUDE_FILES = \ osgUtil/StateSetManipulator\ osgUtil/Tesselator\ osgUtil/TrackballManipulator\ + osgUtil/TransformCallback\ osgUtil/TriStripVisitor\ osgUtil/Version\ osgUtil/VisualsRequirementsVisitor\ diff --git a/src/osgUtil/SceneViewManipulator.cpp b/src/osgUtil/SceneViewManipulator.cpp index b64acfb7f..602fbdc26 100644 --- a/src/osgUtil/SceneViewManipulator.cpp +++ b/src/osgUtil/SceneViewManipulator.cpp @@ -18,7 +18,7 @@ void SceneViewManipulator::setSceneView(SceneView* sv) _sv=sv; _cm->setNode(sv->getSceneData()); _cm->setCamera(sv->getCamera()); - _gm->setStateSet(sv->getGlobalState()); + _gm->setStateSet(sv->getGlobalStateSet()); } SceneView *SceneViewManipulator::getSceneView()