Added a bunch of files synched with 0.8.42
@@ -1,29 +1,32 @@
|
||||
#!smake
|
||||
SHELL=/bin/sh
|
||||
|
||||
DIRS = sgv cube
|
||||
DIRS = sgv osgconv osgcube osgreflect osgtexture osgimpostor osgviews hangglide
|
||||
|
||||
all :
|
||||
for f in $(DIRS) ; do cd $$f; make ; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) || exit 1; cd ..; done
|
||||
|
||||
clean :
|
||||
for f in $(DIRS) ; do cd $$f; make clean; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) clean; cd ..; done
|
||||
|
||||
clobber :
|
||||
for f in $(DIRS) ; do cd $$f; make clobber; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) clobber; cd ..; done
|
||||
|
||||
depend :
|
||||
for f in $(DIRS) ; do cd $$f; make depend; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) depend; cd ..; done
|
||||
|
||||
to_unix :
|
||||
for f in $(DIRS) ; do cd $$f; to_unix Makefile Makefile; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; make to_unix; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE)to_unix; cd ..; done
|
||||
|
||||
beautify :
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE)beautify; cd ..; done
|
||||
|
||||
install :
|
||||
for f in $(DIRS) ; do cd $$f; make install; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) install; cd ..; done
|
||||
|
||||
instlinks :
|
||||
for f in $(DIRS) ; do cd $$f; make instlinks; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) instlinks; cd ..; done
|
||||
|
||||
instclean :
|
||||
for f in $(DIRS) ; do cd $$f; make instclean; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) instclean; cd ..; done
|
||||
|
||||
229
src/Demos/hangglide/GliderManipulator.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
#include <osg/Notify>
|
||||
#include <osg/Types>
|
||||
|
||||
#include "GliderManipulator.h"
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgUtil;
|
||||
|
||||
GliderManipulator::GliderManipulator()
|
||||
{
|
||||
_modelScale = 0.01f;
|
||||
_velocity = 0.0f;
|
||||
_yawMode = YAW_AUTOMATICALLY_WHEN_BANKED;
|
||||
}
|
||||
|
||||
|
||||
GliderManipulator::~GliderManipulator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GliderManipulator::setNode(osg::Node* node)
|
||||
{
|
||||
_node = node;
|
||||
if (_node.get())
|
||||
{
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
_modelScale = boundingSphere._radius;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const osg::Node* GliderManipulator::getNode() const
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
|
||||
void GliderManipulator::home(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
if(_node.get() && _camera.get())
|
||||
{
|
||||
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
|
||||
osg::Vec3 eye = boundingSphere._center+osg::Vec3(-boundingSphere._radius*0.15f,-boundingSphere._radius*0.15f,-boundingSphere._radius*0.03f);
|
||||
|
||||
_camera->setView(eye,
|
||||
eye+osg::Vec3(1.0f,1.0f,-0.1f),
|
||||
osg::Vec3(0.0f,0.0f,1.0f));
|
||||
|
||||
_velocity = boundingSphere._radius*0.01f;
|
||||
|
||||
us.requestRedraw();
|
||||
|
||||
us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2,(ea.getYmin()+ea.getYmax())/2);
|
||||
|
||||
flushMouseEventStack();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GliderManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
flushMouseEventStack();
|
||||
|
||||
us.requestContinuousUpdate(false);
|
||||
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
_velocity = boundingSphere._radius*0.01f;
|
||||
|
||||
us.requestWarpPointer((ea.getXmin()+ea.getXmax())/2,(ea.getYmin()+ea.getYmax())/2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GliderManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
|
||||
{
|
||||
if(!_camera.get()) return false;
|
||||
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(GUIEventAdapter::PUSH):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
|
||||
}
|
||||
return true;
|
||||
case(GUIEventAdapter::RELEASE):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
|
||||
}
|
||||
return true;
|
||||
case(GUIEventAdapter::DRAG):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
|
||||
}
|
||||
return true;
|
||||
case(GUIEventAdapter::MOVE):
|
||||
{
|
||||
|
||||
addMouseEvent(ea);
|
||||
us.requestContinuousUpdate(true);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
case(GUIEventAdapter::KEYBOARD):
|
||||
if (ea.getKey()==' ')
|
||||
{
|
||||
flushMouseEventStack();
|
||||
home(ea,us);
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case(GUIEventAdapter::FRAME):
|
||||
addMouseEvent(ea);
|
||||
if (calcMovement()) us.requestRedraw();
|
||||
return true;
|
||||
case(GUIEventAdapter::RESIZE):
|
||||
{
|
||||
init(ea,us);
|
||||
us.requestRedraw();
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GliderManipulator::flushMouseEventStack()
|
||||
{
|
||||
_ga_t1 = NULL;
|
||||
_ga_t0 = NULL;
|
||||
}
|
||||
|
||||
|
||||
void GliderManipulator::addMouseEvent(const GUIEventAdapter& ea)
|
||||
{
|
||||
_ga_t1 = _ga_t0;
|
||||
_ga_t0 = &ea;
|
||||
}
|
||||
|
||||
|
||||
bool GliderManipulator::calcMovement()
|
||||
{
|
||||
// return if less then two events have been added.
|
||||
if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
|
||||
|
||||
float dt = _ga_t0->time()-_ga_t1->time();
|
||||
|
||||
if (dt<0.0f)
|
||||
{
|
||||
notify(WARN) << "warning dt = "<<dt<<endl;
|
||||
dt = 0.0f;
|
||||
}
|
||||
|
||||
unsigned int buttonMask = _ga_t1->getButtonMask();
|
||||
if (buttonMask==GUIEventAdapter::LEFT_BUTTON)
|
||||
{
|
||||
// pan model.
|
||||
|
||||
_velocity += dt*_modelScale*0.05f;
|
||||
|
||||
}
|
||||
else if (buttonMask==GUIEventAdapter::MIDDLE_BUTTON ||
|
||||
buttonMask==(GUIEventAdapter::LEFT_BUTTON|GUIEventAdapter::RIGHT_BUTTON))
|
||||
{
|
||||
|
||||
_velocity = 0.0f;
|
||||
|
||||
}
|
||||
else if (buttonMask==GUIEventAdapter::RIGHT_BUTTON)
|
||||
{
|
||||
|
||||
_velocity -= dt*_modelScale*0.05f;
|
||||
|
||||
}
|
||||
|
||||
float mx = (_ga_t0->getXmin()+_ga_t0->getXmax())/2.0f;
|
||||
float my = (_ga_t0->getYmin()+_ga_t0->getYmax())/2.0f;
|
||||
|
||||
float dx = _ga_t0->getX()-mx;
|
||||
float dy = _ga_t0->getY()-my;
|
||||
|
||||
osg::Vec3 center = _camera->getEyePoint();
|
||||
osg::Vec3 sv = _camera->getSideVector();
|
||||
osg::Vec3 lv = _camera->getLookVector();
|
||||
|
||||
float pitch = -dy*0.15f*dt;
|
||||
float roll = -dx*0.1f*dt;
|
||||
|
||||
osg::Matrix mat;
|
||||
mat.makeTrans(-center.x(),-center.y(),-center.z());
|
||||
mat.postRot(pitch,sv.x(),sv.y(),sv.z());
|
||||
mat.postRot(roll,lv.x(),lv.y(),lv.z());
|
||||
if (_yawMode==YAW_AUTOMATICALLY_WHEN_BANKED)
|
||||
{
|
||||
float bank = asinf(sv.z());
|
||||
float yaw = (-bank*180.0f/M_PI)*dt;
|
||||
mat.postRot(yaw,0.0f,0.0f,1.0f);
|
||||
}
|
||||
mat.postTrans(center.x(),center.y(),center.z());
|
||||
|
||||
lv *= (_velocity*dt);
|
||||
|
||||
mat.postTrans(lv.x(),lv.y(),lv.z());
|
||||
|
||||
_camera->transformLookAt(mat);
|
||||
|
||||
return true;
|
||||
}
|
||||
65
src/Demos/hangglide/GliderManipulator.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef HANGGLIDE_GLIDERMANIPULATOR
|
||||
#define HANGGLIDE_GLIDERMANIPULATOR 1
|
||||
|
||||
#include <osgUtil/CameraManipulator>
|
||||
|
||||
class GliderManipulator : public osgUtil::CameraManipulator
|
||||
{
|
||||
public:
|
||||
|
||||
GliderManipulator();
|
||||
virtual ~GliderManipulator();
|
||||
|
||||
/** Attach a node to the manipulator.
|
||||
Automatically detaches previously attached node.
|
||||
setNode(NULL) detaches previously nodes.
|
||||
Is ignored by manipulators which do not require a reference model.*/
|
||||
virtual void setNode(osg::Node*);
|
||||
|
||||
/** Return node if attached.*/
|
||||
virtual const osg::Node* getNode() const;
|
||||
|
||||
/** Move the camera to the default position.
|
||||
May be ignored by manipulators if home functionality is not appropriate.*/
|
||||
virtual void home(const osgUtil::GUIEventAdapter& ea,osgUtil::GUIActionAdapter& us);
|
||||
|
||||
/** Start/restart the manipulator.*/
|
||||
virtual void init(const osgUtil::GUIEventAdapter& ea,osgUtil::GUIActionAdapter& us);
|
||||
|
||||
/** handle events, return true if handled, false otherwise.*/
|
||||
virtual bool handle(const osgUtil::GUIEventAdapter& ea,osgUtil::GUIActionAdapter& us);
|
||||
|
||||
enum YawControlMode {
|
||||
YAW_AUTOMATICALLY_WHEN_BANKED,
|
||||
NO_AUTOMATIC_YAW
|
||||
};
|
||||
|
||||
/** Set the yaw control between no yaw and yawing when banked.*/
|
||||
void setYawControlMode(YawControlMode ycm) { _yawMode = ycm; }
|
||||
|
||||
private:
|
||||
|
||||
/** Reset the internal GUIEvent stack.*/
|
||||
void flushMouseEventStack();
|
||||
/** Add the current mouse GUIEvent to internal stack.*/
|
||||
void addMouseEvent(const osgUtil::GUIEventAdapter& ea);
|
||||
|
||||
/** For the give mouse movement calculate the movement of the camera.
|
||||
Return true is camera has moved and a redraw is required.*/
|
||||
bool calcMovement();
|
||||
|
||||
// Internal event stack comprising last three mouse events.
|
||||
osg::ref_ptr<const osgUtil::GUIEventAdapter> _ga_t1;
|
||||
osg::ref_ptr<const osgUtil::GUIEventAdapter> _ga_t0;
|
||||
|
||||
osg::ref_ptr<osg::Node> _node;
|
||||
|
||||
float _modelScale;
|
||||
float _velocity;
|
||||
|
||||
YawControlMode _yawMode;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
0
src/Demos/hangglide/Makedepend
Normal file
28
src/Demos/hangglide/Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
#!smake
|
||||
include ../../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
hangglide.cpp\
|
||||
ReaderWriterFLY.cpp\
|
||||
GliderManipulator.cpp\
|
||||
hat.cpp\
|
||||
terrain.cpp\
|
||||
tank.cpp\
|
||||
sky.cpp\
|
||||
base.cpp\
|
||||
trees.cpp\
|
||||
|
||||
TARGET = ../../../bin/hangglide
|
||||
|
||||
TARGET_BIN_FILES = hangglide
|
||||
|
||||
#note, use this library list when using the Performer osgPlugin.
|
||||
#LIBS = ${PFLIBS} -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
#note, standard library list.
|
||||
LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
C++FLAGS += -I. -I../../../include
|
||||
LDFLAGS += -L../../../lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
13
src/Demos/hangglide/README
Normal file
@@ -0,0 +1,13 @@
|
||||
A simple hang gliding flight simulator demo. The current GliderManipulator
|
||||
does not yet have any dynamics built into it, something TODO...
|
||||
|
||||
A small database is built into the program - Ed Levin park, Don's local flying
|
||||
to be precise! You'll need the textures found in the OpenSceneGraph-Data
|
||||
distribution. To run type :
|
||||
|
||||
hangglide
|
||||
|
||||
To run type with other databases, treat it just like sgv such as :
|
||||
|
||||
hangglide town.osg
|
||||
|
||||
101
src/Demos/hangglide/ReaderWriterFLY.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/Group>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/Registry>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
extern Node *makeTerrain( void );
|
||||
extern Node *makeTrees( void );
|
||||
extern Node *makeTank( void );
|
||||
extern Node *makeWindsocks( void );
|
||||
extern Node *makeGliders( void );
|
||||
extern Node *makeGlider( void );
|
||||
extern Node *makeSky( void );
|
||||
extern Node *makeBase( void );
|
||||
extern Node *makeClouds( void );
|
||||
|
||||
static struct _nodes
|
||||
{
|
||||
char *name;
|
||||
Node *(*fptr)(void);
|
||||
}
|
||||
|
||||
|
||||
nodes[] =
|
||||
{
|
||||
{ "terrain", makeTerrain },
|
||||
{ "tank", makeTank },
|
||||
{ "sky", makeSky },
|
||||
{ "base", makeBase },
|
||||
{ "trees", makeTrees },
|
||||
// { "gliders", makeGliders },
|
||||
// { "clouds", makeClouds },
|
||||
|
||||
{ 0L, 0L }
|
||||
};
|
||||
|
||||
class ReaderWriterFLY : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
virtual const char* className() { return "FLY Database Reader"; }
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension)
|
||||
{
|
||||
return osgDB::equalCaseInsensitive(extension,"fly");
|
||||
}
|
||||
|
||||
virtual Node* readNode(const std::string& fileName)
|
||||
{
|
||||
|
||||
std::string ext = osgDB::getFileExtension(fileName);
|
||||
if (!acceptsExtension(ext)) return NULL;
|
||||
|
||||
char buff[256];
|
||||
|
||||
notify(INFO)<< "ReaderWriterFLY::readNode( "<<fileName.c_str()<<" )\n";
|
||||
|
||||
FILE *fp;
|
||||
|
||||
if( (fp = fopen( fileName.c_str(), "r" )) == (FILE *)0L )
|
||||
{
|
||||
notify(WARN)<< "Unable to open file \""<<fileName.c_str()<<"\"\n";
|
||||
return 0L;
|
||||
}
|
||||
Group *grp = new Group;
|
||||
|
||||
while( !feof( fp ) )
|
||||
{
|
||||
_nodes *nptr;
|
||||
fgets( buff, sizeof( buff ), fp );
|
||||
if( buff[0] == '#' )
|
||||
continue;
|
||||
|
||||
for( nptr = nodes; nptr->name; nptr ++ )
|
||||
{
|
||||
if( !strncmp( buff, nptr->name, strlen( nptr->name ) ))
|
||||
{
|
||||
Node *node = nptr->fptr();
|
||||
node->setName( nptr->name );
|
||||
grp->addChild( node );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
|
||||
return grp;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// now register with osg::Registry to instantiate the above
|
||||
// reader/writer.
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterFLY> g_readerWriter_FLY_Proxy;
|
||||
|
||||
94
src/Demos/hangglide/base.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Texture>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/StateSet>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Node *makeBase( void )
|
||||
{
|
||||
int i, c;
|
||||
float theta;
|
||||
float ir, ori;
|
||||
ir = 6.0;
|
||||
ori = 20.0;
|
||||
|
||||
Vec3 *coords = new Vec3[38];
|
||||
Vec2 *tcoords = new Vec2[38];
|
||||
Vec4 *colors = new Vec4[1];
|
||||
int *lengths = new int[1];
|
||||
|
||||
colors[0][0] = colors[0][1] = colors[0][2] = colors[0][3] = 1;
|
||||
|
||||
c = 0;
|
||||
for( i = 0; i <= 18; i++ )
|
||||
{
|
||||
theta = (float)i * 20.0 * M_PI/180.0;
|
||||
|
||||
coords[c][0] = ir * cosf( theta );
|
||||
coords[c][1] = ir * sinf( theta );
|
||||
coords[c][2] = 0.0;
|
||||
tcoords[c][0] = coords[c][0]/36.;
|
||||
tcoords[c][1] = coords[c][1]/36.;
|
||||
|
||||
c++;
|
||||
|
||||
coords[c][0] = ori * cosf( theta );
|
||||
coords[c][1] = ori * sinf( theta );
|
||||
coords[c][2] = 0.0f;
|
||||
|
||||
tcoords[c][0] = coords[c][0]/36.;
|
||||
tcoords[c][1] = coords[c][1]/36.;
|
||||
|
||||
c++;
|
||||
}
|
||||
*lengths = 38;
|
||||
|
||||
GeoSet *gset = new GeoSet;
|
||||
|
||||
gset->setCoords( coords );
|
||||
|
||||
gset->setTextureCoords( tcoords );
|
||||
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
|
||||
|
||||
gset->setColors( colors );
|
||||
gset->setColorBinding( GeoSet::BIND_OVERALL );
|
||||
|
||||
gset->setPrimType( GeoSet::TRIANGLE_STRIP );
|
||||
gset->setNumPrims( 1 );
|
||||
gset->setPrimLengths( lengths );
|
||||
|
||||
Texture *tex = new Texture;
|
||||
|
||||
tex->setImage(osgDB::readImageFile("water.rgb"));
|
||||
tex->setWrap( Texture::WRAP_S, Texture::REPEAT );
|
||||
tex->setWrap( Texture::WRAP_T, Texture::REPEAT );
|
||||
|
||||
StateSet *dstate = new StateSet;
|
||||
dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
|
||||
dstate->setAttributeAndModes( tex, StateAttribute::ON );
|
||||
|
||||
dstate->setAttribute( new TexEnv );
|
||||
/*
|
||||
pfFog *fog = new pfFog;
|
||||
|
||||
fog->setFogType( PFFOG_PIX_EXP2 );
|
||||
fog->setColor( 0.1, 0.2, 0.2 );
|
||||
fog->setRange( 16.0, 22.0 );
|
||||
|
||||
gstate->setMode( PFSTATE_ENFOG, PF_ON );
|
||||
gstate->setAttr( PFSTATE_FOG, fog );
|
||||
*/
|
||||
|
||||
gset->setStateSet( dstate );
|
||||
|
||||
Geode *geode = new Geode;
|
||||
geode->addDrawable( gset );
|
||||
|
||||
return geode;
|
||||
}
|
||||
152
src/Demos/hangglide/hangglide.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include <osg/Group>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
#include "GliderManipulator.h"
|
||||
|
||||
extern osg::Node *makeTerrain( void );
|
||||
extern osg::Node *makeTrees( void );
|
||||
extern osg::Node *makeTank( void );
|
||||
extern osg::Node *makeWindsocks( void );
|
||||
extern osg::Node *makeGliders( void );
|
||||
extern osg::Node *makeGlider( void );
|
||||
extern osg::Node *makeSky( void );
|
||||
extern osg::Node *makeBase( void );
|
||||
extern osg::Node *makeClouds( void );
|
||||
|
||||
/*
|
||||
* Function to read several files (typically one) as specified on the command
|
||||
* line, and return them in an osg::Node
|
||||
*/
|
||||
osg::Node* getNodeFromFiles(int argc,char **argv)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
typedef std::vector<osg::Node*> NodeList;
|
||||
NodeList nodeList;
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
|
||||
if (argv[i][0]=='-')
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case('l'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
osgDB::Registry::instance()->loadLibrary(argv[i]);
|
||||
}
|
||||
break;
|
||||
case('e'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(argv[i]);
|
||||
osgDB::Registry::instance()->loadLibrary(libName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
osg::Node *node = osgDB::readNodeFile( argv[i] );
|
||||
|
||||
if( node != (osg::Node *)0L )
|
||||
{
|
||||
if (node->getName().empty()) node->setName( argv[i] );
|
||||
nodeList.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (nodeList.size()==0)
|
||||
{
|
||||
osg::notify(osg::INFO) << "No data loaded."<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
osg::Node *rootnode = new osg::Node;
|
||||
if (nodeList.size()==1)
|
||||
{
|
||||
rootnode = nodeList.front();
|
||||
}
|
||||
else // size >1
|
||||
{
|
||||
osg::Group* group = new osg::Group();
|
||||
for(NodeList::iterator itr=nodeList.begin();
|
||||
itr!=nodeList.end();
|
||||
++itr)
|
||||
{
|
||||
group->addChild(*itr);
|
||||
}
|
||||
|
||||
rootnode = group;
|
||||
}
|
||||
|
||||
return rootnode;
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
// if (argc<2)
|
||||
// {
|
||||
// osg::notify(osg::NOTICE)<<"usage:"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" sgv [options] infile1 [infile2 ...]"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<endl;
|
||||
// osg::notify(osg::NOTICE)<<"options:"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" -l libraryName - load plugin of name libraryName"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" i.e. -l osgdb_pfb"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" Useful for loading reader/writers which can load"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" other file formats in addition to its extension."<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" -e extensionName - load reader/wrter plugin for file extension"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" i.e. -e pfb"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" Useful short hand for specifying full library name as"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" done with -l above, as it automatically expands to the"<<endl;
|
||||
// osg::notify(osg::NOTICE)<<" full library name appropriate for each platform."<<endl;
|
||||
// osg::notify(osg::NOTICE)<<endl;
|
||||
//
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
osg::Node* rootnode = getNodeFromFiles( argc, argv);
|
||||
if (rootnode==NULL)
|
||||
{
|
||||
// no database loaded so automatically create Ed Levin Park..
|
||||
osg::Group* group = new osg::Group;
|
||||
rootnode = group;
|
||||
group->addChild(makeTerrain());
|
||||
group->addChild(makeTank());
|
||||
group->addChild(makeSky());
|
||||
group->addChild(makeBase());
|
||||
group->addChild(makeTrees());
|
||||
// add the following in the future...
|
||||
// makeGliders
|
||||
// makeClouds
|
||||
|
||||
}
|
||||
|
||||
glutInit( &argc, argv );
|
||||
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.addViewport( rootnode );
|
||||
|
||||
unsigned int pos = viewer.registerCameraManipulator(new GliderManipulator());
|
||||
|
||||
// Open window so camera manipulator's warp pointer request will succeed
|
||||
viewer.open();
|
||||
|
||||
viewer.selectCameraManipulator(pos);
|
||||
|
||||
viewer.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
150
src/Demos/hangglide/hat.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#pragma warning( disable : 4244 )
|
||||
#endif
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "terrain_data.h"
|
||||
#include "hat.h"
|
||||
|
||||
static int inited = 0;
|
||||
|
||||
static float dbcenter[3];
|
||||
static float dbradius;
|
||||
|
||||
static void getDatabaseCenterRadius( float dbcenter[3], float *dbradius )
|
||||
{
|
||||
int i;
|
||||
double n=0.0;
|
||||
double center[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float cnt;
|
||||
|
||||
cnt = 39 * 38;
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
center[0] += (double)vertex[i][0];
|
||||
center[1] += (double)vertex[i][1];
|
||||
center[2] += (double)vertex[i][2];
|
||||
|
||||
n = n + 1.0;
|
||||
}
|
||||
|
||||
center[0] /= n;
|
||||
center[1] /= n;
|
||||
center[2] /= n;
|
||||
|
||||
float r = 0.0;
|
||||
|
||||
// for( i = 0; i < sizeof( vertex ) / (sizeof( float[3] )); i++ )
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
double d = sqrt(
|
||||
(((double)vertex[i][0] - center[0]) * ((double)vertex[i][0] - center[0])) +
|
||||
(((double)vertex[i][1] - center[1]) * ((double)vertex[i][1] - center[1])) +
|
||||
(((double)vertex[i][2] - center[2]) * ((double)vertex[i][2] - center[2])) );
|
||||
|
||||
if( d > (double)r ) r = (float)d;
|
||||
|
||||
}
|
||||
|
||||
*dbradius = r;
|
||||
dbcenter[0] = (float)center[0];
|
||||
dbcenter[1] = (float)center[1];
|
||||
dbcenter[2] = (float)center[2];
|
||||
|
||||
int index = 19 * 39 + 19;
|
||||
dbcenter[0] = vertex[index][0] - 0.15;
|
||||
dbcenter[1] = vertex[index][1];
|
||||
dbcenter[2] = vertex[index][2] + 0.35;
|
||||
}
|
||||
|
||||
|
||||
static void init( void )
|
||||
{
|
||||
getDatabaseCenterRadius( dbcenter, &dbradius );
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
|
||||
static void getNormal( float *v1, float *v2, float *v3, float *n )
|
||||
{
|
||||
float V1[4], V2[4];
|
||||
float f;
|
||||
int i;
|
||||
|
||||
/* Two vectors v2->v1 and v2->v3 */
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
V1[i] = v1[i] - v2[i];
|
||||
V2[i] = v3[i] - v2[i];
|
||||
}
|
||||
|
||||
/* Cross product between V1 and V2 */
|
||||
|
||||
n[0] = (V1[1] * V2[2]) - (V1[2] * V2[1]);
|
||||
n[1] = -((V1[0] * V2[2]) - ( V1[2] * V2[0] ));
|
||||
n[2] = (V1[0] * V2[1] ) - (V1[1] * V2[0] );
|
||||
|
||||
/* Normalize */
|
||||
|
||||
f = sqrtf( ( n[0] * n[0] ) + ( n[1] * n[1] ) + ( n[2] * n[2] ) );
|
||||
n[0] /= f;
|
||||
n[1] /= f;
|
||||
n[2] /= f;
|
||||
}
|
||||
|
||||
|
||||
float Hat( float x, float y, float z )
|
||||
{
|
||||
int m, n;
|
||||
int i, j;
|
||||
float tri[3][3];
|
||||
float norm[3];
|
||||
float d, pz;
|
||||
|
||||
if( inited == 0 ) init();
|
||||
|
||||
// m = columns
|
||||
// n = rows
|
||||
m = (sizeof( vertex ) /(sizeof( float[3])))/39;
|
||||
n = 39;
|
||||
|
||||
i = 0;
|
||||
while( i < ((m-1)*39) && x > (vertex[i+n][0] - dbcenter[0]) )
|
||||
i += n;
|
||||
|
||||
j = 0;
|
||||
|
||||
while( j < n-1 && y > (vertex[i+j+1][1] - dbcenter[1]) )
|
||||
j++;
|
||||
|
||||
tri[0][0] = vertex[i+0+j+0][0] - dbcenter[0];
|
||||
tri[0][1] = vertex[i+0+j+0][1] - dbcenter[1];
|
||||
//tri[0][2] = vertex[i+0+j+0][2] - dbcenter[2];
|
||||
tri[0][2] = vertex[i+0+j+0][2];
|
||||
|
||||
tri[1][0] = vertex[i+n+j+0][0] - dbcenter[0];
|
||||
tri[1][1] = vertex[i+n+j+0][1] - dbcenter[1];
|
||||
//tri[1][2] = vertex[i+n+j+0][2] - dbcenter[2];
|
||||
tri[1][2] = vertex[i+n+j+0][2];
|
||||
|
||||
tri[2][0] = vertex[i+0+j+1][0] - dbcenter[0];
|
||||
tri[2][1] = vertex[i+0+j+1][1] - dbcenter[1];
|
||||
//tri[2][2] = vertex[i+0+j+1][2] - dbcenter[2];
|
||||
tri[2][2] = vertex[i+0+j+1][2];
|
||||
|
||||
getNormal( tri[0], tri[1], tri[2], norm );
|
||||
|
||||
d = (tri[0][0] * norm[0]) +
|
||||
(tri[0][1] * norm[1]) +
|
||||
(tri[0][2] * norm[2]);
|
||||
|
||||
d *= -1;
|
||||
pz = (-(norm[0] * x) - (norm[1] * y) - d)/norm[2];
|
||||
|
||||
return z - pz;
|
||||
}
|
||||
4
src/Demos/hangglide/hat.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef __HAT_H
|
||||
#define __HAT_H
|
||||
extern float Hat( float x, float y, float z );
|
||||
#endif
|
||||
108
src/Demos/hangglide/sky.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Texture>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/StateSet>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning( disable : 4244 )
|
||||
#pragma warning( disable : 4305 )
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Node *makeSky( void )
|
||||
{
|
||||
int i, j;
|
||||
float lev[] = { -5, -1.0, 1.0, 15.0, 30.0, 60.0, 90.0 };
|
||||
float cc[][4] =
|
||||
{
|
||||
{ 0.0, 0.0, 0.15 },
|
||||
{ 0.0, 0.0, 0.15 },
|
||||
{ 0.4, 0.4, 0.7 },
|
||||
{ 0.2, 0.2, 0.6 },
|
||||
{ 0.1, 0.1, 0.6 },
|
||||
{ 0.1, 0.1, 0.6 },
|
||||
{ 0.1, 0.1, 0.6 },
|
||||
};
|
||||
float x, y, z;
|
||||
float alpha, theta;
|
||||
float radius = 20.0f;
|
||||
int nlev = sizeof( lev )/sizeof(float);
|
||||
|
||||
Vec3 *coords = new Vec3[19*nlev];
|
||||
Vec4 *colors = new Vec4[19*nlev];
|
||||
Vec2 *tcoords = new Vec2[19*nlev];
|
||||
osg::ushort *idx = new osg::ushort[38* nlev];
|
||||
int *lengths = new int[nlev];
|
||||
|
||||
int ci, ii;
|
||||
ii = ci = 0;
|
||||
|
||||
for( i = 0; i < nlev; i++ )
|
||||
{
|
||||
for( j = 0; j <= 18; j++ )
|
||||
{
|
||||
alpha = lev[i] * M_PI/180.0;
|
||||
theta = (float)(j*20) * M_PI/180.0;
|
||||
|
||||
x = radius * cosf( alpha ) * cosf( theta );
|
||||
y = radius * cosf( alpha ) * -sinf( theta );
|
||||
z = radius * sinf( alpha );
|
||||
|
||||
coords[ci][0] = x;
|
||||
coords[ci][1] = y;
|
||||
coords[ci][2] = z;
|
||||
|
||||
colors[ci][0] = cc[i][0];
|
||||
colors[ci][1] = cc[i][1];
|
||||
colors[ci][2] = cc[i][2];
|
||||
colors[ci][3] = 1.0;
|
||||
|
||||
tcoords[ci][0] = (float)j/18.0;
|
||||
tcoords[ci][0] = (float)i/(float)(nlev-1);
|
||||
|
||||
ci++;
|
||||
|
||||
idx[ii++] = ((i+1)*19+j);
|
||||
idx[ii++] = ((i+0)*19+j);
|
||||
}
|
||||
lengths[i] = 38;
|
||||
}
|
||||
|
||||
GeoSet *gset = new GeoSet;
|
||||
|
||||
gset->setCoords( coords, idx );
|
||||
gset->setTextureCoords( tcoords, idx );
|
||||
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
|
||||
|
||||
gset->setColors( colors, idx );
|
||||
gset->setColorBinding( GeoSet::BIND_PERVERTEX );
|
||||
|
||||
gset->setPrimType( GeoSet::TRIANGLE_STRIP );
|
||||
gset->setNumPrims( nlev - 1 );
|
||||
gset->setPrimLengths( lengths );
|
||||
|
||||
Texture *tex = new Texture;
|
||||
tex->setImage(osgDB::readImageFile("white.rgb"));
|
||||
|
||||
StateSet *dstate = new StateSet;
|
||||
|
||||
dstate->setAttributeAndModes( tex, StateAttribute::OFF );
|
||||
dstate->setAttribute( new TexEnv );
|
||||
dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
|
||||
dstate->setMode( GL_CULL_FACE, StateAttribute::ON );
|
||||
|
||||
gset->setStateSet( dstate );
|
||||
|
||||
Geode *geode = new Geode;
|
||||
geode->addDrawable( gset );
|
||||
|
||||
geode->setName( "Sky" );
|
||||
|
||||
return geode;
|
||||
}
|
||||
192
src/Demos/hangglide/tank.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <osg/GL>
|
||||
#include <osg/Group>
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Texture>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Matrix>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning( disable : 4244 )
|
||||
#pragma warning( disable : 4305 )
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
extern void getDatabaseCenterRadius( float dbcenter[3], float *dbradius );
|
||||
|
||||
static float radius = 2.0;
|
||||
static float dbcenter[3], dbradius;
|
||||
|
||||
static void conv( const Vec3& a, const Matrix& mat, Vec3& b )
|
||||
{
|
||||
int i;
|
||||
Vec3 t;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
t[i] = (a[0] * mat._mat[0][i]) +
|
||||
(a[1] * mat._mat[1][i]) +
|
||||
(a[2] * mat._mat[2][i]) +
|
||||
mat._mat[3][i];
|
||||
}
|
||||
b[0] = t[0];
|
||||
b[1] = t[1];
|
||||
b[2] = t[2];
|
||||
}
|
||||
|
||||
|
||||
Node *makeTank( void )
|
||||
{
|
||||
|
||||
Geode *geode1 = new Geode;
|
||||
|
||||
getDatabaseCenterRadius( dbcenter, &dbradius );
|
||||
|
||||
ref_ptr<Matrix> mat = new Matrix(
|
||||
0.05, 0, 0, 0,
|
||||
0, 0.05, 0, 0,
|
||||
0, 0, 0.05, 0,
|
||||
1.5999 - 0.3,
|
||||
3.1474,
|
||||
dbcenter[2] + 0.6542 - 0.09,
|
||||
1
|
||||
);
|
||||
|
||||
Vec3 *vc = new Vec3[42];
|
||||
Vec2 *tc = new Vec2[42];
|
||||
int *lens = new int[1];
|
||||
int i, c;
|
||||
|
||||
c = 0;
|
||||
for( i = 0; i <= 360; i += 18 )
|
||||
{
|
||||
float x, y, z;
|
||||
float s, t;
|
||||
float theta = (float)i * M_PI/180.0;
|
||||
|
||||
s = (float)i/90.0;
|
||||
t = 1.0;
|
||||
|
||||
x = radius * cosf( theta );
|
||||
y = radius * sinf( theta );
|
||||
z = 1.0;
|
||||
|
||||
vc[c][0] = x;
|
||||
vc[c][1] = y;
|
||||
vc[c][2] = z;
|
||||
|
||||
tc[c][0] = s;
|
||||
tc[c][1] = t;
|
||||
|
||||
c++;
|
||||
|
||||
t = 0.0;
|
||||
z = 0.0;
|
||||
|
||||
vc[c][0] = x;
|
||||
vc[c][1] = y;
|
||||
vc[c][2] = z;
|
||||
|
||||
tc[c][0] = s;
|
||||
tc[c][1] = t;
|
||||
c++;
|
||||
}
|
||||
*lens = 42;
|
||||
|
||||
for( i = 0; i < c; i++ )
|
||||
conv( vc[i], *mat, vc[i] );
|
||||
|
||||
GeoSet *gset = new GeoSet;
|
||||
gset->setCoords( vc );
|
||||
|
||||
gset->setTextureCoords( tc );
|
||||
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
|
||||
|
||||
gset->setPrimType( GeoSet::TRIANGLE_STRIP );
|
||||
gset->setNumPrims( 1 );
|
||||
gset->setPrimLengths( lens );
|
||||
|
||||
Texture *tex = new Texture;
|
||||
|
||||
tex->setWrap( Texture::WRAP_S, Texture::REPEAT );
|
||||
tex->setWrap( Texture::WRAP_T, Texture::REPEAT );
|
||||
tex->setImage(osgDB::readImageFile("tank.rgb"));
|
||||
|
||||
StateSet *dstate = new StateSet;
|
||||
dstate->setAttributeAndModes( tex, StateAttribute::ON );
|
||||
dstate->setAttribute( new TexEnv );
|
||||
|
||||
gset->setStateSet( dstate );
|
||||
geode1->addDrawable( gset );
|
||||
|
||||
lens = new int[1];
|
||||
*lens = 22;
|
||||
|
||||
vc = new Vec3[22];
|
||||
tc = new Vec2[22];
|
||||
|
||||
c = 0;
|
||||
vc[c][0] = 0.0f;
|
||||
vc[c][1] = 0.0f;
|
||||
vc[c][2] = 1.0f;
|
||||
|
||||
tc[c][0] = 0.0f;
|
||||
tc[c][1] = 0.0f;
|
||||
c++;
|
||||
|
||||
for( i = 0; i <= 360; i += 18 )
|
||||
{
|
||||
float x, y, z;
|
||||
float s, t;
|
||||
float theta = (float)i * M_PI/180.0;
|
||||
|
||||
// s = (float)i/360.0;
|
||||
// t = 1.0;
|
||||
s = cosf( theta );
|
||||
t = sinf( theta );
|
||||
|
||||
x = radius * cosf( theta );
|
||||
y = radius * sinf( theta );
|
||||
z = 1.0;
|
||||
|
||||
vc[c][0] = x;
|
||||
vc[c][1] = y;
|
||||
vc[c][2] = z;
|
||||
|
||||
tc[c][0] = s;
|
||||
tc[c][1] = t;
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
for( i = 0; i < c; i++ )
|
||||
conv( vc[i], *mat, vc[i] );
|
||||
|
||||
gset = new GeoSet;
|
||||
gset->setCoords( vc );
|
||||
gset->setTextureCoords( tc );
|
||||
gset->setPrimType(GeoSet::TRIANGLE_FAN);
|
||||
gset->setNumPrims( 1 );
|
||||
gset->setPrimLengths( lens );
|
||||
|
||||
gset->setStateSet( dstate );
|
||||
|
||||
Geode *geode2 = new Geode;
|
||||
geode2->addDrawable( gset );
|
||||
|
||||
|
||||
Group *grp = new Group;
|
||||
grp->addChild( geode1 );
|
||||
grp->addChild( geode2 );
|
||||
|
||||
geode1->setName( "Geode 1" );
|
||||
geode2->setName( "Geode 2" );
|
||||
|
||||
return grp;
|
||||
}
|
||||
136
src/Demos/hangglide/terrain.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
// #include <math.h>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Texture>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/StateSet>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include "terrain_data.h"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
void getDatabaseCenterRadius( float dbcenter[3], float *dbradius )
|
||||
{
|
||||
int i;
|
||||
double n=0.0;
|
||||
double center[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float cnt;
|
||||
|
||||
cnt = 39 * 38;
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
center[0] += (double)vertex[i][0];
|
||||
center[1] += (double)vertex[i][1];
|
||||
center[2] += (double)vertex[i][2];
|
||||
|
||||
n = n + 1.0;
|
||||
}
|
||||
|
||||
center[0] /= n;
|
||||
center[1] /= n;
|
||||
center[2] /= n;
|
||||
|
||||
float r = 0.0;
|
||||
|
||||
// for( i = 0; i < sizeof( vertex ) / (sizeof( float[3] )); i++ )
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
double d = sqrt(
|
||||
(((double)vertex[i][0] - center[0]) * ((double)vertex[i][0] - center[0])) +
|
||||
(((double)vertex[i][1] - center[1]) * ((double)vertex[i][1] - center[1])) +
|
||||
(((double)vertex[i][2] - center[2]) * ((double)vertex[i][2] - center[2])) );
|
||||
|
||||
if( d > (double)r ) r = (float)d;
|
||||
|
||||
}
|
||||
|
||||
*dbradius = r;
|
||||
dbcenter[0] = (float)center[0];
|
||||
dbcenter[1] = (float)center[1];
|
||||
dbcenter[2] = (float)center[2];
|
||||
|
||||
int index = 19 * 39 + 19;
|
||||
dbcenter[0] = vertex[index][0] - 0.15;
|
||||
dbcenter[1] = vertex[index][1];
|
||||
dbcenter[2] = vertex[index][2] + 0.35;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Node *makeTerrain( void )
|
||||
{
|
||||
int m, n;
|
||||
int i, j, c;
|
||||
float dbcenter[3];
|
||||
float dbradius;
|
||||
|
||||
getDatabaseCenterRadius( dbcenter, &dbradius );
|
||||
|
||||
m = (sizeof( vertex ) /(sizeof( float[3])))/39;
|
||||
n = 39;
|
||||
|
||||
Vec3 *v = new Vec3[m*n];
|
||||
Vec2 *t = new Vec2[m*n];
|
||||
Vec4 *col = new Vec4[1];
|
||||
osg::ushort *cidx = new osg::ushort;
|
||||
osg::ushort *idx = new osg::ushort[m*n*2];
|
||||
int *lens = new int[m];
|
||||
|
||||
col[0][0] = col[0][1] = col[0][2] = col[0][3] = 1;
|
||||
*cidx = 0;
|
||||
|
||||
for( i = 0; i < m * n; i++ )
|
||||
{
|
||||
v[i][0] = vertex[i][0] - dbcenter[0];
|
||||
v[i][1] = vertex[i][1] - dbcenter[1];
|
||||
v[i][2] = vertex[i][2];
|
||||
|
||||
t[i][0] = texcoord[i][0] + 0.025;
|
||||
t[i][1] = texcoord[i][1];
|
||||
}
|
||||
|
||||
c = 0;
|
||||
for( i = 0; i < m-2; i++ )
|
||||
{
|
||||
for( j = 0; j < n; j++ )
|
||||
{
|
||||
idx[c++] = (i+0)*n+j;
|
||||
idx[c++] = (i+1)*n+j;
|
||||
}
|
||||
lens[i] = 39*2;
|
||||
}
|
||||
|
||||
GeoSet *gset = new GeoSet;
|
||||
|
||||
gset->setCoords( v, idx );
|
||||
gset->setTextureCoords( t, idx );
|
||||
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
|
||||
|
||||
gset->setColors( col, cidx );
|
||||
gset->setColorBinding( GeoSet::BIND_OVERALL );
|
||||
|
||||
gset->setPrimType( GeoSet::TRIANGLE_STRIP );
|
||||
gset->setNumPrims( m-2 );
|
||||
gset->setPrimLengths( lens );
|
||||
|
||||
Texture *tex = new Texture;
|
||||
|
||||
tex->setImage(osgDB::readImageFile("lz.rgb"));
|
||||
|
||||
StateSet *dstate = new StateSet;
|
||||
dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
|
||||
dstate->setAttributeAndModes( tex, StateAttribute::ON );
|
||||
dstate->setAttribute( new TexEnv );
|
||||
|
||||
gset->setStateSet( dstate );
|
||||
|
||||
Geode *geode = new Geode;
|
||||
geode->addDrawable( gset );
|
||||
|
||||
gset->check();
|
||||
|
||||
return geode;
|
||||
}
|
||||
5944
src/Demos/hangglide/terrain_data.h
Normal file
275
src/Demos/hangglide/trees.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <osg/Billboard>
|
||||
#include <osg/Group>
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Texture>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/Transparency>
|
||||
#include <osg/AlphaFunc>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include "hat.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning( disable : 4244 )
|
||||
#pragma warning( disable : 4305 )
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#define sqr(x) ((x)*(x))
|
||||
|
||||
extern void getDatabaseCenterRadius( float dbcenter[3], float *dbradius );
|
||||
|
||||
static float dbcenter[3], dbradius;
|
||||
|
||||
static struct _tree
|
||||
{
|
||||
int n;
|
||||
float x, y, z;
|
||||
float w, h;
|
||||
}
|
||||
|
||||
|
||||
trees[] =
|
||||
{
|
||||
{ 0, -0.4769, -0.8972, -0.4011, 0.2000, 0.1200 },
|
||||
{ 1, -0.2543, -0.9117, -0.3873, 0.2000, 0.1200 },
|
||||
{ 2, -0.0424, -0.8538, -0.3728, 0.2000, 0.1200 },
|
||||
{ 3, 0.1590, -0.8827, -0.3594, 0.2000, 0.1200 },
|
||||
{ 4, -0.4981, -1.0853, -0.4016, 0.3500, 0.1200 },
|
||||
{ 5, -0.5405, -1.2590, -0.4050, 0.2000, 0.1200 },
|
||||
{ 6, -0.5723, -1.5339, -0.4152, 0.2000, 0.1200 },
|
||||
{ 7, -0.6252, -1.8667, -0.4280, 0.2000, 0.1200 },
|
||||
{ 8, -0.5617, -2.1851, -0.4309, 0.2000, 0.1200 },
|
||||
{ 9, -0.5087, -2.4166, -0.4215, 0.2000, 0.1200 },
|
||||
{ 10, -0.4345, -2.3443, -0.4214, 0.2000, 0.1200 },
|
||||
{ 11, -3.0308, -1.5484, -0.4876, 0.2000, 0.1200 },
|
||||
{ 12, -3.0202, -1.6497, -0.4963, 0.2000, 0.1200 },
|
||||
{ 13, -2.9355, -1.8378, -0.4969, 0.2000, 0.1200 },
|
||||
{ 14, -0.6040, -2.0259, -0.4300, 0.2000, 0.1200 },
|
||||
{ 15, -0.5442, -1.3442, -0.4080, 0.1000, 0.1200 },
|
||||
{ 16, -0.5639, -1.6885, -0.4201, 0.1000, 0.1200 },
|
||||
{ 17, 0.9246, 3.4835, 0.5898, 0.2500, 0.1000 },
|
||||
{ 18, 0.0787, 3.8687, 0.3329, 0.2500, 0.1200 },
|
||||
{ 19, 0.2885, 3.7130, 0.4047, 0.2500, 0.1200 },
|
||||
{ 20, 0.2033, 3.6228, 0.3704, 0.2500, 0.1200 },
|
||||
{ 21, -0.2098, 3.9015, 0.2327, 0.2500, 0.1200 },
|
||||
{ 22, -0.3738, 3.7376, 0.1722, 0.2500, 0.1200 },
|
||||
{ 23, -0.2557, 3.6064, 0.1989, 0.2500, 0.1200 },
|
||||
{ 24, 0.0590, 3.7294, 0.3210, 0.2500, 0.1200 },
|
||||
{ 25, -0.4721, 3.8851, 0.1525, 0.2500, 0.1200 },
|
||||
{ 26, 0.9639, 3.2048, 0.5868, 0.1200, 0.0800 },
|
||||
{ 27, 0.7082, -1.0409, -0.3221, 0.1000, 0.1000 },
|
||||
{ 28, -0.2426, -2.3442, -0.4150, 0.1000, 0.1380 },
|
||||
{ 29, -0.1770, -2.4179, -0.4095, 0.1000, 0.1580 },
|
||||
{ 30, -0.0852, -2.5327, -0.4056, 0.1000, 0.1130 },
|
||||
{ 31, -0.0131, -2.6065, -0.4031, 0.1000, 0.1150 },
|
||||
{ 32, 0.0787, -2.6638, -0.4012, 0.1000, 0.1510 },
|
||||
{ 33, 0.1049, -2.7622, -0.3964, 0.1000, 0.1270 },
|
||||
{ 34, 0.1770, -2.8687, -0.3953, 0.1000, 0.1100 },
|
||||
{ 35, 0.3213, -2.9507, -0.3974, 0.1000, 0.1190 },
|
||||
{ 36, 0.4065, -3.0163, -0.4014, 0.1000, 0.1120 },
|
||||
{ 37, 0.3738, -3.1802, -0.4025, 0.1000, 0.1860 },
|
||||
{ 38, 0.5508, -3.2048, -0.3966, 0.1000, 0.1490 },
|
||||
{ 39, 0.5836, -3.3031, -0.3900, 0.1000, 0.1670 },
|
||||
{ 40, -0.3082, -2.7212, -0.3933, 0.1000, 0.1840 },
|
||||
{ 41, -0.1967, -2.6474, -0.4017, 0.1000, 0.1600 },
|
||||
{ 42, -0.1180, -2.7458, -0.3980, 0.1000, 0.1250 },
|
||||
{ 43, -0.3344, -2.8359, -0.3964, 0.1000, 0.1430 },
|
||||
{ 44, -0.2492, -2.8933, -0.3838, 0.1000, 0.1890 },
|
||||
{ 45, -0.1246, -3.0491, -0.3768, 0.1000, 0.1830 },
|
||||
{ 46, 0.0000, -3.0818, -0.3696, 0.1000, 0.1370 },
|
||||
{ 47, -0.2295, -3.0409, -0.3706, 0.1000, 0.1660 },
|
||||
{ 48, -1.3245, 2.6638, 0.0733, 0.0500, 0.0500 },
|
||||
{ 49, 2.2425, -1.5491, -0.2821, 0.2300, 0.1200 },
|
||||
{ 50, 0.2164, -2.1311, -0.4000, 0.1000, 0.0690 },
|
||||
{ 51, 0.2885, -2.2130, -0.4000, 0.1000, 0.0790 },
|
||||
{ 52, 0.3606, -2.2786, -0.4000, 0.1000, 0.0565 },
|
||||
{ 53, 0.4328, -2.3442, -0.4000, 0.1000, 0.0575 },
|
||||
{ 54, 0.5246, -2.4343, -0.4086, 0.1000, 0.0755 },
|
||||
{ 55, 0.6360, -2.5245, -0.4079, 0.1000, 0.0635 },
|
||||
{ 56, 0.7541, -2.4261, -0.4007, 0.1000, 0.0550 },
|
||||
{ 57, 0.7934, -2.2786, -0.3944, 0.1000, 0.0595 },
|
||||
{ 58, 1.0295, -2.2868, -0.3837, 0.1000, 0.0560 },
|
||||
{ 59, 0.8459, -2.6474, -0.4051, 0.1000, 0.0930 },
|
||||
{ 60, 1.0426, -2.6884, -0.4001, 0.1000, 0.0745 },
|
||||
{ 61, 1.1475, -2.7458, -0.3883, 0.1000, 0.0835 },
|
||||
{ 62, -0.1967, -1.4180, -0.3988, 0.1000, 0.0920 },
|
||||
{ 63, -0.0131, -1.2704, -0.3856, 0.1000, 0.0690 },
|
||||
{ 64, 0.2098, -1.2049, -0.3664, 0.1000, 0.0790 },
|
||||
{ 65, 0.3410, -1.3196, -0.3652, 0.1000, 0.0565 },
|
||||
{ 66, 0.5705, -1.2704, -0.3467, 0.1000, 0.0575 },
|
||||
{ 67, 0.6360, -1.4344, -0.3532, 0.1000, 0.0755 },
|
||||
{ 68, 0.9246, -1.4180, -0.3329, 0.1000, 0.0635 },
|
||||
{ 69, 1.0623, -1.3360, -0.3183, 0.1000, 0.0550 },
|
||||
{ 70, 1.2393, -1.3934, -0.3103, 0.1000, 0.0595 },
|
||||
{ 71, 1.3639, -1.4753, -0.3079, 0.1000, 0.0560 },
|
||||
{ 72, 1.4819, -1.5983, -0.3210, 0.1000, 0.0930 },
|
||||
{ 73, 1.7835, -1.5819, -0.3065, 0.1000, 0.0745 },
|
||||
{ 74, 1.9343, -2.1065, -0.3307, 0.1000, 0.0835 },
|
||||
{ 75, 2.1245, -2.3196, -0.3314, 0.1000, 0.0920 },
|
||||
{ 76, 2.2556, -2.3032, -0.3230, 0.1000, 0.0800 },
|
||||
{ 77, 2.4196, -2.3688, -0.3165, 0.1000, 0.0625 },
|
||||
{ 78, 1.7835, -2.5327, -0.3543, 0.1000, 0.0715 },
|
||||
{ 79, 1.7180, -2.8933, -0.3742, 0.1000, 0.0945 },
|
||||
{ 80, 1.9343, -3.0409, -0.3727, 0.1000, 0.0915 },
|
||||
{ 81, 2.4524, -3.4671, -0.3900, 0.1000, 0.0685 },
|
||||
{ 82, 2.4786, -2.8851, -0.3538, 0.1000, 0.0830 },
|
||||
{ 83, 2.3343, -2.6228, -0.3420, 0.1000, 0.0830 },
|
||||
{ 84, 2.8130, -2.0737, -0.2706, 0.1000, 0.0890 },
|
||||
{ 85, 2.6360, -1.8278, -0.2661, 0.1000, 0.0975 },
|
||||
{ 86, 2.3958, -1.7130, -0.2774, 0.2000, 0.1555 },
|
||||
{ 87, 2.2688, -1.2868, -0.2646, 0.1000, 0.0835 },
|
||||
{ 88, 2.4196, -1.1147, -0.2486, 0.1000, 0.0770 },
|
||||
{ 89, 2.7802, -2.3933, -0.3017, 0.1000, 0.0655 },
|
||||
{ 90, 3.0163, -2.4179, -0.2905, 0.1000, 0.0725 },
|
||||
{ 91, 2.9310, -2.2540, -0.2798, 0.1000, 0.0910 },
|
||||
{ 92, 2.6622, -2.0983, -0.2823, 0.1000, 0.0680 },
|
||||
{ 93, 2.3147, -1.9753, -0.2973, 0.1000, 0.0620 },
|
||||
{ 94, 2.1573, -1.8770, -0.3013, 0.1000, 0.0525 },
|
||||
{ 95, 2.0196, -1.7868, -0.3044, 0.1000, 0.0970 },
|
||||
{ 96, 2.7802, -3.3031, -0.3900, 0.1000, 0.0510 },
|
||||
{ 97, 2.8589, -3.1720, -0.3900, 0.1000, 0.0755 },
|
||||
{ 98, 3.0163, -2.8114, -0.3383, 0.1000, 0.0835 },
|
||||
{ 99, 3.5081, -2.4179, -0.2558, 0.1000, 0.0770 },
|
||||
{ 100, 3.5277, -2.3196, -0.2366, 0.1000, 0.0765 },
|
||||
{ 101, 3.6654, -2.5819, -0.2566, 0.1000, 0.0805 },
|
||||
{ 102, 3.7179, -2.7622, -0.2706, 0.1000, 0.0980 },
|
||||
{ 103, 3.7769, -2.4671, -0.2339, 0.1000, 0.0640 },
|
||||
{ 104, 3.3441, -2.4671, -0.2693, 0.1000, 0.0940 },
|
||||
{ -1, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
static GeoSet *makeTree( _tree *tree, StateSet *dstate )
|
||||
{
|
||||
float vv[][3] =
|
||||
{
|
||||
{ -tree->w/2.0, 0.0, 0.0 },
|
||||
{ tree->w/2.0, 0.0, 0.0 },
|
||||
{ tree->w/2.0, 0.0, 2 * tree->h },
|
||||
{ -tree->w/2.0, 0.0, 2 * tree->h },
|
||||
};
|
||||
|
||||
Vec3 *v = new Vec3[4];
|
||||
Vec2 *t = new Vec2[4];
|
||||
Vec4 *l = new Vec4[1];
|
||||
|
||||
int i;
|
||||
|
||||
l[0][0] = l[0][1] = l[0][2] = l[0][3] = 1;
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
v[i][0] = vv[i][0];
|
||||
v[i][1] = vv[i][1];
|
||||
v[i][2] = vv[i][2];
|
||||
}
|
||||
|
||||
t[0][0] = 0.0; t[0][1] = 0.0;
|
||||
t[1][0] = 1.0; t[1][1] = 0.0;
|
||||
t[2][0] = 1.0; t[2][1] = 1.0;
|
||||
t[3][0] = 0.0; t[3][1] = 1.0;
|
||||
|
||||
GeoSet *gset = new GeoSet;
|
||||
|
||||
gset->setCoords( v );
|
||||
|
||||
gset->setTextureCoords( t );
|
||||
gset->setTextureBinding( GeoSet::BIND_PERVERTEX );
|
||||
|
||||
gset->setColors( l );
|
||||
gset->setColorBinding( GeoSet::BIND_OVERALL );
|
||||
|
||||
gset->setPrimType( GeoSet::QUADS );
|
||||
gset->setNumPrims( 1 );
|
||||
|
||||
gset->setStateSet( dstate );
|
||||
|
||||
return gset;
|
||||
}
|
||||
|
||||
|
||||
static float ttx, tty;
|
||||
|
||||
static int ct( const void *a, const void *b )
|
||||
{
|
||||
_tree *ta = (_tree *)a;
|
||||
_tree *tb = (_tree *)b;
|
||||
|
||||
float da = sqrtf( sqr(ta->x - ttx) + sqr(ta->y - tty) );
|
||||
float db = sqrtf( sqr(tb->x - ttx) + sqr(tb->y - tty) );
|
||||
|
||||
if( da < db )
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Node *makeTrees( void )
|
||||
{
|
||||
Group *group = new Group;
|
||||
int i;
|
||||
|
||||
getDatabaseCenterRadius( dbcenter, &dbradius );
|
||||
struct _tree *t;
|
||||
|
||||
Texture *tex = new Texture;
|
||||
tex->setImage(osgDB::readImageFile("tree0.rgba"));
|
||||
|
||||
StateSet *dstate = new StateSet;
|
||||
|
||||
dstate->setAttributeAndModes( tex, StateAttribute::ON );
|
||||
dstate->setAttribute( new TexEnv );
|
||||
|
||||
dstate->setAttributeAndModes( new Transparency, StateAttribute::ON );
|
||||
|
||||
AlphaFunc* alphaFunc = new AlphaFunc;
|
||||
alphaFunc->setFunction(AlphaFunc::GEQUAL,0.05f);
|
||||
dstate->setAttributeAndModes( alphaFunc, StateAttribute::ON );
|
||||
|
||||
dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
|
||||
|
||||
dstate->setRenderingHint( StateSet::TRANSPARENT_BIN );
|
||||
|
||||
int tt[] = { 15, 30, 45, 58, 72, 75, 93, 96, 105, -1 };
|
||||
int *ttp = tt;
|
||||
|
||||
i = 0;
|
||||
while( i < 105 )
|
||||
{
|
||||
ttx = trees[i].x;
|
||||
tty = trees[i].y;
|
||||
qsort( &trees[i], 105 - i, sizeof( _tree ), ct );
|
||||
|
||||
i += *ttp;
|
||||
ttp++;
|
||||
}
|
||||
|
||||
t = trees;
|
||||
i = 0;
|
||||
ttp = tt;
|
||||
while( *ttp != -1 )
|
||||
{
|
||||
Billboard *bb = new Billboard;
|
||||
//int starti = i;
|
||||
|
||||
for( ; i < (*ttp); i++ )
|
||||
{
|
||||
t->x -= 0.3f;
|
||||
float h = Hat(t->x, t->y, t->z );
|
||||
Vec3 pos( t->x, t->y, t->z-h );
|
||||
GeoSet *gset = makeTree( t, dstate );
|
||||
bb->addDrawable( gset, pos );
|
||||
t++;
|
||||
}
|
||||
group->addChild( bb );
|
||||
ttp++;
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
0
src/Demos/osgconv/Makedepend
Normal file
20
src/Demos/osgconv/Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
#!smake
|
||||
include ../../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
osgconv.cpp
|
||||
|
||||
TARGET = ../../../bin/osgconv
|
||||
|
||||
TARGET_BIN_FILES = osgconv
|
||||
|
||||
#note, use this library list when using the Performer osgPlugin.
|
||||
#LIBS = ${PFLIBS} -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
#note, standard library list.
|
||||
LIBS = -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
C++FLAGS += -I../../../include
|
||||
LDFLAGS += -L../../../lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
119
src/Demos/osgconv/osgconv.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <osg/Group>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
if (argc<2)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<endl;
|
||||
osg::notify(osg::NOTICE)<<"usage:"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" osgconv [options] infile1 [infile2 ...] outfile"<<endl;
|
||||
osg::notify(osg::NOTICE)<<endl;
|
||||
osg::notify(osg::NOTICE)<<"options:"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" -l libraryName - load plugin of name libraryName"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" i.e. -l osgdb_pfb"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" Useful for loading reader/writers which can load"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" other file formats in addition to its extension."<<endl;
|
||||
osg::notify(osg::NOTICE)<<" -e extensionName - load reader/wrter plugin for file extension"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" i.e. -e pfb"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" Useful short hand for specifying full library name as"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" done with -l above, as it automatically expands to the"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" full library name appropriate for each platform."<<endl;
|
||||
osg::notify(osg::NOTICE)<<endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef std::vector<std::string> FileNameList;
|
||||
FileNameList fileNames;
|
||||
|
||||
for(int i = 1; i < argc; i++ )
|
||||
{
|
||||
|
||||
if (argv[i][0]=='-')
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case('l'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
osgDB::Registry::instance()->loadLibrary(argv[i]);
|
||||
}
|
||||
break;
|
||||
case('e'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(argv[i]);
|
||||
osgDB::Registry::instance()->loadLibrary(libName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
fileNames.push_back(argv[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fileNames.empty())
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"No files specfied."<<endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fileNames.size()==1)
|
||||
{
|
||||
osg::Node* root = osgDB::readNodeFile(fileNames.front());
|
||||
if (root)
|
||||
{
|
||||
osgDB::writeNodeFile(*root,"converted.osg");
|
||||
osg::notify(osg::NOTICE)<<"Data written to 'converted.osg'."<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Error no data loaded."<<endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fileNameOut = fileNames.back();
|
||||
fileNames.pop_back();
|
||||
|
||||
osg::Group* group = new osg::Group();
|
||||
for(FileNameList::iterator itr=fileNames.begin();
|
||||
itr<fileNames.end();
|
||||
++itr)
|
||||
{
|
||||
osg::Node* child = osgDB::readNodeFile(*itr);
|
||||
if (child)
|
||||
{
|
||||
group->addChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
if (group->getNumChildren()==0)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Error no data loaded."<<endl;
|
||||
return 1;
|
||||
}
|
||||
else if (group->getNumChildren()==1)
|
||||
{
|
||||
osgDB::writeNodeFile(*(group->getChild(0)),fileNameOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
osgDB::writeNodeFile(*group,fileNameOut);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
0
src/Demos/osgcube/Makedepend
Normal file
15
src/Demos/osgcube/Makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
#!smake
|
||||
include ../../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
osgcube.cpp
|
||||
|
||||
TARGET = ../../../bin/osgcube
|
||||
|
||||
TARGET_BIN_FILES = osgcube
|
||||
|
||||
LIBS = -losgGLUT -losgDB -losgUtil -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
C++FLAGS += -I../../../include
|
||||
LDFLAGS += -L../../../lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
189
src/Demos/osgcube/osgcube.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
// simple animation demo written by Graeme Harkness.
|
||||
// note from Robert to Robert. The animiation techinque
|
||||
// present here using glut timer callbacks is one
|
||||
// approach, other approaches will soon be supported
|
||||
// within the osg itself via an app cullback which
|
||||
// can be attached to nodes themselves. This later
|
||||
// method will be the prefered approach (have a look
|
||||
// at osgreflect's app visitor for a clue.)
|
||||
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Material>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Transform>
|
||||
|
||||
#include <osgUtil/TrackballManipulator>
|
||||
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Global variables - this is basically the stuff which will be animated
|
||||
// ----------------------------------------------------------------------
|
||||
osg::Transform* myTransform;
|
||||
osg::GeoSet* cube;
|
||||
|
||||
int mytime=0; // in milliseconds
|
||||
unsigned int dt=50; // in milliseconds
|
||||
double omega=0.002; // in inverse milliseconds
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// This is the callback function registered with GLUT to be called
|
||||
// at a future time in the GLUT loop
|
||||
// ----------------------------------------------------------------
|
||||
void timedCB( int delta_t )
|
||||
{
|
||||
|
||||
static float lastdx = 0;
|
||||
static float lastdy = 0;
|
||||
static float lastdz = 0;
|
||||
|
||||
mytime+=dt;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Update the Transform so that the cube will appear to oscillate
|
||||
// ---------------------------------------------------------
|
||||
double dx = 0.5 * cos( (double) omega * (double) mytime );
|
||||
double dy = 0.5 * sin( (double) omega * (double) mytime );
|
||||
double dz = 0.0;
|
||||
myTransform->preTranslate( -lastdx, -lastdy, -lastdz );
|
||||
myTransform->preTranslate( (float) dx, (float) dy, dz );
|
||||
lastdx=dx; lastdy=dy; lastdz=dz;
|
||||
|
||||
// Graeme, commeted out this call as the cube itself remains static.
|
||||
// cube->dirtyDisplayList();
|
||||
|
||||
// -------------------------------------------
|
||||
// If required, reschedule the timed callback
|
||||
// -------------------------------------------
|
||||
if ( delta_t != 0 )
|
||||
{
|
||||
glutTimerFunc( (unsigned int) delta_t, timedCB, delta_t );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
osg::Geode* createCube()
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
|
||||
// -------------------------------------------
|
||||
// Set up a new GeoSet which will be our cube
|
||||
// -------------------------------------------
|
||||
cube = new osg::GeoSet();
|
||||
|
||||
// set up the primitives
|
||||
cube->setPrimType( osg::GeoSet::POLYGON );
|
||||
cube->setNumPrims( 6 ); // the six square faces
|
||||
|
||||
// set up the primitive indices
|
||||
int* cubeLengthList = new int[6];
|
||||
cubeLengthList[0] = 4; // each side of the cube has 4 vertices
|
||||
cubeLengthList[1] = 4;
|
||||
cubeLengthList[2] = 4;
|
||||
cubeLengthList[3] = 4;
|
||||
cubeLengthList[4] = 4;
|
||||
cubeLengthList[5] = 4;
|
||||
|
||||
cube->setPrimLengths( cubeLengthList );
|
||||
|
||||
|
||||
// set up the coordinates.
|
||||
osg::Vec3 *cubeCoords = new osg::Vec3[24];
|
||||
cubeCoords[0].set( -1.0000f, 1.0000f, -1.000f );
|
||||
cubeCoords[1].set( 1.0000f, 1.0000f, -1.0000f );
|
||||
cubeCoords[2].set( 1.0000f, -1.0000f, -1.0000f );
|
||||
cubeCoords[3].set( -1.0000f, -1.0000f, -1.000 );
|
||||
|
||||
cubeCoords[4].set( 1.0000f, 1.0000f, -1.0000f );
|
||||
cubeCoords[5].set( 1.0000f, 1.0000f, 1.0000f );
|
||||
cubeCoords[6].set( 1.0000f, -1.0000f, 1.0000f );
|
||||
cubeCoords[7].set( 1.0000f, -1.0000f, -1.0000f );
|
||||
|
||||
cubeCoords[8].set( 1.0000f, 1.0000f, 1.0000f );
|
||||
cubeCoords[9].set( -1.0000f, 1.0000f, 1.000f );
|
||||
cubeCoords[10].set( -1.0000f, -1.0000f, 1.000f );
|
||||
cubeCoords[11].set( 1.0000f, -1.0000f, 1.0000f );
|
||||
|
||||
cubeCoords[12].set( -1.0000f, 1.0000f, 1.000 );
|
||||
cubeCoords[13].set( -1.0000f, 1.0000f, -1.000 );
|
||||
cubeCoords[14].set( -1.0000f, -1.0000f, -1.000 );
|
||||
cubeCoords[15].set( -1.0000f, -1.0000f, 1.000 );
|
||||
|
||||
cubeCoords[16].set( -1.0000f, 1.0000f, 1.000 );
|
||||
cubeCoords[17].set( 1.0000f, 1.0000f, 1.0000f );
|
||||
cubeCoords[18].set( 1.0000f, 1.0000f, -1.0000f );
|
||||
cubeCoords[19].set( -1.0000f, 1.0000f, -1.000f );
|
||||
|
||||
cubeCoords[20].set( -1.0000f, -1.0000f, 1.000f );
|
||||
cubeCoords[21].set( -1.0000f, -1.0000f, -1.000f );
|
||||
cubeCoords[22].set( 1.0000f, -1.0000f, -1.0000f );
|
||||
cubeCoords[23].set( 1.0000f, -1.0000f, 1.0000f );
|
||||
|
||||
cube->setCoords( cubeCoords );
|
||||
|
||||
|
||||
// set up the normals.
|
||||
osg::Vec3 *cubeNormals = new osg::Vec3[6];
|
||||
cubeNormals[0].set(0.0f,0.0f,-1.0f);
|
||||
cubeNormals[1].set(1.0f,0.0f,0.0f);
|
||||
cubeNormals[2].set(0.0f,0.0f,1.0f);
|
||||
cubeNormals[3].set(-1.0f,0.0f,0.0f);
|
||||
cubeNormals[4].set(0.0f,1.0f,0.0f);
|
||||
cubeNormals[5].set(0.0f,-1.0f,0.0f);
|
||||
cube->setNormals( cubeNormals );
|
||||
cube->setNormalBinding( osg::GeoSet::BIND_PERPRIM );
|
||||
|
||||
// ---------------------------------------
|
||||
// Set up a StateSet to make the cube red
|
||||
// ---------------------------------------
|
||||
osg::StateSet* cubeState = new osg::StateSet();
|
||||
osg::Material* redMaterial = new osg::Material();
|
||||
osg::Vec4 red( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
redMaterial->setEmission( osg::Material::FRONT_AND_BACK, red );
|
||||
redMaterial->setAmbient( osg::Material::FRONT_AND_BACK, red );
|
||||
redMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, red );
|
||||
redMaterial->setSpecular( osg::Material::FRONT_AND_BACK, red );
|
||||
cubeState->setAttribute( redMaterial );
|
||||
|
||||
cube->setStateSet( cubeState );
|
||||
|
||||
geode->addDrawable( cube );
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
glutInit( &argc, argv );
|
||||
|
||||
|
||||
myTransform = new osg::Transform();
|
||||
myTransform->addChild( createCube() );
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Register a timer callback with GLUT, in the first instance as a test
|
||||
// This will call the function "timedCB(value)" after dt ms
|
||||
// I have decided to use value as the time for the next scheduling
|
||||
// If the last parameter=0 then don't reschedule the timer.
|
||||
// ---------------------------------------------------------------------
|
||||
glutTimerFunc( dt, timedCB, dt );
|
||||
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.addViewport( myTransform );
|
||||
|
||||
// register trackball, flight and drive.
|
||||
viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
|
||||
|
||||
viewer.open();
|
||||
|
||||
viewer.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
0
src/Demos/osgimpostor/Makedepend
Normal file
21
src/Demos/osgimpostor/Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
#!smake
|
||||
include ../../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
osgimpostor.cpp
|
||||
|
||||
TARGET = ../../../bin/osgimpostor
|
||||
|
||||
TARGET_BIN_FILES = osgimpostor
|
||||
|
||||
#note, use this library list when using the Performer osgPlugin.
|
||||
#LIBS = ${PFLIBS} -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
#note, standard library list.
|
||||
LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
C++FLAGS += -I../../../include
|
||||
LDFLAGS += -L../../../lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
|
||||
26
src/Demos/osgimpostor/README
Normal file
@@ -0,0 +1,26 @@
|
||||
Note: Using sgv with Peformer (for IRIX and Linux users only)
|
||||
=============================================================
|
||||
|
||||
If you find problems with loading .pfb files its likely that its due to undefined
|
||||
symbols. This isn't a problem with the OSG implementation, but alas the only
|
||||
current solution is to directly link you app with the Performer libraries. The
|
||||
Makefile contains two library list. In Makefile you'll see something like :
|
||||
|
||||
#note, use this library list when using the Performer osgPlugin.
|
||||
#LIBS = ${PFLIBS} -losgGLUT -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
#note, standard library list.
|
||||
LIBS = -losgGLUT -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
Simple comment in the LIBS line with PFLIBS and comment out the standard LIBS,
|
||||
then :
|
||||
|
||||
make clean
|
||||
make
|
||||
|
||||
Hopefully the Performer distribution will eventually work as a dynamic plugin
|
||||
but until that day we're stuck with this 'hack'...
|
||||
|
||||
|
||||
Robert Osfield,
|
||||
March 20001.
|
||||
198
src/Demos/osgimpostor/osgimpostor.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#ifdef USE_MEM_CHECK
|
||||
#include <mcheck.h>
|
||||
#endif
|
||||
|
||||
#include <osg/Impostor>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <osgUtil/TrackballManipulator>
|
||||
#include <osgUtil/FlightManipulator>
|
||||
#include <osgUtil/DriveManipulator>
|
||||
#include <osgUtil/InsertImpostorsVisitor>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
#include <osg/Quat>
|
||||
|
||||
/*
|
||||
* Function to read several files (typically one) as specified on the command
|
||||
* line, and return them in an osg::Node
|
||||
*/
|
||||
osg::Node* getNodeFromFiles(int argc,char **argv)
|
||||
{
|
||||
osg::Node *rootnode = new osg::Node;
|
||||
|
||||
int i;
|
||||
|
||||
typedef std::vector<osg::Node*> NodeList;
|
||||
NodeList nodeList;
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
|
||||
if (argv[i][0]=='-')
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case('l'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
osgDB::Registry::instance()->loadLibrary(argv[i]);
|
||||
}
|
||||
break;
|
||||
case('e'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(argv[i]);
|
||||
osgDB::Registry::instance()->loadLibrary(libName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
osg::Node *node = osgDB::readNodeFile( argv[i] );
|
||||
|
||||
if( node != (osg::Node *)0L )
|
||||
{
|
||||
if (node->getName().empty()) node->setName( argv[i] );
|
||||
nodeList.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (nodeList.size()==0)
|
||||
{
|
||||
osg::notify(osg::WARN) << "No data loaded."<<endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (nodeList.size()==1)
|
||||
{
|
||||
rootnode = nodeList.front();
|
||||
}
|
||||
else // size >1
|
||||
{
|
||||
osg::Group* group = new osg::Group();
|
||||
for(NodeList::iterator itr=nodeList.begin();
|
||||
itr!=nodeList.end();
|
||||
++itr)
|
||||
{
|
||||
group->addChild(*itr);
|
||||
}
|
||||
|
||||
rootnode = group;
|
||||
}
|
||||
|
||||
return rootnode;
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
#ifdef USE_MEM_CHECK
|
||||
mtrace();
|
||||
#endif
|
||||
|
||||
// initialize the GLUT
|
||||
glutInit( &argc, argv );
|
||||
|
||||
if (argc<2)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"usage:"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" osgimpostor [options] infile1 [infile2 ...]"<<endl;
|
||||
osg::notify(osg::NOTICE)<<endl;
|
||||
osg::notify(osg::NOTICE)<<"options:"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" -l libraryName - load plugin of name libraryName"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" i.e. -l osgdb_pfb"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" Useful for loading reader/writers which can load"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" other file formats in addition to its extension."<<endl;
|
||||
osg::notify(osg::NOTICE)<<" -e extensionName - load reader/wrter plugin for file extension"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" i.e. -e pfb"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" Useful short hand for specifying full library name as"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" done with -l above, as it automatically expands to the"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" full library name appropriate for each platform."<<endl;
|
||||
osg::notify(osg::NOTICE)<<endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
osg::Timer timer;
|
||||
osg::Timer_t before_load = timer.tick();
|
||||
|
||||
osg::Node* model = getNodeFromFiles( argc, argv);
|
||||
|
||||
|
||||
// the osgUtil::InsertImpostorsVisitor used lower down to insert impostors
|
||||
// only operators on subclass of Group's, if the model top node is not
|
||||
// a group then it won't be able to insert an impostor. We therefore
|
||||
// manually insert an impostor above the model.
|
||||
if (dynamic_cast<osg::Group*>(model)==0)
|
||||
{
|
||||
const osg::BoundingSphere& bs = model->getBound();
|
||||
if (bs.isValid())
|
||||
{
|
||||
|
||||
osg::Impostor* impostor = new osg::Impostor;
|
||||
|
||||
// standard LOD settings
|
||||
impostor->addChild(model);
|
||||
impostor->setRange(0,0.0f);
|
||||
impostor->setRange(1,1e7f);
|
||||
impostor->setCenter(bs.center());
|
||||
|
||||
// impostor specfic settings.
|
||||
impostor->setImpostorThresholdToBound(5.0f);
|
||||
|
||||
model = impostor;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// we insert an impostor node above the model, so we keep a handle
|
||||
// on the rootnode of the model, the is required since the
|
||||
// InsertImpostorsVisitor can add a new root in automatically and
|
||||
// we would know about it, other than by following the parent path
|
||||
// up from model. This is really what should be done, but I'll pass
|
||||
// on it right now as it requires a getRoots() method to be added to
|
||||
// osg::Node, and we're about to make a release so no new features!
|
||||
osg::Group* rootnode = new osg::Group;
|
||||
rootnode->addChild(model);
|
||||
|
||||
|
||||
// now insert impostors in the model using the InsertImpostorsVisitor.
|
||||
osgUtil::InsertImpostorsVisitor ov;
|
||||
|
||||
// traverse the model and collect all osg::Group's and osg::LOD's.
|
||||
// however, don't traverse the rootnode since we want to keep it as
|
||||
// the start of traversal, otherwise the insertImpostor could insert
|
||||
// and Impostor above the current root, making it nolonger a root!
|
||||
model->accept(ov);
|
||||
|
||||
// insert the Impostors above groups and LOD's
|
||||
ov.insertImpostors();
|
||||
|
||||
|
||||
osg::Timer_t after_load = timer.tick();
|
||||
cout << "Time for load = "<<timer.delta_s(before_load,after_load)<<" seconds"<<endl;
|
||||
|
||||
// initialize the viewer.
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.addViewport( rootnode );
|
||||
|
||||
// register trackball, flight and drive.
|
||||
viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
|
||||
viewer.registerCameraManipulator(new osgUtil::FlightManipulator);
|
||||
viewer.registerCameraManipulator(new osgUtil::DriveManipulator);
|
||||
|
||||
viewer.open();
|
||||
viewer.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
0
src/Demos/osgviews/Makedepend
Normal file
21
src/Demos/osgviews/Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
#!smake
|
||||
include ../../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
osgviews.cpp
|
||||
|
||||
TARGET = ../../../bin/osgviews
|
||||
|
||||
TARGET_BIN_FILES = osgviews
|
||||
|
||||
#note, use this library list when using the Performer osgPlugin.
|
||||
#LIBS = ${PFLIBS} -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
#note, standard library list.
|
||||
LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
C++FLAGS += -I../../../include
|
||||
LDFLAGS += -L../../../lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
|
||||
26
src/Demos/osgviews/README
Normal file
@@ -0,0 +1,26 @@
|
||||
Note: Using sgv with Peformer (for IRIX and Linux users only)
|
||||
=============================================================
|
||||
|
||||
If you find problems with loading .pfb files its likely that its due to undefined
|
||||
symbols. This isn't a problem with the OSG implementation, but alas the only
|
||||
current solution is to directly link you app with the Performer libraries. The
|
||||
Makefile contains two library list. In Makefile you'll see something like :
|
||||
|
||||
#note, use this library list when using the Performer osgPlugin.
|
||||
#LIBS = ${PFLIBS} -losgGLUT -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
#note, standard library list.
|
||||
LIBS = -losgGLUT -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
Simple comment in the LIBS line with PFLIBS and comment out the standard LIBS,
|
||||
then :
|
||||
|
||||
make clean
|
||||
make
|
||||
|
||||
Hopefully the Performer distribution will eventually work as a dynamic plugin
|
||||
but until that day we're stuck with this 'hack'...
|
||||
|
||||
|
||||
Robert Osfield,
|
||||
March 20001.
|
||||
148
src/Demos/osgviews/osgviews.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#ifdef USE_MEM_CHECK
|
||||
#include <mcheck.h>
|
||||
#endif
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <osgUtil/TrackballManipulator>
|
||||
#include <osgUtil/FlightManipulator>
|
||||
#include <osgUtil/DriveManipulator>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
#include <osg/Quat>
|
||||
|
||||
/*
|
||||
* Function to read several files (typically one) as specified on the command
|
||||
* line, and return them in an osg::Node
|
||||
*/
|
||||
osg::Node* getNodeFromFiles(int argc,char **argv)
|
||||
{
|
||||
osg::Node *rootnode = new osg::Node;
|
||||
|
||||
int i;
|
||||
|
||||
typedef std::vector<osg::Node*> NodeList;
|
||||
NodeList nodeList;
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
|
||||
if (argv[i][0]=='-')
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case('l'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
osgDB::Registry::instance()->loadLibrary(argv[i]);
|
||||
}
|
||||
break;
|
||||
case('e'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(argv[i]);
|
||||
osgDB::Registry::instance()->loadLibrary(libName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
osg::Node *node = osgDB::readNodeFile( argv[i] );
|
||||
|
||||
if( node != (osg::Node *)0L )
|
||||
{
|
||||
if (node->getName().empty()) node->setName( argv[i] );
|
||||
nodeList.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (nodeList.size()==0)
|
||||
{
|
||||
osg::notify(osg::WARN) << "No data loaded."<<endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (nodeList.size()==1)
|
||||
{
|
||||
rootnode = nodeList.front();
|
||||
}
|
||||
else // size >1
|
||||
{
|
||||
osg::Group* group = new osg::Group();
|
||||
for(NodeList::iterator itr=nodeList.begin();
|
||||
itr!=nodeList.end();
|
||||
++itr)
|
||||
{
|
||||
group->addChild(*itr);
|
||||
}
|
||||
|
||||
rootnode = group;
|
||||
}
|
||||
|
||||
return rootnode;
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
#ifdef USE_MEM_CHECK
|
||||
mtrace();
|
||||
#endif
|
||||
|
||||
// initialize the GLUT
|
||||
glutInit( &argc, argv );
|
||||
|
||||
if (argc<2)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"usage:"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" osgviews [options] infile1 [infile2 ...]"<<endl;
|
||||
osg::notify(osg::NOTICE)<<endl;
|
||||
osg::notify(osg::NOTICE)<<"options:"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" -l libraryName - load plugin of name libraryName"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" i.e. -l osgdb_pfb"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" Useful for loading reader/writers which can load"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" other file formats in addition to its extension."<<endl;
|
||||
osg::notify(osg::NOTICE)<<" -e extensionName - load reader/wrter plugin for file extension"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" i.e. -e pfb"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" Useful short hand for specifying full library name as"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" done with -l above, as it automatically expands to the"<<endl;
|
||||
osg::notify(osg::NOTICE)<<" full library name appropriate for each platform."<<endl;
|
||||
osg::notify(osg::NOTICE)<<endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
osg::Timer timer;
|
||||
osg::Timer_t before_load = timer.tick();
|
||||
|
||||
osg::Node* rootnode = getNodeFromFiles( argc, argv);
|
||||
|
||||
osg::Timer_t after_load = timer.tick();
|
||||
cout << "Time for load = "<<timer.delta_s(before_load,after_load)<<" seconds"<<endl;
|
||||
|
||||
// initialize the viewer.
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.addViewport( rootnode,0.0,0.0,0.5,0.5);
|
||||
viewer.addViewport( rootnode,0.5,0.0,0.5,0.5);
|
||||
viewer.addViewport( rootnode,0.0,0.5,1.0,0.5);
|
||||
|
||||
// register trackball, flight and drive.
|
||||
viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
|
||||
viewer.registerCameraManipulator(new osgUtil::FlightManipulator);
|
||||
viewer.registerCameraManipulator(new osgUtil::DriveManipulator);
|
||||
|
||||
viewer.open();
|
||||
viewer.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -8,12 +8,14 @@ TARGET = ../../../bin/sgv
|
||||
|
||||
TARGET_BIN_FILES = sgv
|
||||
|
||||
# LIBS = -losg -lglut -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
# C++FLAGS += -I../../include
|
||||
# LDFLAGS += -L../../lib -L/usr/X11R6/lib
|
||||
#note, use this library list when using the Performer osgPlugin.
|
||||
#LIBS = ${PFLIBS} -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
#note, standard library list.
|
||||
LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
LIBS = -losgGLUT -losgUtil -losg -lglut -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
C++FLAGS += -I../../../include
|
||||
LDFLAGS += -L../../../lib -L/usr/X11R6/lib
|
||||
LDFLAGS += -L../../../lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
#include "osg/OSG"
|
||||
#include "osg/Node"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Notify"
|
||||
#ifdef USE_MEM_CHECK
|
||||
#include <mcheck.h>
|
||||
#endif
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <osgUtil/TrackballManipulator>
|
||||
#include <osgUtil/FlightManipulator>
|
||||
#include <osgUtil/DriveManipulator>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include "osgGLUT/Viewer"
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
#include <osg/Quat>
|
||||
|
||||
/*
|
||||
* Function to read several files (typically one) as specified on the command
|
||||
@@ -25,33 +36,33 @@ osg::Node* getNodeFromFiles(int argc,char **argv)
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case('l'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
osg::Registry::instance()->loadLibrary(argv[i]);
|
||||
}
|
||||
break;
|
||||
case('e'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
std::string libName = osg::Registry::instance()->createLibraryNameForExt(argv[i]);
|
||||
osg::Registry::instance()->loadLibrary(libName);
|
||||
}
|
||||
break;
|
||||
case('l'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
osgDB::Registry::instance()->loadLibrary(argv[i]);
|
||||
}
|
||||
break;
|
||||
case('e'):
|
||||
++i;
|
||||
if (i<argc)
|
||||
{
|
||||
std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(argv[i]);
|
||||
osgDB::Registry::instance()->loadLibrary(libName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
osg::Node *node = osg::loadNodeFile( argv[i] );
|
||||
osg::Node *node = osgDB::readNodeFile( argv[i] );
|
||||
|
||||
if( node != (osg::Node *)0L )
|
||||
{
|
||||
if (node->getName().empty()) node->setName( argv[i] );
|
||||
nodeList.push_back(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (nodeList.size()==0)
|
||||
@@ -59,12 +70,12 @@ osg::Node* getNodeFromFiles(int argc,char **argv)
|
||||
osg::notify(osg::WARN) << "No data loaded."<<endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
if (nodeList.size()==1)
|
||||
{
|
||||
rootnode = nodeList.front();
|
||||
}
|
||||
else // size >1
|
||||
else // size >1
|
||||
{
|
||||
osg::Group* group = new osg::Group();
|
||||
for(NodeList::iterator itr=nodeList.begin();
|
||||
@@ -76,7 +87,7 @@ osg::Node* getNodeFromFiles(int argc,char **argv)
|
||||
|
||||
rootnode = group;
|
||||
}
|
||||
|
||||
|
||||
return rootnode;
|
||||
}
|
||||
|
||||
@@ -84,6 +95,13 @@ osg::Node* getNodeFromFiles(int argc,char **argv)
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
#ifdef USE_MEM_CHECK
|
||||
mtrace();
|
||||
#endif
|
||||
|
||||
// initialize the GLUT
|
||||
glutInit( &argc, argv );
|
||||
|
||||
if (argc<2)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"usage:"<<endl;
|
||||
@@ -104,15 +122,25 @@ int main( int argc, char **argv )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
osg::Node* rootnode = getNodeFromFiles( argc, argv);
|
||||
|
||||
osgGLUT::Viewer viewer;
|
||||
glutInit( &argc, argv );
|
||||
viewer.init( rootnode );
|
||||
viewer.run();
|
||||
osg::Timer timer;
|
||||
osg::Timer_t before_load = timer.tick();
|
||||
|
||||
osg::Node* rootnode = getNodeFromFiles( argc, argv);
|
||||
|
||||
osg::Timer_t after_load = timer.tick();
|
||||
cout << "Time for load = "<<timer.delta_s(before_load,after_load)<<" seconds"<<endl;
|
||||
|
||||
// initialize the viewer.
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.addViewport( rootnode );
|
||||
|
||||
// register trackball, flight and drive.
|
||||
viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
|
||||
viewer.registerCameraManipulator(new osgUtil::FlightManipulator);
|
||||
viewer.registerCameraManipulator(new osgUtil::DriveManipulator);
|
||||
|
||||
viewer.open();
|
||||
viewer.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
0
src/Demos/wxsgv/Makedepend
Normal file
27
src/Demos/wxsgv/Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
#!smake
|
||||
include ../../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
$(wildcard *.cpp)
|
||||
|
||||
TARGET = ../../../bin/wxsgv
|
||||
|
||||
TARGET_BIN_FILES = wxsgv
|
||||
|
||||
C++FLAGS += -I../../include `wx-config --cflags`
|
||||
|
||||
#note, use this library list when using the Performer osgPlugin.
|
||||
#LIBS = ${PFLIBS} -losgWX -losgUtil -losgDB -losg \
|
||||
# `wx-config --libs` -lwx_gtk_gl \
|
||||
# -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
#note, standard library list.
|
||||
LIBS = -losgWX -losgUtil -losgDB -losg \
|
||||
`wx-config --libs` -lwx_gtk_gl \
|
||||
-lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
|
||||
C++FLAGS += -I../../../include -I./icons
|
||||
LDFLAGS += -L../../../lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
|
||||
314
src/Demos/wxsgv/SceneGraphDlg.cpp
Normal file
@@ -0,0 +1,314 @@
|
||||
//
|
||||
// Name: SceneGraphDlg.cpp
|
||||
// Author: Ben Discoe, ben@washedashore.com
|
||||
//
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "SceneGraphDlg.cpp"
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
#ifndef WX_PRECOMP
|
||||
# include "wx/wx.h"
|
||||
#endif
|
||||
#include "wx/treectrl.h"
|
||||
#include <typeinfo>
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/LightSource>
|
||||
#include <osg/LOD>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Transform>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/ImpostorSprite>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#include "app.h"
|
||||
DECLARE_APP(wxosgApp)
|
||||
|
||||
//#include <string>
|
||||
|
||||
#include "SceneGraphDlg.h"
|
||||
|
||||
#if defined(__WXGTK__) || defined(__WXMOTIF__)
|
||||
# include "wxsgv.xpm"
|
||||
# include "icon1.xpm"
|
||||
# include "icon2.xpm"
|
||||
# include "icon3.xpm"
|
||||
# include "icon4.xpm"
|
||||
# include "icon5.xpm"
|
||||
# include "icon6.xpm"
|
||||
# include "icon7.xpm"
|
||||
# include "icon8.xpm"
|
||||
# include "icon9.xpm"
|
||||
# include "icon10.xpm"
|
||||
#endif
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
class MyTreeItemData : public wxTreeItemData
|
||||
{
|
||||
public:
|
||||
MyTreeItemData(Node *pNode)
|
||||
{
|
||||
m_pNode = pNode;
|
||||
}
|
||||
Node *m_pNode;
|
||||
};
|
||||
|
||||
|
||||
// WDR: class implementations
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SceneGraphDlg
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// WDR: event table for SceneGraphDlg
|
||||
|
||||
BEGIN_EVENT_TABLE(SceneGraphDlg,wxDialog)
|
||||
EVT_INIT_DIALOG (SceneGraphDlg::OnInitDialog)
|
||||
EVT_TREE_SEL_CHANGED( ID_SCENETREE, SceneGraphDlg::OnTreeSelChanged )
|
||||
EVT_BUTTON( ID_ZOOMTO, SceneGraphDlg::OnZoomTo )
|
||||
EVT_BUTTON( ID_REFRESH, SceneGraphDlg::OnRefresh )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
SceneGraphDlg::SceneGraphDlg( wxWindow *parent, wxWindowID id, const wxString &title,
|
||||
const wxPoint &position, const wxSize& size, long style ) :
|
||||
wxDialog( parent, id, title, position, size, style )
|
||||
{
|
||||
SceneGraphFunc( this, TRUE );
|
||||
|
||||
m_pZoomTo = GetZoomto();
|
||||
m_pTree = GetScenetree();
|
||||
|
||||
m_pZoomTo->Enable(false);
|
||||
|
||||
m_imageListNormal = NULL;
|
||||
CreateImageList(16);
|
||||
}
|
||||
|
||||
SceneGraphDlg::~SceneGraphDlg()
|
||||
{
|
||||
}
|
||||
|
||||
///////////
|
||||
|
||||
void SceneGraphDlg::CreateImageList(int size)
|
||||
{
|
||||
delete m_imageListNormal;
|
||||
|
||||
if ( size == -1 )
|
||||
{
|
||||
m_imageListNormal = NULL;
|
||||
return;
|
||||
}
|
||||
// Make an image list containing small icons
|
||||
m_imageListNormal = new wxImageList(size, size, TRUE);
|
||||
|
||||
// should correspond to TreeCtrlIcon_xxx enum
|
||||
wxIcon icons[10];
|
||||
icons[0] = wxICON(icon1);
|
||||
icons[1] = wxICON(icon2);
|
||||
icons[2] = wxICON(icon3);
|
||||
icons[3] = wxICON(icon4);
|
||||
icons[4] = wxICON(icon5);
|
||||
icons[5] = wxICON(icon6);
|
||||
icons[6] = wxICON(icon7);
|
||||
icons[7] = wxICON(icon8);
|
||||
icons[8] = wxICON(icon9);
|
||||
icons[9] = wxICON(icon10);
|
||||
|
||||
int sizeOrig = icons[0].GetWidth();
|
||||
for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
|
||||
{
|
||||
if ( size == sizeOrig )
|
||||
m_imageListNormal->Add(icons[i]);
|
||||
else
|
||||
m_imageListNormal->Add(wxImage(icons[i]).Rescale(size, size).
|
||||
ConvertToBitmap());
|
||||
}
|
||||
m_pTree->SetImageList(m_imageListNormal);
|
||||
}
|
||||
|
||||
|
||||
void SceneGraphDlg::RefreshTreeContents()
|
||||
{
|
||||
// start with a blank slate
|
||||
m_pTree->DeleteAllItems();
|
||||
|
||||
Node *pRoot = wxGetApp().Root();
|
||||
if (!pRoot)
|
||||
return;
|
||||
|
||||
// Fill in the tree with nodes
|
||||
wxTreeItemId hRootItem = m_pTree->AddRoot("Root");
|
||||
AddNodeItemsRecursively(hRootItem, pRoot, 0);
|
||||
m_pTree->Expand(hRootItem);
|
||||
|
||||
m_pSelectedNode = NULL;
|
||||
}
|
||||
|
||||
|
||||
void SceneGraphDlg::AddNodeItemsRecursively(wxTreeItemId hParentItem,
|
||||
Node *pNode, int depth)
|
||||
{
|
||||
wxString str;
|
||||
int nImage;
|
||||
wxTreeItemId hNewItem;
|
||||
|
||||
if (!pNode) return;
|
||||
|
||||
else if (dynamic_cast<LightSource*>(pNode))
|
||||
{
|
||||
str = "Light";
|
||||
nImage = 4;
|
||||
}
|
||||
else if (dynamic_cast<Geode*>(pNode))
|
||||
{
|
||||
str = "Geode";
|
||||
nImage = 2;
|
||||
}
|
||||
else if (dynamic_cast<LOD*>(pNode))
|
||||
{
|
||||
str = "LOD";
|
||||
nImage = 5;
|
||||
}
|
||||
else if (dynamic_cast<Transform*>(pNode))
|
||||
{
|
||||
str = "XForm";
|
||||
nImage = 9;
|
||||
}
|
||||
else if (dynamic_cast<Group*>(pNode))
|
||||
{
|
||||
// must be just a group for grouping's sake
|
||||
str = "Group";
|
||||
nImage = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// must be something else
|
||||
str = "Other";
|
||||
nImage = 8;
|
||||
}
|
||||
std::string name = pNode->getName();
|
||||
if (!name.empty())
|
||||
{
|
||||
const char *name2 = name.c_str();
|
||||
str += " \"";
|
||||
str += name2;
|
||||
str += "\"";
|
||||
}
|
||||
|
||||
hNewItem = m_pTree->AppendItem(hParentItem, str, nImage, nImage);
|
||||
|
||||
Geode *pGeode = dynamic_cast<Geode*>(pNode);
|
||||
if (pGeode)
|
||||
{
|
||||
int num_mesh = pGeode->getNumDrawables();
|
||||
wxTreeItemId hDItem;
|
||||
|
||||
for (int i = 0; i < num_mesh; i++)
|
||||
{
|
||||
Drawable *pDraw = pGeode->getDrawable(i);
|
||||
GeoSet *pGeoSet = dynamic_cast<GeoSet*>(pDraw);
|
||||
if (pGeoSet)
|
||||
{
|
||||
int iNumPrim = pGeoSet->getNumPrims();
|
||||
|
||||
GeoSet::PrimitiveType pt = pGeoSet->getPrimType();
|
||||
const char *mtype;
|
||||
switch (pt)
|
||||
{
|
||||
case (GeoSet::POINTS) : mtype = "Points"; break;
|
||||
case (GeoSet::LINES) : mtype = "Lines"; break;
|
||||
case (GeoSet::LINE_LOOP) : mtype = "LineLoop"; break;
|
||||
case (GeoSet::LINE_STRIP): mtype = "LineStrip"; break;
|
||||
case (GeoSet::FLAT_LINE_STRIP) : mtype = "FlatLineStrip"; break;
|
||||
case (GeoSet::TRIANGLES) : mtype = "Triangles"; break;
|
||||
case (GeoSet::TRIANGLE_STRIP) : mtype = "TriStrip"; break;
|
||||
case (GeoSet::FLAT_TRIANGLE_STRIP) : mtype = "FlatTriStrip"; break;
|
||||
case (GeoSet::TRIANGLE_FAN) : mtype = "TriFan"; break;
|
||||
case (GeoSet::FLAT_TRIANGLE_FAN) : mtype = "FlatTriFan"; break;
|
||||
case (GeoSet::QUADS) : mtype = "Quads"; break;
|
||||
case (GeoSet::QUAD_STRIP) : mtype = "QuadStrip"; break;
|
||||
case (GeoSet::POLYGON) : mtype = "Polygon"; break;
|
||||
}
|
||||
str.Printf("GeoSet %d, %s, %d prims", i, mtype, iNumPrim);
|
||||
hDItem = m_pTree->AppendItem(hNewItem, str, 6, 6);
|
||||
}
|
||||
ImpostorSprite *pImpostorSprite = dynamic_cast<ImpostorSprite*>(pDraw);
|
||||
if (pImpostorSprite)
|
||||
{
|
||||
str.Printf("ImposterSprite");
|
||||
hDItem = m_pTree->AppendItem(hNewItem, str, 9, 9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_pTree->SetItemData(hNewItem, new MyTreeItemData(pNode));
|
||||
|
||||
Group *pGroup = dynamic_cast<Group*>(pNode);
|
||||
if (pGroup)
|
||||
{
|
||||
int num_children = pGroup->getNumChildren();
|
||||
if (num_children > 200)
|
||||
{
|
||||
wxTreeItemId hSubItem;
|
||||
str.Format("(%d children)", num_children);
|
||||
hSubItem = m_pTree->AppendItem(hNewItem, str, 8, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < num_children; i++)
|
||||
{
|
||||
Node *pChild = pGroup->getChild(i);
|
||||
if (!pChild) continue;
|
||||
|
||||
AddNodeItemsRecursively(hNewItem, pChild, depth+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// expand a bit so that the tree is initially partially exposed
|
||||
if (depth < 2)
|
||||
m_pTree->Expand(hNewItem);
|
||||
}
|
||||
|
||||
|
||||
// WDR: handler implementations for SceneGraphDlg
|
||||
|
||||
void SceneGraphDlg::OnRefresh( wxCommandEvent &event )
|
||||
{
|
||||
RefreshTreeContents();
|
||||
}
|
||||
|
||||
void SceneGraphDlg::OnZoomTo( wxCommandEvent &event )
|
||||
{
|
||||
if (m_pSelectedNode)
|
||||
wxGetApp().ZoomTo(m_pSelectedNode);
|
||||
}
|
||||
|
||||
void SceneGraphDlg::OnTreeSelChanged( wxTreeEvent &event )
|
||||
{
|
||||
wxTreeItemId item = event.GetItem();
|
||||
MyTreeItemData *data = (MyTreeItemData *)m_pTree->GetItemData(item);
|
||||
|
||||
m_pSelectedNode = NULL;
|
||||
|
||||
if (data && data->m_pNode)
|
||||
{
|
||||
m_pSelectedNode = data->m_pNode;
|
||||
m_pZoomTo->Enable(true);
|
||||
}
|
||||
else
|
||||
m_pZoomTo->Enable(false);
|
||||
}
|
||||
|
||||
void SceneGraphDlg::OnInitDialog(wxInitDialogEvent& event)
|
||||
{
|
||||
RefreshTreeContents();
|
||||
|
||||
wxWindow::OnInitDialog(event);
|
||||
}
|
||||
|
||||
65
src/Demos/wxsgv/SceneGraphDlg.h
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Name: SceneGraphDlg.h
|
||||
// Author: Ben Discoe, ben@washedashore.com
|
||||
//
|
||||
|
||||
#ifndef __SceneGraphDlg_H__
|
||||
#define __SceneGraphDlg_H__
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface "SceneGraphDlg.cpp"
|
||||
#endif
|
||||
|
||||
#include "wx/imaglist.h"
|
||||
#include "wxsgv_wdr.h"
|
||||
|
||||
// WDR: class declarations
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SceneGraphDlg
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class SceneGraphDlg: public wxDialog
|
||||
{
|
||||
public:
|
||||
// constructors and destructors
|
||||
SceneGraphDlg( wxWindow *parent, wxWindowID id, const wxString &title,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~SceneGraphDlg();
|
||||
|
||||
void OnInitDialog(wxInitDialogEvent& event);
|
||||
wxButton *m_pZoomTo;
|
||||
wxCheckBox *m_pEnabled;
|
||||
wxTreeCtrl *m_pTree;
|
||||
|
||||
osg::Node *m_pSelectedNode;
|
||||
|
||||
void CreateImageList(int size = 16);
|
||||
void RefreshTreeContents();
|
||||
void AddNodeItemsRecursively(wxTreeItemId hParentItem,
|
||||
osg::Node *pNode, int depth);
|
||||
|
||||
// WDR: method declarations for SceneGraphDlg
|
||||
wxButton* GetZoomto() { return (wxButton*) FindWindow( ID_ZOOMTO ); }
|
||||
wxTreeCtrl* GetScenetree() { return (wxTreeCtrl*) FindWindow( ID_SCENETREE ); }
|
||||
|
||||
private:
|
||||
// WDR: member variable declarations for SceneGraphDlg
|
||||
wxImageList *m_imageListNormal;
|
||||
|
||||
private:
|
||||
// WDR: handler declarations for SceneGraphDlg
|
||||
void OnRefresh( wxCommandEvent &event );
|
||||
void OnZoomTo( wxCommandEvent &event );
|
||||
void OnTreeSelChanged( wxTreeEvent &event );
|
||||
|
||||
private:
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
110
src/Demos/wxsgv/app.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
//
|
||||
// Name: app.cpp
|
||||
// Purpose: The application class for a wxWindows application.
|
||||
// Author: Ben Discoe, ben@washedashore.com
|
||||
//
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include <osgUtil/SceneView>
|
||||
#include <osgUtil/TrackballManipulator>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgWX/WXEventAdapter>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgWX;
|
||||
|
||||
#include "app.h"
|
||||
#include "frame.h"
|
||||
|
||||
IMPLEMENT_APP(wxosgApp)
|
||||
|
||||
wxosgApp::wxosgApp()
|
||||
{
|
||||
m_bInitialized = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the app object
|
||||
//
|
||||
bool wxosgApp::OnInit()
|
||||
{
|
||||
// Create the main frame window
|
||||
wxString title = "wxsgv Demo Viewer";
|
||||
wxosgFrame *frame = new wxosgFrame(NULL, title,
|
||||
wxPoint(50, 50), wxSize(800, 600));
|
||||
|
||||
//
|
||||
// Create the 3d scene
|
||||
//
|
||||
m_pSceneView = new osgUtil::SceneView();
|
||||
m_pSceneView->setDefaults();
|
||||
Camera *pCam = new Camera();
|
||||
m_pSceneView->setCamera(pCam);
|
||||
|
||||
m_pCameraManipulator = new osgUtil::TrackballManipulator();
|
||||
m_pCameraManipulator->setCamera(pCam);
|
||||
|
||||
ref_ptr<WXEventAdapter> ea = new WXEventAdapter;
|
||||
m_pCameraManipulator->init(*ea, *this);
|
||||
|
||||
m_bInitialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxosgApp::DoUpdate()
|
||||
{
|
||||
if (!m_bInitialized)
|
||||
return;
|
||||
|
||||
m_pSceneView->setViewport(0, 0, m_winx, m_winy);
|
||||
m_pSceneView->cull();
|
||||
m_pSceneView->draw();
|
||||
}
|
||||
|
||||
void wxosgApp::SetWindowSize(int x, int y)
|
||||
{
|
||||
m_winx = x;
|
||||
m_winy = y;
|
||||
}
|
||||
|
||||
void wxosgApp::LoadFile(const char *filename)
|
||||
{
|
||||
Node *node = osgDB::readNodeFile(filename);
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
m_pSceneView->setSceneData(node);
|
||||
m_pCameraManipulator->setNode(node);
|
||||
|
||||
ref_ptr<WXEventAdapter> ea = new WXEventAdapter;
|
||||
m_pCameraManipulator->home(*ea, *this);
|
||||
}
|
||||
|
||||
osg::Node *wxosgApp::Root()
|
||||
{
|
||||
return m_pSceneView->getSceneData();
|
||||
}
|
||||
|
||||
void wxosgApp::ZoomTo(Node *node)
|
||||
{
|
||||
m_pCameraManipulator->setNode(node);
|
||||
ref_ptr<WXEventAdapter> ea = new WXEventAdapter;
|
||||
m_pCameraManipulator->home(*ea, *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
41
src/Demos/wxsgv/app.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright (c) 2001 Virtual Terrain Project
|
||||
// Free for all uses, see license.txt for details.
|
||||
//
|
||||
|
||||
// forward declaration
|
||||
namespace osgUtil {
|
||||
class SceneView;
|
||||
class CameraManipulator;
|
||||
}
|
||||
|
||||
#include <wx/app.h>
|
||||
|
||||
#include <osg/Node>
|
||||
#include <osgUtil/GUIActionAdapter>
|
||||
|
||||
// Define a new application type
|
||||
class wxosgApp: public wxApp, public osgUtil::GUIActionAdapter
|
||||
{
|
||||
public:
|
||||
wxosgApp();
|
||||
bool OnInit();
|
||||
void DoUpdate();
|
||||
void SetWindowSize(int x, int y);
|
||||
void LoadFile(const char *filename);
|
||||
void ZoomTo(osg::Node *node);
|
||||
|
||||
osgUtil::CameraManipulator *Manip() { return m_pCameraManipulator.get(); }
|
||||
osg::Node *Root();
|
||||
|
||||
virtual void requestRedraw() {}
|
||||
virtual void requestContinuousUpdate(bool needed=true) {}
|
||||
virtual void requestWarpPointer(int x,int y) {}
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<osgUtil::SceneView> m_pSceneView;
|
||||
osg::ref_ptr<osgUtil::CameraManipulator> m_pCameraManipulator;
|
||||
int m_winx, m_winy; // Window size
|
||||
bool m_bInitialized;
|
||||
};
|
||||
|
||||
188
src/Demos/wxsgv/canvas.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
//
|
||||
// Name: canvas.cpp
|
||||
// Purpose: Implements the canvas class for a wxWindows application.
|
||||
// Author: Ben Discoe, ben@washedashore.com
|
||||
//
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include <osgWX/WXEventAdapter>
|
||||
#include <osgUtil/CameraManipulator>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgWX;
|
||||
|
||||
#include "canvas.h"
|
||||
#include "frame.h"
|
||||
#include "app.h"
|
||||
|
||||
DECLARE_APP(wxosgApp)
|
||||
|
||||
/*
|
||||
* wxosgGLCanvas implementation
|
||||
*/
|
||||
BEGIN_EVENT_TABLE(wxosgGLCanvas, wxGLCanvas)
|
||||
EVT_CLOSE(wxosgGLCanvas::OnClose)
|
||||
EVT_SIZE(wxosgGLCanvas::OnSize)
|
||||
EVT_PAINT(wxosgGLCanvas::OnPaint)
|
||||
EVT_CHAR(wxosgGLCanvas::OnChar)
|
||||
EVT_MOUSE_EVENTS(wxosgGLCanvas::OnMouseEvent)
|
||||
EVT_ERASE_BACKGROUND(wxosgGLCanvas::OnEraseBackground)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
wxosgGLCanvas::wxosgGLCanvas(wxWindow *parent, wxWindowID id,
|
||||
const wxPoint& pos, const wxSize& size, long style, const wxString& name, int* gl_attrib):
|
||||
wxGLCanvas(parent, id, pos, size, style, name, gl_attrib)
|
||||
{
|
||||
parent->Show(TRUE);
|
||||
SetCurrent();
|
||||
|
||||
m_bPainting = false;
|
||||
m_bRunning = true;
|
||||
QueueRefresh(FALSE);
|
||||
|
||||
m_initialTick = m_timer.tick();
|
||||
}
|
||||
|
||||
|
||||
wxosgGLCanvas::~wxosgGLCanvas(void)
|
||||
{
|
||||
}
|
||||
|
||||
void wxosgGLCanvas::QueueRefresh(bool eraseBackground)
|
||||
// A Refresh routine we can call from inside OnPaint.
|
||||
// (queues the events rather than dispatching them immediately).
|
||||
{
|
||||
// With wxGTK, you can't do a Refresh() in OnPaint because it doesn't
|
||||
// queue (post) a Refresh event for later. Rather it dispatches
|
||||
// (processes) the underlying events immediately via ProcessEvent
|
||||
// (read, recursive call). See the wxPostEvent docs and Refresh code
|
||||
// for more details.
|
||||
if ( eraseBackground )
|
||||
{
|
||||
wxEraseEvent eevent( GetId() );
|
||||
eevent.SetEventObject( this );
|
||||
wxPostEvent( GetEventHandler(), eevent );
|
||||
}
|
||||
|
||||
wxPaintEvent event( GetId() );
|
||||
event.SetEventObject( this );
|
||||
wxPostEvent( GetEventHandler(), event );
|
||||
}
|
||||
|
||||
|
||||
void wxosgGLCanvas::OnPaint( wxPaintEvent& event )
|
||||
{
|
||||
// place the dc inside a scope, to delete it before the end of function
|
||||
if (1)
|
||||
{
|
||||
// This is a dummy, to avoid an endless succession of paint messages.
|
||||
// OnPaint handlers must always create a wxPaintDC.
|
||||
wxPaintDC dc(this);
|
||||
#ifdef __WXMSW__
|
||||
if (!GetContext()) return;
|
||||
#endif
|
||||
|
||||
if (m_bPainting || !m_bRunning) return;
|
||||
|
||||
m_bPainting = true;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// update the camera manipulator.
|
||||
if (wxGetApp().Manip())
|
||||
{
|
||||
ref_ptr<WXEventAdapter> ea = new WXEventAdapter;
|
||||
ea->adaptFrame(clockSeconds());
|
||||
wxGetApp().Manip()->handle(*ea, wxGetApp());
|
||||
}
|
||||
|
||||
// Render the OSG scene
|
||||
wxGetApp().DoUpdate();
|
||||
|
||||
SwapBuffers();
|
||||
|
||||
#ifdef WIN32
|
||||
// Call Refresh again for continuous rendering,
|
||||
if (m_bRunning)
|
||||
Refresh(FALSE);
|
||||
#else
|
||||
// Queue another refresh for continuous rendering.
|
||||
// (Yield first so we don't starve out keyboard & mouse events.)
|
||||
//
|
||||
// FIXME: We may want to use a frame timer instead of immediate-
|
||||
// redraw so we don't eat so much CPU on machines that can
|
||||
// easily handle the frame rate.
|
||||
wxYield();
|
||||
QueueRefresh(FALSE);
|
||||
#endif
|
||||
|
||||
m_bPainting = false;
|
||||
}
|
||||
|
||||
// Must allow some idle processing to occur - or the toolbars will not
|
||||
// update, and the close box will not respond!
|
||||
wxGetApp().ProcessIdle();
|
||||
}
|
||||
|
||||
static void Reshape(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, (GLint)width, (GLint)height);
|
||||
}
|
||||
|
||||
void wxosgGLCanvas::OnClose(wxCloseEvent& event)
|
||||
{
|
||||
m_bRunning = false;
|
||||
}
|
||||
|
||||
void wxosgGLCanvas::OnSize(wxSizeEvent& event)
|
||||
{
|
||||
// Presumably this is a wxMSWism.
|
||||
// For wxGTK & wxMotif, all canvas resize events occur before the context
|
||||
// is set. So ignore this context check and grab the window width/height
|
||||
// when we get it so it (and derived values such as aspect ratio and
|
||||
// viewport parms) are computed correctly.
|
||||
#ifdef __WXMSW__
|
||||
if (!GetContext()) return;
|
||||
#endif
|
||||
|
||||
SetCurrent();
|
||||
int width, height;
|
||||
GetClientSize(& width, & height);
|
||||
Reshape(width, height);
|
||||
|
||||
if (wxGetApp().Manip())
|
||||
{
|
||||
ref_ptr<WXEventAdapter> ea = new WXEventAdapter;
|
||||
ea->adaptResize(clockSeconds(), 0, 0, width, height);
|
||||
wxGetApp().Manip()->handle(*ea, wxGetApp());
|
||||
}
|
||||
|
||||
wxGetApp().SetWindowSize(width, height);
|
||||
}
|
||||
|
||||
void wxosgGLCanvas::OnChar(wxKeyEvent& event)
|
||||
{
|
||||
ref_ptr<WXEventAdapter> ea = new WXEventAdapter;
|
||||
ea->adaptKeyboard(clockSeconds(), event.KeyCode(), event.GetX(), event.GetY());
|
||||
wxGetApp().Manip()->handle(*ea, wxGetApp());
|
||||
}
|
||||
|
||||
void wxosgGLCanvas::OnMouseEvent(wxMouseEvent& event)
|
||||
{
|
||||
// turn WX mouse event into a OSG mouse event
|
||||
ref_ptr<WXEventAdapter> ea = new WXEventAdapter;
|
||||
ea->adaptMouse(clockSeconds(), &event);
|
||||
wxGetApp().Manip()->handle(*ea, wxGetApp());
|
||||
}
|
||||
|
||||
void wxosgGLCanvas::OnEraseBackground(wxEraseEvent& event)
|
||||
{
|
||||
// Do nothing, to avoid flashing.
|
||||
}
|
||||
|
||||
50
src/Demos/wxsgv/canvas.h
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Name: canvas.h
|
||||
//
|
||||
// Copyright (c) 2001 Virtual Terrain Project
|
||||
// Free for all uses, see license.txt for details.
|
||||
//
|
||||
|
||||
#ifndef CANVASH
|
||||
#define CANVASH
|
||||
|
||||
#if !wxUSE_GLCANVAS
|
||||
#error Please set wxUSE_GLCANVAS to 1 in setup.h.
|
||||
#endif
|
||||
#include "wx/glcanvas.h"
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
//
|
||||
// A Canvas for the main view area.
|
||||
//
|
||||
class wxosgGLCanvas: public wxGLCanvas
|
||||
{
|
||||
public:
|
||||
wxosgGLCanvas(wxWindow *parent, const wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "wxosgGLCanvas",
|
||||
int* gl_attrib = NULL);
|
||||
~wxosgGLCanvas(void);
|
||||
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnEraseBackground(wxEraseEvent& event);
|
||||
void OnChar(wxKeyEvent& event);
|
||||
void OnMouseEvent(wxMouseEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void QueueRefresh(bool eraseBackground);
|
||||
|
||||
bool m_bPainting;
|
||||
bool m_bRunning;
|
||||
|
||||
// time since initClock() in seconds.
|
||||
float clockSeconds() { return m_timer.delta_s(m_initialTick, m_timer.tick()); }
|
||||
osg::Timer m_timer;
|
||||
osg::Timer_t clockTick() { return m_timer.tick(); }
|
||||
osg::Timer_t m_initialTick;
|
||||
|
||||
protected:
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif
|
||||
111
src/Demos/wxsgv/frame.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// Name: frame.cpp
|
||||
// Purpose: The frame class for a wxWindows application.
|
||||
// Author: Ben Discoe, ben@washedashore.com
|
||||
//
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include "app.h"
|
||||
#include "frame.h"
|
||||
#include "canvas.h"
|
||||
|
||||
// IDs for the menu commands
|
||||
enum
|
||||
{
|
||||
ID_FILE_OPEN,
|
||||
ID_SCENE_BROWSE
|
||||
};
|
||||
|
||||
DECLARE_APP(wxosgApp)
|
||||
|
||||
BEGIN_EVENT_TABLE(wxosgFrame, wxFrame)
|
||||
EVT_MENU(wxID_EXIT, wxosgFrame::OnExit)
|
||||
EVT_MENU(ID_FILE_OPEN, wxosgFrame::OnOpen)
|
||||
EVT_MENU(ID_SCENE_BROWSE, wxosgFrame::OnSceneBrowse)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
// My frame constructor
|
||||
wxosgFrame::wxosgFrame(wxFrame *parent, const wxString& title, const wxPoint& pos,
|
||||
const wxSize& size, long style):
|
||||
wxFrame(parent, -1, title, pos, size, style)
|
||||
{
|
||||
// Make a wxosgGLCanvas
|
||||
// FIXME: Can remove this special case once wxMotif 2.3 is released
|
||||
#ifdef __WXMOTIF__
|
||||
int gl_attrib[20] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER, None };
|
||||
#else
|
||||
int *gl_attrib = NULL;
|
||||
#endif
|
||||
|
||||
m_canvas = new wxosgGLCanvas(this, -1, wxPoint(0, 0), wxSize(-1, -1), 0,
|
||||
"wxosgGLCanvas", gl_attrib);
|
||||
|
||||
// File (project) menu
|
||||
wxMenu *fileMenu = new wxMenu;
|
||||
fileMenu->Append(ID_FILE_OPEN, "&Open\tCtrl+O", "Open OSG File");
|
||||
fileMenu->AppendSeparator();
|
||||
fileMenu->Append(wxID_EXIT, "&Exit\tEsc", "Exit Viewer");
|
||||
|
||||
// Scene menu
|
||||
wxMenu *sceneMenu = new wxMenu;
|
||||
sceneMenu->Append(ID_SCENE_BROWSE, "&Browse Scene Graph\tCtrl+G", "Browse Scene Graph");
|
||||
|
||||
wxMenuBar *menuBar = new wxMenuBar;
|
||||
menuBar->Append(fileMenu, "&Project");
|
||||
menuBar->Append(sceneMenu, "&Scene");
|
||||
SetMenuBar(menuBar);
|
||||
|
||||
// Show the frame
|
||||
Show(TRUE);
|
||||
|
||||
#if 1
|
||||
m_pSceneGraphDlg = new SceneGraphDlg(this, -1, "Scene Graph",
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
|
||||
m_pSceneGraphDlg->SetSize(250, 350);
|
||||
#endif
|
||||
|
||||
m_canvas->SetCurrent();
|
||||
}
|
||||
|
||||
wxosgFrame::~wxosgFrame()
|
||||
{
|
||||
delete m_canvas;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Handle menu commands
|
||||
//
|
||||
|
||||
void wxosgFrame::OnExit(wxCommandEvent& event)
|
||||
{
|
||||
m_canvas->m_bRunning = false;
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void wxosgFrame::OnOpen(wxCommandEvent& event)
|
||||
{
|
||||
wxFileDialog loadFile(NULL, "Load Project", "", "",
|
||||
"OSG Files (*.osg)|*.osg|", wxOPEN);
|
||||
if (loadFile.ShowModal() == wxID_OK)
|
||||
wxGetApp().LoadFile(loadFile.GetPath());
|
||||
}
|
||||
|
||||
void wxosgFrame::OnSceneBrowse(wxCommandEvent& event)
|
||||
{
|
||||
m_pSceneGraphDlg->Show(TRUE);
|
||||
}
|
||||
|
||||
35
src/Demos/wxsgv/frame.h
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Name: frame.h
|
||||
//
|
||||
// Copyright (c) 2001 Virtual Terrain Project
|
||||
// Free for all uses, see license.txt for details.
|
||||
//
|
||||
|
||||
#ifndef FRAMEH
|
||||
#define FRAMEH
|
||||
|
||||
#include "SceneGraphDlg.h"
|
||||
|
||||
class wxosgFrame: public wxFrame
|
||||
{
|
||||
public:
|
||||
wxosgFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
|
||||
const wxSize& size, long style = wxDEFAULT_FRAME_STYLE);
|
||||
~wxosgFrame();
|
||||
|
||||
// command handlers
|
||||
void OnExit(wxCommandEvent& event);
|
||||
void OnOpen(wxCommandEvent& event);
|
||||
void OnSceneBrowse(wxCommandEvent& event);
|
||||
|
||||
public:
|
||||
class wxosgGLCanvas *m_canvas;
|
||||
SceneGraphDlg *m_pSceneGraphDlg;
|
||||
|
||||
protected:
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
BIN
src/Demos/wxsgv/icons/camera.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/Demos/wxsgv/icons/engine.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/Demos/wxsgv/icons/geom.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/Demos/wxsgv/icons/group.ico
Normal file
|
After Width: | Height: | Size: 318 B |
29
src/Demos/wxsgv/icons/icon1.xpm
Normal file
@@ -0,0 +1,29 @@
|
||||
/* XPM */
|
||||
static char *icon1_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 6 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #C0C0C0",
|
||||
"b c #FF0000",
|
||||
"c c #FFFFFF",
|
||||
"d c #FFFF00",
|
||||
"e c #808000",
|
||||
/* pixels */
|
||||
"cccccccccccccccc",
|
||||
"cccccccccceddecc",
|
||||
"ccccccccceddddec",
|
||||
"ccbbbcccceddddec",
|
||||
"cc```cccceddddec",
|
||||
"a`````````edde`a",
|
||||
"``````accca`````",
|
||||
"``aaa`ccccc`````",
|
||||
"`````ccccccc````",
|
||||
"``````ccccc`````",
|
||||
"``````accca`````",
|
||||
"a``````````````a",
|
||||
"ca````````````ac",
|
||||
"cccccccccccccccc",
|
||||
"cccccccccccccccc",
|
||||
"cccccccccccccccc"
|
||||
};
|
||||
28
src/Demos/wxsgv/icons/icon10.xpm
Normal file
@@ -0,0 +1,28 @@
|
||||
/* XPM */
|
||||
static char *icon10_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 5 1",
|
||||
/* colors */
|
||||
"` c #00FF00",
|
||||
"a c #FF0000",
|
||||
"b c #FFFFFF",
|
||||
"c c #808000",
|
||||
"d c #0000FF",
|
||||
/* pixels */
|
||||
"bbbbbbbbbbbbbbbb",
|
||||
"bbbbbbbbbbbbbbbb",
|
||||
"bbb``bbbbbbbbbbb",
|
||||
"bb````bbbbdddbbb",
|
||||
"bbb``bbbbbdddbbb",
|
||||
"bbb``bbbbddddbbb",
|
||||
"bbb``bbbdddbbbbb",
|
||||
"bbb``bbdddbbbbbb",
|
||||
"bbb``bdddbbbbbbb",
|
||||
"bbb``dddbbbbbbbb",
|
||||
"bbb``ddbbbbbabbb",
|
||||
"bbb`caaaaaaaaabb",
|
||||
"bbbcaaaaaaaaaabb",
|
||||
"bbbbbbbbbbbbabbb",
|
||||
"bbbbbbbbbbbbbbbb",
|
||||
"bbbbbbbbbbbbbbbb"
|
||||
};
|
||||
27
src/Demos/wxsgv/icons/icon2.xpm
Normal file
@@ -0,0 +1,27 @@
|
||||
/* XPM */
|
||||
static char *icon2_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 4 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #C0C0C0",
|
||||
"b c #808080",
|
||||
"c c #FFFFFF",
|
||||
/* pixels */
|
||||
"cccccccccccccccc",
|
||||
"ccccb`bccb`bcccc",
|
||||
"cccca``cc``acccc",
|
||||
"ccccc``bb``ccccc",
|
||||
"ca`ccb````bcc`ac",
|
||||
"c```b``````b```c",
|
||||
"ca`````bb`````ac",
|
||||
"cccb``bccb``bccc",
|
||||
"cccb``bccb``bccc",
|
||||
"ca`````bb`````ac",
|
||||
"c```b``````b```c",
|
||||
"ca`ccb````bcc`ac",
|
||||
"ccccc``bb``ccccc",
|
||||
"cccca``cc``acccc",
|
||||
"ccccb`bccb`bcccc",
|
||||
"cccccccccccccccc"
|
||||
};
|
||||
30
src/Demos/wxsgv/icons/icon3.xpm
Normal file
@@ -0,0 +1,30 @@
|
||||
/* XPM */
|
||||
static char *icon3_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 7 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #00FF00",
|
||||
"b c #C0C0C0",
|
||||
"c c #000080",
|
||||
"d c #FFFFFF",
|
||||
"e c #008000",
|
||||
"f c #0000FF",
|
||||
/* pixels */
|
||||
"ddddddd`dddddddd",
|
||||
"dddddd```ddddddd",
|
||||
"ddddd`a``bdddddd",
|
||||
"dddd`aa`f`dddddd",
|
||||
"ddd`aaa`ff`ddddd",
|
||||
"dd`aaaa`fff`dddd",
|
||||
"d`aaaaacfff`bddd",
|
||||
"`aaaaaecffff`ddd",
|
||||
"b`aaaaecfffff`dd",
|
||||
"d`aaaa`fffffff`d",
|
||||
"dd`aaa`fffffff`b",
|
||||
"ddd`aa`fffffff``",
|
||||
"dddb`a`fff````bd",
|
||||
"dddd`a````bddddd",
|
||||
"ddddd``bdddddddd",
|
||||
"dddddddddddddddd"
|
||||
};
|
||||
27
src/Demos/wxsgv/icons/icon4.xpm
Normal file
@@ -0,0 +1,27 @@
|
||||
/* XPM */
|
||||
static char *icon4_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 4 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #FFFFFF",
|
||||
"b c #FFFF00",
|
||||
"c c #808000",
|
||||
/* pixels */
|
||||
"aaaaaaaaaaaaaaaa",
|
||||
"aaaaac````caaaaa",
|
||||
"aaac`bbbbbb`caaa",
|
||||
"aac`bbbbbbbb`caa",
|
||||
"aa`bbbc``cbbb`aa",
|
||||
"accbb`caac`bbcca",
|
||||
"a`bbccaaaaccbbca",
|
||||
"a`bb`aaaaaa`bb`a",
|
||||
"a`bb`aaaaaa`bb`a",
|
||||
"a`bbccaaaaccbbca",
|
||||
"accbb`caac`bbcca",
|
||||
"aa`bbbc``cbbb`aa",
|
||||
"aaa`bbbbbbbb`aaa",
|
||||
"aaaa`bbbbbb`aaaa",
|
||||
"aaaaac````caaaaa",
|
||||
"aaaaaaaaaaaaaaaa"
|
||||
};
|
||||
28
src/Demos/wxsgv/icons/icon5.xpm
Normal file
@@ -0,0 +1,28 @@
|
||||
/* XPM */
|
||||
static char *icon5_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 5 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #C0C0C0",
|
||||
"b c #FFFFFF",
|
||||
"c c #FFFF00",
|
||||
"d c #808000",
|
||||
/* pixels */
|
||||
"bbbbbbbbbbbbbbbb",
|
||||
"bbbbdbbbbbbbdbbb",
|
||||
"dbbbbd````bdbbbb",
|
||||
"bdbbb`bbcb`bbbbb",
|
||||
"bbdd`bbcccb`bbbb",
|
||||
"bbbb`bcbcbc`dddd",
|
||||
"bbbb`cccbcb`bbbb",
|
||||
"bbdd`ccccbc`dbbb",
|
||||
"ddbb`bccccc`bddb",
|
||||
"bbbbb`bccb`bbbbd",
|
||||
"bbbbdb````bbdbbb",
|
||||
"bbbdbb````bbbdbb",
|
||||
"bbbdbb````bbbdbb",
|
||||
"bbdbbb````bbbbdb",
|
||||
"bbbbbba``abbbbbb",
|
||||
"bbbbbbbbbbbbbbbb"
|
||||
};
|
||||
29
src/Demos/wxsgv/icons/icon6.xpm
Normal file
@@ -0,0 +1,29 @@
|
||||
/* XPM */
|
||||
static char *icon6_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 6 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #C0C0C0",
|
||||
"b c #808080",
|
||||
"c c #FFFFFF",
|
||||
"d c #FFFF00",
|
||||
"e c #808000",
|
||||
/* pixels */
|
||||
"cccccccccccccccc",
|
||||
"cabbbbbbbbaccccc",
|
||||
"cb````````bccccc",
|
||||
"cb`dddddd`bccccc",
|
||||
"cb`dddddd`bbaccc",
|
||||
"cb`dddddd```bacc",
|
||||
"cb`dddddd`dd`bcc",
|
||||
"cb`dddddd`dd`bac",
|
||||
"cb`dddddd`ddd`bc",
|
||||
"cb````````ddd`bc",
|
||||
"cabbb`ddddddebac",
|
||||
"cccab`dddddd`bcc",
|
||||
"ccccab``dde`bacc",
|
||||
"cccccabb``bbaccc",
|
||||
"cccccccabbaccccc",
|
||||
"cccccccccccccccc"
|
||||
};
|
||||
29
src/Demos/wxsgv/icons/icon7.xpm
Normal file
@@ -0,0 +1,29 @@
|
||||
/* XPM */
|
||||
static char *icon7_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 6 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #00FF00",
|
||||
"b c #C0C0C0",
|
||||
"c c #808080",
|
||||
"d c #FFFFFF",
|
||||
"e c #008000",
|
||||
/* pixels */
|
||||
"dddddddddddddddd",
|
||||
"dddddddddddddddd",
|
||||
"ddddddd`dddddddd",
|
||||
"ddddddbe`ddddddd",
|
||||
"dddddd`aebdddddd",
|
||||
"dddddbeaa`dddddd",
|
||||
"ddddd`aaaebddddd",
|
||||
"ddddbeaaaa`ddddd",
|
||||
"dddd`aaaaaaedddd",
|
||||
"ddddeaaaaaa`dddd",
|
||||
"dddeaaaaaaaa`ddd",
|
||||
"ddd`aaaaaaaaebdd",
|
||||
"ddbeaaaaaaaaa`dd",
|
||||
"dd`aaaaaaaaaaacd",
|
||||
"dd`````````````d",
|
||||
"dddddddddddddddd"
|
||||
};
|
||||
26
src/Demos/wxsgv/icons/icon8.xpm
Normal file
@@ -0,0 +1,26 @@
|
||||
/* XPM */
|
||||
static char *icon8_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 3 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #FFFFFF",
|
||||
"b c #0000FF",
|
||||
/* pixels */
|
||||
"aaaaaaaaaaaaaaaa",
|
||||
"aaaaaaaa`aaaaaaa",
|
||||
"aaaaaaaa``aaaaaa",
|
||||
"aaaaaaaa`b`aaaaa",
|
||||
"aaaaaaaa`bb`aaaa",
|
||||
"aaaaaaaa`bbb`aaa",
|
||||
"a````````bbbb`aa",
|
||||
"a`bbbbbbbbbbbb`a",
|
||||
"a`bbbbbbbbbbbb`a",
|
||||
"a````````bbbb`aa",
|
||||
"aaaaaaaa`bbb`aaa",
|
||||
"aaaaaaaa`bb`aaaa",
|
||||
"aaaaaaaa`b`aaaaa",
|
||||
"aaaaaaaa``aaaaaa",
|
||||
"aaaaaaaa`aaaaaaa",
|
||||
"aaaaaaaaaaaaaaaa"
|
||||
};
|
||||
28
src/Demos/wxsgv/icons/icon9.xpm
Normal file
@@ -0,0 +1,28 @@
|
||||
/* XPM */
|
||||
static char *icon9_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"16 16 5 1",
|
||||
/* colors */
|
||||
"` c #000000",
|
||||
"a c #C0C0C0",
|
||||
"b c #808080",
|
||||
"c c #000080",
|
||||
"d c #FFFFFF",
|
||||
/* pixels */
|
||||
"dddddddddddddddd",
|
||||
"dddddacccccadddd",
|
||||
"ddddacccccccaddd",
|
||||
"dddacccbdacccddd",
|
||||
"dddacccddacccddd",
|
||||
"dddabcbddacccddd",
|
||||
"ddddddddacccaddd",
|
||||
"dddddddacccaaddd",
|
||||
"ddddddaacccadddd",
|
||||
"ddddddacccaddddd",
|
||||
"ddddddabcbaddddd",
|
||||
"dddddddddddddddd",
|
||||
"dddddddb`bdddddd",
|
||||
"ddddddacccaddddd",
|
||||
"dddddddbcbdddddd",
|
||||
"dddddddddddddddd"
|
||||
};
|
||||
BIN
src/Demos/wxsgv/icons/light.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/Demos/wxsgv/icons/lod.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/Demos/wxsgv/icons/mesh.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/Demos/wxsgv/icons/top.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/Demos/wxsgv/icons/unknown.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
src/Demos/wxsgv/icons/wxsgv.ico
Normal file
|
After Width: | Height: | Size: 766 B |
48
src/Demos/wxsgv/icons/wxsgv.xpm
Normal file
@@ -0,0 +1,48 @@
|
||||
/* XPM */
|
||||
static char *wxsgv[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 32 32 9 1",
|
||||
/* colors */
|
||||
". c #000000",
|
||||
"# c #000080",
|
||||
"a c #0000ff",
|
||||
"b c #008000",
|
||||
"c c #00ff00",
|
||||
"d c #808000",
|
||||
"e c #808080",
|
||||
"f c #ffff00",
|
||||
"g c #ffffff",
|
||||
/* pixels */
|
||||
"gggggggggggggggggggggggggggggggg",
|
||||
"ggggd....dgggggggggggggggggggggg",
|
||||
"ggd.ffffffddgggggggggggggggggggg",
|
||||
"gd.ffffffffddggggggggggggggggggg",
|
||||
"g.fffd..dfffdggggggggggggggggggg",
|
||||
"ddffddggdddfddgggggggggggggggggg",
|
||||
".ffddggggddffdgggggggggggggggggg",
|
||||
".ff.gggggg.dfdgggggggggggggggggg",
|
||||
".ff.gggggg.dfdgggggggggggggggggg",
|
||||
".ffddgggg.ddfdgggggggggggggggggg",
|
||||
"ddffddgg..dffdgggggggggggggggggg",
|
||||
"g.ffdd..ddffdggggggggggggggggggg",
|
||||
"ggdfffdddffdgggggggggggggggggggg",
|
||||
"gggdffffffdggggggggggggggggggggg",
|
||||
"ggggddddddgggggggggggggggggggggg",
|
||||
"gggggggggggggggggggggggggggggggg",
|
||||
"gggggggeggggggggggggggg.gggggggg",
|
||||
"gggggggggggggggggggggg...ggggggg",
|
||||
"gggggggeggggggggggggg.b..egggggg",
|
||||
"gggggggggggggggggggg.cc.##gggggg",
|
||||
"gggeeeeeeeeeggggggg.ccc.#a#ggggg",
|
||||
"gggegggggggegggggg.cccc.#aa#gggg",
|
||||
"gggeggg.gggeggggg.ccccc#aaa#eggg",
|
||||
"gggeggg.gggegggg.bccccb#aaaa#ggg",
|
||||
"gggeg.....gegegeebccccb#aaaaa#gg",
|
||||
"gggeggg.gggeggggg.ccccb#aaaaaa#g",
|
||||
"gggeggg.gggeggggggbccc.aaaaaaa#e",
|
||||
"gggegggggggegggggggbcc.aaaaaaa#.",
|
||||
"gggeeeeeeeeegggggggebc.aaa#####g",
|
||||
"gggggggggggggggggggg.c.###eggggg",
|
||||
"gggggggggggggggggggggb.egggggggg",
|
||||
"gggggggggggggggggggggggggggggggg"
|
||||
};
|
||||
BIN
src/Demos/wxsgv/icons/xform.ico
Normal file
|
After Width: | Height: | Size: 318 B |
14
src/Demos/wxsgv/wxsgv.rc
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
application ICON "wxsgv.ico"
|
||||
#include "wx/msw/wx.rc"
|
||||
|
||||
icon1 ICON "icons/camera.ico"
|
||||
icon2 ICON "icons/engine.ico"
|
||||
icon3 ICON "icons/geom.ico"
|
||||
icon4 ICON "icons/group.ico"
|
||||
icon5 ICON "icons/light.ico"
|
||||
icon6 ICON "icons/lod.ico"
|
||||
icon7 ICON "icons/mesh.ico"
|
||||
icon8 ICON "icons/top.ico"
|
||||
icon9 ICON "icons/unknown.ico"
|
||||
icon10 ICON "icons/xform.ico"
|
||||
BIN
src/Demos/wxsgv/wxsgv.wdr
Normal file
125
src/Demos/wxsgv/wxsgv_wdr.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Source code generated by wxDesigner from file: wxsgv.wdr
|
||||
// Do not modify this file, all changes will be lost!
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "wxsgv_wdr.cpp"
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// Include private header
|
||||
#include "wxsgv_wdr.h"
|
||||
|
||||
|
||||
// Implement window functions
|
||||
|
||||
void SceneGraphFunc( wxPanel *parent, bool call_fit )
|
||||
{
|
||||
wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxTreeCtrl *item1 = new wxTreeCtrl( parent, ID_SCENETREE, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxSUNKEN_BORDER );
|
||||
item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
wxSizer *item2 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxButton *item3 = new wxButton( parent, ID_ZOOMTO, "Zoom To", wxDefaultPosition, wxSize(60,-1), 0 );
|
||||
item2->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 );
|
||||
|
||||
wxButton *item4 = new wxButton( parent, ID_REFRESH, "Refresh", wxDefaultPosition, wxSize(55,-1), 0 );
|
||||
item2->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 );
|
||||
|
||||
item0->Add( item2, 0, wxALIGN_CENTRE|wxALL, 0 );
|
||||
|
||||
parent->SetAutoLayout( TRUE );
|
||||
parent->SetSizer( item0 );
|
||||
if (call_fit)
|
||||
{
|
||||
item0->Fit( parent );
|
||||
item0->SetSizeHints( parent );
|
||||
}
|
||||
}
|
||||
|
||||
void CameraDialogFunc( wxPanel *parent, bool call_fit )
|
||||
{
|
||||
wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxStaticText *item2 = new wxStaticText( parent, ID_TEXT, "Horizontal FOV (degrees)", wxDefaultPosition, wxDefaultSize, 0 );
|
||||
item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 );
|
||||
|
||||
wxTextCtrl *item3 = new wxTextCtrl( parent, ID_FOV, "", wxDefaultPosition, wxSize(60,-1), 0 );
|
||||
item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 0 );
|
||||
|
||||
wxSlider *item4 = new wxSlider( parent, ID_FOVSLIDER, 0, 0, 100, wxDefaultPosition, wxSize(100,-1), 0 );
|
||||
item1->Add( item4, 0, wxALIGN_CENTRE|wxALL, 0 );
|
||||
|
||||
item0->Add( item1, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
|
||||
|
||||
wxSizer *item5 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxStaticText *item6 = new wxStaticText( parent, ID_TEXT, "Near Clipping Plane (meters):", wxDefaultPosition, wxDefaultSize, 0 );
|
||||
item5->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
|
||||
|
||||
wxTextCtrl *item7 = new wxTextCtrl( parent, ID_NEAR, "", wxDefaultPosition, wxSize(60,-1), 0 );
|
||||
item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 0 );
|
||||
|
||||
wxSlider *item8 = new wxSlider( parent, ID_NEARSLIDER, 0, 0, 100, wxDefaultPosition, wxSize(100,-1), 0 );
|
||||
item5->Add( item8, 0, wxALIGN_CENTRE|wxALL, 0 );
|
||||
|
||||
item0->Add( item5, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 0 );
|
||||
|
||||
wxSizer *item9 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxStaticText *item10 = new wxStaticText( parent, ID_TEXT, "Far Clipping Plane (meters):", wxDefaultPosition, wxDefaultSize, 0 );
|
||||
item9->Add( item10, 0, wxALIGN_CENTRE|wxALL, 5 );
|
||||
|
||||
wxTextCtrl *item11 = new wxTextCtrl( parent, ID_FAR, "", wxDefaultPosition, wxSize(60,-1), 0 );
|
||||
item9->Add( item11, 0, wxALIGN_CENTRE|wxALL, 0 );
|
||||
|
||||
wxSlider *item12 = new wxSlider( parent, ID_FARSLIDER, 0, 0, 100, wxDefaultPosition, wxSize(100,-1), 0 );
|
||||
item9->Add( item12, 0, wxALIGN_CENTRE|wxALL, 0 );
|
||||
|
||||
item0->Add( item9, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 0 );
|
||||
|
||||
wxStaticLine *item13 = new wxStaticLine( parent, ID_LINE, wxDefaultPosition, wxSize(20,-1), wxLI_HORIZONTAL );
|
||||
item0->Add( item13, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
wxSizer *item14 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxStaticText *item15 = new wxStaticText( parent, ID_TEXT, "Navigation Speed (m/frame):", wxDefaultPosition, wxDefaultSize, 0 );
|
||||
item14->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 );
|
||||
|
||||
wxTextCtrl *item16 = new wxTextCtrl( parent, ID_SPEED, "", wxDefaultPosition, wxSize(60,-1), 0 );
|
||||
item14->Add( item16, 0, wxALIGN_CENTRE|wxALL, 0 );
|
||||
|
||||
wxSlider *item17 = new wxSlider( parent, ID_SPEEDSLIDER, 0, 0, 100, wxDefaultPosition, wxSize(100,-1), 0 );
|
||||
item14->Add( item17, 0, wxALIGN_CENTRE, 0 );
|
||||
|
||||
item0->Add( item14, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
|
||||
|
||||
parent->SetAutoLayout( TRUE );
|
||||
parent->SetSizer( item0 );
|
||||
if (call_fit)
|
||||
{
|
||||
item0->Fit( parent );
|
||||
item0->SetSizeHints( parent );
|
||||
}
|
||||
}
|
||||
|
||||
// Implement bitmap functions
|
||||
|
||||
wxBitmap MyBitmapsFunc( size_t index )
|
||||
{
|
||||
return wxNullBitmap;
|
||||
}
|
||||
|
||||
|
||||
// End of generated file
|
||||
53
src/Demos/wxsgv/wxsgv_wdr.h
Normal file
@@ -0,0 +1,53 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Header generated by wxDesigner from file: wxsgv.wdr
|
||||
// Do not modify this file, all changes will be lost!
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __WDR_wxsgv_H__
|
||||
#define __WDR_wxsgv_H__
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface "wxsgv_wdr.cpp"
|
||||
#endif
|
||||
|
||||
// Include wxWindows' headers
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
|
||||
#include <wx/image.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/spinbutt.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/notebook.h>
|
||||
|
||||
// Declare window functions
|
||||
|
||||
#define ID_SCENETREE 10000
|
||||
#define ID_ZOOMTO 10001
|
||||
#define ID_REFRESH 10002
|
||||
void SceneGraphFunc( wxPanel *parent, bool call_fit = TRUE );
|
||||
|
||||
#define ID_TEXT 10003
|
||||
#define ID_FOV 10004
|
||||
#define ID_FOVSLIDER 10005
|
||||
#define ID_NEAR 10006
|
||||
#define ID_NEARSLIDER 10007
|
||||
#define ID_FAR 10008
|
||||
#define ID_FARSLIDER 10009
|
||||
#define ID_LINE 10010
|
||||
#define ID_SPEED 10011
|
||||
#define ID_SPEEDSLIDER 10012
|
||||
void CameraDialogFunc( wxPanel *parent, bool call_fit = TRUE );
|
||||
|
||||
// Declare bitmap functions
|
||||
|
||||
wxBitmap MyBitmapsFunc( size_t index );
|
||||
|
||||
#endif
|
||||
|
||||
// End of generated file
|
||||
27
src/Makefile
@@ -2,35 +2,38 @@
|
||||
SHELL=/bin/sh
|
||||
|
||||
|
||||
DIRS = osg osgUtil osgGLUT Demos osgPlugins
|
||||
DIRS = osg osgDB osgUtil osgGLUT Demos osgPlugins
|
||||
|
||||
all :
|
||||
for f in $(DIRS) ; do cd $$f; make ; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) || exit 1; cd ..; done
|
||||
|
||||
clean :
|
||||
for f in $(DIRS) ; do cd $$f; make clean; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) clean; cd ..; done
|
||||
|
||||
clobber :
|
||||
for f in $(DIRS) ; do cd $$f; make clobber; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) clobber; cd ..; done
|
||||
|
||||
depend :
|
||||
for f in $(DIRS) ; do cd $$f; make depend; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) depend; cd ..; done
|
||||
|
||||
docs :
|
||||
(cd osg; make docs;)
|
||||
(cd osgUtil; make docs; )
|
||||
(cd osgGLUT; make docs; )
|
||||
(cd osg; $(MAKE) docs;)
|
||||
(cd osgUtil; $(MAKE) docs; )
|
||||
(cd osgDB; $(MAKE) docs; )
|
||||
(cd osgGLUT; $(MAKE) docs; )
|
||||
|
||||
to_unix :
|
||||
for f in $(DIRS) ; do cd $$f; to_unix Makefile Makefile; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; make to_unix; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) to_unix; cd ..; done
|
||||
|
||||
beautify :
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) beautify; cd ..; done
|
||||
|
||||
install :
|
||||
for f in $(DIRS) ; do cd $$f; make install; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) install; cd ..; done
|
||||
|
||||
instlinks :
|
||||
for f in $(DIRS) ; do cd $$f; make instlinks; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) instlinks; cd ..; done
|
||||
|
||||
instclean :
|
||||
for f in $(DIRS) ; do cd $$f; make instclean; cd ..; done
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) instclean; cd ..; done
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/AlphaFunc"
|
||||
#include "osg/Output"
|
||||
#include "osg/Input"
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
@@ -12,90 +8,13 @@ AlphaFunc::AlphaFunc()
|
||||
_referenceValue = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
AlphaFunc::~AlphaFunc()
|
||||
{
|
||||
}
|
||||
|
||||
AlphaFunc* AlphaFunc::instance()
|
||||
{
|
||||
static ref_ptr<AlphaFunc> s_AlphaFunc(new AlphaFunc);
|
||||
return s_AlphaFunc.get();
|
||||
}
|
||||
|
||||
void AlphaFunc::enable()
|
||||
{
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
}
|
||||
|
||||
void AlphaFunc::disable()
|
||||
{
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
}
|
||||
|
||||
void AlphaFunc::apply()
|
||||
void AlphaFunc::apply(State&) const
|
||||
{
|
||||
glAlphaFunc((GLenum)_comparisonFunc,_referenceValue);
|
||||
}
|
||||
|
||||
|
||||
bool AlphaFunc::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
ComparisonFunction func;
|
||||
if (fr[0].matchWord("comparisonFunc") && matchFuncStr(fr[1].getStr(),func))
|
||||
{
|
||||
_comparisonFunc = func;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
float ref;
|
||||
if (fr[0].matchWord("referenceValue") && fr[1].getFloat(ref))
|
||||
{
|
||||
_referenceValue = ref;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool AlphaFunc::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "comparisonFunc " << getFuncStr(_comparisonFunc) << endl;
|
||||
fw.indent() << "referenceValue " << _referenceValue << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AlphaFunc::matchFuncStr(const char* str,ComparisonFunction& func)
|
||||
{
|
||||
if (strcmp(str,"NEVER")==0) func = NEVER;
|
||||
else if (strcmp(str,"LESS")==0) func = LESS;
|
||||
else if (strcmp(str,"EQUAL")==0) func = EQUAL;
|
||||
else if (strcmp(str,"LEQUAL")==0) func = LEQUAL;
|
||||
else if (strcmp(str,"GREATER")==0) func = GREATER;
|
||||
else if (strcmp(str,"NOTEQUAL")==0) func = NOTEQUAL;
|
||||
else if (strcmp(str,"GEQUAL")==0) func = GEQUAL;
|
||||
else if (strcmp(str,"ALWAYS")==0) func = ALWAYS;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* AlphaFunc::getFuncStr(ComparisonFunction func)
|
||||
{
|
||||
switch(func)
|
||||
{
|
||||
case(NEVER): return "NEVER";
|
||||
case(LESS): return "LESS";
|
||||
case(EQUAL): return "EQUAL";
|
||||
case(LEQUAL): return "LEQUAL";
|
||||
case(GREATER): return "GREATER";
|
||||
case(NOTEQUAL): return "NOTEQUAL";
|
||||
case(GEQUAL): return "GEQUAL";
|
||||
case(ALWAYS): return "ALWAYS";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "osg/Billboard"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Billboard> g_BillboardProxy;
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
Billboard::Billboard()
|
||||
{
|
||||
_mode = AXIAL_ROT;
|
||||
// _mode = POINT_ROT_WORLD;
|
||||
// _mode = POINT_ROT_WORLD;
|
||||
_axis.set(0.0f,0.0f,1.0f);
|
||||
}
|
||||
|
||||
@@ -23,12 +18,13 @@ Billboard::~Billboard()
|
||||
{
|
||||
}
|
||||
|
||||
bool Billboard::addGeoSet(GeoSet *gset)
|
||||
|
||||
const bool Billboard::addDrawable(Drawable *gset)
|
||||
{
|
||||
if (Geode::addGeoSet(gset))
|
||||
if (Geode::addDrawable(gset))
|
||||
{
|
||||
Vec3 pos(0.0f,0.0f,0.0f);
|
||||
while (_positionList.size()<_geosets.size())
|
||||
while (_positionList.size()<_drawables.size())
|
||||
{
|
||||
_positionList.push_back(pos);
|
||||
}
|
||||
@@ -37,11 +33,12 @@ bool Billboard::addGeoSet(GeoSet *gset)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Billboard::addGeoSet(GeoSet *gset,const Vec3& pos)
|
||||
|
||||
const bool Billboard::addDrawable(Drawable *gset,const Vec3& pos)
|
||||
{
|
||||
if (Geode::addGeoSet(gset))
|
||||
if (Geode::addDrawable(gset))
|
||||
{
|
||||
while (_positionList.size()<_geosets.size())
|
||||
while (_positionList.size()<_drawables.size())
|
||||
{
|
||||
_positionList.push_back(pos);
|
||||
}
|
||||
@@ -50,36 +47,41 @@ bool Billboard::addGeoSet(GeoSet *gset,const Vec3& pos)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Billboard::removeGeoSet( GeoSet *gset )
|
||||
|
||||
const bool Billboard::removeDrawable( Drawable *gset )
|
||||
{
|
||||
PositionList::iterator pitr = _positionList.begin();
|
||||
for (GeoSetList::iterator itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr,++pitr)
|
||||
for (DrawableList::iterator itr=_drawables.begin();
|
||||
itr!=_drawables.end();
|
||||
++itr,++pitr)
|
||||
{
|
||||
if (itr->get()==gset)
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing gset's reference count.
|
||||
_geosets.erase(itr);
|
||||
_drawables.erase(itr);
|
||||
_positionList.erase(pitr);
|
||||
_bsphere_computed = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Billboard::calcRotation(const Vec3& eye_local, const Vec3& pos_local,Matrix& mat)
|
||||
void Billboard::calcRotation(const Vec3& eye_local, const Vec3& pos_local,Matrix& mat) const
|
||||
{
|
||||
switch(_mode)
|
||||
{
|
||||
case(AXIAL_ROT):
|
||||
{
|
||||
// note currently assumes that axis is (0,0,1) for speed of
|
||||
// executation and implementation. This will be rewritten
|
||||
// on second pass of Billboard. Robert Osfield Jan 2001.
|
||||
Vec3 ev = pos_local-eye_local;
|
||||
ev.z() = 0.0f;
|
||||
float ev_length = ev.length();
|
||||
if (ev_length>0.0f) {
|
||||
if (ev_length>0.0f)
|
||||
{
|
||||
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
|
||||
//mat.makeRot(rotation_z*180.0f/M_PI,0.0f,0.0f,1.0f);
|
||||
float inv = 1.0f/ev_length;
|
||||
@@ -92,9 +94,16 @@ void Billboard::calcRotation(const Vec3& eye_local, const Vec3& pos_local,Matrix
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(POINT_ROT_WORLD):
|
||||
case(POINT_ROT_WORLD):
|
||||
case(POINT_ROT_EYE):
|
||||
{
|
||||
// currently treat both POINT_ROT_WORLD and POINT_ROT_EYE the same,
|
||||
// this is only a temporary and 'incorrect' implementation, will
|
||||
// implement fully on second pass of Billboard.
|
||||
// Will also need up vector to calc POINT_ROT_EYE, so this will
|
||||
// have to be added to the above method paramters.
|
||||
// Robert Osfield, Jan 2001.
|
||||
|
||||
Vec3 ev = pos_local-eye_local;
|
||||
ev.normalize();
|
||||
|
||||
@@ -120,122 +129,24 @@ void Billboard::calcRotation(const Vec3& eye_local, const Vec3& pos_local,Matrix
|
||||
}
|
||||
}
|
||||
|
||||
void Billboard::calcTransform(const Vec3& eye_local, const Vec3& pos_local,Matrix& mat)
|
||||
|
||||
void Billboard::calcTransform(const Vec3& eye_local, const Vec3& pos_local,Matrix& mat) const
|
||||
{
|
||||
// mat.makeTrans(pos_local[0],pos_local[1],pos_local[2]);
|
||||
// mat.makeIdent();
|
||||
// mat.makeTrans(pos_local[0],pos_local[1],pos_local[2]);
|
||||
// mat.makeIdent();
|
||||
calcRotation(eye_local,pos_local,mat);
|
||||
|
||||
// mat.postTrans(pos_local[0],pos_local[1],pos_local[2]);
|
||||
// mat.postTrans(pos_local[0],pos_local[1],pos_local[2]);
|
||||
mat._mat[3][0] += pos_local[0];
|
||||
mat._mat[3][1] += pos_local[1];
|
||||
mat._mat[3][2] += pos_local[2];
|
||||
|
||||
}
|
||||
|
||||
bool Billboard::readLocalData(Input& fr)
|
||||
{
|
||||
// note, free done by Node::read(Input& fr)
|
||||
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr[0].matchWord("Mode"))
|
||||
{
|
||||
if (fr[1].matchWord("AXIAL_ROT"))
|
||||
{
|
||||
_mode = AXIAL_ROT;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("POINT_ROT_EYE"))
|
||||
{
|
||||
_mode = POINT_ROT_EYE;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("POINT_ROT_WORLD"))
|
||||
{
|
||||
_mode = POINT_ROT_WORLD;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
// read the position data.
|
||||
bool matchFirst = false;
|
||||
if ((matchFirst=fr.matchSequence("Positions {")) || fr.matchSequence("Positions %i {"))
|
||||
{
|
||||
|
||||
// set up coordinates.
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
|
||||
if (matchFirst)
|
||||
{
|
||||
fr += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//_positionList.(capacity);
|
||||
fr += 3;
|
||||
}
|
||||
|
||||
Vec3 pos;
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
{
|
||||
if (fr[0].getFloat(pos[0]) && fr[1].getFloat(pos[1]) && fr[2].getFloat(pos[2]))
|
||||
{
|
||||
fr += 3;
|
||||
_positionList.push_back(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
++fr;
|
||||
}
|
||||
}
|
||||
|
||||
iteratorAdvanced = true;
|
||||
++fr;
|
||||
|
||||
}
|
||||
|
||||
if (Geode::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
bool Billboard::writeLocalData(Output& fw)
|
||||
{
|
||||
|
||||
switch(_mode)
|
||||
{
|
||||
case(AXIAL_ROT): fw.indent() << "Mode AXIAL_ROT"<<endl; break;
|
||||
case(POINT_ROT_EYE): fw.indent() << "Mode POINT_ROT_EYE"<<endl; break;
|
||||
case(POINT_ROT_WORLD): fw.indent() << "Mode POINT_ROT_WORLD"<<endl; break;
|
||||
}
|
||||
|
||||
fw.indent() << "Axis " << _axis[0] << " "<<_axis[1]<<" "<<_axis[2]<<endl;
|
||||
|
||||
fw.indent() << "Positions {"<<endl;
|
||||
fw.moveIn();
|
||||
for(PositionList::iterator piter = _positionList.begin();
|
||||
piter != _positionList.end();
|
||||
++piter)
|
||||
{
|
||||
fw.indent() << (*piter)[0] << " "<<(*piter)[1]<<" "<<(*piter)[2]<<endl;
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent() << "}"<<endl;
|
||||
|
||||
Geode::writeLocalData(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Billboard::computeBound( void )
|
||||
const bool Billboard::computeBound() const
|
||||
{
|
||||
int i;
|
||||
int ngsets = _geosets.size();
|
||||
int ngsets = _drawables.size();
|
||||
|
||||
if( ngsets == 0 ) return false;
|
||||
|
||||
@@ -243,7 +154,7 @@ bool Billboard::computeBound( void )
|
||||
|
||||
for( i = 0; i < ngsets; i++ )
|
||||
{
|
||||
GeoSet *gset = _geosets[i].get();
|
||||
const Drawable *gset = _drawables[i].get();
|
||||
const BoundingBox& bbox = gset->getBound();
|
||||
|
||||
_bsphere._center += bbox.center();
|
||||
@@ -255,7 +166,7 @@ bool Billboard::computeBound( void )
|
||||
float maxd = 0.0;
|
||||
for( i = 0; i < ngsets; ++i )
|
||||
{
|
||||
GeoSet *gset = _geosets[i].get();
|
||||
const Drawable *gset = _drawables[i].get();
|
||||
const BoundingBox& bbox = gset->getBound();
|
||||
Vec3 local_center = _bsphere._center-_positionList[i];
|
||||
for(unsigned int c=0;c<8;++c)
|
||||
|
||||
@@ -7,38 +7,40 @@ void BoundingBox::expandBy(const Vec3& v)
|
||||
{
|
||||
if(v.x()<_min.x()) _min.x() = v.x();
|
||||
if(v.x()>_max.x()) _max.x() = v.x();
|
||||
|
||||
|
||||
if(v.y()<_min.y()) _min.y() = v.y();
|
||||
if(v.y()>_max.y()) _max.y() = v.y();
|
||||
|
||||
|
||||
if(v.z()<_min.z()) _min.z() = v.z();
|
||||
if(v.z()>_max.z()) _max.z() = v.z();
|
||||
}
|
||||
|
||||
|
||||
void BoundingBox::expandBy(const BoundingBox& bb)
|
||||
{
|
||||
if (!bb.isValid()) return;
|
||||
|
||||
if(bb._min.x()<_min.x()) _min.x() = bb._min.x();
|
||||
if(bb._max.x()>_max.x()) _max.x() = bb._max.x();
|
||||
|
||||
|
||||
if(bb._min.y()<_min.y()) _min.y() = bb._min.y();
|
||||
if(bb._max.y()>_max.y()) _max.y() = bb._max.y();
|
||||
|
||||
|
||||
if(bb._min.z()<_min.z()) _min.z() = bb._min.z();
|
||||
if(bb._max.z()>_max.z()) _max.z() = bb._max.z();
|
||||
}
|
||||
|
||||
|
||||
void BoundingBox::expandBy(const BoundingSphere& sh)
|
||||
{
|
||||
if (!sh.isValid()) return;
|
||||
|
||||
if(sh._center.x()-sh._radius<_min.x()) _min.x() = sh._center.x()-sh._radius;
|
||||
if(sh._center.x()+sh._radius>_max.x()) _max.x() = sh._center.x()+sh._radius;
|
||||
|
||||
|
||||
if(sh._center.y()-sh._radius<_min.y()) _min.y() = sh._center.y()-sh._radius;
|
||||
if(sh._center.y()+sh._radius>_max.y()) _max.y() = sh._center.y()+sh._radius;
|
||||
|
||||
|
||||
if(sh._center.z()-sh._radius<_min.z()) _min.z() = sh._center.z()-sh._radius;
|
||||
if(sh._center.z()+sh._radius>_max.z()) _max.z() = sh._center.z()+sh._radius;
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ void BoundingSphere::expandBy(const Vec3& v)
|
||||
Vec3 dv = v-_center;
|
||||
float r = dv.length();
|
||||
if (r>_radius)
|
||||
{
|
||||
{
|
||||
float dr = (r-_radius)*0.5f;
|
||||
_center += dv*(dr/r);
|
||||
_radius += dr;
|
||||
} // else do nothing as vertex is within sphere.
|
||||
} // else do nothing as vertex is within sphere.
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -22,6 +22,7 @@ void BoundingSphere::expandBy(const Vec3& v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BoundingSphere::expandRadiusBy(const Vec3& v)
|
||||
{
|
||||
if (isValid())
|
||||
@@ -37,6 +38,7 @@ void BoundingSphere::expandRadiusBy(const Vec3& v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BoundingSphere::expandBy(const BoundingSphere& sh)
|
||||
{
|
||||
if (sh.isValid())
|
||||
@@ -47,13 +49,13 @@ void BoundingSphere::expandBy(const BoundingSphere& sh)
|
||||
float dv_len = dv.length();
|
||||
if (dv_len+sh._radius>_radius)
|
||||
{
|
||||
|
||||
|
||||
Vec3 e1 = _center-(dv*(_radius/dv_len));
|
||||
Vec3 e2 = sh._center+(dv*(sh._radius/dv_len));
|
||||
_center = (e1+e2)*0.5f;
|
||||
_radius = (e2-_center).length();
|
||||
|
||||
} // else do nothing as vertex is within sphere.
|
||||
|
||||
} // else do nothing as vertex is within sphere.
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -62,6 +64,8 @@ void BoundingSphere::expandBy(const BoundingSphere& sh)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BoundingSphere::expandRadiusBy(const BoundingSphere& sh)
|
||||
{
|
||||
if (sh.isValid())
|
||||
|
||||
@@ -1,85 +1,705 @@
|
||||
#include "osg/GL"
|
||||
#include <osg/GL>
|
||||
#include <osg/Camera>
|
||||
#include <osg/Types>
|
||||
#include <osg/Notify>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
#define RAD2DEG(x) ((x)*180.0/M_PI)
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
_fovy = 60.0;
|
||||
_aspectRatio = 1.0;
|
||||
home();
|
||||
|
||||
// projection details.
|
||||
setPerspective(60,1.0,1.0,1000.0);
|
||||
|
||||
// look at details.
|
||||
_lookAtType =USE_HOME_POSITON;
|
||||
|
||||
_eye.set(0.0f,0.0f,0.0f);
|
||||
_center.set(0.0f,0.0f,-1.0f);
|
||||
_up.set(0.0f,1.0f,0.0f);
|
||||
|
||||
_focalLength = 1.0f;
|
||||
|
||||
_useNearClippingPlane = false;
|
||||
_useFarClippingPlane = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Set a orthographics projection. See glOrtho for further details.*/
|
||||
void Camera::setOrtho(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
_projectionType = ORTHO;
|
||||
_left = left;
|
||||
_right = right;
|
||||
_bottom = bottom;
|
||||
_top = top;
|
||||
_zNear = zNear;
|
||||
_zFar = zFar;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
/** Set a 2D orthographics projection. See gluOrtho2D for further details.*/
|
||||
void Camera::setOrtho2D(const double left, const double right,
|
||||
const double bottom, const double top)
|
||||
{
|
||||
_projectionType = ORTHO2D;
|
||||
_left = left;
|
||||
_right = right;
|
||||
_bottom = bottom;
|
||||
_top = top;
|
||||
_zNear = -1.0;
|
||||
_zFar = 1.0;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
/** Set a perspective projection. See glFrustum for further details.*/
|
||||
void Camera::setFrustum(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
_projectionType = FRUSTUM;
|
||||
// note, in Frustum/Perspective mode these values are scaled
|
||||
// by the zNear from when they were initialised to ensure that
|
||||
// subsequent changes in zNear do not affect them.
|
||||
_left = left/zNear;
|
||||
_right = right/zNear;
|
||||
_bottom = bottom/zNear;
|
||||
_top = top/zNear;
|
||||
_zNear = zNear;
|
||||
_zFar = zFar;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Set a sysmetical perspective projection, See gluPerspective for further details.*/
|
||||
void Camera::setPerspective(const double fovy,const double aspectRatio,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
_projectionType = PERSPECTIVE;
|
||||
|
||||
// note, in Frustum/Perspective mode these values are scaled
|
||||
// by the zNear from when they were initialised to ensure that
|
||||
// subsequent changes in zNear do not affect them.
|
||||
|
||||
// calculate the appropriate left, right etc.
|
||||
double tan_fovy = tan(DEG2RAD(fovy*0.5));
|
||||
_right = tan_fovy * aspectRatio;
|
||||
_left = -_right;
|
||||
_top = tan_fovy;
|
||||
_bottom = -_top;
|
||||
|
||||
_zNear = zNear;
|
||||
_zFar = zFar;
|
||||
|
||||
notify(INFO)<<"osg::Camera::setPerspective(fovy="<<fovy<<",aspectRatio="<<aspectRatio<<","<<endl;
|
||||
notify(INFO)<<" zNear="<<zNear<<", zFar="<<zFar<<")"<<endl;
|
||||
notify(INFO)<<" osg::Camera::calc_fovx()="<<calc_fovx()<<endl;
|
||||
notify(INFO)<<" osg::Camera::calc_fovy()="<<calc_fovy()<<endl;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
/** Set the near and far clipping planes.*/
|
||||
void Camera::setNearFar(const double zNear, const double zFar)
|
||||
{
|
||||
_zNear = zNear;
|
||||
_zFar = zFar;
|
||||
_dirty = true;
|
||||
if (_projectionType==ORTHO2D)
|
||||
{
|
||||
if (_zNear!=-1.0 || _zFar!=1.0) _projectionType = ORTHO;
|
||||
}
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/** Adjust the clipping planes to account for a new window aspcect ratio.
|
||||
* Typicall used after resizeing a window.*/
|
||||
void Camera::adjustAspectRatio(const double newAspectRatio, const AdjustAxis aa)
|
||||
{
|
||||
double previousAspectRatio = (_right-_left)/(_top-_bottom);
|
||||
double deltaRatio = newAspectRatio/previousAspectRatio;
|
||||
if (aa == ADJUST_HORIZONTAL)
|
||||
{
|
||||
_left *= deltaRatio;
|
||||
_right *= deltaRatio;
|
||||
}
|
||||
else // aa == ADJUST_VERTICAL
|
||||
{
|
||||
_bottom /= deltaRatio;
|
||||
_top /= deltaRatio;
|
||||
}
|
||||
|
||||
notify(INFO)<<"osg::Camera::adjustAspectRatio(newAspectRatio="<<newAspectRatio<<", AdjustAxis="<<aa<<")"<<endl;
|
||||
notify(INFO)<<" osg::Camera::calc_fovx()="<<calc_fovx()<<endl;
|
||||
notify(INFO)<<" osg::Camera::calc_fovy()="<<calc_fovy()<<endl;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
const double Camera::left() const
|
||||
{
|
||||
switch(_projectionType)
|
||||
{
|
||||
case(FRUSTUM):
|
||||
case(PERSPECTIVE): return _left * _zNear;
|
||||
}
|
||||
return _left;
|
||||
}
|
||||
const double Camera::right() const
|
||||
{
|
||||
switch(_projectionType)
|
||||
{
|
||||
case(FRUSTUM):
|
||||
case(PERSPECTIVE): return _right * _zNear;
|
||||
}
|
||||
return _right;
|
||||
}
|
||||
|
||||
const double Camera::top() const
|
||||
{
|
||||
switch(_projectionType)
|
||||
{
|
||||
case(FRUSTUM):
|
||||
case(PERSPECTIVE): return _top * _zNear;
|
||||
}
|
||||
return _top;
|
||||
}
|
||||
|
||||
const double Camera::bottom() const
|
||||
{
|
||||
switch(_projectionType)
|
||||
{
|
||||
case(FRUSTUM):
|
||||
case(PERSPECTIVE): return _bottom * _zNear;
|
||||
}
|
||||
return _bottom;
|
||||
}
|
||||
|
||||
const double Camera::zNear() const
|
||||
{
|
||||
return _zNear;
|
||||
}
|
||||
|
||||
const double Camera::zFar() const
|
||||
{
|
||||
return _zFar;
|
||||
}
|
||||
|
||||
/** Calculate and return the equivilant fovx for the current project setting.
|
||||
* This value is only valid for when a symetric persepctive projection exists.
|
||||
* i.e. getProjectionType()==PERSPECTIVE.*/
|
||||
const double Camera::calc_fovy() const
|
||||
{
|
||||
// note, _right & _left are prescaled by znear so
|
||||
// no need to account for it.
|
||||
return RAD2DEG(atan(_top)-atan(_bottom));
|
||||
}
|
||||
|
||||
|
||||
/** Calculate and return the equivilant fovy for the current project setting.
|
||||
* This value is only valid for when a symetric persepctive projection exists.
|
||||
* i.e. getProjectionType()==PERSPECTIVE.*/
|
||||
const double Camera::calc_fovx() const
|
||||
{
|
||||
// note, _right & _left are prescaled by znear so
|
||||
// no need to account for it.
|
||||
return RAD2DEG(atan(_right)-atan(_left));
|
||||
}
|
||||
|
||||
|
||||
/** Calculate and return the projection aspect ratio.*/
|
||||
const double Camera::calc_aspectRatio() const
|
||||
{
|
||||
double delta_x = _right-_left;
|
||||
double delta_y = _top-_bottom;
|
||||
return delta_x/delta_y;
|
||||
}
|
||||
|
||||
const Matrix& Camera::getProjectionMatrix() const
|
||||
{
|
||||
if (_dirty) calculateMatricesAndClippingVolume();
|
||||
return *_projectionMatrix;
|
||||
}
|
||||
|
||||
void Camera::home()
|
||||
{
|
||||
_eyePoint.set(0.0f,0.0f,0.0f);
|
||||
_lookPoint.set(0.0f,0.0f,-1.0f);
|
||||
_upVector.set(0.0f,1.0f,0.0f);
|
||||
_nearPlane = 1.0;
|
||||
_farPlane = 1000.0;
|
||||
// OpenGL default position.
|
||||
_lookAtType = USE_HOME_POSITON;
|
||||
_eye.set(0.0f,0.0f,0.0f);
|
||||
_center.set(0.0f,0.0f,-1.0f);
|
||||
_up.set(0.0f,1.0f,0.0f);
|
||||
|
||||
// need to set to appropriate values..
|
||||
_focalLength = 1.0f;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void Camera::setView(osg::Vec3 eyePoint, osg::Vec3 lookPoint, osg::Vec3 upVector)
|
||||
void Camera::setView(const Vec3& eyePoint, const Vec3& lookPoint, const Vec3& upVector)
|
||||
{
|
||||
// Should do some checking here!
|
||||
_eyePoint = eyePoint;
|
||||
_lookPoint = lookPoint;
|
||||
_upVector = upVector;
|
||||
setLookAt(eyePoint,lookPoint,upVector);
|
||||
}
|
||||
|
||||
void Camera::draw_PROJECTION() const
|
||||
{
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
gluPerspective(_fovy, _aspectRatio, static_cast<GLdouble>(_nearPlane), static_cast<GLdouble>(_farPlane));
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
|
||||
void Camera::setLookAt(const Vec3& eye,
|
||||
const Vec3& center,
|
||||
const Vec3& up)
|
||||
{
|
||||
_lookAtType = USE_EYE_CENTER_AND_UP;
|
||||
_eye = eye;
|
||||
_center = center;
|
||||
_up = up;
|
||||
|
||||
ensureOrthogonalUpVector();
|
||||
|
||||
// need to set to appropriate values..
|
||||
_focalLength = (center-eye).length();
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void Camera::draw_MODELVIEW() const
|
||||
{
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
gluLookAt( _eyePoint.x(), _eyePoint.y(), _eyePoint.z(),
|
||||
_lookPoint.x(), _lookPoint.y(), _lookPoint.z(),
|
||||
_upVector.x(), _upVector.y(), _upVector.z());
|
||||
|
||||
void Camera::setLookAt(const double eyeX, const double eyeY, const double eyeZ,
|
||||
const double centerX, const double centerY, const double centerZ,
|
||||
const double upX, const double upY, const double upZ)
|
||||
{
|
||||
_lookAtType = USE_EYE_CENTER_AND_UP;
|
||||
_eye.set(eyeX,eyeY,eyeZ);
|
||||
_center.set(centerX,centerY,centerZ);
|
||||
_up.set(upX,upY,upZ);
|
||||
|
||||
ensureOrthogonalUpVector();
|
||||
|
||||
// need to set to appropriate values..
|
||||
_focalLength = (_center-_eye).length();
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
/** post multiple the existing eye point and orientation by matrix.
|
||||
* note, does not affect any ModelTransforms that are applied.*/
|
||||
void Camera::transformLookAt(const Matrix& matrix)
|
||||
{
|
||||
// cout << "transformLookAt"<<matrix<<endl;
|
||||
_up = (_up+_eye)*matrix;
|
||||
_eye = _eye*matrix;
|
||||
_center = _center*matrix;
|
||||
_up -= _eye;
|
||||
_up.normalize();
|
||||
}
|
||||
|
||||
const Vec3 Camera::getLookVector() const
|
||||
{
|
||||
osg::Vec3 lv(_center-_eye);
|
||||
lv.normalize();
|
||||
return lv;
|
||||
}
|
||||
|
||||
const Vec3 Camera::getSideVector() const
|
||||
{
|
||||
osg::Vec3 lv(_center-_eye);
|
||||
lv.normalize();
|
||||
osg::Vec3 sv(lv^_up);
|
||||
sv.normalize();
|
||||
return sv;
|
||||
}
|
||||
|
||||
|
||||
void Camera::attachTransform(const TransformMode mode, Matrix* matrix)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(EYE_TO_MODEL):
|
||||
{
|
||||
_eyeToModelTransform = matrix;
|
||||
if (_eyeToModelTransform.valid())
|
||||
{
|
||||
_attachedTransformMode = mode;
|
||||
if (!_modelToEyeTransform.valid()) _modelToEyeTransform = new Matrix;
|
||||
_modelToEyeTransform->invert(*_eyeToModelTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
_attachedTransformMode = NO_ATTACHED_TRANSFORM;
|
||||
_modelToEyeTransform = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case(MODEL_TO_EYE):
|
||||
{
|
||||
_modelToEyeTransform = matrix;
|
||||
if (_modelToEyeTransform.valid())
|
||||
{
|
||||
_attachedTransformMode = mode;
|
||||
if (!_eyeToModelTransform.valid()) _eyeToModelTransform = new Matrix;
|
||||
_eyeToModelTransform->invert(*_modelToEyeTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
_attachedTransformMode = NO_ATTACHED_TRANSFORM;
|
||||
_eyeToModelTransform = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case(NO_ATTACHED_TRANSFORM):
|
||||
_attachedTransformMode = NO_ATTACHED_TRANSFORM;
|
||||
_eyeToModelTransform = NULL;
|
||||
_modelToEyeTransform = NULL;
|
||||
break;
|
||||
default:
|
||||
_attachedTransformMode = NO_ATTACHED_TRANSFORM;
|
||||
notify(WARN)<<"Warning: invalid TransformMode pass to osg::Camera::attachTransform(..)"<<endl;
|
||||
notify(WARN)<<" setting Camera to NO_ATTACHED_TRANSFORM."<<endl;
|
||||
break;
|
||||
}
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void Camera::dirtyTransform()
|
||||
{
|
||||
_dirty = true;
|
||||
|
||||
switch(_attachedTransformMode)
|
||||
{
|
||||
case(EYE_TO_MODEL):
|
||||
// should be safe to assume that these matrices are valid
|
||||
// as attachTransform will ensure it.
|
||||
_modelToEyeTransform->invert(*_eyeToModelTransform);
|
||||
break;
|
||||
case(MODEL_TO_EYE):
|
||||
// should be safe to assume that these matrices are valid
|
||||
// as attachTransform will ensure it.
|
||||
_eyeToModelTransform->invert(*_modelToEyeTransform);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Matrix* Camera::getTransform(const TransformMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(EYE_TO_MODEL): return _eyeToModelTransform.get();
|
||||
case(MODEL_TO_EYE): return _modelToEyeTransform.get();
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const Matrix* Camera::getTransform(const TransformMode mode) const
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(EYE_TO_MODEL): return _eyeToModelTransform.get();
|
||||
case(MODEL_TO_EYE): return _modelToEyeTransform.get();
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Vec3 Camera::getEyePoint_Model() const
|
||||
{
|
||||
if (_eyeToModelTransform.valid()) return _eye*(*_eyeToModelTransform);
|
||||
else return _eye;
|
||||
}
|
||||
|
||||
const Vec3 Camera::getCenterPoint_Model() const
|
||||
{
|
||||
if (_eyeToModelTransform.valid()) return _center*(*_eyeToModelTransform);
|
||||
else return _center;
|
||||
}
|
||||
|
||||
|
||||
const Vec3 Camera::getLookVector_Model() const
|
||||
{
|
||||
if (_eyeToModelTransform.valid())
|
||||
{
|
||||
Vec3 zero_transformed = Vec3(0.0f,0.0f,0.0f)*(*_eyeToModelTransform);
|
||||
Vec3 look_transformed = getLookVector()*(*_eyeToModelTransform);
|
||||
look_transformed -= zero_transformed;
|
||||
look_transformed.normalize();
|
||||
return look_transformed;
|
||||
}
|
||||
else return getLookVector();
|
||||
}
|
||||
|
||||
const Vec3 Camera::getUpVector_Model() const
|
||||
{
|
||||
if (_eyeToModelTransform.valid())
|
||||
{
|
||||
Vec3 zero_transformed = Vec3(0.0f,0.0f,0.0f)*(*_eyeToModelTransform);
|
||||
Vec3 up_transformed = getUpVector()*(*_eyeToModelTransform);
|
||||
up_transformed -= zero_transformed;
|
||||
up_transformed.normalize();
|
||||
return up_transformed;
|
||||
}
|
||||
else return getUpVector();
|
||||
}
|
||||
|
||||
const Vec3 Camera::getSideVector_Model() const
|
||||
{
|
||||
if (_eyeToModelTransform.valid())
|
||||
{
|
||||
Vec3 zero_transformed = Vec3(0.0f,0.0f,0.0f)*(*_eyeToModelTransform);
|
||||
Vec3 side_transformed = getSideVector()*(*_eyeToModelTransform);
|
||||
side_transformed -= zero_transformed;
|
||||
side_transformed.normalize();
|
||||
return side_transformed;
|
||||
}
|
||||
else return getSideVector();
|
||||
}
|
||||
|
||||
const Matrix& Camera::getModelViewMatrix() const
|
||||
{
|
||||
if (_dirty) calculateMatricesAndClippingVolume();
|
||||
return *_modelViewMatrix;
|
||||
}
|
||||
|
||||
void Camera::setUseNearClippingPlane(const bool use)
|
||||
{
|
||||
if (_useNearClippingPlane != use)
|
||||
{
|
||||
_useNearClippingPlane = use;
|
||||
_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::setUseFarClippingPlane(const bool use)
|
||||
{
|
||||
if (_useFarClippingPlane != use)
|
||||
{
|
||||
_useFarClippingPlane = use;
|
||||
_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
const ClippingVolume& Camera::getClippingVolume() const
|
||||
{
|
||||
if (_dirty) calculateMatricesAndClippingVolume();
|
||||
return _clippingVolume;
|
||||
}
|
||||
|
||||
void Camera::calculateMatricesAndClippingVolume() const
|
||||
{
|
||||
|
||||
// set up the projection matrix.
|
||||
switch(_projectionType)
|
||||
{
|
||||
case(ORTHO):
|
||||
case(ORTHO2D):
|
||||
{
|
||||
float A = 2.0/(_right-_left);
|
||||
float B = 2.0/(_top-_bottom);
|
||||
float C = -2.0 / (_zFar-_zNear);
|
||||
float tx = -(_right+_left)/(_right-_left);
|
||||
float ty = -(_top+_bottom)/(_top-_bottom);
|
||||
float tz = -(_zFar+_zNear)/(_zFar-_zNear);
|
||||
|
||||
_projectionMatrix = new Matrix(
|
||||
A, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, B, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, C, 0.0f,
|
||||
tx, ty, tz, 1.0f );
|
||||
}
|
||||
break;
|
||||
case(FRUSTUM):
|
||||
case(PERSPECTIVE):
|
||||
{
|
||||
|
||||
// note, in Frustum/Perspective mode these values are scaled
|
||||
// by the zNear from when they were initialised to ensure that
|
||||
// subsequent changes in zNear do not affect them.
|
||||
|
||||
float A = (2.0)/(_right-_left);
|
||||
float B = (2.0)/(_top-_bottom);
|
||||
float C = (_right+_left) / (_right-_left);
|
||||
float D = (_top+_bottom) / (_top-_bottom);
|
||||
float E = -(_zFar+_zNear) / (_zFar-_zNear);
|
||||
float F = -(2.0*_zFar*_zNear) / (_zFar-_zNear);
|
||||
|
||||
_projectionMatrix = new Matrix(
|
||||
A, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, B, 0.0f, 0.0f,
|
||||
C, D, E, -1.0f,
|
||||
0.0f, 0.0f, F, 0.0f );
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// set up the model view matrix.
|
||||
switch(_lookAtType)
|
||||
{
|
||||
case(USE_HOME_POSITON):
|
||||
if (_modelToEyeTransform.valid())
|
||||
{
|
||||
_modelViewMatrix = _modelToEyeTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
_modelViewMatrix = new Matrix;
|
||||
_modelViewMatrix->makeIdent();
|
||||
}
|
||||
break;
|
||||
case(USE_EYE_AND_QUATERNION): // not implemented yet, default to eye,center,up.
|
||||
case(USE_EYE_CENTER_AND_UP):
|
||||
default:
|
||||
{
|
||||
|
||||
Vec3 f(_center-_eye);
|
||||
f.normalize();
|
||||
Vec3 s(f^_up);
|
||||
s.normalize();
|
||||
Vec3 u(s^f);
|
||||
u.normalize();
|
||||
|
||||
ref_ptr<Matrix> matrix = new Matrix(
|
||||
s[0], u[0], -f[0], 0.0f,
|
||||
s[1], u[1], -f[1], 0.0f,
|
||||
s[2], u[2], -f[2], 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
matrix->preTrans(-_eye[0], -_eye[1], -_eye[2]);
|
||||
|
||||
if (_modelToEyeTransform.valid())
|
||||
{
|
||||
_modelViewMatrix = new Matrix;
|
||||
_modelViewMatrix->mult(*matrix,*_modelToEyeTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
_modelViewMatrix = matrix;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_clippingVolume.clear();
|
||||
|
||||
// set the clipping volume.
|
||||
switch(_projectionType)
|
||||
{
|
||||
case(ORTHO):
|
||||
case(ORTHO2D):
|
||||
{
|
||||
}
|
||||
break;
|
||||
case(FRUSTUM):
|
||||
case(PERSPECTIVE):
|
||||
{
|
||||
// calculate the frustum normals, postive pointing inwards.
|
||||
// left clipping plane
|
||||
// note, _left,_right,_top and _bottom are already devided
|
||||
// by _zNear so no need to take into account for normal
|
||||
// calculations.
|
||||
Vec3 leftNormal (1.0f,0.0f,_left);
|
||||
leftNormal.normalize();
|
||||
_clippingVolume.add(Plane(leftNormal,0.0f));
|
||||
|
||||
|
||||
Vec3 rightNormal (-1.0f,0.0f,-_right);
|
||||
rightNormal.normalize();
|
||||
_clippingVolume.add(Plane(rightNormal,0.0f));
|
||||
|
||||
Vec3 bottomNormal(0.0f,1.0f,_bottom);
|
||||
bottomNormal.normalize();
|
||||
_clippingVolume.add(Plane(bottomNormal,0.0f));
|
||||
|
||||
Vec3 topNormal(0.0f,-1.0f,-_top);
|
||||
topNormal.normalize();
|
||||
_clippingVolume.add(Plane(topNormal,0.0f));
|
||||
|
||||
if (_useNearClippingPlane)
|
||||
{
|
||||
_clippingVolume.add(Plane(0.0f,0.0f,-1.0f,-_zNear));
|
||||
}
|
||||
|
||||
if (_useFarClippingPlane)
|
||||
{
|
||||
_clippingVolume.add(Plane(0.0f,0.0f,1.0f,_zFar));
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
_clippingVolume.transformProvidingInverse(*_modelViewMatrix);
|
||||
|
||||
if (!_MP.valid()) _MP = new Matrix;
|
||||
_MP->mult(*_modelViewMatrix,*_projectionMatrix);
|
||||
|
||||
if (!_inverseMP.valid()) _inverseMP = new Matrix;
|
||||
_inverseMP->invert(*_MP);
|
||||
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
void Camera::ensureOrthogonalUpVector()
|
||||
{
|
||||
Vec3 lv = _lookPoint-_eyePoint;
|
||||
Vec3 sv = lv^_upVector;
|
||||
_upVector = sv^lv;
|
||||
_upVector.normalize();
|
||||
Vec3 lv = _center-_eye;
|
||||
Vec3 sv = lv^_up;
|
||||
_up = sv^lv;
|
||||
_up.normalize();
|
||||
}
|
||||
|
||||
void Camera::mult(const Camera& camera,const Matrix& m)
|
||||
const bool Camera::project(const Vec3& obj,const int* view,Vec3& win) const
|
||||
{
|
||||
// transform camera.
|
||||
_upVector = (camera._lookPoint+camera._upVector)*m;
|
||||
_eyePoint = camera._eyePoint*m;
|
||||
_lookPoint = camera._lookPoint*m;
|
||||
_upVector -= _lookPoint;
|
||||
|
||||
// now reset up vector so it remains at 90 degrees to look vector,
|
||||
// as it may drift during transformation.
|
||||
ensureOrthogonalUpVector();
|
||||
if (_MP.valid())
|
||||
{
|
||||
Vec3 v = obj * (*_MP);
|
||||
|
||||
win.set(
|
||||
view[0] + view[2]*(v[0]+1.0f)*0.5f,
|
||||
view[1] + view[3]*(v[1]+1.0f)*0.5f,
|
||||
(v[2]+1.0f)*0.5f
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Camera::mult(const Matrix& m,const Camera& camera)
|
||||
const bool Camera::unproject(const Vec3& win,const int* view,Vec3& obj) const
|
||||
{
|
||||
// transform camera.
|
||||
_upVector = m*(camera._lookPoint+camera._upVector);
|
||||
_eyePoint = m*camera._eyePoint;
|
||||
_lookPoint = m*camera._lookPoint;
|
||||
_upVector -= _lookPoint;
|
||||
|
||||
// now reset up vector so it remains at 90 degrees to look vector,
|
||||
// as it may drift during transformation.
|
||||
ensureOrthogonalUpVector();
|
||||
if (_inverseMP.valid())
|
||||
{
|
||||
Vec3 v(
|
||||
2.0f*(win[0]-view[0])/view[2] - 1.0f,
|
||||
2.0f*(win[1]-view[1])/view[3] - 1.0f,
|
||||
2.0f*(win[2]) - 1.0f
|
||||
);
|
||||
|
||||
obj = v * (*_inverseMP);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/CullFace"
|
||||
#include "osg/Output"
|
||||
#include "osg/Input"
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
@@ -11,70 +8,12 @@ CullFace::CullFace()
|
||||
_mode = BACK;
|
||||
}
|
||||
|
||||
|
||||
CullFace::~CullFace()
|
||||
{
|
||||
}
|
||||
|
||||
CullFace* CullFace::instance()
|
||||
{
|
||||
static ref_ptr<CullFace> s_CullFace(new CullFace);
|
||||
return s_CullFace.get();
|
||||
}
|
||||
|
||||
void CullFace::enable( void )
|
||||
{
|
||||
glEnable( GL_CULL_FACE );
|
||||
}
|
||||
|
||||
|
||||
void CullFace::disable( void )
|
||||
{
|
||||
glDisable( GL_CULL_FACE );
|
||||
}
|
||||
|
||||
void CullFace::apply()
|
||||
void CullFace::apply(State&) const
|
||||
{
|
||||
glCullFace((GLenum)_mode);
|
||||
}
|
||||
|
||||
|
||||
bool CullFace::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr[0].matchWord("mode"))
|
||||
{
|
||||
if (fr[1].matchWord("FRONT"))
|
||||
{
|
||||
_mode = FRONT;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("BACK"))
|
||||
{
|
||||
_mode = BACK;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("FRONT_AND_BACK"))
|
||||
{
|
||||
_mode = FRONT_AND_BACK;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool CullFace::writeLocalData(Output& fw)
|
||||
{
|
||||
switch(_mode)
|
||||
{
|
||||
case(FRONT): fw.indent() << "mode FRONT" << endl; break;
|
||||
case(BACK): fw.indent() << "mode BACK" << endl; break;
|
||||
case(FRONT_AND_BACK): fw.indent() << "mode FRONT_AND_BACK" << endl; break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/Fog"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Fog::Fog( void )
|
||||
Fog::Fog()
|
||||
{
|
||||
_mode = EXP;
|
||||
_density = 1.0f;
|
||||
@@ -13,31 +12,11 @@ Fog::Fog( void )
|
||||
}
|
||||
|
||||
|
||||
Fog::~Fog( void )
|
||||
Fog::~Fog()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Fog* Fog::instance()
|
||||
{
|
||||
static ref_ptr<Fog> s_fog(new Fog);
|
||||
return s_fog.get();
|
||||
}
|
||||
|
||||
|
||||
void Fog::enable( void )
|
||||
{
|
||||
glEnable( GL_FOG );
|
||||
}
|
||||
|
||||
|
||||
void Fog::disable( void )
|
||||
{
|
||||
glDisable( GL_FOG );
|
||||
}
|
||||
|
||||
|
||||
void Fog::apply( void )
|
||||
void Fog::apply(State&) const
|
||||
{
|
||||
glFogi( GL_FOG_MODE, _mode );
|
||||
glFogf( GL_FOG_DENSITY, _density );
|
||||
|
||||
1767
src/osg/GeoSet.cpp
@@ -1,3 +1,7 @@
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "osg/GL"
|
||||
#include "osg/GeoSet"
|
||||
@@ -5,6 +9,7 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#define DEBUG
|
||||
#define DO_SHADING 1
|
||||
|
||||
#define I_ON (1<<4)
|
||||
@@ -21,53 +26,52 @@ void GeoSet::set_fast_path( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( _normal_binding != BIND_PERPRIM) &&
|
||||
( _nindex == 0L ) &&
|
||||
( _color_binding != BIND_PERPRIM) &&
|
||||
( _colindex == 0L ) &&
|
||||
( _primtype != FLAT_LINE_STRIP ) &&
|
||||
( _primtype != FLAT_TRIANGLE_STRIP ) &&
|
||||
( _primtype != FLAT_TRIANGLE_FAN )
|
||||
)
|
||||
_fast_path = V_ON;
|
||||
if( ( _normal_binding != BIND_PERPRIM) &&
|
||||
( _nindex.null() || _nindex ==_cindex) &&
|
||||
( _color_binding != BIND_PERPRIM) &&
|
||||
( _colindex.null() || _colindex ==_cindex ) &&
|
||||
( _primtype != FLAT_LINE_STRIP ) &&
|
||||
( _primtype != FLAT_TRIANGLE_STRIP ) &&
|
||||
( _primtype != FLAT_TRIANGLE_FAN )
|
||||
)
|
||||
_fast_path = V_ON;
|
||||
else
|
||||
{
|
||||
_fast_path = 0;
|
||||
{
|
||||
_fast_path = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because NORMALS are bound PER_PRIM\n";
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because NORMALS are bound PER_PRIM\n";
|
||||
|
||||
if( _nindex != 0L )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because NORMAL indeces are specified\n";
|
||||
if( _nindex.valid() )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because NORMAL indeces are specified\n";
|
||||
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because COLORS are bound PER_PRIM\n";
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because COLORS are bound PER_PRIM\n";
|
||||
|
||||
if( _cindex != 0L )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because COLOR indeces are specified\n";
|
||||
if( _cindex.valid() )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because COLOR indeces are specified\n";
|
||||
|
||||
if( _primtype == FLAT_LINE_STRIP )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_LINE_STRIP\n";
|
||||
if( _primtype == FLAT_LINE_STRIP )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_LINE_STRIP\n";
|
||||
|
||||
if ( _primtype == FLAT_TRIANGLE_STRIP )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_TRIANGLE_STRIP\n";
|
||||
if ( _primtype == FLAT_TRIANGLE_STRIP )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_TRIANGLE_STRIP\n";
|
||||
|
||||
if ( _primtype == FLAT_TRIANGLE_FAN )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_TRIANGLE_FAN\n";
|
||||
|
||||
#endif
|
||||
}
|
||||
if ( _primtype == FLAT_TRIANGLE_FAN )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_TRIANGLE_FAN\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
if( _fast_path )
|
||||
{
|
||||
if( _color_binding == BIND_PERVERTEX )
|
||||
_fast_path |= C_ON;
|
||||
_fast_path |= C_ON;
|
||||
if( _normal_binding == BIND_PERVERTEX )
|
||||
_fast_path |= N_ON;
|
||||
_fast_path |= N_ON;
|
||||
if( _texture_binding == BIND_PERVERTEX )
|
||||
_fast_path |= T_ON;
|
||||
_fast_path |= T_ON;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,113 +80,113 @@ void GeoSet::set_fast_path( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void GeoSet::draw_fast_path( void )
|
||||
{
|
||||
ushort *ocindex = _cindex;
|
||||
IndexPointer ocindex = _cindex;
|
||||
|
||||
switch( _fast_path )
|
||||
{
|
||||
case (I_ON) :
|
||||
_cindex = _iaindex;
|
||||
glInterleavedArrays( (GLenum)_ogliaformat, 0, _iarray );
|
||||
break;
|
||||
break;
|
||||
|
||||
case (V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (T_ON|V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
case (T_ON|V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (N_ON|V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
case (N_ON|V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (N_ON|T_ON|V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (C_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
case (C_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
|
||||
case (C_ON|T_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
case (C_ON|T_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
break;
|
||||
|
||||
case (C_ON|N_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
case (C_ON|N_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (C_ON|N_ON|T_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
case (C_ON|N_ON|T_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
}
|
||||
|
||||
if( _color_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _colindex != 0L )
|
||||
glColor4fv( (GLfloat * )&_colors[_colindex[0]] );
|
||||
else
|
||||
glColor4fv( (GLfloat * )&_colors[0] );
|
||||
if( _colindex.valid() )
|
||||
glColor4fv( (GLfloat * )&_colors[_colindex[0]] );
|
||||
else
|
||||
glColor4fv( (GLfloat * )&_colors[0] );
|
||||
}
|
||||
|
||||
if( _normal_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _nindex != 0L )
|
||||
glNormal3fv( (GLfloat * )&_normals[_nindex[0]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat * )&_normals[0] );
|
||||
if( _nindex.valid() )
|
||||
glNormal3fv( (GLfloat * )&_normals[_nindex[0]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat * )&_normals[0] );
|
||||
}
|
||||
|
||||
if( _needprimlen ) // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
if( _needprimlen ) // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
{
|
||||
int index = 0;
|
||||
if( _primLengths == (int *)0 )
|
||||
@@ -192,18 +196,29 @@ void GeoSet::draw_fast_path( void )
|
||||
}
|
||||
|
||||
for( int i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _primLengths[i], GL_UNSIGNED_SHORT, &_cindex[index] );
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, index, _primLengths[i] );
|
||||
index += _primLengths[i];
|
||||
}
|
||||
{
|
||||
if( _cindex.valid() )
|
||||
{
|
||||
if (_cindex._is_ushort)
|
||||
glDrawElements( (GLenum)_oglprimtype, _primLengths[i], GL_UNSIGNED_SHORT, &_cindex._ptr._ushort[index] );
|
||||
else
|
||||
glDrawElements( (GLenum)_oglprimtype, _primLengths[i], GL_UNSIGNED_INT, &_cindex._ptr._uint[index] );
|
||||
}
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, index, _primLengths[i] );
|
||||
|
||||
index += _primLengths[i];
|
||||
}
|
||||
}
|
||||
else // POINTS, LINES, TRIANGLES, QUADS
|
||||
else // POINTS, LINES, TRIANGLES, QUADS
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _numindices, GL_UNSIGNED_SHORT, _cindex );
|
||||
if( _cindex.valid())
|
||||
{
|
||||
if (_cindex._is_ushort)
|
||||
glDrawElements( (GLenum)_oglprimtype, _cindex._size, GL_UNSIGNED_SHORT, _cindex._ptr._ushort );
|
||||
else
|
||||
glDrawElements( (GLenum)_oglprimtype, _cindex._size, GL_UNSIGNED_INT, _cindex._ptr._uint );
|
||||
}
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, 0, _numcoords );
|
||||
}
|
||||
@@ -211,63 +226,64 @@ void GeoSet::draw_fast_path( void )
|
||||
_cindex = ocindex;
|
||||
}
|
||||
|
||||
|
||||
void GeoSet::draw_alternate_path( void )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_cindex == 0L) && (_flat_shaded_skip == 0) )
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_colindex.null() || _colindex ==_cindex) && (_flat_shaded_skip == 0) )
|
||||
{
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
if( _color_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _colindex )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[0]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[0] );
|
||||
}
|
||||
}
|
||||
if( _color_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _colindex.valid() )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[0]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[0] );
|
||||
}
|
||||
}
|
||||
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex == 0L) && (_flat_shaded_skip == 0) )
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex.null() || _nindex ==_cindex) && (_flat_shaded_skip == 0) )
|
||||
{
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
if( _normal_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _nindex )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[0]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[0] );
|
||||
}
|
||||
}
|
||||
if( _normal_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _nindex.valid() )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[0]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[0] );
|
||||
}
|
||||
}
|
||||
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex == 0L) )
|
||||
{
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, _tcoords );
|
||||
}
|
||||
else
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex.null()) )
|
||||
{
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, _tcoords );
|
||||
}
|
||||
else
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
|
||||
if( _needprimlen ) // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
// FLAT_LINE_STRIP, FLAT_TRIANGLE_STRIP, FLAT_TRIANGLE_FAN
|
||||
if( _needprimlen ) // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
// FLAT_LINE_STRIP, FLAT_TRIANGLE_STRIP, FLAT_TRIANGLE_FAN
|
||||
{
|
||||
int i, j;
|
||||
int index = 0;
|
||||
int ai = 0;
|
||||
int ci = 0;
|
||||
int ni = 0;
|
||||
int ti = 0;
|
||||
int ai = 0;
|
||||
int ci = 0;
|
||||
int ni = 0;
|
||||
int ti = 0;
|
||||
|
||||
if( _primLengths == (int *)0 )
|
||||
{
|
||||
@@ -276,152 +292,166 @@ void GeoSet::draw_alternate_path( void )
|
||||
}
|
||||
|
||||
for( i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _colindex )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[ci++] );
|
||||
}
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _nindex )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ni++]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[ni++] );
|
||||
}
|
||||
{
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _colindex.valid() )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[ci++] );
|
||||
}
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _nindex.valid() )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ni++]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[ni++] );
|
||||
}
|
||||
|
||||
if( _flat_shaded_skip )
|
||||
{
|
||||
#ifdef DO_SHADING
|
||||
glShadeModel( GL_FLAT );
|
||||
#endif
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( j = 0; j < _primLengths[i]; j++ )
|
||||
{
|
||||
if( j >= _flat_shaded_skip )
|
||||
{
|
||||
if( _color_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if( (_colindex != 0L) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[ci++] );
|
||||
}
|
||||
if( _flat_shaded_skip )
|
||||
{
|
||||
#ifdef DO_SHADING
|
||||
glShadeModel( GL_FLAT );
|
||||
#endif
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( j = 0; j < _primLengths[i]; j++ )
|
||||
{
|
||||
if( j >= _flat_shaded_skip )
|
||||
{
|
||||
if( _color_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if( (_colindex.valid()) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[ci++] );
|
||||
}
|
||||
|
||||
if( _normal_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if(_nindex != 0L)
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ni++]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[ni++] );
|
||||
}
|
||||
}
|
||||
if( _normal_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if(_nindex.valid())
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ni++]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[ni++] );
|
||||
}
|
||||
}
|
||||
|
||||
if( _texture_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if( _tindex != 0L )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[ti++]] );
|
||||
else
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[ti++] );
|
||||
}
|
||||
if( _texture_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if( _tindex.valid() )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[ti++]] );
|
||||
else
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[ti++] );
|
||||
}
|
||||
|
||||
if( _cindex )
|
||||
glArrayElement( _cindex[ai++] );
|
||||
else
|
||||
glArrayElement( ai++ );
|
||||
}
|
||||
glEnd();
|
||||
if( _cindex.valid() )
|
||||
glArrayElement( _cindex[ai++] );
|
||||
else
|
||||
glArrayElement( ai++ );
|
||||
}
|
||||
glEnd();
|
||||
|
||||
#ifdef DO_SHADING
|
||||
glShadeModel( GL_SMOOTH );
|
||||
#endif
|
||||
}
|
||||
#ifdef DO_SHADING
|
||||
glShadeModel( GL_SMOOTH );
|
||||
#endif
|
||||
}
|
||||
|
||||
else
|
||||
if( ((_color_binding == BIND_PERVERTEX ) && (_colindex != 0L) ) ||
|
||||
((_normal_binding == BIND_PERVERTEX ) && (_nindex != 0L) ) ||
|
||||
((_texture_binding == BIND_PERVERTEX ) && (_tindex != 0L) ) )
|
||||
{
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( j = 0; j < _primLengths[i]; j++ )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_colindex != 0L) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
else
|
||||
if( ((_color_binding == BIND_PERVERTEX ) && (_colindex.valid()) ) ||
|
||||
((_normal_binding == BIND_PERVERTEX ) && (_nindex.valid()) ) ||
|
||||
((_texture_binding == BIND_PERVERTEX ) && (_tindex.valid()) ) )
|
||||
{
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( j = 0; j < _primLengths[i]; j++ )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_colindex.valid()) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex != 0L) )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ci++]] );
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex.valid()) )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ni++]] );
|
||||
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex != 0L) )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[ti++]] );
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex.valid()) )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[ti++]] );
|
||||
|
||||
if( _cindex )
|
||||
glArrayElement( _cindex[ai++] );
|
||||
else
|
||||
glArrayElement( ai++ );
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _primLengths[i], GL_UNSIGNED_SHORT, &_cindex[index] );
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, index, _primLengths[i] );
|
||||
}
|
||||
index += _primLengths[i];
|
||||
}
|
||||
if( _cindex.valid() )
|
||||
glArrayElement( _cindex[ai++] );
|
||||
else
|
||||
glArrayElement( ai++ );
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if( _cindex.valid() )
|
||||
{
|
||||
if (_cindex._is_ushort)
|
||||
glDrawElements( (GLenum)_oglprimtype, _primLengths[i], GL_UNSIGNED_SHORT, &_cindex._ptr._ushort[index] );
|
||||
else
|
||||
glDrawElements( (GLenum)_oglprimtype, _primLengths[i], GL_UNSIGNED_INT, &_cindex._ptr._uint[index] );
|
||||
}
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, index, _primLengths[i] );
|
||||
}
|
||||
index += _primLengths[i];
|
||||
}
|
||||
}
|
||||
else // POINTS, LINES, TRIANGLES, QUADS
|
||||
else // POINTS, LINES, TRIANGLES, QUADS
|
||||
{
|
||||
int i, j;
|
||||
if( _normal_binding == BIND_PERPRIM || _color_binding == BIND_PERPRIM ||
|
||||
((_color_binding == BIND_PERVERTEX ) && (_colindex != 0L) ) ||
|
||||
((_normal_binding == BIND_PERVERTEX ) && (_nindex != 0L) ) ||
|
||||
((_texture_binding == BIND_PERVERTEX ) && (_tindex != 0L) ) )
|
||||
{
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _colindex )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[i]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[i] );
|
||||
}
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _nindex )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[i]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[i] );
|
||||
}
|
||||
((_color_binding == BIND_PERVERTEX ) && (_colindex.valid()) ) ||
|
||||
((_normal_binding == BIND_PERVERTEX ) && (_nindex.valid()) ) ||
|
||||
((_texture_binding == BIND_PERVERTEX ) && (_tindex.valid()) ) )
|
||||
{
|
||||
|
||||
for( j = 0; j < _primlength; j++ )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_colindex != 0L ) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[i*_primlength+j]] );
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _colindex.valid() )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[i]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[i] );
|
||||
}
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _nindex.valid() )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[i]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[i] );
|
||||
}
|
||||
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex != 0L ) )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[i*_primlength+j]] );
|
||||
for( j = 0; j < _primlength; j++ )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_colindex.valid() ) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[i*_primlength+j]] );
|
||||
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex != 0L ) )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[i*_primlength+j]] );
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex.valid() ) )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[i*_primlength+j]] );
|
||||
|
||||
glArrayElement( i*_primlength+j );
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _numindices, GL_UNSIGNED_SHORT, _cindex );
|
||||
else
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex.valid() ) )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[i*_primlength+j]] );
|
||||
|
||||
if( _cindex.valid())
|
||||
glArrayElement( _cindex[i*_primlength+j] );
|
||||
else
|
||||
glArrayElement( i*_primlength+j );
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( _cindex.valid())
|
||||
{
|
||||
if (_cindex._is_ushort)
|
||||
glDrawElements( (GLenum)_oglprimtype, _cindex._size, GL_UNSIGNED_SHORT, _cindex._ptr._ushort );
|
||||
else
|
||||
glDrawElements( (GLenum)_oglprimtype, _cindex._size, GL_UNSIGNED_INT, _cindex._ptr._uint );
|
||||
}
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, 0, _numcoords );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "osg/Geode"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -13,101 +11,51 @@ using std::for_each;
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Geode> g_GeodeProxy;
|
||||
|
||||
Geode::Geode()
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
}
|
||||
|
||||
|
||||
Geode::~Geode()
|
||||
{
|
||||
// ref_ptr<> automactially decrements the reference count of all geosets.
|
||||
// ref_ptr<> automactially decrements the reference count of all drawables.
|
||||
}
|
||||
|
||||
|
||||
bool Geode::readLocalData(Input& fr)
|
||||
const bool Geode::addDrawable( Drawable *gset )
|
||||
{
|
||||
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (Node::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
int num_geosets;
|
||||
if (fr[0].matchWord("num_geosets") &&
|
||||
fr[1].getInt(num_geosets))
|
||||
{
|
||||
// could allocate space for children here...
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
GeoSet* gset_read = NULL;
|
||||
do
|
||||
{
|
||||
if ((gset_read=static_cast<GeoSet*>(GeoSet::instance()->readClone(fr))))
|
||||
{
|
||||
addGeoSet(gset_read);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
} while(gset_read != NULL);
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Geode::writeLocalData(Output& fw)
|
||||
{
|
||||
Node::writeLocalData(fw);
|
||||
|
||||
fw.indent() << "num_geosets " << getNumGeosets() << endl;
|
||||
for(GeoSetList::iterator itr = _geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->write(fw);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Geode::addGeoSet( GeoSet *gset )
|
||||
{
|
||||
if (gset && !containsGeoSet(gset))
|
||||
if (gset && !containsDrawable(gset))
|
||||
{
|
||||
// note ref_ptr<> automatically handles incrementing gset's reference count.
|
||||
_geosets.push_back(gset);
|
||||
_drawables.push_back(gset);
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Geode::removeGeoSet( GeoSet *gset )
|
||||
|
||||
const bool Geode::removeDrawable( Drawable *gset )
|
||||
{
|
||||
GeoSetList::iterator itr = findGeoSet(gset);
|
||||
if (itr!=_geosets.end())
|
||||
DrawableList::iterator itr = findDrawable(gset);
|
||||
if (itr!=_drawables.end())
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing gset's reference count.
|
||||
_geosets.erase(itr);
|
||||
_drawables.erase(itr);
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Geode::replaceGeoSet( GeoSet *origGset, GeoSet *newGset )
|
||||
|
||||
const bool Geode::replaceDrawable( Drawable *origGset, Drawable *newGset )
|
||||
{
|
||||
if (newGset==NULL || origGset==newGset) return false;
|
||||
|
||||
GeoSetList::iterator itr = findGeoSet(origGset);
|
||||
if (itr!=_geosets.end())
|
||||
DrawableList::iterator itr = findDrawable(origGset);
|
||||
if (itr!=_drawables.end())
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing origGset's reference count,
|
||||
// and inccrementing newGset's reference count.
|
||||
@@ -116,46 +64,56 @@ bool Geode::replaceGeoSet( GeoSet *origGset, GeoSet *newGset )
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Geode::computeBound( void )
|
||||
{
|
||||
const bool Geode::computeBound() const
|
||||
{
|
||||
BoundingBox bb;
|
||||
GeoSetList::iterator itr;
|
||||
for(itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
|
||||
DrawableList::const_iterator itr;
|
||||
for(itr=_drawables.begin();
|
||||
itr!=_drawables.end();
|
||||
++itr)
|
||||
{
|
||||
bb.expandBy((*itr)->getBound());
|
||||
}
|
||||
|
||||
_bsphere._center = bb.center();
|
||||
_bsphere._radius = 0.0f;
|
||||
|
||||
for(itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
|
||||
if (bb.isValid())
|
||||
{
|
||||
const BoundingBox& bbox = (*itr)->getBound();
|
||||
for(unsigned int c=0;c<8;++c)
|
||||
|
||||
_bsphere._center = bb.center();
|
||||
_bsphere._radius = 0.0f;
|
||||
|
||||
for(itr=_drawables.begin();
|
||||
itr!=_drawables.end();
|
||||
++itr)
|
||||
{
|
||||
_bsphere.expandRadiusBy(bbox.corner(c));
|
||||
const BoundingBox& bbox = (*itr)->getBound();
|
||||
for(unsigned int c=0;c<8;++c)
|
||||
{
|
||||
_bsphere.expandRadiusBy(bbox.corner(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_bsphere_computed=true;
|
||||
return true;
|
||||
_bsphere_computed=true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bsphere.init();
|
||||
_bsphere_computed=true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Geode::compileGeoSets( void )
|
||||
void Geode::compileDrawables(State& state)
|
||||
{
|
||||
for(GeoSetList::iterator itr = _geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
for(DrawableList::iterator itr = _drawables.begin();
|
||||
itr!=_drawables.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->compile();
|
||||
(*itr)->compile(state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "osg/Group"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
#include "osg/BoundingBox"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -18,8 +15,6 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Group> g_GroupProxy;
|
||||
|
||||
Group::Group()
|
||||
{
|
||||
}
|
||||
@@ -29,8 +24,8 @@ Group::~Group()
|
||||
{
|
||||
|
||||
for(ChildList::iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
Node* child = itr->get();
|
||||
ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),this);
|
||||
@@ -43,8 +38,8 @@ Group::~Group()
|
||||
void Group::traverse(NodeVisitor& nv)
|
||||
{
|
||||
for(ChildList::iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->accept(nv);
|
||||
}
|
||||
@@ -68,23 +63,26 @@ bool Group::addChild( Node *child )
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Group::removeChild( Node *child )
|
||||
{
|
||||
ChildList::iterator itr = findNode(child);
|
||||
if (itr!=_children.end())
|
||||
{
|
||||
// remove this group from the child parent list.
|
||||
ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),this);
|
||||
if (pitr!=child->_parents.end()) child->_parents.erase(pitr);
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing child's reference count.
|
||||
_children.erase(itr);
|
||||
dirtyBound();
|
||||
|
||||
ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),child);
|
||||
if (pitr!=child->_parents.end()) child->_parents.erase(pitr);
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Group::replaceChild( Node *origNode, Node *newNode )
|
||||
{
|
||||
if (newNode==NULL || origNode==newNode) return false;
|
||||
@@ -92,7 +90,7 @@ bool Group::replaceChild( Node *origNode, Node *newNode )
|
||||
ChildList::iterator itr = findNode(origNode);
|
||||
if (itr!=_children.end())
|
||||
{
|
||||
ParentList::iterator pitr = std::find(origNode->_parents.begin(),origNode->_parents.end(),origNode);
|
||||
ParentList::iterator pitr = std::find(origNode->_parents.begin(),origNode->_parents.end(),this);
|
||||
if (pitr!=origNode->_parents.end()) origNode->_parents.erase(pitr);
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing origNode's reference count,
|
||||
@@ -106,67 +104,29 @@ bool Group::replaceChild( Node *origNode, Node *newNode )
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool Group::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (Node::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
int num_children;
|
||||
if (fr[0].matchWord("num_children") &&
|
||||
fr[1].getInt(num_children))
|
||||
{
|
||||
// could allocate space for children here...
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
Node* node = NULL;
|
||||
while((node=fr.readNode())!=NULL)
|
||||
{
|
||||
addChild(node);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Group::writeLocalData(Output& fw)
|
||||
{
|
||||
Node::writeLocalData(fw);
|
||||
|
||||
fw.indent() << "num_children " << getNumChildren() << endl;
|
||||
for(int i=0;i<getNumChildren();++i)
|
||||
{
|
||||
getChild(i)->write(fw);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Group::computeBound()
|
||||
const bool Group::computeBound() const
|
||||
{
|
||||
|
||||
_bsphere_computed = true;
|
||||
|
||||
_bsphere.init();
|
||||
if (_children.empty()) return false;
|
||||
|
||||
|
||||
BoundingBox bb;
|
||||
bb.init();
|
||||
ChildList::iterator itr;
|
||||
ChildList::const_iterator itr;
|
||||
for(itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
bb.expandBy((*itr)->getBound());
|
||||
}
|
||||
}
|
||||
|
||||
if (!bb.isValid()) return false;
|
||||
|
||||
|
||||
_bsphere._center = bb.center();
|
||||
_bsphere._radius = 0.0f;
|
||||
for(itr=_children.begin();
|
||||
@@ -174,7 +134,7 @@ bool Group::computeBound()
|
||||
++itr)
|
||||
{
|
||||
_bsphere.expandRadiusBy((*itr)->getBound());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#include "osg/Image"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/GL"
|
||||
#include "osg/Notify"
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/GeoState>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Texture>
|
||||
|
||||
#include <GL/glu.h>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Image::Image()
|
||||
{
|
||||
_fileName = NULL;
|
||||
_fileName = "";
|
||||
_s = _t = _r = 0;
|
||||
_internalFormat = 0;
|
||||
_pixelFormat = (unsigned int)0;
|
||||
@@ -26,26 +26,22 @@ Image::Image()
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
if (_fileName) ::free(_fileName);
|
||||
if (_data) ::free(_data);
|
||||
}
|
||||
|
||||
|
||||
void Image::setFileName(const char* fileName)
|
||||
void Image::setFileName(const std::string& fileName)
|
||||
{
|
||||
if (_fileName) ::free(_fileName);
|
||||
|
||||
if (fileName) _fileName = strdup(fileName);
|
||||
else _fileName = NULL;
|
||||
_fileName = fileName;
|
||||
}
|
||||
|
||||
|
||||
void Image::setImage(int s,int t,int r,
|
||||
int internalFormat,
|
||||
unsigned int pixelFormat,
|
||||
unsigned int dataType,
|
||||
void Image::setImage(const int s,const int t,const int r,
|
||||
const int internalFormat,
|
||||
const unsigned int pixelFormat,
|
||||
const unsigned int dataType,
|
||||
unsigned char *data,
|
||||
int packing)
|
||||
const int packing)
|
||||
{
|
||||
if (_data) ::free(_data);
|
||||
|
||||
@@ -58,48 +54,23 @@ void Image::setImage(int s,int t,int r,
|
||||
_dataType = dataType;
|
||||
|
||||
_data = data;
|
||||
|
||||
|
||||
|
||||
if (packing<0)
|
||||
{
|
||||
if (_s%4==0)
|
||||
_packing = 4;
|
||||
else
|
||||
_packing = 1;
|
||||
_packing = 1;
|
||||
}
|
||||
else
|
||||
_packing = packing;
|
||||
|
||||
// scaleImageTo(16,16,_r);
|
||||
|
||||
// test scaling...
|
||||
// scaleImageTo(16,16,_r);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Image::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (fr[0].matchWord("file") && fr[1].isString())
|
||||
{
|
||||
//loadFile(fr[1].getStr());
|
||||
fr += 2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Image::writeLocalData(Output& fw)
|
||||
{
|
||||
if (_fileName)
|
||||
{
|
||||
fw.indent() << "file \""<<_fileName<<"\""<<endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Image::scaleImage(int s,int t,int /*r*/)
|
||||
void Image::scaleImage(const int s,const int t,const int /*r*/)
|
||||
{
|
||||
if (_data==NULL) return;
|
||||
|
||||
@@ -109,20 +80,21 @@ void Image::scaleImage(int s,int t,int /*r*/)
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,_packing);
|
||||
|
||||
GLint status = gluScaleImage((GLenum)_pixelFormat,
|
||||
_s,
|
||||
_t,
|
||||
(GLenum)_dataType,
|
||||
_data,
|
||||
s,
|
||||
t,
|
||||
(GLenum)_dataType,
|
||||
newData);
|
||||
|
||||
if (status==0) {
|
||||
|
||||
_s,
|
||||
_t,
|
||||
(GLenum)_dataType,
|
||||
_data,
|
||||
s,
|
||||
t,
|
||||
(GLenum)_dataType,
|
||||
newData);
|
||||
|
||||
if (status==0)
|
||||
{
|
||||
|
||||
// free old image.
|
||||
::free(_data);
|
||||
|
||||
|
||||
_s = s;
|
||||
_t = t;
|
||||
_data = newData;
|
||||
@@ -135,29 +107,34 @@ void Image::scaleImage(int s,int t,int /*r*/)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Image::ensureDimensionsArePowerOfTwo()
|
||||
{
|
||||
float sp2 = logf((float)_s)/logf(2.0f);
|
||||
float rounded_sp2 = floorf(sp2+0.5f);
|
||||
int new_s = (int)(powf(2.0f,rounded_sp2));
|
||||
|
||||
|
||||
float tp2 = logf((float)_t)/logf(2.0f);
|
||||
float rounded_tp2 = floorf(tp2+0.5f);
|
||||
int new_t = (int)(powf(2.0f,rounded_tp2));
|
||||
|
||||
|
||||
if (new_s!=_s && new_t!=_t)
|
||||
{
|
||||
notify(NOTICE) << "Scaling image '"<<_fileName<<"' from ("<<_s<<","<<_t<<") to ("<<new_s<<","<<new_t<<")"<<endl;
|
||||
if (!_fileName.empty()) notify(NOTICE) << "Scaling image '"<<_fileName<<"' from ("<<_s<<","<<_t<<") to ("<<new_s<<","<<new_t<<")"<<endl;
|
||||
else notify(NOTICE) << "Scaling image from ("<<_s<<","<<_t<<") to ("<<new_s<<","<<new_t<<")"<<endl;
|
||||
|
||||
scaleImage(new_s,new_t,_r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Geode* osg::createGeodeForImage(osg::Image* image)
|
||||
{
|
||||
return createGeodeForImage(image,image->s(),image->t());
|
||||
}
|
||||
|
||||
Geode* osg::createGeodeForImage(osg::Image* image,float s,float t)
|
||||
|
||||
Geode* osg::createGeodeForImage(osg::Image* image,const float s,const float t)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
@@ -167,20 +144,19 @@ Geode* osg::createGeodeForImage(osg::Image* image,float s,float t)
|
||||
float y = 1.0;
|
||||
float x = y*(s/t);
|
||||
|
||||
// set up the texture.
|
||||
// set up the texture.
|
||||
osg::Texture* texture = new osg::Texture;
|
||||
texture->setImage(image);
|
||||
|
||||
// set up the geostate.
|
||||
osg::GeoState* gstate = new osg::GeoState;
|
||||
gstate->setMode(osg::GeoState::FACE_CULL,osg::GeoState::OFF);
|
||||
gstate->setMode(osg::GeoState::LIGHTING,osg::GeoState::OFF);
|
||||
gstate->setMode(osg::GeoState::TEXTURE,osg::GeoState::ON);
|
||||
gstate->setAttribute(osg::GeoState::TEXTURE,texture);
|
||||
// set up the drawstate.
|
||||
osg::StateSet* dstate = new osg::StateSet;
|
||||
dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
|
||||
dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
|
||||
dstate->setAttributeAndModes(texture,osg::StateAttribute::ON);
|
||||
|
||||
// set up the geoset.
|
||||
osg::GeoSet* gset = new osg::GeoSet;
|
||||
gset->setGeoState(gstate);
|
||||
gset->setStateSet(dstate);
|
||||
|
||||
osg::Vec3* coords = new Vec3 [4];
|
||||
coords[0].set(-x,0.0f,y);
|
||||
@@ -198,7 +174,7 @@ Geode* osg::createGeodeForImage(osg::Image* image,float s,float t)
|
||||
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
|
||||
osg::Vec4* colours = new Vec4;
|
||||
colours->set(1.0f,1.0f,1.0,0.0f);
|
||||
colours->set(1.0f,1.0f,1.0,1.0f);
|
||||
gset->setColors(colours);
|
||||
gset->setColorBinding(osg::GeoSet::BIND_OVERALL);
|
||||
|
||||
@@ -207,7 +183,7 @@ Geode* osg::createGeodeForImage(osg::Image* image,float s,float t)
|
||||
|
||||
// set up the geode.
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addGeoSet(gset);
|
||||
geode->addDrawable(gset);
|
||||
|
||||
return geode;
|
||||
|
||||
|
||||
115
src/osg/LOD.cpp
@@ -1,30 +1,26 @@
|
||||
#include "osg/LOD"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<LOD> g_LODProxy;
|
||||
|
||||
void LOD::traverse(NodeVisitor& nv)
|
||||
{
|
||||
switch(nv.getTraverseMode())
|
||||
switch(nv.getTraversalMode())
|
||||
{
|
||||
case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
|
||||
if (_children.size()!=0) _children.front()->accept(nv);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
|
||||
if (_children.size()!=0) _children.front()->accept(nv);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LOD::setRange(unsigned int index, float range)
|
||||
|
||||
void LOD::setRange(const unsigned int index, const float range)
|
||||
{
|
||||
if (index<_rangeList.size()) _rangeList[index] = range;
|
||||
else while (index>=_rangeList.size()) _rangeList.push_back(range);
|
||||
@@ -33,98 +29,23 @@ void LOD::setRange(unsigned int index, float range)
|
||||
else while (index>=_rangeList2.size()) _rangeList2.push_back(range*range);
|
||||
}
|
||||
|
||||
int LOD::evaluate(const Vec3& eye_local, float bias)
|
||||
|
||||
const int LOD::evaluate(const Vec3& eye_local, const float bias) const
|
||||
{
|
||||
// For cache coherency, use _rangeList2 exclusively
|
||||
// For cache coherency, use _rangeList2 exclusively
|
||||
if (_rangeList2.size()==0) return -1;
|
||||
|
||||
// Test distance-squared against the stored array of squared ranges
|
||||
// Test distance-squared against the stored array of squared ranges
|
||||
float LODRange = (eye_local-_center).length2()*bias;
|
||||
if (LODRange<_rangeList2[0]) return -1;
|
||||
|
||||
|
||||
for(unsigned int i=0;i<_rangeList2.size()-1;++i)
|
||||
{
|
||||
if (_rangeList2[i]<=LODRange && LODRange<_rangeList2[i+1]) {
|
||||
if (_rangeList2[i]<=LODRange && LODRange<_rangeList2[i+1])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool LOD::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr.matchSequence("Center %f %f %f"))
|
||||
{
|
||||
|
||||
fr[1].getFloat(_center[0]);
|
||||
fr[2].getFloat(_center[1]);
|
||||
fr[3].getFloat(_center[2]);
|
||||
|
||||
iteratorAdvanced = true;
|
||||
fr+=3;
|
||||
}
|
||||
|
||||
bool matchFirst = false;
|
||||
if ((matchFirst=fr.matchSequence("Ranges {")) || fr.matchSequence("Ranges %i {"))
|
||||
{
|
||||
|
||||
// set up coordinates.
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
|
||||
if (matchFirst)
|
||||
{
|
||||
fr += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//_rangeList.(capacity);
|
||||
fr += 3;
|
||||
}
|
||||
|
||||
float range;
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
{
|
||||
if (fr[0].getFloat(range))
|
||||
{
|
||||
++fr;
|
||||
_rangeList.push_back(range);
|
||||
_rangeList2.push_back(range*range);
|
||||
}
|
||||
else
|
||||
{
|
||||
++fr;
|
||||
}
|
||||
}
|
||||
|
||||
iteratorAdvanced = true;
|
||||
++fr;
|
||||
|
||||
}
|
||||
|
||||
if (Group::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool LOD::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "Center "<<_center[0] << " "<<_center[1] << " "<<_center[2] <<endl;
|
||||
|
||||
fw.indent() << "Ranges {"<<endl;
|
||||
fw.moveIn();
|
||||
for(RangeList::iterator riter = _rangeList.begin();
|
||||
riter != _rangeList.end();
|
||||
++riter)
|
||||
{
|
||||
fw.indent() << (*riter) <<endl;
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent() << "}"<<endl;
|
||||
|
||||
Group::writeLocalData(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,17 +11,17 @@ Light::Light( void )
|
||||
_on = 1;
|
||||
|
||||
init();
|
||||
|
||||
// notify(DEBUG) << "_ambient "<<_ambient<<endl;
|
||||
// notify(DEBUG) << "_diffuse "<<_diffuse<<endl;
|
||||
// notify(DEBUG) << "_specular "<<_specular<<endl;
|
||||
// notify(DEBUG) << "_position "<<_position<<endl;
|
||||
// notify(DEBUG) << "_direction "<<_direction<<endl;
|
||||
// notify(DEBUG) << "_spot_exponent "<<_spot_exponent<<endl;
|
||||
// notify(DEBUG) << "_spot_cutoff "<<_spot_cutoff<<endl;
|
||||
// notify(DEBUG) << "_constant_attenuation "<<_constant_attenuation<<endl;
|
||||
// notify(DEBUG) << "_linear_attenuation "<<_linear_attenuation<<endl;
|
||||
// notify(DEBUG) << "_quadratic_attenuation "<<_quadratic_attenuation<<endl;
|
||||
|
||||
// notify(DEBUG) << "_ambient "<<_ambient<<endl;
|
||||
// notify(DEBUG) << "_diffuse "<<_diffuse<<endl;
|
||||
// notify(DEBUG) << "_specular "<<_specular<<endl;
|
||||
// notify(DEBUG) << "_position "<<_position<<endl;
|
||||
// notify(DEBUG) << "_direction "<<_direction<<endl;
|
||||
// notify(DEBUG) << "_spot_exponent "<<_spot_exponent<<endl;
|
||||
// notify(DEBUG) << "_spot_cutoff "<<_spot_cutoff<<endl;
|
||||
// notify(DEBUG) << "_constant_attenuation "<<_constant_attenuation<<endl;
|
||||
// notify(DEBUG) << "_linear_attenuation "<<_linear_attenuation<<endl;
|
||||
// notify(DEBUG) << "_quadratic_attenuation "<<_quadratic_attenuation<<endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,6 @@ Light::~Light( void )
|
||||
{
|
||||
}
|
||||
|
||||
Light* Light::instance()
|
||||
{
|
||||
static ref_ptr<Light> s_Light(new Light);
|
||||
return s_Light.get();
|
||||
}
|
||||
|
||||
void Light::init( void )
|
||||
{
|
||||
@@ -49,6 +44,7 @@ void Light::init( void )
|
||||
_quadratic_attenuation = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
void Light::captureLightState()
|
||||
{
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_AMBIENT, _ambient.ptr() );
|
||||
@@ -63,23 +59,11 @@ void Light::captureLightState()
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_QUADRATIC_ATTENUATION, &_quadratic_attenuation );
|
||||
}
|
||||
|
||||
|
||||
void Light::enable( void )
|
||||
{
|
||||
glEnable( GL_LIGHTING );
|
||||
}
|
||||
|
||||
|
||||
void Light::disable( void )
|
||||
{
|
||||
glDisable( GL_LIGHTING );
|
||||
}
|
||||
|
||||
|
||||
void Light::apply( void )
|
||||
void Light::apply(State&) const
|
||||
{
|
||||
if( _on )
|
||||
{
|
||||
// note state should probably be handling the glEnable...
|
||||
glEnable ( (GLenum)((int)GL_LIGHT0 + _lightnum) );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_AMBIENT, _ambient.ptr() );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_DIFFUSE, _diffuse.ptr() );
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
#include "osg/LightSource"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<LightSource> g_LightSourceProxy;
|
||||
|
||||
LightSource::LightSource()
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
@@ -19,41 +13,13 @@ LightSource::~LightSource()
|
||||
// ref_ptr<> automactially decrements the reference count of attached lights.
|
||||
}
|
||||
|
||||
|
||||
bool LightSource::readLocalData(Input& fr)
|
||||
const bool LightSource::computeBound() const
|
||||
{
|
||||
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (Node::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
Light* light = static_cast<Light*>(Light::instance()->readClone(fr));
|
||||
if (light)
|
||||
{
|
||||
_light = light;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool LightSource::writeLocalData(Output& fw)
|
||||
{
|
||||
Node::writeLocalData(fw);
|
||||
|
||||
if (_light.valid()) _light->write(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LightSource::computeBound( void )
|
||||
{
|
||||
// note, don't do anything right now as the light itself is not
|
||||
// visualised, just having an effect on the lighting of geodes.
|
||||
_bsphere.init();
|
||||
|
||||
|
||||
_bsphere_computed = true;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
109
src/osg/Makefile
@@ -2,55 +2,51 @@
|
||||
include ../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
Registry.cpp\
|
||||
OSG.cpp\
|
||||
AlphaFunc.cpp\
|
||||
Group.cpp\
|
||||
Field.cpp\
|
||||
FieldReader.cpp\
|
||||
FieldReaderIterator.cpp\
|
||||
Billboard.cpp\
|
||||
BoundingBox.cpp\
|
||||
BoundingSphere.cpp\
|
||||
Camera.cpp\
|
||||
ClipPlane.cpp \
|
||||
ColorMask.cpp \
|
||||
CullFace.cpp\
|
||||
Depth.cpp \
|
||||
Drawable.cpp\
|
||||
Fog.cpp\
|
||||
FrontFace.cpp\
|
||||
Geode.cpp\
|
||||
GeoSet.cpp\
|
||||
GeoSet_ogl.cpp\
|
||||
GeoState.cpp\
|
||||
Geode.cpp\
|
||||
Input.cpp\
|
||||
FileNameUtils.cpp\
|
||||
GLExtensions.cpp\
|
||||
Group.cpp\
|
||||
Image.cpp\
|
||||
Impostor.cpp\
|
||||
ImpostorSprite.cpp\
|
||||
Light.cpp\
|
||||
LightSource.cpp\
|
||||
Lighting.cpp\
|
||||
LineSegment.cpp\
|
||||
LOD.cpp\
|
||||
Material.cpp\
|
||||
Matrix.cpp\
|
||||
Quat.cpp\
|
||||
Seg.cpp\
|
||||
Node.cpp\
|
||||
NodeVisitor.cpp\
|
||||
Notify.cpp\
|
||||
Object.cpp\
|
||||
Output.cpp\
|
||||
DynamicLibrary.cpp\
|
||||
Point.cpp\
|
||||
PolygonMode.cpp\
|
||||
PolygonOffset.cpp\
|
||||
Quat.cpp\
|
||||
State.cpp\
|
||||
StateSet.cpp\
|
||||
Stencil.cpp \
|
||||
Switch.cpp\
|
||||
TexEnv.cpp\
|
||||
TexGen.cpp\
|
||||
Image.cpp\
|
||||
Texture.cpp\
|
||||
DCS.cpp\
|
||||
Scene.cpp\
|
||||
Switch.cpp\
|
||||
Sequence.cpp\
|
||||
LOD.cpp\
|
||||
Billboard.cpp\
|
||||
BoundingSphere.cpp\
|
||||
BoundingBox.cpp\
|
||||
Transparency.cpp\
|
||||
CullFace.cpp\
|
||||
TexMat.cpp\
|
||||
Texture.cpp\
|
||||
Timer.cpp\
|
||||
Fog.cpp\
|
||||
ReaderWriterOSG.cpp\
|
||||
ReaderWriterRGB.cpp\
|
||||
Camera.cpp\
|
||||
Notify.cpp\
|
||||
ExtensionSupported.cpp\
|
||||
Point.cpp\
|
||||
PolygonOffset.cpp\
|
||||
Transform.cpp\
|
||||
Transparency.cpp\
|
||||
Version.cpp\
|
||||
|
||||
|
||||
@@ -63,56 +59,61 @@ TARGET_INCLUDE_FILES = \
|
||||
osg/Billboard\
|
||||
osg/BoundingBox\
|
||||
osg/BoundingSphere\
|
||||
osg/BoundsChecking\
|
||||
osg/Camera\
|
||||
osg/ClipPlane\
|
||||
osg/ClippingVolume\
|
||||
osg/ColorMask\
|
||||
osg/CullFace\
|
||||
osg/DCS\
|
||||
osg/DynamicLibrary\
|
||||
osg/Depth\
|
||||
osg/Drawable\
|
||||
osg/Export\
|
||||
osg/Field\
|
||||
osg/FieldReader\
|
||||
osg/FieldReaderIterator\
|
||||
osg/FileNameUtils\
|
||||
osg/Fog\
|
||||
osg/FrontFace\
|
||||
osg/GL\
|
||||
osg/GLExtensions\
|
||||
osg/GeoSet\
|
||||
osg/GeoState\
|
||||
osg/Geode\
|
||||
osg/Group\
|
||||
osg/GL\
|
||||
osg/Image\
|
||||
osg/Input\
|
||||
osg/Impostor\
|
||||
osg/ImpostorSprite\
|
||||
osg/LOD\
|
||||
osg/Light\
|
||||
osg/LightSource\
|
||||
osg/Lighting\
|
||||
osg/LineSegment\
|
||||
osg/Material\
|
||||
osg/Matrix\
|
||||
osg/MemoryAdapter\
|
||||
osg/Node\
|
||||
osg/Notify\
|
||||
osg/NodeVisitor\
|
||||
osg/OSG\
|
||||
osg/Notify\
|
||||
osg/Object\
|
||||
osg/Output\
|
||||
osg/Point\
|
||||
osg/PolygonMode\
|
||||
osg/PolygonOffset\
|
||||
osg/Plane\
|
||||
osg/Quat\
|
||||
osg/Referenced\
|
||||
osg/Registry\
|
||||
osg/Scene\
|
||||
osg/Seg\
|
||||
osg/Sequence\
|
||||
osg/State\
|
||||
osg/StateAttribute\
|
||||
osg/StateSet\
|
||||
osg/Stencil\
|
||||
osg/Switch\
|
||||
osg/TexEnv\
|
||||
osg/TexGen\
|
||||
osg/TexMat\
|
||||
osg/Texture\
|
||||
osg/Transparency\
|
||||
osg/Timer\
|
||||
osg/Transform\
|
||||
osg/Transparency\
|
||||
osg/Types\
|
||||
osg/Vec2\
|
||||
osg/Vec3\
|
||||
osg/Vec4\
|
||||
osg/Version\
|
||||
osg/mem_ptr\
|
||||
osg/ref_ptr\
|
||||
|
||||
|
||||
TARGET_DATA_FILES = \
|
||||
@@ -137,7 +138,7 @@ TARGET_DATA_FILES = \
|
||||
Images/white.rgb\
|
||||
|
||||
|
||||
LIBS = -ldl
|
||||
LIBS = -lGLU -lGL -lm
|
||||
|
||||
LIB = ../../lib/lib$(TARGET_BASENAME).so
|
||||
#LIB = ../../lib/lib$(TARGET_BASENAME).a
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#include "osg/Material"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
#include "osg/BoundsChecking"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Material::Material( void )
|
||||
Material::Material()
|
||||
{
|
||||
_colorMode = OFF;
|
||||
|
||||
@@ -31,467 +29,309 @@ Material::Material( void )
|
||||
}
|
||||
|
||||
|
||||
Material::~Material( void )
|
||||
Material::~Material()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Material* Material::instance()
|
||||
void Material::setAmbient( const Face face, const Vec4& ambient )
|
||||
{
|
||||
static ref_ptr<Material> s_Material(new Material);
|
||||
return s_Material.get();
|
||||
}
|
||||
|
||||
void Material::setAmbient( MaterialFace face, const Vec4& ambient )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_ambientFrontAndBack = false;
|
||||
_ambientFront = ambient;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_ambientFrontAndBack = false;
|
||||
_ambientBack = ambient;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_ambientFrontAndBack = true;
|
||||
_ambientFront = ambient;
|
||||
_ambientBack = ambient;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setAmbient()."<<endl;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
_ambientFrontAndBack = false;
|
||||
_ambientFront = ambient;
|
||||
clampArray4BetweenRange(_ambientFront,0.0f,1.0f,"osg::Material::setAmbient(..)");
|
||||
break;
|
||||
case(BACK):
|
||||
_ambientFrontAndBack = false;
|
||||
_ambientBack = ambient;
|
||||
clampArray4BetweenRange(_ambientBack,0.0f,1.0f,"Material::setAmbient(..)");
|
||||
break;
|
||||
case(FRONT_AND_BACK):
|
||||
_ambientFrontAndBack = true;
|
||||
_ambientFront = ambient;
|
||||
clampArray4BetweenRange(_ambientFront,0.0f,1.0f,"Material::setAmbient(..)");
|
||||
_ambientBack = _ambientFront;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::setAmbient()."<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getAmbient(MaterialFace face) const
|
||||
|
||||
const Vec4& Material::getAmbient(const Face face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _ambientFront;
|
||||
case(FACE_BACK):
|
||||
return _ambientBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_ambientFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getAmbient(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK ambient colors."<<endl;
|
||||
}
|
||||
return _ambientFront;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
return _ambientFront;
|
||||
case(BACK):
|
||||
return _ambientBack;
|
||||
case(FRONT_AND_BACK):
|
||||
if (!_ambientFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getAmbient(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK ambient colors."<<endl;
|
||||
}
|
||||
return _ambientFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getAmbient()."<<endl;
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::getAmbient()."<<endl;
|
||||
return _ambientFront;
|
||||
}
|
||||
|
||||
void Material::setDiffuse( MaterialFace face, const Vec4& diffuse )
|
||||
|
||||
void Material::setDiffuse( const Face face, const Vec4& diffuse )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_diffuseFrontAndBack = false;
|
||||
_diffuseFront = diffuse;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_diffuseFrontAndBack = false;
|
||||
_diffuseBack = diffuse;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_diffuseFrontAndBack = true;
|
||||
_diffuseFront = diffuse;
|
||||
_diffuseBack = diffuse;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setDiffuse()."<<endl;
|
||||
break;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
_diffuseFrontAndBack = false;
|
||||
_diffuseFront = diffuse;
|
||||
clampArray4BetweenRange(_diffuseFront,0.0f,1.0f,"Material::setDiffuse(..)");
|
||||
break;
|
||||
case(BACK):
|
||||
_diffuseFrontAndBack = false;
|
||||
_diffuseBack = diffuse;
|
||||
clampArray4BetweenRange(_diffuseBack,0.0f,1.0f,"Material::setDiffuse(..)");
|
||||
break;
|
||||
case(FRONT_AND_BACK):
|
||||
_diffuseFrontAndBack = true;
|
||||
_diffuseFront = diffuse;
|
||||
clampArray4BetweenRange(_diffuseFront,0.0f,1.0f,"Material::setDiffuse(..)");
|
||||
_diffuseBack = _diffuseFront;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::setDiffuse()."<<endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getDiffuse(MaterialFace face) const
|
||||
|
||||
const Vec4& Material::getDiffuse(const Face face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _diffuseFront;
|
||||
case(FACE_BACK):
|
||||
return _diffuseBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_diffuseFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getDiffuse(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK diffuse colors."<<endl;
|
||||
}
|
||||
return _diffuseFront;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
return _diffuseFront;
|
||||
case(BACK):
|
||||
return _diffuseBack;
|
||||
case(FRONT_AND_BACK):
|
||||
if (!_diffuseFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getDiffuse(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK diffuse colors."<<endl;
|
||||
}
|
||||
return _diffuseFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getDiffuse()."<<endl;
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::getDiffuse()."<<endl;
|
||||
return _diffuseFront;
|
||||
}
|
||||
|
||||
void Material::setSpecular( MaterialFace face, const Vec4& specular )
|
||||
|
||||
void Material::setSpecular( const Face face, const Vec4& specular )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_specularFrontAndBack = false;
|
||||
_specularFront = specular;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_specularFrontAndBack = false;
|
||||
_specularBack = specular;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_specularFrontAndBack = true;
|
||||
_specularFront = specular;
|
||||
_specularBack = specular;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setSpecular()."<<endl;
|
||||
break;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
_specularFrontAndBack = false;
|
||||
_specularFront = specular;
|
||||
clampArray4BetweenRange(_specularFront,0.0f,1.0f,"Material::setSpecular(..)");
|
||||
break;
|
||||
case(BACK):
|
||||
_specularFrontAndBack = false;
|
||||
_specularBack = specular;
|
||||
clampArray4BetweenRange(_specularBack,0.0f,1.0f,"Material::setSpecular(..)");
|
||||
break;
|
||||
case(FRONT_AND_BACK):
|
||||
_specularFrontAndBack = true;
|
||||
_specularFront = specular;
|
||||
clampArray4BetweenRange(_specularFront,0.0f,1.0f,"Material::setSpecular(..)");
|
||||
_specularBack = _specularFront;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::setSpecular()."<<endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getSpecular(MaterialFace face) const
|
||||
|
||||
const Vec4& Material::getSpecular(const Face face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _specularFront;
|
||||
case(FACE_BACK):
|
||||
return _specularBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_specularFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getSpecular(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK specular colors."<<endl;
|
||||
}
|
||||
return _specularFront;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
return _specularFront;
|
||||
case(BACK):
|
||||
return _specularBack;
|
||||
case(FRONT_AND_BACK):
|
||||
if (!_specularFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getSpecular(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK specular colors."<<endl;
|
||||
}
|
||||
return _specularFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getSpecular()."<<endl;
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::getSpecular()."<<endl;
|
||||
return _specularFront;
|
||||
}
|
||||
|
||||
void Material::setEmission( MaterialFace face, const Vec4& emission )
|
||||
|
||||
void Material::setEmission( const Face face, const Vec4& emission )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_emissionFrontAndBack = false;
|
||||
_emissionFront = emission;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_emissionFrontAndBack = false;
|
||||
_emissionBack = emission;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_emissionFrontAndBack = true;
|
||||
_emissionFront = emission;
|
||||
_emissionBack = emission;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setEmission()."<<endl;
|
||||
break;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
_emissionFrontAndBack = false;
|
||||
_emissionFront = emission;
|
||||
clampArray4BetweenRange(_emissionFront,0.0f,1.0f,"Material::setEmission(..)");
|
||||
break;
|
||||
case(BACK):
|
||||
_emissionFrontAndBack = false;
|
||||
_emissionBack = emission;
|
||||
clampArray4BetweenRange(_emissionBack,0.0f,1.0f,"Material::setEmission(..)");
|
||||
break;
|
||||
case(FRONT_AND_BACK):
|
||||
_emissionFrontAndBack = true;
|
||||
_emissionFront = emission;
|
||||
clampArray4BetweenRange(_emissionFront,0.0f,1.0f,"Material::setEmission(..)");
|
||||
_emissionBack = _emissionFront;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::setEmission()."<<endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getEmission(MaterialFace face) const
|
||||
|
||||
const Vec4& Material::getEmission(const Face face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _emissionFront;
|
||||
case(FACE_BACK):
|
||||
return _emissionBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_emissionFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getEmission(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK emission colors."<<endl;
|
||||
}
|
||||
return _emissionFront;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
return _emissionFront;
|
||||
case(BACK):
|
||||
return _emissionBack;
|
||||
case(FRONT_AND_BACK):
|
||||
if (!_emissionFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getEmission(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK emission colors."<<endl;
|
||||
}
|
||||
return _emissionFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getEmission()."<<endl;
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::getEmission()."<<endl;
|
||||
return _emissionFront;
|
||||
}
|
||||
|
||||
void Material::setShininess( MaterialFace face, float shininess )
|
||||
|
||||
void Material::setShininess( const Face face, float shininess )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_shininessFrontAndBack = false;
|
||||
_shininessFront = shininess;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_shininessFrontAndBack = false;
|
||||
_shininessBack = shininess;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_shininessFrontAndBack = true;
|
||||
_shininessFront = shininess;
|
||||
_shininessBack = shininess;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setShininess()."<<endl;
|
||||
break;
|
||||
clampBetweenRange(shininess,0.0f,1.0f,"Material::setShininess()");
|
||||
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
_shininessFrontAndBack = false;
|
||||
_shininessFront = shininess;
|
||||
break;
|
||||
case(BACK):
|
||||
_shininessFrontAndBack = false;
|
||||
_shininessBack = shininess;
|
||||
break;
|
||||
case(FRONT_AND_BACK):
|
||||
_shininessFrontAndBack = true;
|
||||
_shininessFront = shininess;
|
||||
_shininessBack = shininess;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::setShininess()."<<endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float Material::getShininess(MaterialFace face) const
|
||||
|
||||
const float Material::getShininess(const Face face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _shininessFront;
|
||||
case(FACE_BACK):
|
||||
return _shininessBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_shininessFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getShininess(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK shininess colors."<<endl;
|
||||
}
|
||||
return _shininessFront;
|
||||
switch(face)
|
||||
{
|
||||
case(FRONT):
|
||||
return _shininessFront;
|
||||
case(BACK):
|
||||
return _shininessBack;
|
||||
case(FRONT_AND_BACK):
|
||||
if (!_shininessFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getShininess(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK shininess colors."<<endl;
|
||||
}
|
||||
return _shininessFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getShininess()."<<endl;
|
||||
notify(NOTICE)<<"Notice: invalid Face passed to Material::getShininess()."<<endl;
|
||||
return _shininessFront;
|
||||
}
|
||||
|
||||
|
||||
bool Material::matchFaceAndColor(Input& fr,const char* name,MaterialFace& mf,Vec4& color)
|
||||
void Material::setTransparency(const Face face,float transparency)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr[0].matchWord(name))
|
||||
{
|
||||
int fr_inc = 1;
|
||||
if (fr[1].matchWord("FRONT"))
|
||||
{
|
||||
mf = FACE_FRONT;
|
||||
++fr_inc;
|
||||
}
|
||||
else if (fr[1].matchWord("BACK"))
|
||||
{
|
||||
mf = FACE_BACK;
|
||||
++fr_inc;
|
||||
}
|
||||
|
||||
if (fr[fr_inc].getFloat(color[0]) && fr[fr_inc+1].getFloat(color[1]) && fr[fr_inc+2].getFloat(color[2]))
|
||||
{
|
||||
fr_inc += 3;
|
||||
|
||||
if (fr[fr_inc].getFloat(color[3])) ++fr_inc;
|
||||
else color[3] = 1.0f;
|
||||
|
||||
fr+=fr_inc;
|
||||
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Material::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
Vec4 data(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
MaterialFace mf = FACE_FRONT_AND_BACK;
|
||||
|
||||
if (fr[0].matchWord("ColorMode"))
|
||||
{
|
||||
if (fr[1].matchWord("AMBIENT"))
|
||||
{
|
||||
setColorMode(AMBIENT);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("DIFFUSE"))
|
||||
{
|
||||
setColorMode(DIFFUSE);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("SPECULAR"))
|
||||
{
|
||||
setColorMode(SPECULAR);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("EMISSION"))
|
||||
{
|
||||
setColorMode(EMISSION);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("AMBIENT_AND_DIFFUSE"))
|
||||
{
|
||||
setColorMode(AMBIENT_AND_DIFFUSE);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("OFF"))
|
||||
{
|
||||
setColorMode(OFF);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (matchFaceAndColor(fr,"ambientColor",mf,data))
|
||||
{
|
||||
setAmbient(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (matchFaceAndColor(fr,"diffuseColor",mf,data))
|
||||
{
|
||||
setDiffuse(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (matchFaceAndColor(fr,"specularColor",mf,data))
|
||||
{
|
||||
setSpecular(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (matchFaceAndColor(fr,"emissionColor",mf,data))
|
||||
{
|
||||
setEmission(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (matchFaceAndColor(fr,"ambientColor",mf,data))
|
||||
{
|
||||
setAmbient(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
float shininess = 0.0f;
|
||||
if (fr[0].matchWord("shininess"))
|
||||
{
|
||||
|
||||
mf = FACE_FRONT_AND_BACK;
|
||||
int fr_inc = 1;
|
||||
|
||||
if (fr[1].matchWord("FRONT"))
|
||||
{
|
||||
mf = FACE_FRONT;
|
||||
++fr_inc;
|
||||
}
|
||||
else if (fr[1].matchWord("BACK"))
|
||||
{
|
||||
mf = FACE_BACK;
|
||||
++fr_inc;
|
||||
}
|
||||
|
||||
if (fr[fr_inc].getFloat(shininess))
|
||||
{
|
||||
fr+=(fr_inc+1);
|
||||
setShininess(mf,shininess);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float transparency = 0.0f;
|
||||
if (fr[0].matchWord("transparency") && fr[1].getFloat(transparency))
|
||||
{
|
||||
clampBetweenRange(transparency,0.0f,1.0f,"Material::setTransparency()");
|
||||
|
||||
if (face==FRONT || face==FRONT_AND_BACK)
|
||||
{
|
||||
_ambientFront[3] = 1.0f-transparency;
|
||||
_diffuseFront[3] = 1.0f-transparency;
|
||||
_specularFront[3] = 1.0f-transparency;
|
||||
_emissionFront[3] = 1.0f-transparency;
|
||||
}
|
||||
|
||||
if (face==BACK || face==FRONT_AND_BACK)
|
||||
{
|
||||
_ambientBack[3] = 1.0f-transparency;
|
||||
_diffuseBack[3] = 1.0f-transparency;
|
||||
_specularBack[3] = 1.0f-transparency;
|
||||
_emissionBack[3] = 1.0f-transparency;
|
||||
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Material::writeLocalData(Output& fw)
|
||||
void Material::setAlpha(const Face face,float alpha)
|
||||
{
|
||||
switch(_colorMode)
|
||||
{
|
||||
case(AMBIENT): fw.indent() << "ColorMode AMBIENT" << endl; break;
|
||||
case(DIFFUSE): fw.indent() << "ColorMode DIFFUSE" << endl; break;
|
||||
case(SPECULAR): fw.indent() << "ColorMode SPECULAR" << endl; break;
|
||||
case(EMISSION): fw.indent() << "ColorMode EMISSION" << endl; break;
|
||||
case(AMBIENT_AND_DIFFUSE): fw.indent() << "ColorMode AMBIENT_AND_DIFFUSE" << endl; break;
|
||||
case(OFF): fw.indent() << "ColorMode OFF" << endl; break;
|
||||
clampBetweenRange(alpha,0.0f,1.0f,"Material::setAlpha()");
|
||||
|
||||
if (face==FRONT || face==FRONT_AND_BACK)
|
||||
{
|
||||
_ambientFront[3] = alpha;
|
||||
_diffuseFront[3] = alpha;
|
||||
_specularFront[3] = alpha;
|
||||
_emissionFront[3] = alpha;
|
||||
}
|
||||
|
||||
if (_ambientFrontAndBack)
|
||||
if (face==BACK || face==FRONT_AND_BACK)
|
||||
{
|
||||
fw.indent() << "ambientColor " << _ambientFront << endl;
|
||||
_ambientBack[3] = alpha;
|
||||
_diffuseBack[3] = alpha;
|
||||
_specularBack[3] = alpha;
|
||||
_emissionBack[3] = alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "ambientColor FRONT " << _ambientFront << endl;
|
||||
fw.indent() << "ambientColor BACK " << _ambientBack << endl;
|
||||
}
|
||||
|
||||
if (_diffuseFrontAndBack)
|
||||
{
|
||||
fw.indent() << "diffuseColor " << _diffuseFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "diffuseColor FRONT " << _diffuseFront << endl;
|
||||
fw.indent() << "diffuseColor BACK " << _diffuseBack << endl;
|
||||
}
|
||||
|
||||
if (_specularFrontAndBack)
|
||||
{
|
||||
fw.indent() << "specularColor " << _specularFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "specularColor FRONT " << _specularFront << endl;
|
||||
fw.indent() << "specularColor BACK " << _specularBack << endl;
|
||||
}
|
||||
|
||||
if (_emissionFrontAndBack)
|
||||
{
|
||||
fw.indent() << "emissionColor " << _emissionFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "emissionColor FRONT " << _emissionFront << endl;
|
||||
fw.indent() << "emissionColor BACK " << _emissionBack << endl;
|
||||
}
|
||||
|
||||
if (_shininessFrontAndBack)
|
||||
{
|
||||
fw.indent() << "shininess " << _shininessFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "shininess FRONT " << _shininessFront << endl;
|
||||
fw.indent() << "shininess BACK " << _shininessBack << endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void Material::apply( void )
|
||||
|
||||
void Material::apply(State&) const
|
||||
{
|
||||
if (_colorMode==OFF)
|
||||
{
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glColor4fv(_diffuseFront.ptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glColorMaterial(GL_FRONT_AND_BACK,(GLenum)_colorMode);
|
||||
switch(_colorMode) {
|
||||
case(AMBIENT): glColor4fv(_ambientFront.ptr()); break;
|
||||
case(DIFFUSE): glColor4fv(_diffuseFront.ptr()); break;
|
||||
case(SPECULAR): glColor4fv(_specularFront.ptr()); break;
|
||||
case(EMISSION): glColor4fv(_emissionFront.ptr()); break;
|
||||
case(AMBIENT_AND_DIFFUSE): glColor4fv(_diffuseFront.ptr()); break;
|
||||
case(OFF): break;
|
||||
switch(_colorMode)
|
||||
{
|
||||
case(AMBIENT): glColor4fv(_ambientFront.ptr()); break;
|
||||
case(DIFFUSE): glColor4fv(_diffuseFront.ptr()); break;
|
||||
case(SPECULAR): glColor4fv(_specularFront.ptr()); break;
|
||||
case(EMISSION): glColor4fv(_emissionFront.ptr()); break;
|
||||
case(AMBIENT_AND_DIFFUSE): glColor4fv(_diffuseFront.ptr()); break;
|
||||
case(OFF): break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,7 +347,7 @@ void Material::apply( void )
|
||||
glMaterialfv( GL_BACK, GL_AMBIENT, _ambientBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_colorMode!=DIFFUSE && _colorMode!=AMBIENT_AND_DIFFUSE)
|
||||
{
|
||||
if (_diffuseFrontAndBack)
|
||||
@@ -520,7 +360,7 @@ void Material::apply( void )
|
||||
glMaterialfv( GL_BACK, GL_DIFFUSE, _diffuseBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_colorMode!=SPECULAR)
|
||||
{
|
||||
if (_specularFrontAndBack)
|
||||
@@ -533,7 +373,7 @@ void Material::apply( void )
|
||||
glMaterialfv( GL_BACK, GL_SPECULAR, _specularBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_colorMode!=EMISSION)
|
||||
{
|
||||
if (_emissionFrontAndBack)
|
||||
@@ -546,7 +386,7 @@ void Material::apply( void )
|
||||
glMaterialfv( GL_BACK, GL_EMISSION, _emissionBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_shininessFrontAndBack)
|
||||
{
|
||||
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, _shininessFront* 128.0f );
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include <math.h>
|
||||
#include "osg/Matrix"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
#include <string.h>
|
||||
|
||||
#include <osg/Types>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Notify>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
#define RAD2DEG(x) ((x)*180.0/M_PI)
|
||||
|
||||
using namespace osg;
|
||||
|
||||
@@ -51,7 +54,7 @@ typedef struct quaternion_
|
||||
|
||||
static void quaternion_matrix( quaternion *q, double mat[4][4] )
|
||||
{
|
||||
/* copied from Shoemake/ACM SIGGRAPH 89 */
|
||||
/* copied from Shoemake/ACM SIGGRAPH 89 */
|
||||
double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz ;
|
||||
|
||||
xs = q->x + q->x;
|
||||
@@ -136,50 +139,6 @@ Matrix::~Matrix()
|
||||
}
|
||||
|
||||
|
||||
Matrix* Matrix::instance()
|
||||
{
|
||||
static ref_ptr<Matrix> s_matrix(new Matrix());
|
||||
return s_matrix.get();
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
bool matched = true;
|
||||
for(int k=0;k<16 && matched;++k)
|
||||
{
|
||||
matched = fr[k].isFloat();
|
||||
}
|
||||
if (matched)
|
||||
{
|
||||
int k=0;
|
||||
for(int i=0;i<4;++i)
|
||||
{
|
||||
for(int j=0;j<4;++j)
|
||||
{
|
||||
fr[k].getFloat(_mat[i][j]);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
fr += 16;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << _mat[0][0] << " " << _mat[0][1] << " " << _mat[0][2] << " " << _mat[0][3] << endl;
|
||||
fw.indent() << _mat[1][0] << " " << _mat[1][1] << " " << _mat[1][2] << " " << _mat[1][3] << endl;
|
||||
fw.indent() << _mat[2][0] << " " << _mat[2][1] << " " << _mat[2][2] << " " << _mat[2][3] << endl;
|
||||
fw.indent() << _mat[3][0] << " " << _mat[3][1] << " " << _mat[3][2] << " " << _mat[3][3] << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::makeIdent()
|
||||
{
|
||||
_mat[0][0] = 1.0f;
|
||||
@@ -203,11 +162,63 @@ void Matrix::makeIdent()
|
||||
_mat[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
void Matrix::set(const float* m)
|
||||
{
|
||||
_mat[0][0] = m[0];
|
||||
_mat[0][1] = m[1];
|
||||
_mat[0][2] = m[2];
|
||||
_mat[0][3] = m[3];
|
||||
|
||||
_mat[1][0] = m[4];
|
||||
_mat[1][1] = m[5];
|
||||
_mat[1][2] = m[6];
|
||||
_mat[1][3] = m[7];
|
||||
|
||||
_mat[2][0] = m[8];
|
||||
_mat[2][1] = m[9];
|
||||
_mat[2][2] = m[10];
|
||||
_mat[2][3] = m[11];
|
||||
|
||||
_mat[3][0] = m[12];
|
||||
_mat[3][1] = m[13];
|
||||
_mat[3][2] = m[14];
|
||||
_mat[3][3] = m[15];
|
||||
}
|
||||
|
||||
|
||||
void Matrix::set(
|
||||
float a00, float a01, float a02, float a03,
|
||||
float a10, float a11, float a12, float a13,
|
||||
float a20, float a21, float a22, float a23,
|
||||
float a30, float a31, float a32, float a33)
|
||||
{
|
||||
_mat[0][0] = a00;
|
||||
_mat[0][1] = a01;
|
||||
_mat[0][2] = a02;
|
||||
_mat[0][3] = a03;
|
||||
|
||||
_mat[1][0] = a10;
|
||||
_mat[1][1] = a11;
|
||||
_mat[1][2] = a12;
|
||||
_mat[1][3] = a13;
|
||||
|
||||
_mat[2][0] = a20;
|
||||
_mat[2][1] = a21;
|
||||
_mat[2][2] = a22;
|
||||
_mat[2][3] = a23;
|
||||
|
||||
_mat[3][0] = a30;
|
||||
_mat[3][1] = a31;
|
||||
_mat[3][2] = a32;
|
||||
_mat[3][3] = a33;
|
||||
}
|
||||
|
||||
void Matrix::copy(const Matrix& matrix)
|
||||
{
|
||||
memcpy(_mat,matrix._mat,sizeof(_mat));
|
||||
}
|
||||
|
||||
|
||||
void Matrix::makeScale(float sx, float sy, float sz)
|
||||
{
|
||||
makeIdent();
|
||||
@@ -224,6 +235,7 @@ void Matrix::preScale( float sx, float sy, float sz, const Matrix& m )
|
||||
mult(transMat,m);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::postScale( const Matrix& m, float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
@@ -231,6 +243,7 @@ void Matrix::postScale( const Matrix& m, float sx, float sy, float sz )
|
||||
mult(m,transMat);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preScale( float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
@@ -238,6 +251,7 @@ void Matrix::preScale( float sx, float sy, float sz )
|
||||
preMult(transMat);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::postScale( float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
@@ -246,8 +260,6 @@ void Matrix::postScale( float sx, float sy, float sz )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Matrix::makeTrans( float tx, float ty, float tz )
|
||||
{
|
||||
makeIdent();
|
||||
@@ -256,6 +268,7 @@ void Matrix::makeTrans( float tx, float ty, float tz )
|
||||
_mat[3][2] = tz;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m )
|
||||
{
|
||||
Matrix transMat;
|
||||
@@ -263,6 +276,7 @@ void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m )
|
||||
mult(transMat,m);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz )
|
||||
{
|
||||
Matrix transMat;
|
||||
@@ -270,6 +284,7 @@ void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz )
|
||||
mult(m,transMat);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preTrans( float tx, float ty, float tz )
|
||||
{
|
||||
_mat[3][0] = (tx * _mat[0][0]) + (ty * _mat[1][0]) + (tz * _mat[2][0]) + _mat[3][0];
|
||||
@@ -278,6 +293,7 @@ void Matrix::preTrans( float tx, float ty, float tz )
|
||||
_mat[3][3] = (tx * _mat[0][3]) + (ty * _mat[1][3]) + (tz * _mat[2][3]) + _mat[3][3];
|
||||
}
|
||||
|
||||
|
||||
void Matrix::postTrans( float tx, float ty, float tz )
|
||||
{
|
||||
Matrix transMat;
|
||||
@@ -285,6 +301,21 @@ void Matrix::postTrans( float tx, float ty, float tz )
|
||||
postMult(transMat);
|
||||
}
|
||||
|
||||
void Matrix::makeRot( const Vec3& old_vec, const Vec3& new_vec )
|
||||
{
|
||||
/* dot product == cos(angle old_vec<>new_vec). */
|
||||
double d = new_vec * old_vec;
|
||||
if ( d < 0.9999 )
|
||||
{
|
||||
double angle = acos( d );
|
||||
Vec3 rot_axis = new_vec ^ old_vec;
|
||||
makeRot( RAD2DEG(angle),
|
||||
rot_axis.x(), rot_axis.y(), rot_axis.z() );
|
||||
}
|
||||
else
|
||||
makeIdent();
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float deg, float x, float y, float z )
|
||||
{
|
||||
double __mat[4][4];
|
||||
@@ -313,6 +344,7 @@ void Matrix::makeRot( float deg, float x, float y, float z )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m )
|
||||
{
|
||||
Matrix rotMat;
|
||||
@@ -320,6 +352,7 @@ void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m )
|
||||
mult(rotMat,m);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z )
|
||||
{
|
||||
Matrix rotMat;
|
||||
@@ -327,6 +360,7 @@ void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z )
|
||||
mult(m,rotMat);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preRot( float deg, float x, float y, float z )
|
||||
{
|
||||
quaternion q;
|
||||
@@ -351,6 +385,7 @@ void Matrix::preRot( float deg, float x, float y, float z )
|
||||
memcpy( _mat, res_mat, sizeof( _mat ) );
|
||||
}
|
||||
|
||||
|
||||
void Matrix::postRot( float deg, float x, float y, float z )
|
||||
{
|
||||
quaternion q;
|
||||
@@ -375,12 +410,15 @@ void Matrix::postRot( float deg, float x, float y, float z )
|
||||
memcpy( _mat, res_mat, sizeof( _mat ) );
|
||||
}
|
||||
|
||||
|
||||
void Matrix::setTrans( float tx, float ty, float tz )
|
||||
{
|
||||
_mat[3][0] = tx;
|
||||
_mat[3][1] = ty;
|
||||
_mat[3][1] = ty;
|
||||
_mat[3][2] = tz;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::setTrans( const Vec3& v )
|
||||
{
|
||||
_mat[3][0] = v[0];
|
||||
@@ -388,6 +426,7 @@ void Matrix::setTrans( const Vec3& v )
|
||||
_mat[3][2] = v[2];
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preMult(const Matrix& m)
|
||||
{
|
||||
Matrix tm;
|
||||
@@ -395,6 +434,7 @@ void Matrix::preMult(const Matrix& m)
|
||||
*this = tm;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::postMult(const Matrix& m)
|
||||
{
|
||||
Matrix tm;
|
||||
@@ -402,25 +442,41 @@ void Matrix::postMult(const Matrix& m)
|
||||
*this = tm;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::mult(const Matrix& lhs,const Matrix& rhs)
|
||||
{
|
||||
matrix_mult( lhs._mat, rhs._mat, _mat );
|
||||
if (&lhs==this || &rhs==this)
|
||||
{
|
||||
osg::Matrix tm;
|
||||
matrix_mult( lhs._mat, rhs._mat, tm._mat );
|
||||
*this = tm;
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix_mult( lhs._mat, rhs._mat, _mat );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Matrix Matrix::operator * (const Matrix& m) const
|
||||
{
|
||||
Matrix nm;
|
||||
matrix_mult( _mat,m._mat, nm._mat );
|
||||
return nm;
|
||||
Matrix tm;
|
||||
matrix_mult( _mat,m._mat, tm._mat );
|
||||
return tm;
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::invert(const Matrix& _m)
|
||||
bool Matrix::invert(const Matrix& invm)
|
||||
{
|
||||
if (&invm==this) {
|
||||
Matrix tm(invm);
|
||||
return invert(tm);
|
||||
}
|
||||
|
||||
// code lifted from VR Juggler.
|
||||
// not cleanly added, but seems to work. RO.
|
||||
|
||||
const float* a = reinterpret_cast<const float*>(_m._mat);
|
||||
const float* a = reinterpret_cast<const float*>(invm._mat);
|
||||
float* b = reinterpret_cast<float*>(_mat);
|
||||
|
||||
int n = 4;
|
||||
@@ -428,14 +484,14 @@ bool Matrix::invert(const Matrix& _m)
|
||||
int r[ 4], c[ 4], row[ 4], col[ 4];
|
||||
float m[ 4][ 4*2], pivot, max_m, tmp_m, fac;
|
||||
|
||||
/* Initialization */
|
||||
/* Initialization */
|
||||
for ( i = 0; i < n; i ++ )
|
||||
{
|
||||
r[ i] = c[ i] = 0;
|
||||
row[ i] = col[ i] = 0;
|
||||
}
|
||||
|
||||
/* Set working matrix */
|
||||
/* Set working matrix */
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
for ( j = 0; j < n; j++ )
|
||||
@@ -445,10 +501,10 @@ bool Matrix::invert(const Matrix& _m)
|
||||
}
|
||||
}
|
||||
|
||||
/* Begin of loop */
|
||||
/* Begin of loop */
|
||||
for ( k = 0; k < n; k++ )
|
||||
{
|
||||
/* Choosing the pivot */
|
||||
/* Choosing the pivot */
|
||||
for ( i = 0, max_m = 0; i < n; i++ )
|
||||
{
|
||||
if ( row[ i] ) continue;
|
||||
@@ -470,11 +526,11 @@ bool Matrix::invert(const Matrix& _m)
|
||||
if ( fabs( pivot) <= 1e-20)
|
||||
{
|
||||
notify(WARN) << "*** pivot = %f in mat_inv. ***\n";
|
||||
//exit( 0);
|
||||
//exit( 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Normalization */
|
||||
/* Normalization */
|
||||
for ( j = 0; j < 2*n; j++ )
|
||||
{
|
||||
if ( j == c[ k] )
|
||||
@@ -483,7 +539,7 @@ bool Matrix::invert(const Matrix& _m)
|
||||
m[ r[ k]][ j] /=pivot;
|
||||
}
|
||||
|
||||
/* Reduction */
|
||||
/* Reduction */
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
if ( i == r[ k] )
|
||||
@@ -499,7 +555,7 @@ bool Matrix::invert(const Matrix& _m)
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign invers to a matrix */
|
||||
/* Assign invers to a matrix */
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = 0; j < n; j++ )
|
||||
row[ i] = ( c[ j] == i ) ? r[j] : row[ i];
|
||||
@@ -508,5 +564,5 @@ bool Matrix::invert(const Matrix& _m)
|
||||
for ( j = 0; j < n; j++ )
|
||||
b[ i * n + j] = m[ row[ i]][j + n];
|
||||
|
||||
return true; // It worked
|
||||
return true; // It worked
|
||||
}
|
||||
|
||||
120
src/osg/Node.cpp
@@ -2,18 +2,12 @@
|
||||
#include "osg/Group"
|
||||
#include "osg/NodeVisitor"
|
||||
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include "osg/Registry"
|
||||
#include "osg/Notify"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Node> g_NodeProxy;
|
||||
|
||||
Node::Node()
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
@@ -24,7 +18,7 @@ Node::Node()
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
if (_userData && _memoryAdapter.valid()) _memoryAdapter->decrementReference(_userData);
|
||||
if (_userData && _memoryAdapter.valid()) _memoryAdapter->unref_data(_userData);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,122 +27,18 @@ void Node::accept(NodeVisitor& nv)
|
||||
nv.apply(*this);
|
||||
}
|
||||
|
||||
|
||||
void Node::ascend(NodeVisitor& nv)
|
||||
{
|
||||
std::for_each(_parents.begin(),_parents.end(),NodeAcceptOp(nv));
|
||||
}
|
||||
|
||||
bool Node::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (Object::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
if (fr.matchSequence("name %s"))
|
||||
{
|
||||
_name = fr[1].takeStr();
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
// if (fr.matchSequence("user_data {"))
|
||||
// {
|
||||
// notify(DEBUG) << "Matched user_data {"<<endl;
|
||||
// int entry = fr[0].getNoNestedBrackets();
|
||||
// fr += 2;
|
||||
//
|
||||
// while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
// {
|
||||
// Object* object = fr.readObject();
|
||||
// if (object) setUserData(object);
|
||||
// notify(DEBUG) << "read "<<object<<endl;
|
||||
// ++fr;
|
||||
// }
|
||||
// iteratorAdvanced = true;
|
||||
// }
|
||||
|
||||
while (fr.matchSequence("description {"))
|
||||
{
|
||||
notify(DEBUG) << "Matched description {"<<endl;
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
fr += 2;
|
||||
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
{
|
||||
_descriptions.push_back(fr[0].getStr());
|
||||
notify(DEBUG) << "read "<<_descriptions.back()<<endl;
|
||||
++fr;
|
||||
}
|
||||
iteratorAdvanced = true;
|
||||
|
||||
}
|
||||
|
||||
while (fr.matchSequence("description %s"))
|
||||
{
|
||||
notify(DEBUG) << "Matched description %s"<<endl;
|
||||
_descriptions.push_back(fr[1].getStr());
|
||||
notify(DEBUG) << "read "<<_descriptions.back()<<endl;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Node::writeLocalData(Output& fw)
|
||||
{
|
||||
Object::writeLocalData(fw);
|
||||
if (!_name.empty()) fw.indent() << "name "<<'"'<<_name<<'"'<<endl;
|
||||
|
||||
// if (_userData)
|
||||
// {
|
||||
// Object* object = dynamic_cast<Object*>(_userData);
|
||||
// if (object)
|
||||
// {
|
||||
// fw.indent() << "user_data {"<<endl;
|
||||
// fw.moveIn();
|
||||
// object->write(fw);
|
||||
// fw.moveOut();
|
||||
// fw.indent() << "}"<<endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!_descriptions.empty())
|
||||
{
|
||||
if (_descriptions.size()==1)
|
||||
{
|
||||
fw.indent() << "description "<<'"'<<_descriptions.front()<<'"'<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "description {"<<endl;
|
||||
fw.moveIn();
|
||||
for(DescriptionList::iterator ditr=_descriptions.begin();
|
||||
ditr!=_descriptions.end();
|
||||
++ditr)
|
||||
{
|
||||
fw.indent() << '"'<<*ditr<<'"'<<endl;
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent() << "}"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Node::computeBound()
|
||||
const bool Node::computeBound() const
|
||||
{
|
||||
_bsphere.init();
|
||||
return false;
|
||||
}
|
||||
|
||||
const BoundingSphere& Node::getBound()
|
||||
{
|
||||
if(!_bsphere_computed) computeBound();
|
||||
return _bsphere;
|
||||
}
|
||||
|
||||
void Node::dirtyBound()
|
||||
{
|
||||
@@ -158,8 +48,8 @@ void Node::dirtyBound()
|
||||
|
||||
// dirty parent bounding sphere's to ensure that all are valid.
|
||||
for(ParentList::iterator itr=_parents.begin();
|
||||
itr!=_parents.end();
|
||||
++itr)
|
||||
itr!=_parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->dirtyBound();
|
||||
}
|
||||
|
||||
@@ -5,36 +5,37 @@ using namespace osg;
|
||||
|
||||
NodeVisitor::NodeVisitor(TraversalMode tm)
|
||||
{
|
||||
_traverseVisitor = NULL;
|
||||
_traverseMode = tm;
|
||||
_traversalVisitor = NULL;
|
||||
_traversalMode = tm;
|
||||
}
|
||||
|
||||
|
||||
NodeVisitor::~NodeVisitor()
|
||||
{
|
||||
// if (_traverseVisitor) detach from _traverseVisitor;
|
||||
// if (_traversalVisitor) detach from _traversalVisitor;
|
||||
}
|
||||
|
||||
void NodeVisitor::setTraverseMode(TraversalMode mode)
|
||||
|
||||
void NodeVisitor::setTraversalMode(const TraversalMode mode)
|
||||
{
|
||||
if (_traverseMode==mode) return;
|
||||
if (_traversalMode==mode) return;
|
||||
if (mode==TRAVERSE_VISITOR)
|
||||
{
|
||||
if (_traverseVisitor==NULL) _traverseMode = TRAVERSE_NONE;
|
||||
else _traverseMode = TRAVERSE_VISITOR;
|
||||
if (_traversalVisitor==NULL) _traversalMode = TRAVERSE_NONE;
|
||||
else _traversalMode = TRAVERSE_VISITOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_traverseVisitor) _traverseVisitor=NULL;
|
||||
_traverseMode = mode;
|
||||
if (_traversalVisitor.valid()) _traversalVisitor=NULL;
|
||||
_traversalMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeVisitor::setTraverseVisitor(NodeVisitor* nv)
|
||||
|
||||
void NodeVisitor::setTraversalVisitor(NodeVisitor* nv)
|
||||
{
|
||||
if (_traverseVisitor==nv) return;
|
||||
// if (_traverseVisitor) detach from _traverseVisitor;
|
||||
_traverseVisitor = nv;
|
||||
if (_traverseVisitor) _traverseMode = TRAVERSE_VISITOR;
|
||||
else _traverseMode = TRAVERSE_NONE;
|
||||
// attach to _traverseVisitor;
|
||||
if (_traversalVisitor==nv) return;
|
||||
_traversalVisitor = nv;
|
||||
if (_traversalVisitor.valid()) _traversalMode = TRAVERSE_VISITOR;
|
||||
else _traversalMode = TRAVERSE_NONE;
|
||||
}
|
||||
|
||||
@@ -1,87 +1,60 @@
|
||||
#include "osg/Notify"
|
||||
#include <string>
|
||||
|
||||
using namespace osg;
|
||||
osg::NotifySeverity osg::g_NotifyLevel = osg::NOTICE;
|
||||
|
||||
int osg::NotifyInit::count_ = 0;
|
||||
NotifySeverity osg::g_NotifyLevel = osg::NOTICE;
|
||||
ofstream *osg::g_absorbStreamPtr = NULL;
|
||||
|
||||
void osg::setNotifyLevel(NotifySeverity severity)
|
||||
void osg::setNotifyLevel(osg::NotifySeverity severity)
|
||||
{
|
||||
g_NotifyLevel = severity;
|
||||
osg::initNotifyLevel();
|
||||
g_NotifyLevel = severity;
|
||||
}
|
||||
|
||||
int osg::getNotifyLevel()
|
||||
|
||||
osg::NotifySeverity osg::getNotifyLevel()
|
||||
{
|
||||
osg::initNotifyLevel();
|
||||
return g_NotifyLevel;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
ostream& osg::notify(NotifySeverity severity)
|
||||
|
||||
bool osg::initNotifyLevel()
|
||||
{
|
||||
if (severity<=g_NotifyLevel || g_absorbStreamPtr==NULL)
|
||||
static bool s_local_intialized = false;
|
||||
|
||||
if (s_local_intialized) return true;
|
||||
|
||||
s_local_intialized = true;
|
||||
|
||||
// g_NotifyLevel
|
||||
// =============
|
||||
|
||||
g_NotifyLevel = osg::NOTICE; // Default value
|
||||
|
||||
char *OSGNOTIFYLEVEL=getenv("OSGNOTIFYLEVEL");
|
||||
if(OSGNOTIFYLEVEL)
|
||||
{
|
||||
if (severity<=osg::WARN) return cerr;
|
||||
else return cout;
|
||||
}
|
||||
return *g_absorbStreamPtr;
|
||||
}
|
||||
#endif
|
||||
|
||||
NotifyInit::NotifyInit()
|
||||
{
|
||||
if (count_++ == 0) {
|
||||
std::string stringOSGNOTIFYLEVEL(OSGNOTIFYLEVEL);
|
||||
|
||||
// g_NotifyLevel
|
||||
// =============
|
||||
|
||||
g_NotifyLevel = osg::NOTICE; // Default value
|
||||
|
||||
char *OSGNOTIFYLEVEL=getenv("OSGNOTIFYLEVEL");
|
||||
if(OSGNOTIFYLEVEL){
|
||||
|
||||
std::string stringOSGNOTIFYLEVEL(OSGNOTIFYLEVEL);
|
||||
|
||||
// Convert to upper case
|
||||
for(std::string::iterator i=stringOSGNOTIFYLEVEL.begin();
|
||||
i!=stringOSGNOTIFYLEVEL.end();
|
||||
++i) *i=toupper(*i);
|
||||
|
||||
if(stringOSGNOTIFYLEVEL.find("ALWAYS")!=std::string::npos) g_NotifyLevel=osg::ALWAYS;
|
||||
else if(stringOSGNOTIFYLEVEL.find("FATAL")!=std::string::npos) g_NotifyLevel=osg::FATAL;
|
||||
else if(stringOSGNOTIFYLEVEL.find("WARN")!=std::string::npos) g_NotifyLevel=osg::WARN;
|
||||
else if(stringOSGNOTIFYLEVEL.find("NOTICE")!=std::string::npos) g_NotifyLevel=osg::NOTICE;
|
||||
else if(stringOSGNOTIFYLEVEL.find("INFO")!=std::string::npos) g_NotifyLevel=osg::INFO;
|
||||
else if(stringOSGNOTIFYLEVEL.find("DEBUG")!=std::string::npos) g_NotifyLevel=osg::DEBUG;
|
||||
else if(stringOSGNOTIFYLEVEL.find("FP_DEBUG")!=std::string::npos) g_NotifyLevel=osg::FP_DEBUG;
|
||||
|
||||
}
|
||||
|
||||
// g_absorbStreamPtr
|
||||
// =================
|
||||
|
||||
char *OSGNOTIFYABSORBFILE=getenv("OSGNOTIFYABSORBFILE");
|
||||
if (OSGNOTIFYABSORBFILE)
|
||||
// Convert to upper case
|
||||
for(std::string::iterator i=stringOSGNOTIFYLEVEL.begin();
|
||||
i!=stringOSGNOTIFYLEVEL.end();
|
||||
++i)
|
||||
{
|
||||
g_absorbStreamPtr=new ofstream(OSGNOTIFYABSORBFILE);
|
||||
*i=toupper(*i);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WIN32
|
||||
// What's the Windows equivalent of /dev/null?
|
||||
g_absorbStreamPtr=new ofstream("C:/Windows/Tmp/osg.log");
|
||||
#else
|
||||
g_absorbStreamPtr=new ofstream("/dev/null");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotifyInit::~NotifyInit()
|
||||
{
|
||||
if(--count_ == 0) {
|
||||
delete g_absorbStreamPtr;
|
||||
g_absorbStreamPtr=NULL;
|
||||
if(stringOSGNOTIFYLEVEL.find("ALWAYS")!=std::string::npos) g_NotifyLevel=osg::ALWAYS;
|
||||
else if(stringOSGNOTIFYLEVEL.find("FATAL")!=std::string::npos) g_NotifyLevel=osg::FATAL;
|
||||
else if(stringOSGNOTIFYLEVEL.find("WARN")!=std::string::npos) g_NotifyLevel=osg::WARN;
|
||||
else if(stringOSGNOTIFYLEVEL.find("NOTICE")!=std::string::npos) g_NotifyLevel=osg::NOTICE;
|
||||
else if(stringOSGNOTIFYLEVEL.find("INFO")!=std::string::npos) g_NotifyLevel=osg::INFO;
|
||||
else if(stringOSGNOTIFYLEVEL.find("DEBUG_INFO")!=std::string::npos) g_NotifyLevel=osg::DEBUG_INFO;
|
||||
else if(stringOSGNOTIFYLEVEL.find("DEBUG_FP")!=std::string::npos) g_NotifyLevel=osg::DEBUG_FP;
|
||||
else if(stringOSGNOTIFYLEVEL.find("DEBUG")!=std::string::npos) g_NotifyLevel=osg::DEBUG_INFO;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,78 +1,5 @@
|
||||
#include "osg/Object"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Object* Object::readClone(Input& fr)
|
||||
{
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString())
|
||||
{
|
||||
Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
|
||||
if (obj && isSameKindAs(obj))
|
||||
{
|
||||
fr+=2;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
if (!fr[0].matchWord(className()) ||
|
||||
!fr[1].isOpenBracket()) return NULL;
|
||||
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
|
||||
Object* obj = clone();
|
||||
|
||||
fr+=2;
|
||||
|
||||
while(!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (fr[0].matchWord("UniqueID") && fr[1].isString()) {
|
||||
fr.regisiterUniqueIDForObject(fr[1].getStr(),obj);
|
||||
fr += 2;
|
||||
}
|
||||
if (obj->readLocalData(fr)) iteratorAdvanced = true;
|
||||
if (!iteratorAdvanced) ++fr;
|
||||
}
|
||||
++fr; // step over trailing '}'
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
bool Object::write(Output& fw)
|
||||
{
|
||||
if (_refCount>1) {
|
||||
std::string uniqueID;
|
||||
if (fw.getUniqueIDForObject(this,uniqueID)) {
|
||||
fw.indent() << "Use " << uniqueID << endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fw.indent() << className() << " {"<<endl;
|
||||
|
||||
fw.moveIn();
|
||||
|
||||
if (_refCount>1) {
|
||||
std::string uniqueID;
|
||||
fw.createUniqueIDForObject(this,uniqueID);
|
||||
fw.registerUniqueIDForObject(this,uniqueID);
|
||||
fw.indent() << "UniqueID " << uniqueID << endl;
|
||||
}
|
||||
|
||||
writeLocalData(fw);
|
||||
|
||||
fw.moveOut();
|
||||
|
||||
fw.indent() << "}"<<endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
// no non inline functions yet for Object...
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
// Ideas and code borrowed from GLUT pointburst demo
|
||||
// written by Mark J. Kilgard
|
||||
// written by Mark J. Kilgard
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "osg/GL"
|
||||
#include "osg/GLExtensions"
|
||||
#include "osg/Point"
|
||||
#include "osg/ExtensionSupported"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
// if extensions not defined by gl.h (or via glext.h) define them
|
||||
// ourselves and allow the extensions to detectd at runtine using
|
||||
// osg::isGLExtensionSupported().
|
||||
#if defined(GL_SGIS_point_parameters) && !defined(GL_EXT_point_parameters)
|
||||
/* Use the EXT point parameters interface for the SGIS implementation. */
|
||||
# define GL_POINT_SIZE_MIN_EXT GL_POINT_SIZE_MIN_SGIS
|
||||
# define GL_POINT_SIZE_MAX_EXT GL_POINT_SIZE_MAX_SGIS
|
||||
# define GL_POINT_FADE_THRESHOLD_SIZE_EXT GL_POINT_FADE_THRESHOLD_SIZE_SGIS
|
||||
# define GL_DISTANCE_ATTENUATION_EXT GL_DISTANCE_ATTENUATION_SGIS
|
||||
# define glPointParameterfEXT glPointParameterfSGIS
|
||||
# define glPointParameterfvEXT glPointParameterfvSGIS
|
||||
# define GL_EXT_point_parameters 1
|
||||
#endif
|
||||
|
||||
@@ -30,91 +29,73 @@ using namespace osg;
|
||||
# define GL_POINT_SIZE_MAX_EXT 0x8127
|
||||
# define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
|
||||
# define GL_DISTANCE_ATTENUATION_EXT 0x8129
|
||||
# ifdef _WIN32
|
||||
// Curse Microsoft for the insanity of wglGetProcAddress.
|
||||
typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
|
||||
typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
|
||||
# define GL_EXT_point_parameters 1
|
||||
# endif
|
||||
# define GL_EXT_point_parameters 1
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
PFNGLPOINTPARAMETERFEXTPROC glPointParameterfEXT;
|
||||
PFNGLPOINTPARAMETERFVEXTPROC glPointParameterfvEXT;
|
||||
#ifndef PFNGLPOINTPARAMETERFEXTPROC
|
||||
typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
|
||||
#endif
|
||||
#ifndef PFNGLPOINTPARAMETERFVEXTPROC
|
||||
typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
|
||||
#endif
|
||||
|
||||
static int s_hasPointParameters;
|
||||
PFNGLPOINTPARAMETERFEXTPROC s_PointParameterfEXT = NULL;
|
||||
PFNGLPOINTPARAMETERFVEXTPROC s_PointParameterfvEXT = NULL;
|
||||
|
||||
|
||||
Point::Point( void )
|
||||
Point::Point()
|
||||
{
|
||||
_size = 1.0f; // TODO find proper default
|
||||
_fadeThresholdSize = 1.0f; // TODO find proper default
|
||||
_distanceAttenuation = Vec3(0.0f, 1.0f/5.f, 0.0f); // TODO find proper default
|
||||
_size = 1.0f; // TODO find proper default
|
||||
_fadeThresholdSize = 1.0f; // TODO find proper default
|
||||
// TODO find proper default
|
||||
_distanceAttenuation = Vec3(0.0f, 1.0f/5.f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
Point::~Point( void )
|
||||
Point::~Point()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Point* Point::instance()
|
||||
{
|
||||
static ref_ptr<Point> s_point(new Point);
|
||||
return s_point.get();
|
||||
}
|
||||
|
||||
|
||||
void Point::init_GL_EXT()
|
||||
{
|
||||
s_hasPointParameters =
|
||||
ExtensionSupported("GL_SGIS_point_parameters") ||
|
||||
ExtensionSupported("GL_EXT_point_parameters");
|
||||
#ifdef _WIN32
|
||||
if (s_hasPointParameters)
|
||||
if (isGLExtensionSupported("GL_EXT_point_parameters"))
|
||||
{
|
||||
glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)
|
||||
wglGetProcAddress("glPointParameterfEXT");
|
||||
glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)
|
||||
wglGetProcAddress("glPointParameterfvEXT");
|
||||
s_PointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)
|
||||
getGLExtensionFuncPtr("glPointParameterfEXT");
|
||||
s_PointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)
|
||||
getGLExtensionFuncPtr("glPointParameterfvEXT");
|
||||
}
|
||||
#endif
|
||||
else if (isGLExtensionSupported("GL_SGIS_point_parameters"))
|
||||
{
|
||||
s_PointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)
|
||||
getGLExtensionFuncPtr("glPointParameterfSGIS");
|
||||
s_PointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)
|
||||
getGLExtensionFuncPtr("glPointParameterfvSGIS");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Point::enableSmooth( void )
|
||||
{
|
||||
glEnable( GL_POINT_SMOOTH );
|
||||
}
|
||||
|
||||
|
||||
void Point::disableSmooth( void )
|
||||
{
|
||||
glDisable( GL_POINT_SMOOTH );
|
||||
}
|
||||
|
||||
|
||||
void Point::setSize( float size )
|
||||
void Point::setSize( const float size )
|
||||
{
|
||||
_size = size;
|
||||
}
|
||||
|
||||
void Point::setFadeThresholdSize(float fadeThresholdSize)
|
||||
|
||||
void Point::setFadeThresholdSize(const float fadeThresholdSize)
|
||||
{
|
||||
_fadeThresholdSize = fadeThresholdSize;
|
||||
}
|
||||
|
||||
|
||||
void Point::setDistanceAttenuation(const Vec3& distanceAttenuation)
|
||||
{
|
||||
_distanceAttenuation = distanceAttenuation;
|
||||
}
|
||||
|
||||
void Point::apply( void )
|
||||
|
||||
void Point::apply(State&) const
|
||||
{
|
||||
glPointSize(_size);
|
||||
|
||||
#if GL_EXT_point_parameters
|
||||
static bool s_gl_ext_init=false;
|
||||
|
||||
if (!s_gl_ext_init)
|
||||
@@ -123,56 +104,8 @@ void Point::apply( void )
|
||||
init_GL_EXT();
|
||||
}
|
||||
|
||||
if (s_hasPointParameters)
|
||||
{
|
||||
glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, (const GLfloat*)&_distanceAttenuation);
|
||||
glPointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, _fadeThresholdSize);
|
||||
}
|
||||
#endif
|
||||
if (s_PointParameterfvEXT) s_PointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, (const GLfloat*)&_distanceAttenuation);
|
||||
if (s_PointParameterfEXT) s_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, _fadeThresholdSize);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Point::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
float data;
|
||||
if (fr[0].matchWord("size") && fr[1].getFloat(data))
|
||||
{
|
||||
|
||||
_size = data;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("fade_threshold_size") && fr[1].getFloat(data))
|
||||
{
|
||||
|
||||
_fadeThresholdSize = data;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
Vec3 distAtten;
|
||||
if (fr[0].matchWord("distance_attenuation") &&
|
||||
fr[1].getFloat(distAtten[0]) && fr[2].getFloat(distAtten[1]) && fr[3].getFloat(distAtten[2]))
|
||||
{
|
||||
|
||||
_distanceAttenuation = distAtten;
|
||||
fr+=4;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Point::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "size " << _size << endl;
|
||||
fw.indent() << "fade_threshold_size " << _fadeThresholdSize << endl;
|
||||
fw.indent() << "distance_attenuation " << _distanceAttenuation << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,85 +1,20 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/PolygonOffset"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
PolygonOffset::PolygonOffset( void )
|
||||
PolygonOffset::PolygonOffset()
|
||||
{
|
||||
_factor = 0.0f; // are these sensible defaut values?
|
||||
_factor = 0.0f; // are these sensible defaut values?
|
||||
_units = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
PolygonOffset::~PolygonOffset( void )
|
||||
PolygonOffset::~PolygonOffset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PolygonOffset* PolygonOffset::instance()
|
||||
{
|
||||
static ref_ptr<PolygonOffset> s_PolygonOffset(new PolygonOffset);
|
||||
return s_PolygonOffset.get();
|
||||
}
|
||||
|
||||
void PolygonOffset::setOffset(float factor,float units)
|
||||
{
|
||||
_factor = factor;
|
||||
_units = units;
|
||||
}
|
||||
|
||||
void PolygonOffset::enable( void )
|
||||
{
|
||||
glEnable( GL_POLYGON_OFFSET_FILL);
|
||||
glEnable( GL_POLYGON_OFFSET_LINE);
|
||||
glEnable( GL_POLYGON_OFFSET_POINT);
|
||||
}
|
||||
|
||||
|
||||
void PolygonOffset::disable( void )
|
||||
{
|
||||
glDisable( GL_POLYGON_OFFSET_FILL);
|
||||
glDisable( GL_POLYGON_OFFSET_LINE);
|
||||
glDisable( GL_POLYGON_OFFSET_POINT);
|
||||
}
|
||||
|
||||
void PolygonOffset::apply( void )
|
||||
void PolygonOffset::apply(State&) const
|
||||
{
|
||||
glPolygonOffset(_factor,_units);
|
||||
}
|
||||
|
||||
bool PolygonOffset::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
float data;
|
||||
if (fr[0].matchWord("factor") && fr[1].getFloat(data))
|
||||
{
|
||||
|
||||
_factor = data;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("units") && fr[1].getFloat(data))
|
||||
{
|
||||
|
||||
_units = data;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool PolygonOffset::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "factor " << _factor << endl;
|
||||
fw.indent() << "units " << _units << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
117
src/osg/Quat.cpp
@@ -11,29 +11,13 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
/// Default constructor is empty
|
||||
Quat::Quat( void )
|
||||
{
|
||||
}
|
||||
|
||||
/// Constructor with four floats - just call the constructor for the Vec4
|
||||
Quat::Quat( const float x, const float y, const float z, const float w )
|
||||
{
|
||||
_fv = Vec4( x, y, z, w );
|
||||
}
|
||||
|
||||
/// Constructor with a Vec4
|
||||
Quat::Quat( const Vec4& vec )
|
||||
{
|
||||
_fv = vec;
|
||||
}
|
||||
|
||||
/// Set the elements of the Quat to represent a rotation of angle
|
||||
/// (radians) around the axis (x,y,z)
|
||||
void Quat::makeRot( const float angle,
|
||||
const float x,
|
||||
const float y,
|
||||
const float z )
|
||||
const float x,
|
||||
const float y,
|
||||
const float z )
|
||||
{
|
||||
float inversenorm = 1.0/sqrt( x*x + y*y + z*z );
|
||||
float coshalfangle = cos( 0.5*angle );
|
||||
@@ -45,11 +29,13 @@ void Quat::makeRot( const float angle,
|
||||
_fv[3] = coshalfangle;
|
||||
}
|
||||
|
||||
|
||||
void Quat::makeRot( const float angle, const Vec3& vec )
|
||||
{
|
||||
makeRot( angle, vec[0], vec[1], vec[2] );
|
||||
}
|
||||
|
||||
|
||||
// Make a rotation Quat which will rotate vec1 to vec2
|
||||
// Generally take adot product to get the angle between these
|
||||
// and then use a cross product to get the rotation axis
|
||||
@@ -61,39 +47,41 @@ void Quat::makeRot( const Vec3& vec1, const Vec3& vec2 )
|
||||
|
||||
float length1 = vec1.length();
|
||||
float length2 = vec2.length();
|
||||
float cosangle = vec1*vec2/(2*length1*length2); // dot product vec1*vec2
|
||||
|
||||
// dot product vec1*vec2
|
||||
float cosangle = vec1*vec2/(length1*length2);
|
||||
|
||||
if ( fabs(cosangle - 1) < epsilon )
|
||||
{
|
||||
// cosangle is close to 1, so the vectors are close to being coincident
|
||||
// Need to generate an angle of zero with any vector we like
|
||||
// We'll choose (1,0,0)
|
||||
makeRot( 0.0, 1.0, 0.0, 0.0 );
|
||||
// cosangle is close to 1, so the vectors are close to being coincident
|
||||
// Need to generate an angle of zero with any vector we like
|
||||
// We'll choose (1,0,0)
|
||||
makeRot( 0.0, 1.0, 0.0, 0.0 );
|
||||
}
|
||||
else
|
||||
if ( fabs(cosangle + 1) < epsilon )
|
||||
{
|
||||
// cosangle is close to -1, so the vectors are close to being opposite
|
||||
// The angle of rotation is going to be Pi, but around which axis?
|
||||
// Basically, any one perpendicular to vec1 = (x,y,z) is going to work.
|
||||
// Choose a vector to cross product vec1 with. Find the biggest
|
||||
// in magnitude of x, y and z and then put a zero in that position.
|
||||
float biggest = fabs(vec1[0]); int bigposn = 0;
|
||||
if ( fabs(vec1[1]) > biggest ) { biggest=fabs(vec1[1]); bigposn = 1; }
|
||||
if ( fabs(vec1[2]) > biggest ) { biggest=fabs(vec1[2]); bigposn = 2; }
|
||||
Vec3 temp = Vec3( 1.0, 1.0, 1.0 );
|
||||
temp[bigposn] = 0.0;
|
||||
Vec3 axis = vec1^temp; // this is a cross-product to generate the
|
||||
// axis around which to rotate
|
||||
makeRot( (float)M_PI, axis );
|
||||
// cosangle is close to -1, so the vectors are close to being opposite
|
||||
// The angle of rotation is going to be Pi, but around which axis?
|
||||
// Basically, any one perpendicular to vec1 = (x,y,z) is going to work.
|
||||
// Choose a vector to cross product vec1 with. Find the biggest
|
||||
// in magnitude of x, y and z and then put a zero in that position.
|
||||
float biggest = fabs(vec1[0]); int bigposn = 0;
|
||||
if ( fabs(vec1[1]) > biggest ) { biggest=fabs(vec1[1]); bigposn = 1; }
|
||||
if ( fabs(vec1[2]) > biggest ) { biggest=fabs(vec1[2]); bigposn = 2; }
|
||||
Vec3 temp = Vec3( 1.0, 1.0, 1.0 );
|
||||
temp[bigposn] = 0.0;
|
||||
Vec3 axis = vec1^temp; // this is a cross-product to generate the
|
||||
// axis around which to rotate
|
||||
makeRot( (float)M_PI, axis );
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the usual situation - take a cross-product of vec1 and vec2
|
||||
// and that is the axis around which to rotate.
|
||||
Vec3 axis = vec1^vec2;
|
||||
float angle = acos( cosangle );
|
||||
makeRot( angle, axis );
|
||||
// This is the usual situation - take a cross-product of vec1 and vec2
|
||||
// and that is the axis around which to rotate.
|
||||
Vec3 axis = vec1^vec2;
|
||||
float angle = acos( cosangle );
|
||||
makeRot( angle, axis );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,10 +100,12 @@ void Quat::getRot( float& angle, Vec3& vec ) const
|
||||
/// if ( abs(coshalfangle) > 1.0 ) { error };
|
||||
|
||||
// *angle = atan2( sinhalfangle, coshalfangle ); // see man atan2
|
||||
angle = 2 * atan2( sinhalfangle, _fv[3] ); // -pi < angle < pi
|
||||
// -pi < angle < pi
|
||||
angle = 2 * atan2( sinhalfangle, _fv[3] );
|
||||
vec = Vec3(_fv[0], _fv[1], _fv[2]) / sinhalfangle;
|
||||
}
|
||||
|
||||
|
||||
void Quat::getRot( float& angle, float& x, float& y, float& z ) const
|
||||
{
|
||||
float sinhalfangle = sqrt( _fv[0]*_fv[0] + _fv[1]*_fv[1] + _fv[2]*_fv[2] );
|
||||
@@ -137,34 +127,34 @@ void Quat::slerp( const float t, const Quat& from, const Quat& to )
|
||||
const double epsilon = 0.00001;
|
||||
double omega, cosomega, sinomega, scale_from, scale_to ;
|
||||
|
||||
cosomega = from.asVec4() * to.asVec4() ; // this is a dot product
|
||||
// this is a dot product
|
||||
cosomega = from.asVec4() * to.asVec4() ;
|
||||
|
||||
if( (1.0 - cosomega) > epsilon )
|
||||
{
|
||||
omega= acos(cosomega) ; // 0 <= omega <= Pi (see man acos)
|
||||
sinomega = sin(omega) ; // this sinomega should always be +ve so
|
||||
// could try sinomega=sqrt(1-cosomega*cosomega) to avoid a sin()?
|
||||
scale_from = sin((1.0-t)*omega)/sinomega ;
|
||||
scale_to = sin(t*omega)/sinomega ;
|
||||
omega= acos(cosomega) ; // 0 <= omega <= Pi (see man acos)
|
||||
sinomega = sin(omega) ; // this sinomega should always be +ve so
|
||||
// could try sinomega=sqrt(1-cosomega*cosomega) to avoid a sin()?
|
||||
scale_from = sin((1.0-t)*omega)/sinomega ;
|
||||
scale_to = sin(t*omega)/sinomega ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* --------------------------------------------------
|
||||
The ends of the vectors are very close
|
||||
we can use simple linear interpolation - no need
|
||||
to worry about the "spherical" interpolation
|
||||
-------------------------------------------------- */
|
||||
scale_from = 1.0 - t ;
|
||||
scale_to = t ;
|
||||
/* --------------------------------------------------
|
||||
The ends of the vectors are very close
|
||||
we can use simple linear interpolation - no need
|
||||
to worry about the "spherical" interpolation
|
||||
-------------------------------------------------- */
|
||||
scale_from = 1.0 - t ;
|
||||
scale_to = t ;
|
||||
}
|
||||
|
||||
_fv = (from._fv*scale_from) + (to._fv*scale_to); // use Vec4 arithmetic
|
||||
// so that we get a Vec4
|
||||
// use Vec4 arithmetic
|
||||
_fv = (from._fv*scale_from) + (to._fv*scale_to);
|
||||
// so that we get a Vec4
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define QX _fv[0]
|
||||
#define QY _fv[1]
|
||||
#define QZ _fv[2]
|
||||
@@ -173,7 +163,7 @@ void Quat::slerp( const float t, const Quat& from, const Quat& to )
|
||||
void Quat::set( const Matrix& m )
|
||||
{
|
||||
// Source: Gamasutra, Rotating Objects Using Quaternions
|
||||
//
|
||||
//
|
||||
//http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
|
||||
float tr, s;
|
||||
@@ -196,7 +186,7 @@ void Quat::set( const Matrix& m )
|
||||
}
|
||||
else
|
||||
{
|
||||
// diagonal is negative
|
||||
// diagonal is negative
|
||||
i = 0;
|
||||
if (m._mat[1][1] > m._mat[0][0])
|
||||
i = 1;
|
||||
@@ -224,11 +214,10 @@ void Quat::set( const Matrix& m )
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Quat::get( Matrix& m ) const
|
||||
{
|
||||
// Source: Gamasutra, Rotating Objects Using Quaternions
|
||||
//
|
||||
//
|
||||
//http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
|
||||
float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
|
||||
|
||||
@@ -1,87 +1,41 @@
|
||||
#include "osg/Switch"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Switch> g_SwitchProxy;
|
||||
|
||||
/**
|
||||
* Switch constructor. The default setting of _value is
|
||||
* ALL_CHILDREN_OFF.
|
||||
*/
|
||||
Switch::Switch()
|
||||
{
|
||||
_value = ALL_CHILDREN_OFF;
|
||||
}
|
||||
|
||||
|
||||
void Switch::traverse(NodeVisitor& nv)
|
||||
{
|
||||
switch(nv.getTraverseMode())
|
||||
switch(nv.getTraversalMode())
|
||||
{
|
||||
case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
|
||||
switch(_value)
|
||||
{
|
||||
case(ALL_CHILDREN_ON):
|
||||
case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
case(ALL_CHILDREN_OFF):
|
||||
return;
|
||||
default:
|
||||
if (_value>=0 && (unsigned int)_value<_children.size()) _children[_value]->accept(nv);
|
||||
case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
|
||||
switch(_value)
|
||||
{
|
||||
case(ALL_CHILDREN_ON):
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
case(ALL_CHILDREN_OFF):
|
||||
return;
|
||||
default:
|
||||
if (_value>=0 && (unsigned int)_value<_children.size()) _children[_value]->accept(nv);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Switch::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr.matchSequence("value"))
|
||||
{
|
||||
if (fr[1].matchWord("ALL_CHILDREN_ON"))
|
||||
{
|
||||
_value = ALL_CHILDREN_ON;
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
else if (fr[1].matchWord("ALL_CHILDREN_ON"))
|
||||
{
|
||||
_value = ALL_CHILDREN_OFF;
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
else if (fr[1].isInt())
|
||||
{
|
||||
fr[1].getInt(_value);
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
}
|
||||
|
||||
if (Group::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
bool Switch::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "value ";
|
||||
switch(_value)
|
||||
{
|
||||
case(ALL_CHILDREN_ON): fw<<"ALL_CHILDREN_ON"<<endl;break;
|
||||
case(ALL_CHILDREN_OFF): fw<<"ALL_CHILDREN_OFF"<<endl;break;
|
||||
default: fw<<_value<<endl;break;
|
||||
}
|
||||
|
||||
Group::writeLocalData(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,78 +1,28 @@
|
||||
#include "osg/TexEnv"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexEnv::TexEnv( void )
|
||||
TexEnv::TexEnv()
|
||||
{
|
||||
_mode = MODULATE;
|
||||
}
|
||||
|
||||
TexEnv::~TexEnv( void )
|
||||
|
||||
TexEnv::~TexEnv()
|
||||
{
|
||||
}
|
||||
|
||||
TexEnv* TexEnv::instance()
|
||||
{
|
||||
static ref_ptr<TexEnv> s_TexEnv(new TexEnv);
|
||||
return s_TexEnv.get();
|
||||
}
|
||||
|
||||
|
||||
void TexEnv::setMode( TexEnvMode mode )
|
||||
void TexEnv::setMode( const Mode mode )
|
||||
{
|
||||
_mode = (mode == DECAL ||
|
||||
mode == MODULATE ||
|
||||
mode == BLEND ) ?
|
||||
mode : MODULATE;
|
||||
mode == MODULATE ||
|
||||
mode == BLEND ||
|
||||
mode == REPLACE ) ?
|
||||
mode : MODULATE;
|
||||
}
|
||||
|
||||
void TexEnv::apply( void )
|
||||
|
||||
void TexEnv::apply(State&) const
|
||||
{
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, _mode);
|
||||
}
|
||||
|
||||
bool TexEnv::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
TexEnvMode mode;
|
||||
if (fr[0].matchWord("mode") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_mode = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool TexEnv::matchModeStr(const char* str,TexEnvMode& mode)
|
||||
{
|
||||
if (strcmp(str,"DECAL")==0) mode = DECAL;
|
||||
else if (strcmp(str,"MODULATE")==0) mode = MODULATE;
|
||||
else if (strcmp(str,"BLEND")==0) mode = BLEND;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* TexEnv::getModeStr(TexEnvMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(DECAL): return "DECAL";
|
||||
case(MODULATE): return "MODULATE";
|
||||
case(BLEND): return "BLEND";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool TexEnv::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "mode " << getModeStr(_mode) << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,89 +1,92 @@
|
||||
|
||||
#include "osg/TexGen"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexGen::TexGen( void )
|
||||
TexGen::TexGen()
|
||||
{
|
||||
_mode = OBJECT_LINEAR;
|
||||
_plane_s.set(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
_plane_t.set(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
_plane_r.set(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
_plane_q.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
TexGen::~TexGen( void )
|
||||
TexGen::~TexGen()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TexGen* TexGen::instance()
|
||||
void TexGen::setPlane(const Coord which, const Vec4& plane)
|
||||
{
|
||||
static ref_ptr<TexGen> s_texgen(new TexGen);
|
||||
return s_texgen.get();
|
||||
}
|
||||
|
||||
|
||||
bool TexGen::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
TexGenMode mode;
|
||||
if (fr[0].matchWord("mode") && matchModeStr(fr[1].getStr(),mode))
|
||||
switch( which )
|
||||
{
|
||||
_mode = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
case S : _plane_s = plane; break;
|
||||
case T : _plane_t = plane; break;
|
||||
case R : _plane_r = plane; break;
|
||||
case Q : _plane_q = plane; break;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed TexGen::setPlane("<<(unsigned int)which<<","<<plane<<")"<<endl; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Vec4& TexGen::getPlane(const Coord which) const
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case S : return _plane_s;
|
||||
case T : return _plane_t;
|
||||
case R : return _plane_r;
|
||||
case Q : return _plane_q;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<endl; return _plane_r;
|
||||
}
|
||||
}
|
||||
|
||||
void TexGen::apply(State&) const
|
||||
{
|
||||
|
||||
if (_mode == OBJECT_LINEAR)
|
||||
{
|
||||
glTexGenfv(GL_S, GL_OBJECT_PLANE, _plane_s.ptr());
|
||||
glTexGenfv(GL_T, GL_OBJECT_PLANE, _plane_t.ptr());
|
||||
glTexGenfv(GL_R, GL_OBJECT_PLANE, _plane_r.ptr());
|
||||
glTexGenfv(GL_Q, GL_OBJECT_PLANE, _plane_q.ptr());
|
||||
|
||||
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
|
||||
|
||||
// note, R & Q will be disabled so R&Q settings won't
|
||||
// have an effect, see above comment in enable(). RO.
|
||||
|
||||
}
|
||||
else if (_mode == EYE_LINEAR)
|
||||
{
|
||||
glTexGenfv(GL_S, GL_EYE_PLANE, _plane_s.ptr());
|
||||
glTexGenfv(GL_T, GL_EYE_PLANE, _plane_t.ptr());
|
||||
glTexGenfv(GL_R, GL_EYE_PLANE, _plane_r.ptr());
|
||||
glTexGenfv(GL_Q, GL_EYE_PLANE, _plane_q.ptr());
|
||||
|
||||
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
|
||||
|
||||
// note, R & Q will be disabled so R&Q settings won't
|
||||
// have an effect, see above comment in enable(). RO.
|
||||
|
||||
}
|
||||
else // SPHERE_MAP
|
||||
{
|
||||
// We ignore the planes if we are not in OBJECT_ or EYE_LINEAR mode.
|
||||
|
||||
// Also don't set the mode of GL_R & GL_Q as these will generate
|
||||
// GL_INVALID_ENUM (See OpenGL Refrence Guide, glTexGEn.)
|
||||
|
||||
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool TexGen::matchModeStr(const char* str,TexGenMode& mode)
|
||||
{
|
||||
if (strcmp(str,"EYE_LINEAR")==0) mode = EYE_LINEAR;
|
||||
else if (strcmp(str,"OBJECT_LINEAR")==0) mode = OBJECT_LINEAR;
|
||||
else if (strcmp(str,"SPHERE_MAP")==0) mode = SPHERE_MAP;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* TexGen::getModeStr(TexGenMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(EYE_LINEAR): return "EYE_LINEAR";
|
||||
case(OBJECT_LINEAR): return "OBJECT_LINEAR";
|
||||
case(SPHERE_MAP): return "SPHERE_MAP";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool TexGen::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "mode " << getModeStr(_mode) << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TexGen::enable( void )
|
||||
{
|
||||
glEnable( GL_TEXTURE_GEN_S );
|
||||
glEnable( GL_TEXTURE_GEN_T );
|
||||
}
|
||||
|
||||
|
||||
void TexGen::disable( void )
|
||||
{
|
||||
glDisable( GL_TEXTURE_GEN_S );
|
||||
glDisable( GL_TEXTURE_GEN_T );
|
||||
}
|
||||
|
||||
|
||||
void TexGen::apply( void )
|
||||
{
|
||||
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
|
||||
}
|
||||
|
||||
@@ -3,23 +3,17 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexMat::TexMat( void )
|
||||
TexMat::TexMat()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TexMat::~TexMat( void )
|
||||
TexMat::~TexMat()
|
||||
{
|
||||
}
|
||||
|
||||
TexMat* TexMat::instance()
|
||||
{
|
||||
static ref_ptr<TexMat> s_texmat(new TexMat);
|
||||
return s_texmat.get();
|
||||
}
|
||||
|
||||
void TexMat::apply( void )
|
||||
void TexMat::apply(State&) const
|
||||
{
|
||||
glMatrixMode( GL_TEXTURE );
|
||||
glLoadMatrixf( (GLfloat *)_mat );
|
||||
glLoadMatrixf( (GLfloat *)_matrix._mat );
|
||||
}
|
||||
|
||||
@@ -1,161 +1,72 @@
|
||||
#include "osg/Texture"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Image"
|
||||
#include "osg/Referenced"
|
||||
#include "osg/Notify"
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Image>
|
||||
#include <osg/Texture>
|
||||
#include <osg/State>
|
||||
#include <osg/Notify>
|
||||
#include <osg/GLExtensions>
|
||||
|
||||
#include <GL/glu.h>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
Texture::DeletedTextureObjectCache Texture::s_deletedTextureObjectCache;
|
||||
|
||||
Texture::Texture()
|
||||
{
|
||||
_handle = 0;
|
||||
_textureUnit = 0;
|
||||
|
||||
_wrap_s = CLAMP;
|
||||
_wrap_t = CLAMP;
|
||||
_wrap_r = CLAMP;
|
||||
_min_filter = NEAREST_MIPMAP_LINEAR;
|
||||
_mag_filter = LINEAR;
|
||||
//_min_filter = LINEAR_MIPMAP_LINEAR; // trilinear
|
||||
//_min_filter = LINEAR_MIPMAP_NEAREST; // bilinear
|
||||
_min_filter = NEAREST_MIPMAP_LINEAR; // OpenGL default
|
||||
_mag_filter = LINEAR;
|
||||
|
||||
_internalFormatMode = USE_IMAGE_DATA_FORMAT;
|
||||
_internalFormatValue = 0;
|
||||
|
||||
_textureWidth = _textureHeight = 0;
|
||||
|
||||
_textureObjectSize = 0;
|
||||
|
||||
_subloadMode = OFF;
|
||||
_subloadOffsX = _subloadOffsY = 0;
|
||||
}
|
||||
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
if (_handle!=0) glDeleteTextures( 1, &_handle );
|
||||
}
|
||||
|
||||
|
||||
Texture* Texture::instance()
|
||||
{
|
||||
static ref_ptr<Texture> s_texture(new Texture);
|
||||
return s_texture.get();
|
||||
}
|
||||
|
||||
|
||||
bool Texture::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (fr[0].matchWord("file") && fr[1].isString())
|
||||
{
|
||||
_image = fr.readImage(fr[1].getStr());
|
||||
fr += 2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
WrapMode wrap;
|
||||
if (fr[0].matchWord("wrap_s") && matchWrapStr(fr[1].getStr(),wrap))
|
||||
{
|
||||
_wrap_s = wrap;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("wrap_t") && matchWrapStr(fr[1].getStr(),wrap))
|
||||
{
|
||||
_wrap_t = wrap;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("wrap_r") && matchWrapStr(fr[1].getStr(),wrap))
|
||||
{
|
||||
_wrap_r = wrap;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
FilterMode filter;
|
||||
if (fr[0].matchWord("min_filter") && matchFilterStr(fr[1].getStr(),filter))
|
||||
{
|
||||
_min_filter = filter;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("mag_filter") && matchFilterStr(fr[1].getStr(),filter))
|
||||
{
|
||||
_mag_filter = filter;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Texture::writeLocalData(Output& fw)
|
||||
{
|
||||
if (_image.valid())
|
||||
{
|
||||
fw.indent() << "file \""<<_image->getFileName()<<"\""<<endl;
|
||||
}
|
||||
|
||||
fw.indent() << "wrap_s " << getWrapStr(_wrap_s) << endl;
|
||||
fw.indent() << "wrap_t " << getWrapStr(_wrap_t) << endl;
|
||||
fw.indent() << "wrap_r " << getWrapStr(_wrap_r) << endl;
|
||||
|
||||
fw.indent() << "min_filter " << getFilterStr(_min_filter) << endl;
|
||||
fw.indent() << "mag_filter " << getFilterStr(_mag_filter) << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Texture::matchWrapStr(const char* str,WrapMode& wrap)
|
||||
{
|
||||
if (strcmp(str,"CLAMP")==0) wrap = CLAMP;
|
||||
else if (strcmp(str,"REPEAT")==0) wrap = REPEAT;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* Texture::getWrapStr(WrapMode wrap)
|
||||
{
|
||||
switch(wrap)
|
||||
{
|
||||
case(CLAMP): return "CLAMP";
|
||||
case(REPEAT): return "REPEAT";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool Texture::matchFilterStr(const char* str,FilterMode& filter)
|
||||
{
|
||||
if (strcmp(str,"NEAREST")==0) filter = NEAREST;
|
||||
else if (strcmp(str,"LINEAR")==0) filter = LINEAR;
|
||||
else if (strcmp(str,"NEAREST_MIPMAP_NEAREST")==0) filter = NEAREST_MIPMAP_NEAREST;
|
||||
else if (strcmp(str,"LINEAR_MIPMAP_NEAREST")==0) filter = LINEAR_MIPMAP_NEAREST;
|
||||
else if (strcmp(str,"NEAREST_MIPMAP_LINEAR")==0) filter = NEAREST_MIPMAP_LINEAR;
|
||||
else if (strcmp(str,"LINEAR_MIPMAP_LINEAR")==0) filter = LINEAR_MIPMAP_LINEAR;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* Texture::getFilterStr(FilterMode filter)
|
||||
{
|
||||
switch(filter)
|
||||
{
|
||||
case(NEAREST): return "NEAREST";
|
||||
case(LINEAR): return "LINEAR";
|
||||
case(NEAREST_MIPMAP_NEAREST): return "NEAREST_MIPMAP_NEAREST";
|
||||
case(LINEAR_MIPMAP_NEAREST): return "LINEAR_MIPMAP_NEAREST";
|
||||
case(NEAREST_MIPMAP_LINEAR): return "NEAREST_MIPMAP_LINEAR";
|
||||
case(LINEAR_MIPMAP_LINEAR): return "LINEAR_MIPMAP_LINEAR";
|
||||
}
|
||||
return "";
|
||||
// delete old texture objects.
|
||||
dirtyTextureObject();
|
||||
}
|
||||
|
||||
void Texture::setImage(Image* image)
|
||||
{
|
||||
if (_handle!=0) glDeleteTextures( 1, &_handle );
|
||||
_handle = 0;
|
||||
_image = image;
|
||||
// delete old texture objects.
|
||||
for(TextureNameList::iterator itr=_handleList.begin();
|
||||
itr!=_handleList.end();
|
||||
++itr)
|
||||
{
|
||||
if (*itr != 0)
|
||||
{
|
||||
// contact global texture object handler to delete texture objects
|
||||
// in appropriate context.
|
||||
// glDeleteTextures( 1L, (const GLuint *)itr );
|
||||
*itr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_image = image;
|
||||
}
|
||||
|
||||
void Texture::setWrap(WrapParameter which, WrapMode wrap)
|
||||
|
||||
void Texture::setWrap(const WrapParameter which, const WrapMode wrap)
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
@@ -166,7 +77,8 @@ void Texture::setWrap(WrapParameter which, WrapMode wrap)
|
||||
}
|
||||
}
|
||||
|
||||
Texture::WrapMode Texture::getWrap(WrapParameter which) const
|
||||
|
||||
const Texture::WrapMode Texture::getWrap(const WrapParameter which) const
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
@@ -178,7 +90,7 @@ Texture::WrapMode Texture::getWrap(WrapParameter which) const
|
||||
}
|
||||
|
||||
|
||||
void Texture::setFilter(FilterParameter which, FilterMode filter)
|
||||
void Texture::setFilter(const FilterParameter which, const FilterMode filter)
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
@@ -189,7 +101,7 @@ void Texture::setFilter(FilterParameter which, FilterMode filter)
|
||||
}
|
||||
|
||||
|
||||
Texture::FilterMode Texture::getFilter(FilterParameter which) const
|
||||
const Texture::FilterMode Texture::getFilter(const FilterParameter which) const
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
@@ -199,59 +111,424 @@ Texture::FilterMode Texture::getFilter(FilterParameter which) const
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::enable( void )
|
||||
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
|
||||
void Texture::dirtyTextureObject()
|
||||
{
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
|
||||
void Texture::disable( void )
|
||||
{
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
|
||||
void Texture::apply( void )
|
||||
{
|
||||
if(_handle!=0)
|
||||
for(uint i=0;i<_handleList.size();++i)
|
||||
{
|
||||
glBindTexture( GL_TEXTURE_2D, _handle );
|
||||
if (_handleList[i] != 0)
|
||||
{
|
||||
Texture::deleteTextureObject(i,_handleList[i]);
|
||||
_handleList[i] = 0;
|
||||
}
|
||||
}
|
||||
else if (_image.valid())
|
||||
}
|
||||
|
||||
void Texture::apply(State& state) const
|
||||
{
|
||||
|
||||
// get the contextID (user defined ID of 0 upwards) for the
|
||||
// current OpenGL context.
|
||||
const uint contextID = state.getContextID();
|
||||
|
||||
// get the globj for the current contextID.
|
||||
uint& handle = getHandle(contextID);
|
||||
|
||||
// For multi-texturing will need something like...
|
||||
// glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB+_textureUnit));
|
||||
|
||||
if (handle != 0)
|
||||
{
|
||||
if (_subloadMode == OFF)
|
||||
{
|
||||
glBindTexture( GL_TEXTURE_2D, handle );
|
||||
}
|
||||
else if (_image.valid() && _image->data())
|
||||
{
|
||||
// pad out the modified tag list, if required.
|
||||
while (_modifiedTag.size() <= contextID)
|
||||
_modifiedTag.push_back(0);
|
||||
|
||||
if (_subloadMode == AUTO ||
|
||||
(_subloadMode == IF_DIRTY && _modifiedTag[contextID] != _image->getModifiedTag()))
|
||||
{
|
||||
glBindTexture( GL_TEXTURE_2D, handle );
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
_subloadOffsX, _subloadOffsY,
|
||||
_image->s(), _image->t(),
|
||||
(GLenum) _image->pixelFormat(), (GLenum) _image->dataType(),
|
||||
_image->data());
|
||||
// update the modified flag to show that the image has been loaded.
|
||||
_modifiedTag[contextID] = _image->getModifiedTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
glGenTextures( 1L, (GLuint *)&handle );
|
||||
glBindTexture( GL_TEXTURE_2D, handle );
|
||||
|
||||
applyImmediateMode(state);
|
||||
|
||||
// in theory the following line is redundent, but in practice
|
||||
// have found that the first frame drawn doesn't apply the textures
|
||||
// unless a second bind is called?!!
|
||||
// perhaps it is the first glBind which is not required...
|
||||
glBindTexture( GL_TEXTURE_2D, handle );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::compile(State& state) const
|
||||
{
|
||||
apply(state);
|
||||
}
|
||||
|
||||
|
||||
void Texture::applyImmediateMode(State& state) const
|
||||
{
|
||||
// if we don't have a valid image we can't create a texture!
|
||||
if (!_image.valid() || !_image->data())
|
||||
return;
|
||||
|
||||
// get the contextID (user defined ID of 0 upwards) for the
|
||||
// current OpenGL context.
|
||||
const uint contextID = state.getContextID();
|
||||
|
||||
// pad out the modified tag list, if required.
|
||||
while (_modifiedTag.size() <= contextID)
|
||||
_modifiedTag.push_back(0);
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
_modifiedTag[contextID] = _image->getModifiedTag();
|
||||
|
||||
|
||||
if (_subloadMode == OFF)
|
||||
_image->ensureDimensionsArePowerOfTwo();
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,_image->packing());
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,_image->packing());
|
||||
|
||||
glGenTextures( 1, &_handle );
|
||||
glBindTexture( GL_TEXTURE_2D, _handle );
|
||||
if (_wrap_s == MIRROR || _wrap_t == MIRROR)
|
||||
{
|
||||
static bool s_mirroredSupported = isGLExtensionSupported("GL_IBM_texture_mirrored_repeat");
|
||||
|
||||
// check for support of mirror-repeated textures
|
||||
// if not supported fall back to repeated textures
|
||||
WrapMode ws = _wrap_s, wt = _wrap_t;
|
||||
if (!s_mirroredSupported)
|
||||
{
|
||||
if (ws == MIRROR)
|
||||
ws = REPEAT;
|
||||
if (wt == MIRROR)
|
||||
wt = REPEAT;
|
||||
}
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ws );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wt );
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrap_s );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter);
|
||||
}
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter);
|
||||
|
||||
if (_mag_filter == ANISOTROPIC)
|
||||
{
|
||||
// check for support for anisotropic filter,
|
||||
// note since this is static varible it is intialised
|
||||
// only on the first time entering this code block,
|
||||
// is then never reevaluated on subsequent calls.
|
||||
static bool s_anisotropicSupported =
|
||||
isGLExtensionSupported("GL_EXT_texture_filter_anisotropic");
|
||||
|
||||
if (s_anisotropicSupported)
|
||||
{
|
||||
// note, GL_TEXTURE_MAX_ANISOTROPY_EXT will either be defined
|
||||
// by gl.h (or via glext.h) or by include/osg/Texture.
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, LINEAR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter);
|
||||
}
|
||||
|
||||
|
||||
static bool s_ARB_Compression = isGLExtensionSupported("GL_ARB_texture_compression");
|
||||
static bool s_S3TC_Compression = isGLExtensionSupported("GL_EXT_texture_compression_s3tc");
|
||||
|
||||
// select the internalFormat required for the texture.
|
||||
int internalFormat = _image->internalFormat();
|
||||
switch(_internalFormatMode)
|
||||
{
|
||||
case(USE_IMAGE_DATA_FORMAT):
|
||||
internalFormat = _image->internalFormat();
|
||||
break;
|
||||
|
||||
case(USE_ARB_COMPRESSION):
|
||||
if (s_ARB_Compression)
|
||||
{
|
||||
switch(_image->pixelFormat())
|
||||
{
|
||||
case(1): internalFormat = GL_COMPRESSED_ALPHA_ARB; break;
|
||||
case(2): internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_ARB; break;
|
||||
case(3): internalFormat = GL_COMPRESSED_RGB_ARB; break;
|
||||
case(4): internalFormat = GL_COMPRESSED_RGBA_ARB; break;
|
||||
case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_ARB; break;
|
||||
case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_ARB; break;
|
||||
case(GL_ALPHA): internalFormat = GL_COMPRESSED_ALPHA_ARB; break;
|
||||
case(GL_LUMINANCE): internalFormat = GL_COMPRESSED_LUMINANCE_ARB; break;
|
||||
case(GL_LUMINANCE_ALPHA): internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_ARB; break;
|
||||
case(GL_INTENSITY): internalFormat = GL_COMPRESSED_INTENSITY_ARB; break;
|
||||
}
|
||||
}
|
||||
else internalFormat = _image->internalFormat();
|
||||
break;
|
||||
|
||||
case(USE_S3TC_DXT1_COMPRESSION):
|
||||
if (s_S3TC_Compression)
|
||||
{
|
||||
switch(_image->pixelFormat())
|
||||
{
|
||||
case(3): internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break;
|
||||
case(4): internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
|
||||
case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break;
|
||||
case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
|
||||
default: internalFormat = _image->internalFormat(); break;
|
||||
}
|
||||
}
|
||||
else internalFormat = _image->internalFormat();
|
||||
break;
|
||||
|
||||
case(USE_S3TC_DXT3_COMPRESSION):
|
||||
if (s_S3TC_Compression)
|
||||
{
|
||||
switch(_image->pixelFormat())
|
||||
{
|
||||
case(3):
|
||||
case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break;
|
||||
case(4):
|
||||
case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
|
||||
default: internalFormat = _image->internalFormat(); break;
|
||||
}
|
||||
}
|
||||
else internalFormat = _image->internalFormat();
|
||||
break;
|
||||
|
||||
case(USE_S3TC_DXT5_COMPRESSION):
|
||||
if (s_S3TC_Compression)
|
||||
{
|
||||
switch(_image->pixelFormat())
|
||||
{
|
||||
case(3):
|
||||
case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break;
|
||||
case(4):
|
||||
case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
|
||||
default: internalFormat = _image->internalFormat(); break;
|
||||
}
|
||||
}
|
||||
else internalFormat = _image->internalFormat();
|
||||
break;
|
||||
|
||||
case(USE_USER_DEFINED_FORMAT):
|
||||
internalFormat = _internalFormatValue;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (_subloadMode == OFF) {
|
||||
if( _min_filter == LINEAR || _min_filter == NEAREST )
|
||||
{
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, internalFormat,
|
||||
_image->s(), _image->t(), 0,
|
||||
(GLenum)_image->pixelFormat(),
|
||||
(GLenum)_image->dataType(),
|
||||
_image->data() );
|
||||
|
||||
// just estimate estimate it right now..
|
||||
// note, ignores texture compression..
|
||||
_textureObjectSize = _image->s()*_image->t()*4;
|
||||
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, _image->internalFormat(),
|
||||
_image->s(), _image->t(), 0,
|
||||
(GLenum)_image->pixelFormat(),
|
||||
(GLenum)_image->dataType(),
|
||||
_image->data() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
gluBuild2DMipmaps( GL_TEXTURE_2D, _image->internalFormat(),
|
||||
gluBuild2DMipmaps( GL_TEXTURE_2D, internalFormat,
|
||||
_image->s(),_image->t(),
|
||||
(GLenum)_image->pixelFormat(), (GLenum)_image->dataType(),
|
||||
_image->data() );
|
||||
|
||||
// just estimate size it right now..
|
||||
// crude x2 multiplier to account for minmap storage.
|
||||
// note, ignores texture compression..
|
||||
_textureObjectSize = _image->s()*_image->t()*4;
|
||||
|
||||
}
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, _handle );
|
||||
_textureWidth = _image->s();
|
||||
_textureHeight = _image->t();
|
||||
}
|
||||
else
|
||||
{
|
||||
static bool s_SGIS_GenMipmap = isGLExtensionSupported("GL_SGIS_generate_mipmap");
|
||||
|
||||
if (s_SGIS_GenMipmap && (_min_filter != LINEAR && _min_filter != NEAREST)) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
}
|
||||
|
||||
// calculate texture dimension
|
||||
_textureWidth = 1;
|
||||
for (; _textureWidth < (_subloadOffsX + _image->s()); _textureWidth <<= 1)
|
||||
;
|
||||
|
||||
_textureHeight = 1;
|
||||
for (; _textureHeight < (_subloadOffsY + _image->t()); _textureHeight <<= 1)
|
||||
;
|
||||
|
||||
// reserve appropriate texture memory
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat,
|
||||
_textureWidth, _textureHeight, 0,
|
||||
(GLenum) _image->pixelFormat(), (GLenum) _image->dataType(),
|
||||
NULL);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
_subloadOffsX, _subloadOffsY,
|
||||
_image->s(), _image->t(),
|
||||
(GLenum) _image->pixelFormat(), (GLenum) _image->dataType(),
|
||||
_image->data());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** use deleteTextureObject instead of glDeleteTextures to allow
|
||||
* OpenGL texture objects to cached until they can be deleted
|
||||
* by the OpenGL context in which they were created, specified
|
||||
* by contextID.*/
|
||||
void Texture::deleteTextureObject(uint contextID,uint handle)
|
||||
{
|
||||
if (handle!=0)
|
||||
{
|
||||
// insert the handle into the cache for the appropriate context.
|
||||
s_deletedTextureObjectCache[contextID].insert(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** flush all the cached display list which need to be deleted
|
||||
* in the OpenGL context related to contextID.*/
|
||||
void Texture::flushDeletedTextureObjects(uint contextID)
|
||||
{
|
||||
DeletedTextureObjectCache::iterator citr = s_deletedTextureObjectCache.find(contextID);
|
||||
if (citr!=s_deletedTextureObjectCache.end())
|
||||
{
|
||||
std::set<uint>& textureObjectSet = citr->second;
|
||||
for(std::set<uint>::iterator titr=textureObjectSet.begin();
|
||||
titr!=textureObjectSet.end();
|
||||
++titr)
|
||||
{
|
||||
glDeleteTextures( 1L, (const GLuint *)&(*titr ));
|
||||
}
|
||||
s_deletedTextureObjectCache.erase(citr);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::copyTexImage2D(State& state, int x, int y, int width, int height )
|
||||
{
|
||||
const uint contextID = state.getContextID();
|
||||
|
||||
// get the globj for the current contextID.
|
||||
uint& handle = getHandle(contextID);
|
||||
|
||||
if (handle)
|
||||
{
|
||||
if (width==(int)_textureWidth && height==(int)_textureHeight)
|
||||
{
|
||||
// we have a valid texture object which is the right size
|
||||
// so lets play clever and use copyTexSubImage2D instead.
|
||||
// this allows use to reuse the texture object and avoid
|
||||
// expensive memory allocations.
|
||||
copyTexSubImage2D(state,0 ,0, x, y, width, height);
|
||||
return;
|
||||
}
|
||||
// the relevent texture object is not of the right size so
|
||||
// needs to been deleted
|
||||
// remove previously bound textures.
|
||||
dirtyTextureObject();
|
||||
// note, dirtyTextureObject() dirties all the texture objects for
|
||||
// this texture, is this right? Perhaps we should dirty just the
|
||||
// one for this context. Note sure yet will leave till later.
|
||||
// RO July 2001.
|
||||
}
|
||||
|
||||
// For multi-texturing will need something like...
|
||||
// glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB+_textureUnit));
|
||||
|
||||
// remove any previously assigned images as these are nolonger valid.
|
||||
_image = NULL;
|
||||
|
||||
// switch off mip-mapping.
|
||||
_min_filter = LINEAR;
|
||||
_mag_filter = LINEAR;
|
||||
|
||||
// Get a new 2d texture handle.
|
||||
glGenTextures( 1, &handle );
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, handle );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrap_s );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter );
|
||||
// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, width, height, 0 );
|
||||
|
||||
|
||||
/* Redundant, delete later */
|
||||
// glBindTexture( GL_TEXTURE_2D, handle );
|
||||
|
||||
_textureWidth = width;
|
||||
_textureHeight = height;
|
||||
|
||||
// cout<<"copyTexImage2D x="<<x<<" y="<<y<<" w="<<width<<" h="<<height<<endl;
|
||||
|
||||
// inform state that this texture is the current one bound.
|
||||
state.have_applied(this);
|
||||
}
|
||||
|
||||
void Texture::copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, int y, int width, int height )
|
||||
{
|
||||
const uint contextID = state.getContextID();
|
||||
|
||||
// get the globj for the current contextID.
|
||||
uint& handle = getHandle(contextID);
|
||||
|
||||
if (handle)
|
||||
{
|
||||
// we have a valid image
|
||||
glBindTexture( GL_TEXTURE_2D, handle );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrap_s );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter );
|
||||
// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, xoffset,yoffset, x, y, width, height);
|
||||
|
||||
/* Redundant, delete later */
|
||||
glBindTexture( GL_TEXTURE_2D, handle );
|
||||
|
||||
// inform state that this texture is the current one bound.
|
||||
state.have_applied(this);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// no texture object already exsits for this context so need to
|
||||
// create it upfront - simply call copyTexImage2D.
|
||||
copyTexImage2D(state,x,y,width,height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef macintosh
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#ifdef WIN32 // [
|
||||
#ifdef WIN32 // [
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
@@ -26,48 +28,71 @@ void Timer::init( void )
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
if( !inited ) init();
|
||||
if( !inited ) init();
|
||||
}
|
||||
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (((double)delta/cpu_mhz)*1e-6);
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (((double)delta/cpu_mhz)*1e-3);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0)/cpu_mhz);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0) * 1e3/cpu_mhz);
|
||||
}
|
||||
#endif // ]
|
||||
|
||||
#endif // ]
|
||||
#if defined(__linux) || defined(__FreeBSD__) // [
|
||||
|
||||
#ifdef __linux // [
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
# include <unistd.h>
|
||||
# if defined(__linux)
|
||||
# include <sys/mman.h>
|
||||
# elif defined(__FreeBSD__)
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
# endif
|
||||
|
||||
int Timer::inited = 0;
|
||||
double Timer::cpu_mhz = 0.0;
|
||||
|
||||
void Timer::init( void )
|
||||
{
|
||||
# if defined(__FreeBSD__)
|
||||
int cpuspeed;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(cpuspeed);
|
||||
if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &len, NULL, NULL) == -1) {
|
||||
perror("sysctlbyname(machdep.tsc_freq)");
|
||||
return;
|
||||
}
|
||||
cpu_mhz = cpuspeed / 1e6;
|
||||
|
||||
# elif defined(__linux)
|
||||
char buff[128];
|
||||
FILE *fp = fopen( "/proc/cpuinfo", "r" );
|
||||
|
||||
@@ -87,43 +112,48 @@ void Timer::init( void )
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
# endif
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
if( !inited ) init();
|
||||
if( !inited ) init();
|
||||
}
|
||||
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta/cpu_mhz*1e-6);
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta/cpu_mhz*1e-3);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0)/cpu_mhz);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0) * 1e3/cpu_mhz);
|
||||
}
|
||||
|
||||
#endif // ]
|
||||
#ifdef __sgi // [
|
||||
|
||||
#endif // ]
|
||||
#ifdef __sgi // [
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/syssgi.h>
|
||||
@@ -132,7 +162,6 @@ Timer_t Timer::delta_n( Timer_t t0, Timer_t t1 )
|
||||
|
||||
unsigned long Timer::dummy = 0;
|
||||
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
__psunsigned_t phys_addr, raddr;
|
||||
@@ -154,26 +183,66 @@ Timer::Timer( void )
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
iotimer_addr = (volatile unsigned long *)mmap(
|
||||
(void *)0L,
|
||||
(size_t)poffmask,
|
||||
(int)PROT_READ,
|
||||
(int)MAP_PRIVATE, fd, (off_t)raddr);
|
||||
(void *)0L,
|
||||
(size_t)poffmask,
|
||||
(int)PROT_READ,
|
||||
(int)MAP_PRIVATE, fd, (off_t)raddr);
|
||||
|
||||
iotimer_addr = (unsigned long *)(
|
||||
(__psunsigned_t)iotimer_addr + (phys_addr & poffmask)
|
||||
);
|
||||
|
||||
(__psunsigned_t)iotimer_addr + (phys_addr & poffmask)
|
||||
);
|
||||
|
||||
cycleCntrSize = syssgi( SGI_CYCLECNTR_SIZE );
|
||||
|
||||
if( cycleCntrSize > 32 )
|
||||
if( cycleCntrSize > 32 )
|
||||
++iotimer_addr;
|
||||
|
||||
clk = (unsigned long *)iotimer_addr;
|
||||
}
|
||||
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-6);
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-3);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (Timer_t)((double)delta * microseconds_per_click);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
unsigned long delta = t2 - t1;
|
||||
return (Timer_t )((double)delta * nanoseconds_per_click);
|
||||
}
|
||||
|
||||
#endif // ]
|
||||
|
||||
#ifdef macintosh // [
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
microseconds_per_click = (1.0 / (double) CLOCKS_PER_SEC) * 1e6;
|
||||
nanoseconds_per_click = (1.0 / (double) CLOCKS_PER_SEC) * 1e9;
|
||||
}
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
@@ -201,5 +270,4 @@ Timer_t Timer::delta_n( Timer_t t1, Timer_t t2 )
|
||||
unsigned long delta = t2 - t1;
|
||||
return (Timer_t )((double)delta * nanoseconds_per_click);
|
||||
}
|
||||
|
||||
#endif // ]
|
||||
#endif // ]
|
||||
|
||||