diff --git a/VisualStudio/osgPlugins/osg/dot_osg.dsp b/VisualStudio/osgPlugins/osg/dot_osg.dsp index 64933c60f..e3261a4a9 100755 --- a/VisualStudio/osgPlugins/osg/dot_osg.dsp +++ b/VisualStudio/osgPlugins/osg/dot_osg.dsp @@ -210,6 +210,10 @@ SOURCE=..\..\..\src\osgPlugins\osg\PolygonOffset.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\Projection.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\ReaderWriterOSG.cpp # End Source File # Begin Source File diff --git a/VisualStudio/osgText/osgText.dsp b/VisualStudio/osgText/osgText.dsp index 48374fda9..ba7851ceb 100644 --- a/VisualStudio/osgText/osgText.dsp +++ b/VisualStudio/osgText/osgText.dsp @@ -169,6 +169,18 @@ SOURCE=..\..\src\osgText\FTVectoriser.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgText\IO_Font.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osgText\IO_Paragraph.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osgText\IO_Text.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgText\Paragraph.cpp # End Source File # Begin Source File diff --git a/include/osg/Notify b/include/osg/Notify index 72b175e45..ff007ae56 100644 --- a/include/osg/Notify +++ b/include/osg/Notify @@ -30,13 +30,13 @@ enum NotifySeverity { }; /** global notify level. */ -SG_EXPORT extern NotifySeverity g_NotifyLevel; +//SG_EXPORT extern NotifySeverity g_NotifyLevel; /** global notify nul stream. added for Mac OSX */ -SG_EXPORT extern std::auto_ptr g_NotifyNulStream; +//SG_EXPORT extern std::auto_ptr g_NotifyNulStream; /** global notify nul stream. added for Mac OSX */ -SG_EXPORT extern bool g_NotifyInit; +//SG_EXPORT extern bool g_NotifyInit; /** set the notify level, overriding the default or value set by * the environmental variable OSGNOTIFYLEVEL. @@ -69,17 +69,21 @@ SG_EXPORT extern bool initNotifyLevel(); // previous implementation was causing Mac OSX to misbehave. This version // places less stress on compiler and runs on Mac -inline std::ostream& notify(const NotifySeverity severity) -{ - if (!g_NotifyInit) initNotifyLevel(); - - if (severity<=g_NotifyLevel) - { - if (severity<=osg::WARN) return std::cerr; - else return std::cout; - } - return *osg::g_NotifyNulStream; -} +SG_EXPORT extern std::ostream& notify(const NotifySeverity severity); +// { +// static bool initilized = false; +// if (!initilized) initilized = initNotifyLevel(); +// +// if (severity<=g_NotifyLevel) +// { +// if (severity<=osg::WARN) return std::cerr; +// else return std::cout; +// } +// cout << "doing a notify to null stream "< > CameraManipList; - protected: virtual void clear(); diff --git a/include/osgText/Font b/include/osgText/Font index 05aa4b52f..4f8ee95f7 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -85,7 +85,10 @@ class OSGTEXT_EXPORT Font : public osg::Object int getPointSize(void) const { return _pointSize; } int getTextureSize(void) const { return _textureSize; } - const std::string& getFontName(); + const std::string& getFontName() const { return _fontName; } + + /// Transfer font settings to another Font object and invalidate this one. + void copyAndInvalidate(Font &dest); FTFont* getFont(void) { return _font; } diff --git a/include/osgText/Paragraph b/include/osgText/Paragraph index 56c18b3be..af7366dfd 100644 --- a/include/osgText/Paragraph +++ b/include/osgText/Paragraph @@ -36,7 +36,7 @@ class OSGTEXT_EXPORT Paragraph : public osg::Geode const osg::Vec3& getPosition() const { return _position; } void setAlignment(int alignment); - int getAlignment() { return _alignment; } + int getAlignment() const { return _alignment; } float getHeight() const; diff --git a/include/osgText/Text b/include/osgText/Text index b28d09e8b..345da1407 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -72,6 +72,7 @@ class OSGTEXT_EXPORT Text : public osg::Drawable virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Text(*this,copyop); } virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* className() const { return "Text"; } + virtual const char* libraryName() const { return "osgText"; } void setPosition(const osg::Vec2& pos); void setPosition(const osg::Vec3& pos); diff --git a/include/osgUtil/AppVisitor b/include/osgUtil/AppVisitor index 58559f798..a26b025a8 100644 --- a/include/osgUtil/AppVisitor +++ b/include/osgUtil/AppVisitor @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -34,18 +35,19 @@ class OSGUTIL_EXPORT AppVisitor : public osg::NodeVisitor virtual void reset(); - virtual void apply(osg::Node& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::Node& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Geode& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Billboard& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::LightSource& node){ handle_callbacks_and_traverse(node); } + virtual void apply(osg::Geode& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::Billboard& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::LightSource& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Group& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Transform& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Projection& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Switch& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::LOD& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Impostor& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::Group& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::Transform& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::Projection& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::Switch& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::LOD& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::Impostor& node) { handle_callbacks_and_traverse(node); } + virtual void apply(osg::OccluderNode& node) { handle_callbacks_and_traverse(node); } protected: diff --git a/src/Demos/osgparticle/osgparticle.cpp b/src/Demos/osgparticle/osgparticle.cpp index ab546c6ec..5ebe10ea4 100644 --- a/src/Demos/osgparticle/osgparticle.cpp +++ b/src/Demos/osgparticle/osgparticle.cpp @@ -1,120 +1,355 @@ -#include -#include -#include - -#include -#include -#include #include -#include - -#include -#include - -#include -#include -#include -#include - -// ---------------------------------------------------------------------------------- -// These lines are necessary under Windows because if we don't instantiate at least -// one object of osgParticle, the library will not be linked to the exe even if we -// add it to the dependancies list, leading to failure when importing .osg files. - -#ifdef WIN32 +#include #include -osgParticle::Particle dummy_Particle__; +#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif +#include -// ---------------------------------------------------------------------------------- +////////////////////////////////////////////////////////////////////////////// +// CUSTOM OPERATOR CLASS +////////////////////////////////////////////////////////////////////////////// -void write_usage(std::ostream& out,const std::string& name) +// This class demonstrates Operator subclassing. This way you can create +// custom operators to apply your motion effects to the particles. See docs +// for more details. +class VortexOperator: public osgParticle::Operator { +public: + VortexOperator() + : osgParticle::Operator(), center_(0, 0, 0), axis_(0, 0, 1), intensity_(0.1f) {} + + VortexOperator(const VortexOperator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY) + : Operator(copy, copyop), center_(copy.center_), axis_(copy.axis_), intensity_(copy.intensity_) {} + + META_Object(osgParticle, VortexOperator); + + void setCenter(const osg::Vec3 &c) + { + center_ = c; + } + + void setAxis(const osg::Vec3 &a) + { + axis_ = a / a.length(); + } + + // this method is called by ModularProgram before applying + // operators on the particle set via the operate() method. + void beginOperate(osgParticle::Program *prg) + { + // we have to check whether the reference frame is relative to parents + // or it's absolute; in the first case, we must transform the vectors + // from local to world space. + if (prg->getReferenceFrame() == osgParticle::Program::RELATIVE_TO_PARENTS) { + // transform the center point (full transformation) + xf_center_ = prg->transformLocalToWorld(center_); + // transform the axis vector (only rotation and scale) + xf_axis_ = prg->rotateLocalToWorld(axis_); + } else { + xf_center_ = center_; + xf_axis_ = axis_; + } + } + + // apply a vortex-like acceleration. This code is not optimized, + // it's here only for demonstration purposes. + void operate(osgParticle::Particle *P, double dt) + { + float l = xf_axis_ * (P->getPosition() - xf_center_); + osg::Vec3 lc = xf_center_ + xf_axis_ * l; + osg::Vec3 R = P->getPosition() - lc; + osg::Vec3 v = (R ^ xf_axis_) * P->getMassInv() * intensity_; + + // compute new position + osg::Vec3 newpos = P->getPosition() + v * dt; + + // update the position of the particle without modifying its + // velocity vector (this is unusual, normally you should call + // the Particle::setVelocity() or Particle::addVelocity() + // methods). + P->setPosition(newpos); + } + +protected: + virtual ~VortexOperator() {} + +private: + osg::Vec3 center_; + osg::Vec3 xf_center_; + osg::Vec3 axis_; + osg::Vec3 xf_axis_; + float intensity_; +}; + + +////////////////////////////////////////////////////////////////////////////// +// SIMPLE PARTICLE SYSTEM CREATION +////////////////////////////////////////////////////////////////////////////// + + +osgParticle::ParticleSystem *create_simple_particle_system(osg::Group *root) { - out << std::endl; - out <<"usage:"<< std::endl; - out <<" "<setDefaultAttributes("", true, false); + + // Now that our particle system is set we have to create an emitter, that is + // an object (actually a Node descendant) that generate new particles at + // each frame. The best choice is to use a ModularEmitter, which allow us to + // achieve a wide variety of emitting styles by composing the emitter using + // three objects: a "counter", a "placer" and a "shooter". The counter must + // tell the ModularEmitter how many particles it has to create for the + // current frame; then, the ModularEmitter creates these particles, and for + // each new particle it instructs the placer and the shooter to set its + // position vector and its velocity vector, respectively. + // By default, a ModularEmitter object initializes itself with a counter of + // type RandomRateCounter, a placer of type PointPlacer and a shooter of + // type RadialShooter (see documentation for details). We are going to leave + // these default objects there, but we'll modify the counter so that it + // counts faster (more particles are emitted at each frame). + + osgParticle::ModularEmitter *emitter = osgNew osgParticle::ModularEmitter; + + // the first thing you *MUST* do after creating an emitter is to set the + // destination particle system, otherwise it won't know where to create + // new particles. + + emitter->setParticleSystem(ps); + + // Ok, get a pointer to the emitter's Counter object. We could also + // create a new RandomRateCounter object and assign it to the emitter, + // but since the default counter is already a RandomRateCounter, we + // just get a pointer to it and change a value. + + osgParticle::RandomRateCounter *rrc = + static_cast(emitter->getCounter()); + + // Now set the rate range to a better value. The actual rate at each frame + // will be chosen randomly within that range. + + rrc->setRateRange(20, 30); // generate 20 to 30 particles per second + + // The emitter is done! Let's add it to the scene graph. The cool thing is + // that any emitter node will take into account the accumulated local-to-world + // matrix, so you can attach an emitter to a transform node and see it move. + + root->addChild(emitter); + + // Ok folks, we have almost finished. We don't add any particle modifier + // here (see ModularProgram and Operator classes), so all we still need is + // to create a Geode and add the particle system to it, so it can be + // displayed. + + osg::Geode *geode = osgNew osg::Geode; + geode->addDrawable(ps); + + // add the geode to the scene graph + root->addChild(geode); + + return ps; + } -int main( int argc, char **argv ) + +////////////////////////////////////////////////////////////////////////////// +// COMPLEX PARTICLE SYSTEM CREATION +////////////////////////////////////////////////////////////////////////////// + + +osgParticle::ParticleSystem *create_complex_particle_system(osg::Group *root) { - // initialize the GLUT - glutInit( &argc, argv ); + // Are you ready for a more complex particle system? Well, read on! - if (argc<2) - { - write_usage(std::cout,argv[0]); - return 0; - } - - // create the commandline args. - std::vector commandLine; - for(int i=1;isetDefaultAttributes("smoke.rgb", false, false); + + // assign the particle template to the system. + ps->setDefaultParticleTemplate(ptemplate); + + // now we have to create an emitter; this will be a ModularEmitter, for which + // we define a RandomRateCounter as counter, a SectorPlacer as placer, and + // a RadialShooter as shooter. + osgParticle::ModularEmitter *emitter = osgNew osgParticle::ModularEmitter; + emitter->setParticleSystem(ps); + + // setup the counter + osgParticle::RandomRateCounter *counter = osgNew osgParticle::RandomRateCounter; + counter->setRateRange(60, 60); + emitter->setCounter(counter); + + // setup the placer; it will be a circle of radius 5 (the particles will + // be placed inside this circle). + osgParticle::SectorPlacer *placer = osgNew osgParticle::SectorPlacer; + placer->setCenter(8, 0, 10); + placer->setRadiusRange(2.5, 5); + placer->setPhiRange(0, 2 * osg::PI); // 360° angle to make a circle + emitter->setPlacer(placer); + + // now let's setup the shooter; we use a RadialShooter but we set the + // initial speed to zero, because we want the particles to fall down + // only under the effect of the gravity force. Since we se the speed + // to zero, there is no need to setup the shooting angles. + osgParticle::RadialShooter *shooter = osgNew osgParticle::RadialShooter; + shooter->setInitialSpeedRange(0, 0); + emitter->setShooter(shooter); + + // add the emitter to the scene graph + root->addChild(emitter); + + // WELL, we got our particle system and a nice emitter. Now we want to + // simulate the effect of the earth gravity, so first of all we have to + // create a Program. It is a particle processor just like the Emitter + // class, but it allows to modify particle properties *after* they have + // been created. + // The ModularProgram class can be thought as a sequence of operators, + // each one performing some actions on the particles. So, the trick is: + // create the ModularProgram object, create one or more Operator objects, + // add those operators to the ModularProgram, and finally add the + // ModularProgram object to the scene graph. + // NOTE: since the Program objects perform actions after the particles + // have been emitted by one or more Emitter objects, all instances of + // Program (and its descendants) should be placed *after* the instances + // of Emitter objects in the scene graph. + + osgParticle::ModularProgram *program = osgNew osgParticle::ModularProgram; + program->setParticleSystem(ps); + + // create an operator that simulates the gravity acceleration. + osgParticle::AccelOperator *op1 = osgNew osgParticle::AccelOperator; + op1->setToGravity(); + program->addOperator(op1); + + // now create a custom operator, we have defined it before (see + // class VortexOperator). + VortexOperator *op2 = osgNew VortexOperator; + op2->setCenter(osg::Vec3(8, 0, 0)); + program->addOperator(op2); + + // let's add a fluid operator to simulate air friction. + osgParticle::FluidFrictionOperator *op3 = osgNew osgParticle::FluidFrictionOperator; + op3->setFluidToAir(); + program->addOperator(op3); + + // add the program to the scene graph + root->addChild(program); + + // create a Geode to contain our particle system. + osg::Geode *geode = osgNew osg::Geode; + geode->addDrawable(ps); + + // add the geode to the scene graph. + root->addChild(geode); + + return ps; +} + + +////////////////////////////////////////////////////////////////////////////// +// MAIN SCENE GRAPH BUILDING FUNCTION +////////////////////////////////////////////////////////////////////////////// + + +void build_world(osg::Group *root) +{ + + // In this function we are going to create two particle systems; + // the first one will be very simple, based mostly on default properties; + // the second one will be a little bit more complex, showing how to + // create custom operators. + // To avoid inserting too much code in a single function, we have + // splitted the work into two functions which accept a Group node as + // parameter, and return a pointer to the particle system they created. + + osgParticle::ParticleSystem *ps1 = create_simple_particle_system(root); + osgParticle::ParticleSystem *ps2 = create_complex_particle_system(root); + + // Now that the particle systems and all other related objects have been + // created, we have to add an "updater" node to the scene graph. This node + // will react to cull traversal by updating the specified particles system. + + osgParticle::ParticleSystemUpdater *psu = osgNew osgParticle::ParticleSystemUpdater; + psu->addParticleSystem(ps1); + psu->addParticleSystem(ps2); + + // add the updater node to the scene graph + root->addChild(psu); + +} + + +////////////////////////////////////////////////////////////////////////////// +// main() +////////////////////////////////////////////////////////////////////////////// + + +int main() +{ + osgGLUT::Viewer viewer; + + osg::Group *root = osgNew osg::Group; + build_world(root); + + viewer.addViewport(root); + viewer.open(); + viewer.run(); + + return 0; } diff --git a/src/osg/Notify.cpp b/src/osg/Notify.cpp index 9d8845e78..87b1d8728 100644 --- a/src/osg/Notify.cpp +++ b/src/osg/Notify.cpp @@ -3,9 +3,7 @@ using namespace std; -osg::NotifySeverity osg::g_NotifyLevel = osg::NOTICE; -std::auto_ptr osg::g_NotifyNulStream; -bool osg::g_NotifyInit = false; +osg::NotifySeverity g_NotifyLevel = osg::NOTICE; void osg::setNotifyLevel(osg::NotifySeverity severity) { @@ -23,16 +21,11 @@ osg::NotifySeverity osg::getNotifyLevel() bool osg::initNotifyLevel() { - if (g_NotifyInit) return true; - - g_NotifyInit = true; + static bool s_NotifyInit = false; - // set up global notify null stream for inline notify -#if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW32__)) - g_NotifyNulStream = std::auto_ptr(osgNew std::ofstream ("nul")); -#else - g_NotifyNulStream.reset(osgNew std::ofstream ("/dev/null")); -#endif + if (s_NotifyInit) return true; + + s_NotifyInit = true; // g_NotifyLevel // ============= @@ -68,3 +61,23 @@ bool osg::initNotifyLevel() return true; } + +std::ostream& osg::notify(const osg::NotifySeverity severity) +{ + // set up global notify null stream for inline notify +#if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW32__)) + static std::ofstream s_NotifyNulStream("nul"); +#else + static std::ofstream s_NotifyNulStream("/dev/null"); +#endif + + static bool initialized = osg::initNotifyLevel(); + initialized=initialized; // statement with no effect to stop GCC warning. + + if (severity<=g_NotifyLevel) + { + if (severity<=osg::WARN) return std::cerr; + else return std::cout; + } + return s_NotifyNulStream; +} diff --git a/src/osgDB/DotOsgWrapper.cpp b/src/osgDB/DotOsgWrapper.cpp index addf1b76e..24478cbac 100644 --- a/src/osgDB/DotOsgWrapper.cpp +++ b/src/osgDB/DotOsgWrapper.cpp @@ -9,6 +9,8 @@ DotOsgWrapper::DotOsgWrapper(osg::Object* proto, WriteFunc writeFunc, ReadWriteMode readWriteMode) { + + _prototype = proto; _name = name; diff --git a/src/osgPlugins/osg/Makefile b/src/osgPlugins/osg/Makefile index 3fe88a285..b72ecf23f 100644 --- a/src/osgPlugins/osg/Makefile +++ b/src/osgPlugins/osg/Makefile @@ -31,6 +31,7 @@ CXXFILES =\ Point.cpp\ PolygonMode.cpp\ PolygonOffset.cpp\ + Projection.cpp\ ReaderWriterOSG.cpp\ ShadeModel.cpp\ StateSet.cpp\ diff --git a/src/osgPlugins/osg/Projection.cpp b/src/osgPlugins/osg/Projection.cpp new file mode 100644 index 000000000..6e92286bc --- /dev/null +++ b/src/osgPlugins/osg/Projection.cpp @@ -0,0 +1,49 @@ +#include +#include + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" + +using namespace osg; +using namespace osgDB; + +// forward declare functions to use later. +bool Projection_readLocalData(Object& obj, Input& fr); +bool Projection_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_ProjectionProxy +( + osgNew osg::Projection, + "Projection", + "Object Node Group Projection", + &Projection_readLocalData, + &Projection_writeLocalData +); + +bool Projection_readLocalData(Object& obj, Input& fr) +{ + Projection &myobj = static_cast(obj); + bool iteratorAdvanced = false; + + static Matrix s_matrix; + + if (Matrix* tmpMatrix = static_cast(fr.readObjectOfType(s_matrix))) + { + myobj.setMatrix(*tmpMatrix); + iteratorAdvanced = true; + } + + return iteratorAdvanced; +} + + +bool Projection_writeLocalData(const Object& obj, Output& fw) +{ + const Projection& myobj = static_cast(obj); + + fw.writeObject(myobj.getMatrix()); + + return true; +} diff --git a/src/osgPlugins/osg/Transform.cpp b/src/osgPlugins/osg/Transform.cpp index a1b0657e0..0105a4923 100644 --- a/src/osgPlugins/osg/Transform.cpp +++ b/src/osgPlugins/osg/Transform.cpp @@ -39,7 +39,6 @@ bool Transform_readLocalData(Object& obj, Input& fr) Transform& transform = static_cast(obj); - if (fr[0].matchWord("Type")) { if (fr[1].matchWord("DYNAMIC")) @@ -69,6 +68,19 @@ bool Transform_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } + if (fr[0].matchWord("referenceFrame")) { + if (fr[1].matchWord("RELATIVE_TO_ABSOLUTE")) { + transform.setReferenceFrame(Transform::RELATIVE_TO_ABSOLUTE); + fr += 2; + iteratorAdvanced = true; + } + if (fr[1].matchWord("RELATIVE_TO_PARENTS")) { + transform.setReferenceFrame(Transform::RELATIVE_TO_PARENTS); + fr += 2; + iteratorAdvanced = true; + } + } + return iteratorAdvanced; } @@ -79,5 +91,15 @@ bool Transform_writeLocalData(const Object& obj, Output& fw) fw.writeObject(transform.getMatrix()); + fw.indent() << "referenceFrame "; + switch (transform.getReferenceFrame()) { + case Transform::RELATIVE_TO_ABSOLUTE: + fw << "RELATIVE_TO_ABSOLUTE\n"; + break; + case Transform::RELATIVE_TO_PARENTS: + default: + fw << "RELATIVE_TO_PARENTS\n"; + }; + return true; } diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index ff9190614..abc6b5121 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -77,7 +77,7 @@ Font() _created=false; _pointSize=14; - _textureSize=0; + _textureSize=0; _res=72; } @@ -101,6 +101,27 @@ Font:: clear(); } +void Font::copyAndInvalidate(Font &dest) +{ + // delete destination's font object + delete dest._font; + + // copy local data to destination object + dest._init = _init; + dest._created = _created; + dest._font = _font; + dest._fontName = _fontName; + dest._pointSize = _pointSize; + dest._res = _res; + dest._textureSize = _textureSize; + + // invalidate this object + _init = false; + _created = false; + _font = 0; + _fontName = std::string(); +} + bool Font:: open(const std::string& font) { @@ -269,7 +290,7 @@ TextureFont(const std::string& font, int point_size): RasterFont(font) { - _textureSize=0; + _textureSize=0; if(init(font)) { } @@ -280,10 +301,10 @@ RasterFont(font) TextureFont:: TextureFont(const std::string& font, int point_size, - int textureSize ): + int textureSize ): RasterFont(font) { - _textureSize=textureSize; + _textureSize=textureSize; if(init(font)) { } diff --git a/src/osgText/IO_Font.cpp b/src/osgText/IO_Font.cpp new file mode 100644 index 000000000..d46e59631 --- /dev/null +++ b/src/osgText/IO_Font.cpp @@ -0,0 +1,205 @@ +#include +#include + +#include +#include + +#include + +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// class Font +///////////////////////////////////////////////////////////////////////////// + +bool Font_writeLocalData(const osg::Object &obj, osgDB::Output &fw); + +osgDB::RegisterDotOsgWrapperProxy Font_Proxy +( + 0, + "Font", + "Object Font", + 0, + Font_writeLocalData +); + +bool Font_writeLocalData(const osg::Object &obj, osgDB::Output &fw) +{ + const osgText::Font &myobj = static_cast(obj); + + fw.indent() << "parameters "; + fw << myobj.getPointSize() << " " << myobj.getTextureSize() << " "; + fw << "\"" << myobj.getFontName() << "\"" << std::endl; + + return true; +} + + +///////////////////////////////////////////////////////////////////////////// +// class BitmapFont +///////////////////////////////////////////////////////////////////////////// + +bool BitmapFont_readLocalData(osg::Object &obj, osgDB::Input &fr); + +osgDB::RegisterDotOsgWrapperProxy BitmapFont_Proxy +( + osgNew osgText::BitmapFont, + "BitmapFont", + "Object Font RasterFont BitmapFont", + BitmapFont_readLocalData, + 0 +); + +bool BitmapFont_readLocalData(osg::Object &obj, osgDB::Input &fr) +{ + osgText::BitmapFont &myobj = static_cast(obj); + bool itAdvanced = false; + + if (fr[0].matchWord("parameters")) { + int psize; + if (fr[1].getInt(psize) && fr[2].isInt() && fr[3].isString()) { + osgText::BitmapFont *temp = new osgText::BitmapFont(std::string(fr[3].getStr()), psize); + temp->copyAndInvalidate(myobj); + fr += 4; + itAdvanced = true; + } + } + + return itAdvanced; +} + + +///////////////////////////////////////////////////////////////////////////// +// class PixmapFont +///////////////////////////////////////////////////////////////////////////// + +bool PixmapFont_readLocalData(osg::Object &obj, osgDB::Input &fr); + +osgDB::RegisterDotOsgWrapperProxy PixmapFont_Proxy +( + osgNew osgText::PixmapFont, + "PixmapFont", + "Object Font RasterFont PixmapFont", + PixmapFont_readLocalData, + 0 +); + +bool PixmapFont_readLocalData(osg::Object &obj, osgDB::Input &fr) +{ + osgText::PixmapFont &myobj = static_cast(obj); + bool itAdvanced = false; + + if (fr[0].matchWord("parameters")) { + int psize; + if (fr[1].getInt(psize) && fr[2].isInt() && fr[3].isString()) { + osgText::PixmapFont *temp = new osgText::PixmapFont(std::string(fr[3].getStr()), psize); + temp->copyAndInvalidate(myobj); + fr += 4; + itAdvanced = true; + } + } + + return itAdvanced; +} + +///////////////////////////////////////////////////////////////////////////// +// class TextureFont +///////////////////////////////////////////////////////////////////////////// + +bool TextureFont_readLocalData(osg::Object &obj, osgDB::Input &fr); + +osgDB::RegisterDotOsgWrapperProxy TextureFont_Proxy +( + osgNew osgText::TextureFont, + "TextureFont", + "Object Font RasterFont TextureFont", + TextureFont_readLocalData, + 0 +); + +bool TextureFont_readLocalData(osg::Object &obj, osgDB::Input &fr) +{ + osgText::TextureFont &myobj = static_cast(obj); + bool itAdvanced = false; + + if (fr[0].matchWord("parameters")) { + int psize, txsize; + if (fr[1].getInt(psize) && fr[2].getInt(txsize) && fr[3].isString()) { + osgText::TextureFont *temp = new osgText::TextureFont(std::string(fr[3].getStr()), psize, txsize); + temp->copyAndInvalidate(myobj); + fr += 4; + itAdvanced = true; + } + } + + return itAdvanced; +} + + +///////////////////////////////////////////////////////////////////////////// +// class OutlineFont +///////////////////////////////////////////////////////////////////////////// + +bool OutlineFont_readLocalData(osg::Object &obj, osgDB::Input &fr); + +osgDB::RegisterDotOsgWrapperProxy OutlineFont_Proxy +( + osgNew osgText::OutlineFont, + "OutlineFont", + "Object Font VectorFont OutlineFont", + OutlineFont_readLocalData, + 0 +); + +bool OutlineFont_readLocalData(osg::Object &obj, osgDB::Input &fr) +{ + osgText::OutlineFont &myobj = static_cast(obj); + bool itAdvanced = false; + + if (fr[0].matchWord("parameters")) { + int psize; + if (fr[1].getInt(psize) && fr[2].isInt() && fr[3].isString()) { + osgText::OutlineFont *temp = new osgText::OutlineFont(std::string(fr[3].getStr()), psize, 1); + temp->copyAndInvalidate(myobj); + fr += 4; + itAdvanced = true; + } + } + + return itAdvanced; +} + +///////////////////////////////////////////////////////////////////////////// +// class PolygonFont +///////////////////////////////////////////////////////////////////////////// + +bool PolygonFont_readLocalData(osg::Object &obj, osgDB::Input &fr); + +osgDB::RegisterDotOsgWrapperProxy PolygonFont_Proxy +( + osgNew osgText::PolygonFont, + "PolygonFont", + "Object Font VectorFont PolygonFont", + PolygonFont_readLocalData, + 0 +); + +bool PolygonFont_readLocalData(osg::Object &obj, osgDB::Input &fr) +{ + osgText::PolygonFont &myobj = static_cast(obj); + bool itAdvanced = false; + + if (fr[0].matchWord("parameters")) { + int psize; + if (fr[1].getInt(psize) && fr[2].isInt() && fr[3].isString()) { + osgText::PolygonFont *temp = new osgText::PolygonFont(std::string(fr[3].getStr()), psize, 1); + temp->copyAndInvalidate(myobj); + fr += 4; + itAdvanced = true; + } + } + + return itAdvanced; +} diff --git a/src/osgText/IO_Paragraph.cpp b/src/osgText/IO_Paragraph.cpp new file mode 100644 index 000000000..2d133c307 --- /dev/null +++ b/src/osgText/IO_Paragraph.cpp @@ -0,0 +1,100 @@ +#include +#include + +#include +#include + +#include + +#include +#include +#include + +bool Paragraph_readLocalData(osg::Object &obj, osgDB::Input &fr); +bool Paragraph_writeLocalData(const osg::Object &obj, osgDB::Output &fw); + +// osgDB::RegisterDotOsgWrapperProxy Paragraph_Proxy +// ( +// osgNew osgText::Paragraph, +// "Paragraph", +// "Object Node Geode Paragraph", +// Paragraph_readLocalData, +// Paragraph_writeLocalData +// ); +// +bool Paragraph_readLocalData(osg::Object &obj, osgDB::Input &fr) +{ + osgText::Paragraph &myobj = static_cast(obj); + bool itAdvanced = false; + + // font + osgText::Font *font = dynamic_cast(fr.readObject()); + if (font) { + myobj.setFont(font); + itAdvanced = true; + } + + // maximum chars + if (fr[0].matchWord("maximumNoCharactersPerLine")) { + int i; + if (fr[1].getInt(i)) { + myobj.setMaximumNoCharactersPerLine(i); + fr += 2; + itAdvanced = true; + } + } + + // text + if (fr[0].matchWord("text") && fr[1].isString()) { + myobj.setText(std::string(fr[1].getStr())); + fr += 2; + itAdvanced = true; + } + + // position + if (fr[0].matchWord("position")) { + osg::Vec3 p; + if (fr[1].getFloat(p.x()) && fr[2].getFloat(p.y()) && fr[3].getFloat(p.z())) { + myobj.setPosition(p); + fr += 4; + itAdvanced = true; + } + } + + // alignment + if (fr[0].matchWord("alignment")) { + int i; + if (fr[1].getInt(i)) { + myobj.setAlignment(i); + fr += 2; + itAdvanced = true; + } + } + + return itAdvanced; +} + +bool Paragraph_writeLocalData(const osg::Object &obj, osgDB::Output &fw) +{ + const osgText::Paragraph &myobj = static_cast(obj); + + // font + fw.writeObject(*myobj.getFont()); + + // maximum chars + fw.indent() << "maximumNoCharactersPerLine " << myobj.getMaximumNoCharactersPerLine() << std::endl; + + // text + fw.indent() << "text " << myobj.getText() << std::endl; + + // position + osg::Vec3 p = myobj.getPosition(); + fw.indent() << "position " << p.x() << " " << p.y() << " " << p.z() << std::endl; + + // alignment + fw.indent() << "alignment " << myobj.getAlignment() << std::endl; + + return true; +} + + diff --git a/src/osgText/IO_Text.cpp b/src/osgText/IO_Text.cpp new file mode 100644 index 000000000..2b32b6b92 --- /dev/null +++ b/src/osgText/IO_Text.cpp @@ -0,0 +1,128 @@ +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr); +bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw); + +osgDB::RegisterDotOsgWrapperProxy Text_Proxy +( + osgNew osgText::Text, + "Text", + "Object Drawable Text", + Text_readLocalData, + Text_writeLocalData +); + +bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) +{ + osgText::Text &myobj = static_cast(obj); + bool itAdvanced = false; + + // position + if (fr[0].matchWord("position")) { + osg::Vec3 p; + if (fr[1].getFloat(p.x()) && fr[2].getFloat(p.y()) && fr[3].getFloat(p.z())) { + myobj.setPosition(p); + fr += 4; + itAdvanced = true; + } + } + + // color + if (fr[0].matchWord("color")) { + osg::Vec4 c; + if (fr[1].getFloat(c.x()) && fr[2].getFloat(c.y()) && fr[3].getFloat(c.z()) && fr[4].getFloat(c.w())) { + myobj.setColor(c); + fr += 4; + itAdvanced = true; + } + } + + // draw mode + if (fr[0].matchWord("drawMode")) { + int i; + if (fr[1].getInt(i)) { + myobj.setDrawMode(i); + fr += 2; + itAdvanced = true; + } + } + + // bounding box + if (fr[0].matchWord("boundingBox")) { + int i; + if (fr[1].getInt(i)) { + myobj.setBoundingBox(i); + fr += 2; + itAdvanced = true; + } + } + + // alignment + if (fr[0].matchWord("alignment")) { + int i; + if (fr[1].getInt(i)) { + myobj.setAlignment(i); + fr += 2; + itAdvanced = true; + } + } + + // font + osgText::Font *font = dynamic_cast(fr.readObject()); + if (font) { + myobj.setFont(font); + itAdvanced = true; + } + + // text + if (fr.matchSequence("text %s")) { + myobj.setText(std::string(fr[1].getStr())); + fr += 2; + itAdvanced = true; + } + + return itAdvanced; +} + +bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) +{ + const osgText::Text &myobj = static_cast(obj); + + // position + osg::Vec3 p = myobj.getPosition(); + fw.indent() << "position " << p.x() << " " << p.y() << " " << p.z() << std::endl; + + // color + osg::Vec4 c = myobj.getColor(); + fw.indent() << "color " << c.x() << " " << c.y() << " " << c.z() << " " << c.w() << std::endl; + + // draw mode + fw.indent() << "drawMode " << myobj.getDrawMode() << std::endl; + + // bounding box + fw.indent() << "boundingBox " << myobj.getBoundingBox() << std::endl; + + // alignment + fw.indent() << "alignment " << myobj.getAlignment() << std::endl; + + // font + fw.writeObject(*myobj.getFont()); + + // text + fw.indent() << "text \"" << myobj.getText() << "\"" << std::endl; + + return true; +} + + diff --git a/src/osgText/Makefile b/src/osgText/Makefile index 1168d1fff..86a77c332 100644 --- a/src/osgText/Makefile +++ b/src/osgText/Makefile @@ -23,8 +23,13 @@ CXXFILES =\ Font.cpp \ Paragraph.cpp \ Text.cpp \ + IO_Text.cpp \ + IO_Font.cpp \ + IO_Paragraph.cpp \ Version.cpp + + LIBS += $(OSG_LIBS) $(FREETYPE_LIB) $(OTHER_LIBS) INC += -I$(OSGHOME)/include \ diff --git a/src/osgText/Paragraph.cpp b/src/osgText/Paragraph.cpp index 1211abd88..c6935ffca 100644 --- a/src/osgText/Paragraph.cpp +++ b/src/osgText/Paragraph.cpp @@ -3,6 +3,7 @@ using namespace osgText; Paragraph::Paragraph() +: osg::Geode() { _alignment = osgText::Text::LEFT_TOP; _maxCharsPerLine = 80; @@ -19,6 +20,7 @@ Paragraph::Paragraph(const Paragraph& paragraph,const osg::CopyOp& copyop): } Paragraph::Paragraph(const osg::Vec3& position,const std::string& text,osgText::Font* font) +: osg::Geode() { _maxCharsPerLine = 80; _position = position; diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index dd6831608..9fc0cee18 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -370,10 +370,12 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil switch(_lightingMode) { case(HEADLIGHT): - renderStage->addPositionedAttribute(NULL,_light.get()); + if (_light.valid()) renderStage->addPositionedAttribute(NULL,_light.get()); + else osg::notify(osg::WARN)<<"Warning: no osg::Light attached to ogUtil::SceneView to provide head light.*/"<addPositionedAttribute(modelview,_light.get()); + if (_light.valid()) renderStage->addPositionedAttribute(modelview,_light.get()); + else osg::notify(osg::WARN)<<"Warning: no osg::Light attached to ogUtil::SceneView to provide sky light.*/"<