Added a bunch of files synched with 0.8.42

This commit is contained in:
Don BURNS
2001-09-19 21:08:56 +00:00
parent fed86f3f03
commit e8f256a59d
446 changed files with 58397 additions and 10552 deletions

View File

@@ -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

View 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;
}

View 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

View File

View 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

View 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

View 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;

View 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;
}

View 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
View 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;
}

View 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
View 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;
}

View 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;
}

View 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;
}

File diff suppressed because it is too large Load Diff

View 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;
}

View File

View 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

View 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;
}

View File

View 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

View 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;
}

View File

View 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

View 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.

View 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;
}

View File

View 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
View 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.

View 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;
}

View File

@@ -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

View File

@@ -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;
}

View File

27
src/Demos/wxsgv/Makefile Normal file
View 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

View 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);
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View 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"
};

View 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"
};

View 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"
};

View 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"
};

View 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"
};

View 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"
};

View 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"
};

View 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"
};

View 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"
};

View 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"
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View 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"
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

14
src/Demos/wxsgv/wxsgv.rc Normal file
View 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

Binary file not shown.

View 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

View 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

View File

@@ -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

View File

@@ -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 "";
}

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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())

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 );

File diff suppressed because it is too large Load Diff

View File

@@ -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 );
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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() );

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 );

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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...

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 );
}

View File

@@ -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 );
}

View File

@@ -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);
}
}

View File

@@ -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 // ]

Some files were not shown because too many files have changed in this diff Show More