Checked in Macro Jez's additions to osgText to support .osg IO make it
a fully functioning NodeKit. Also reimplement notify() to try an prevent a crash which has been caused by to objects in notify.cpp being initiliazed twice, the second time the auto_ptr holding the dev/null ofstream was being initilized to 0.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<std::ofstream> g_NotifyNulStream;
|
||||
//SG_EXPORT extern std::auto_ptr<std::ofstream> 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 "<<osg::g_NotifyLevel<<" "<<osg::g_NotifyNulStream.get()<<" "<<osg::g_NotifyInit<<endl;
|
||||
// //if (osg::g_NotifyNulStream.get()==0L) abort();
|
||||
// return std::cout;
|
||||
// //return *osg::g_NotifyNulStream;
|
||||
// }
|
||||
|
||||
inline std::ostream& notify(void) { return notify(osg::INFO); }
|
||||
|
||||
|
||||
@@ -93,8 +93,6 @@ class OSGGLUT_EXPORT Viewer : public Window, public osgGA::GUIActionAdapter
|
||||
osg::DisplaySettings* getDisplaySettings() { return _displaySettings.get(); }
|
||||
const osg::DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
|
||||
|
||||
typedef std::vector<osg::ref_ptr<osgGA::CameraManipulator> > CameraManipList;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void clear();
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<const Text*>(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);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <osg/Transform>
|
||||
#include <osg/Projection>
|
||||
#include <osg/Impostor>
|
||||
#include <osg/OccluderNode>
|
||||
|
||||
#include <osgUtil/Export>
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1,120 +1,355 @@
|
||||
#include <osg/GL>
|
||||
#include <osgGLUT/glut>
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
#include <osg/Transform>
|
||||
#include <osg/Billboard>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Group>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgGA/FlightManipulator>
|
||||
#include <osgGA/DriveManipulator>
|
||||
#include <osgUtil/Optimizer>
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// 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 <osg/Geode>
|
||||
|
||||
#include <osgParticle/Particle>
|
||||
osgParticle::Particle dummy_Particle__;
|
||||
#include <osgParticle/ParticleSystem>
|
||||
#include <osgParticle/ParticleSystemUpdater>
|
||||
#include <osgParticle/ModularEmitter>
|
||||
#include <osgParticle/ModularProgram>
|
||||
#include <osgParticle/RandomRateCounter>
|
||||
#include <osgParticle/SectorPlacer>
|
||||
#include <osgParticle/RadialShooter>
|
||||
#include <osgParticle/AccelOperator>
|
||||
#include <osgParticle/FluidFrictionOperator>
|
||||
|
||||
#endif
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// 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 <<" "<<name<<" [options] infile1 [infile2 ...]"<< std::endl;
|
||||
out << std::endl;
|
||||
out <<"options:"<< std::endl;
|
||||
out <<" -l libraryName - load plugin of name libraryName"<< std::endl;
|
||||
out <<" i.e. -l osgdb_pfb"<< std::endl;
|
||||
out <<" Useful for loading reader/writers which can load"<< std::endl;
|
||||
out <<" other file formats in addition to its extension."<< std::endl;
|
||||
out <<" -e extensionName - load reader/wrter plugin for file extension"<< std::endl;
|
||||
out <<" i.e. -e pfb"<< std::endl;
|
||||
out <<" Useful short hand for specifying full library name as"<< std::endl;
|
||||
out <<" done with -l above, as it automatically expands to"<< std::endl;
|
||||
out <<" the full library name appropriate for each platform."<< std::endl;
|
||||
out <<std::endl;
|
||||
out <<" -stereo - switch on stereo rendering, using the default of,"<< std::endl;
|
||||
out <<" ANAGLYPHIC or the value set in the OSG_STEREO_MODE "<< std::endl;
|
||||
out <<" environmental variable. See doc/stereo.html for "<< std::endl;
|
||||
out <<" further details on setting up accurate stereo "<< std::endl;
|
||||
out <<" for your system. "<< std::endl;
|
||||
out <<" -stereo ANAGLYPHIC - switch on anaglyphic(red/cyan) stereo rendering."<< std::endl;
|
||||
out <<" -stereo QUAD_BUFFER - switch on quad buffered stereo rendering."<< std::endl;
|
||||
out <<std::endl;
|
||||
out <<" -stencil - use a visual with stencil buffer enabled, this "<< std::endl;
|
||||
out <<" also allows the depth complexity statistics mode"<< std::endl;
|
||||
out <<" to be used (press 'p' three times to cycle to it)."<< std::endl;
|
||||
out << std::endl;
|
||||
|
||||
// Ok folks, this is the first particle system we build; it will be
|
||||
// very simple, with no textures and no special effects, just default
|
||||
// values except for a couple of attributes.
|
||||
|
||||
// First of all, we create the ParticleSystem object; it will hold
|
||||
// our particles and expose the interface for managing them; this object
|
||||
// is a Drawable, so we'll have to add it to a Geode later.
|
||||
|
||||
osgParticle::ParticleSystem *ps = osgNew osgParticle::ParticleSystem;
|
||||
|
||||
// As for other Drawable classes, the aspect of graphical elements of
|
||||
// ParticleSystem (the particles) depends on the StateAttribute's we
|
||||
// give it. The ParticleSystem class has an helper function that let
|
||||
// us specify a set of the most common attributes: setDefaultAttributes().
|
||||
// This method can accept up to three parameters; the first is a texture
|
||||
// name (std::string), which can be empty to disable texturing, the second
|
||||
// sets whether particles have to be "emissive" (additive blending) or not;
|
||||
// the third parameter enables or disables lighting.
|
||||
|
||||
ps->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<osgParticle::RandomRateCounter *>(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<std::string> commandLine;
|
||||
for(int i=1;i<argc;++i) commandLine.push_back(argv[i]);
|
||||
|
||||
// Now we take one step we didn't before: create a particle template.
|
||||
// A particle template is simply a Particle object for which you set
|
||||
// the desired properties (see documentation for details). When the
|
||||
// particle system has to create a new particle and it's been assigned
|
||||
// a particle template, the new particle will inherit the template's
|
||||
// properties.
|
||||
// You can even assign different particle templates to each emitter; in
|
||||
// this case, the emitter's template will override the particle system's
|
||||
// default template.
|
||||
|
||||
// initialize the viewer.
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.setWindowTitle(argv[0]);
|
||||
osgParticle::Particle ptemplate;
|
||||
|
||||
// configure the viewer from the commandline arguments, and eat any
|
||||
// parameters that have been matched.
|
||||
viewer.readCommandLine(commandLine);
|
||||
|
||||
// configure the plugin registry from the commandline arguments, and
|
||||
// eat any parameters that have been matched.
|
||||
osgDB::readCommandLine(commandLine);
|
||||
ptemplate.setLifeTime(3); // 3 seconds of life
|
||||
|
||||
// load the nodes from the commandline arguments.
|
||||
osg::Node* rootnode = osgDB::readNodeFiles(commandLine);
|
||||
if (!rootnode)
|
||||
{
|
||||
// write_usage(osg::notify(osg::NOTICE),argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// run optimization over the scene graph
|
||||
osgUtil::Optimizer optimzer;
|
||||
optimzer.optimize(rootnode);
|
||||
|
||||
// add a viewport to the viewer and attach the scene graph.
|
||||
viewer.addViewport( rootnode );
|
||||
|
||||
// register trackball, flight and drive.
|
||||
viewer.registerCameraManipulator(new osgGA::TrackballManipulator);
|
||||
viewer.registerCameraManipulator(new osgGA::FlightManipulator);
|
||||
viewer.registerCameraManipulator(new osgGA::DriveManipulator);
|
||||
// the following ranges set the envelope of the respective
|
||||
// graphical properties in time.
|
||||
ptemplate.setSizeRange(osgParticle::rangef(0.75f, 3.0f));
|
||||
ptemplate.setAlphaRange(osgParticle::rangef(0.0f, 1.5f));
|
||||
ptemplate.setColorRange(osgParticle::rangev4(
|
||||
osg::Vec4(1, 0.5f, 0.3f, 1.5f),
|
||||
osg::Vec4(0, 0.7f, 1.0f, 0.0f)));
|
||||
|
||||
// open the viewer window.
|
||||
viewer.open();
|
||||
|
||||
// fire up the event loop.
|
||||
viewer.run();
|
||||
// these are physical properties of the particle
|
||||
ptemplate.setRadius(0.05f); // 5 cm wide particles
|
||||
ptemplate.setMass(0.05f); // 50 g heavy
|
||||
|
||||
return 0;
|
||||
// As usual, let's create the ParticleSystem object and set its
|
||||
// default state attributes. This time we use a texture named
|
||||
// "smoke.rgb", you can find it in the data distribution of OSG.
|
||||
// We turn off the additive blending, because smoke has no self-
|
||||
// illumination.
|
||||
osgParticle::ParticleSystem *ps = osgNew osgParticle::ParticleSystem;
|
||||
ps->setDefaultAttributes("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<36> 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;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
osg::NotifySeverity osg::g_NotifyLevel = osg::NOTICE;
|
||||
std::auto_ptr<ofstream> 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<ofstream>(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;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ DotOsgWrapper::DotOsgWrapper(osg::Object* proto,
|
||||
WriteFunc writeFunc,
|
||||
ReadWriteMode readWriteMode)
|
||||
{
|
||||
|
||||
|
||||
_prototype = proto;
|
||||
_name = name;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ CXXFILES =\
|
||||
Point.cpp\
|
||||
PolygonMode.cpp\
|
||||
PolygonOffset.cpp\
|
||||
Projection.cpp\
|
||||
ReaderWriterOSG.cpp\
|
||||
ShadeModel.cpp\
|
||||
StateSet.cpp\
|
||||
|
||||
49
src/osgPlugins/osg/Projection.cpp
Normal file
49
src/osgPlugins/osg/Projection.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <osg/Projection>
|
||||
#include <osg/Matrix>
|
||||
|
||||
#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<Projection &>(obj);
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
static Matrix s_matrix;
|
||||
|
||||
if (Matrix* tmpMatrix = static_cast<Matrix*>(fr.readObjectOfType(s_matrix)))
|
||||
{
|
||||
myobj.setMatrix(*tmpMatrix);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Projection_writeLocalData(const Object& obj, Output& fw)
|
||||
{
|
||||
const Projection& myobj = static_cast<const Projection&>(obj);
|
||||
|
||||
fw.writeObject(myobj.getMatrix());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -39,7 +39,6 @@ bool Transform_readLocalData(Object& obj, Input& fr)
|
||||
|
||||
Transform& transform = static_cast<Transform&>(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;
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
}
|
||||
|
||||
205
src/osgText/IO_Font.cpp
Normal file
205
src/osgText/IO_Font.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include <osgText/Font>
|
||||
#include <osgText/Font>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <osg/Vec3>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/Input>
|
||||
#include <osgDB/Output>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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<const osgText::Font &>(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<osgText::BitmapFont &>(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<osgText::PixmapFont &>(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<osgText::TextureFont &>(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<osgText::OutlineFont &>(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<osgText::PolygonFont &>(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;
|
||||
}
|
||||
100
src/osgText/IO_Paragraph.cpp
Normal file
100
src/osgText/IO_Paragraph.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include <osgText/Paragraph>
|
||||
#include <osgText/Font>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <osg/Vec3>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/Input>
|
||||
#include <osgDB/Output>
|
||||
|
||||
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<osgText::Paragraph &>(obj);
|
||||
bool itAdvanced = false;
|
||||
|
||||
// font
|
||||
osgText::Font *font = dynamic_cast<osgText::Font *>(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<const osgText::Paragraph &>(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;
|
||||
}
|
||||
|
||||
|
||||
128
src/osgText/IO_Text.cpp
Normal file
128
src/osgText/IO_Text.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include <osgText/Text>
|
||||
#include <osgText/Font>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/Input>
|
||||
#include <osgDB/Output>
|
||||
|
||||
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<osgText::Text &>(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<osgText::Font *>(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<const osgText::Text &>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.*/"<<std::endl;
|
||||
break;
|
||||
case(SKY_LIGHT):
|
||||
renderStage->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.*/"<<std::endl;
|
||||
break;
|
||||
case(NO_SCENEVIEW_LIGHT):
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user