Initial revision
This commit is contained in:
29
src/Demos/Makefile
Normal file
29
src/Demos/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
#!smake
|
||||
SHELL=/bin/sh
|
||||
|
||||
DIRS = sgv cube
|
||||
|
||||
all :
|
||||
for f in $(DIRS) ; do cd $$f; make ; cd ..; done
|
||||
|
||||
clean :
|
||||
for f in $(DIRS) ; do cd $$f; make clean; cd ..; done
|
||||
|
||||
clobber :
|
||||
for f in $(DIRS) ; do cd $$f; make clobber; cd ..; done
|
||||
|
||||
depend :
|
||||
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
|
||||
|
||||
install :
|
||||
for f in $(DIRS) ; do cd $$f; make install; cd ..; done
|
||||
|
||||
instlinks :
|
||||
for f in $(DIRS) ; do cd $$f; make instlinks; cd ..; done
|
||||
|
||||
instclean :
|
||||
for f in $(DIRS) ; do cd $$f; make instclean; cd ..; done
|
||||
0
src/Demos/cube/Makedepend
Normal file
0
src/Demos/cube/Makedepend
Normal file
15
src/Demos/cube/Makefile
Normal file
15
src/Demos/cube/Makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
#!smake
|
||||
include ../../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
cube.cpp
|
||||
|
||||
TARGET = ../../../bin/cube
|
||||
|
||||
TARGET_BIN_FILES = cube
|
||||
|
||||
LIBS = -losgGLUT -losgUtil -losg -lglut -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
C++FLAGS += -I../../../include
|
||||
LDFLAGS += -L../../../lib -L/usr/X11R6/lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
135
src/Demos/cube/cube.cpp
Normal file
135
src/Demos/cube/cube.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include "osgGLUT/Viewer"
|
||||
|
||||
#include "osg/Geode"
|
||||
#include "osg/GeoSet"
|
||||
#include "osg/GeoState"
|
||||
#include "osg/Material"
|
||||
#include "osg/Vec3"
|
||||
#include "osg/DCS"
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <math.h>
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Global variables - this is basically the stuff which will be animated
|
||||
// ----------------------------------------------------------------------
|
||||
osg::DCS* myDCS;
|
||||
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 DCS 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;
|
||||
myDCS->preTranslate( -lastdx, -lastdy, -lastdz );
|
||||
myDCS->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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
|
||||
// -------------------------------------------
|
||||
// Set up a new GeoSet which will be our cube
|
||||
// -------------------------------------------
|
||||
cube = new osg::GeoSet();
|
||||
|
||||
cube->setPrimType( osg::GeoSet::POLYGON );
|
||||
cube->setNumPrims( 6 ); // the six square faces
|
||||
|
||||
int cubeLengthList[6] = { 4, 4, 4, 4, 4, 4 }; // each has 4 vertices
|
||||
cube->setPrimLengths( cubeLengthList );
|
||||
|
||||
osg::Vec3 cubeCoords[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 a GeoState to make the cube red
|
||||
// ---------------------------------------
|
||||
osg::GeoState* cubeState = new osg::GeoState();
|
||||
osg::Material* redMaterial = new osg::Material();
|
||||
osg::Vec4 red( 1.0f, 0.0f, 0.0f, 0.0f );
|
||||
redMaterial->setEmission( osg::Material::FACE_FRONT_AND_BACK, red );
|
||||
redMaterial->setAmbient( osg::Material::FACE_FRONT_AND_BACK, red );
|
||||
redMaterial->setDiffuse( osg::Material::FACE_FRONT_AND_BACK, red );
|
||||
redMaterial->setSpecular( osg::Material::FACE_FRONT_AND_BACK, red );
|
||||
cubeState->setAttribute( osg::GeoState::MATERIAL, redMaterial );
|
||||
|
||||
cube->setGeoState( cubeState );
|
||||
|
||||
geode->addGeoSet( cube );
|
||||
|
||||
myDCS = new osg::DCS();
|
||||
myDCS->addChild( geode );
|
||||
|
||||
glutInit( &argc, argv );
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 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.init( myDCS );
|
||||
viewer.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
0
src/Demos/sgv/Makedepend
Normal file
0
src/Demos/sgv/Makedepend
Normal file
19
src/Demos/sgv/Makefile
Normal file
19
src/Demos/sgv/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
#!smake
|
||||
include ../../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
sgv.cpp
|
||||
|
||||
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
|
||||
|
||||
LIBS = -losgGLUT -losgUtil -losg -lglut -lGLU -lGL -lm -lXmu -lX11 -lXi
|
||||
C++FLAGS += -I../../../include
|
||||
LDFLAGS += -L../../../lib -L/usr/X11R6/lib
|
||||
|
||||
include ../../../Make/makerules
|
||||
118
src/Demos/sgv/sgv.cpp
Normal file
118
src/Demos/sgv/sgv.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "osg/OSG"
|
||||
#include "osg/Node"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Notify"
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include "osgGLUT/Viewer"
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
} else
|
||||
{
|
||||
osg::Node *node = osg::loadNodeFile( 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 )
|
||||
{
|
||||
|
||||
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);
|
||||
|
||||
osgGLUT::Viewer viewer;
|
||||
glutInit( &argc, argv );
|
||||
viewer.init( rootnode );
|
||||
viewer.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
36
src/Makefile
Normal file
36
src/Makefile
Normal file
@@ -0,0 +1,36 @@
|
||||
#!smake
|
||||
SHELL=/bin/sh
|
||||
|
||||
|
||||
DIRS = osg osgUtil osgGLUT Demos osgPlugins
|
||||
|
||||
all :
|
||||
for f in $(DIRS) ; do cd $$f; make ; cd ..; done
|
||||
|
||||
clean :
|
||||
for f in $(DIRS) ; do cd $$f; make clean; cd ..; done
|
||||
|
||||
clobber :
|
||||
for f in $(DIRS) ; do cd $$f; make clobber; cd ..; done
|
||||
|
||||
depend :
|
||||
for f in $(DIRS) ; do cd $$f; make depend; cd ..; done
|
||||
|
||||
docs :
|
||||
(cd osg; make docs;)
|
||||
(cd osgUtil; 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
|
||||
|
||||
|
||||
install :
|
||||
for f in $(DIRS) ; do cd $$f; make install; cd ..; done
|
||||
|
||||
instlinks :
|
||||
for f in $(DIRS) ; do cd $$f; make instlinks; cd ..; done
|
||||
|
||||
instclean :
|
||||
for f in $(DIRS) ; do cd $$f; make instclean; cd ..; done
|
||||
101
src/osg/AlphaFunc.cpp
Normal file
101
src/osg/AlphaFunc.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/AlphaFunc"
|
||||
#include "osg/Output"
|
||||
#include "osg/Input"
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
AlphaFunc::AlphaFunc()
|
||||
{
|
||||
_comparisonFunc = ALWAYS;
|
||||
_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()
|
||||
{
|
||||
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 "";
|
||||
}
|
||||
272
src/osg/Billboard.cpp
Normal file
272
src/osg/Billboard.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
#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;
|
||||
_axis.set(0.0f,0.0f,1.0f);
|
||||
}
|
||||
|
||||
|
||||
Billboard::~Billboard()
|
||||
{
|
||||
}
|
||||
|
||||
bool Billboard::addGeoSet(GeoSet *gset)
|
||||
{
|
||||
if (Geode::addGeoSet(gset))
|
||||
{
|
||||
Vec3 pos(0.0f,0.0f,0.0f);
|
||||
while (_positionList.size()<_geosets.size())
|
||||
{
|
||||
_positionList.push_back(pos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Billboard::addGeoSet(GeoSet *gset,const Vec3& pos)
|
||||
{
|
||||
if (Geode::addGeoSet(gset))
|
||||
{
|
||||
while (_positionList.size()<_geosets.size())
|
||||
{
|
||||
_positionList.push_back(pos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Billboard::removeGeoSet( GeoSet *gset )
|
||||
{
|
||||
PositionList::iterator pitr = _positionList.begin();
|
||||
for (GeoSetList::iterator itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr,++pitr)
|
||||
{
|
||||
if (itr->get()==gset)
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing gset's reference count.
|
||||
_geosets.erase(itr);
|
||||
_positionList.erase(pitr);
|
||||
_bsphere_computed = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Billboard::calcRotation(const Vec3& eye_local, const Vec3& pos_local,Matrix& mat)
|
||||
{
|
||||
switch(_mode)
|
||||
{
|
||||
case(AXIAL_ROT):
|
||||
{
|
||||
Vec3 ev = pos_local-eye_local;
|
||||
ev.z() = 0.0f;
|
||||
float ev_length = ev.length();
|
||||
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;
|
||||
float c = ev.y()*inv;
|
||||
float s = ev.x()*inv;
|
||||
mat._mat[0][0] = c;
|
||||
mat._mat[0][1] = -s;
|
||||
mat._mat[1][0] = s;
|
||||
mat._mat[1][1] = c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(POINT_ROT_WORLD):
|
||||
case(POINT_ROT_EYE):
|
||||
{
|
||||
Vec3 ev = pos_local-eye_local;
|
||||
ev.normalize();
|
||||
|
||||
float ev_len = ev.length();
|
||||
if (ev_len != 0.0f)
|
||||
{
|
||||
ev /= ev_len;
|
||||
|
||||
Vec3 cp = ev^Vec3(0.0f,1.0f,0.0f);
|
||||
float dot = ev*Vec3(0.0f,1.0f,0.0f);
|
||||
|
||||
float cp_len = cp.length();
|
||||
if (cp_len != 0.0f)
|
||||
{
|
||||
cp /= cp_len;
|
||||
|
||||
float rotation_cp = acosf(dot);
|
||||
mat.makeRot(rotation_cp*180.0f/M_PI,cp[0],cp[1],cp[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Billboard::calcTransform(const Vec3& eye_local, const Vec3& pos_local,Matrix& mat)
|
||||
{
|
||||
// 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._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 )
|
||||
{
|
||||
int i;
|
||||
int ngsets = _geosets.size();
|
||||
|
||||
if( ngsets == 0 ) return false;
|
||||
|
||||
_bsphere._center.set(0.0f,0.0f,0.0f);
|
||||
|
||||
for( i = 0; i < ngsets; i++ )
|
||||
{
|
||||
GeoSet *gset = _geosets[i].get();
|
||||
const BoundingBox& bbox = gset->getBound();
|
||||
|
||||
_bsphere._center += bbox.center();
|
||||
_bsphere._center += _positionList[i];
|
||||
}
|
||||
|
||||
_bsphere._center /= (float)(ngsets);
|
||||
|
||||
float maxd = 0.0;
|
||||
for( i = 0; i < ngsets; ++i )
|
||||
{
|
||||
GeoSet *gset = _geosets[i].get();
|
||||
const BoundingBox& bbox = gset->getBound();
|
||||
Vec3 local_center = _bsphere._center-_positionList[i];
|
||||
for(unsigned int c=0;c<8;++c)
|
||||
{
|
||||
float d = (bbox.corner(c)-local_center).length2();
|
||||
if( d > maxd ) maxd = d;
|
||||
}
|
||||
}
|
||||
_bsphere._radius = sqrtf(maxd);
|
||||
|
||||
_bsphere_computed=true;
|
||||
|
||||
return true;
|
||||
}
|
||||
44
src/osg/BoundingBox.cpp
Normal file
44
src/osg/BoundingBox.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "osg/BoundingBox"
|
||||
#include "osg/BoundingSphere"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
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;
|
||||
}
|
||||
81
src/osg/BoundingSphere.cpp
Normal file
81
src/osg/BoundingSphere.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "osg/BoundingSphere"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
void BoundingSphere::expandBy(const Vec3& v)
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
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
|
||||
{
|
||||
_center = v;
|
||||
_radius = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BoundingSphere::expandRadiusBy(const Vec3& v)
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
float r = (v-_center).length();
|
||||
if (r>_radius) _radius = r;
|
||||
// else do nothing as vertex is within sphere.
|
||||
}
|
||||
else
|
||||
{
|
||||
_center = v;
|
||||
_radius = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BoundingSphere::expandBy(const BoundingSphere& sh)
|
||||
{
|
||||
if (sh.isValid())
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
Vec3 dv = sh._center-_center;
|
||||
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
|
||||
{
|
||||
_center = sh._center;
|
||||
_radius = sh._radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
void BoundingSphere::expandRadiusBy(const BoundingSphere& sh)
|
||||
{
|
||||
if (sh.isValid())
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
float r = (sh._center-_center).length()+sh._radius;
|
||||
if (r>_radius) _radius = r;
|
||||
// else do nothing as vertex is within sphere.
|
||||
}
|
||||
else
|
||||
{
|
||||
_center = sh._center;
|
||||
_radius = sh._radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
85
src/osg/Camera.cpp
Normal file
85
src/osg/Camera.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "osg/GL"
|
||||
#include <osg/Camera>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
_fovy = 60.0;
|
||||
_aspectRatio = 1.0;
|
||||
home();
|
||||
}
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Camera::setView(osg::Vec3 eyePoint, osg::Vec3 lookPoint, osg::Vec3 upVector)
|
||||
{
|
||||
// Should do some checking here!
|
||||
_eyePoint = eyePoint;
|
||||
_lookPoint = lookPoint;
|
||||
_upVector = 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::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::ensureOrthogonalUpVector()
|
||||
{
|
||||
Vec3 lv = _lookPoint-_eyePoint;
|
||||
Vec3 sv = lv^_upVector;
|
||||
_upVector = sv^lv;
|
||||
_upVector.normalize();
|
||||
}
|
||||
|
||||
void Camera::mult(const Camera& camera,const Matrix& m)
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
|
||||
void Camera::mult(const Matrix& m,const Camera& camera)
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
|
||||
80
src/osg/CullFace.cpp
Normal file
80
src/osg/CullFace.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/CullFace"
|
||||
#include "osg/Output"
|
||||
#include "osg/Input"
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
112
src/osg/DCS.cpp
Normal file
112
src/osg/DCS.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "osg/DCS"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<DCS> g_DCSProxy;
|
||||
|
||||
DCS::DCS()
|
||||
{
|
||||
_mat = new Matrix(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0 );
|
||||
|
||||
_mat->ref();
|
||||
}
|
||||
|
||||
|
||||
DCS::DCS(const Matrix& mat )
|
||||
{
|
||||
_mat = new Matrix(mat);
|
||||
_mat->ref();
|
||||
}
|
||||
|
||||
|
||||
DCS::~DCS()
|
||||
{
|
||||
_mat->unref();
|
||||
}
|
||||
|
||||
void DCS::setMatrix(const Matrix& mat )
|
||||
{
|
||||
*_mat = mat;
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
void DCS::preTranslate( float tx, float ty, float tz )
|
||||
{
|
||||
_mat->preTrans( tx, ty, tz );
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
void DCS::preRotate( float deg, float x, float y, float z )
|
||||
{
|
||||
_mat->preRot( deg, x, y, z );
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
bool DCS::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (Matrix* tmpMatrix = static_cast<Matrix*>(Matrix::instance()->readClone(fr)))
|
||||
{
|
||||
|
||||
if (_mat) _mat->unref();
|
||||
_mat = tmpMatrix;
|
||||
_mat->ref();
|
||||
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (Group::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool DCS::writeLocalData(Output& fw)
|
||||
{
|
||||
if (_mat) _mat->write(fw);
|
||||
|
||||
|
||||
return Group::writeLocalData(fw);
|
||||
}
|
||||
|
||||
bool DCS::computeBound( void )
|
||||
{
|
||||
if (!Group::computeBound()) return false;
|
||||
|
||||
Vec3 xdash = _bsphere._center;
|
||||
xdash.x() += _bsphere._radius;
|
||||
xdash = xdash*(*_mat);
|
||||
|
||||
Vec3 ydash = _bsphere._center;
|
||||
ydash.y() += _bsphere._radius;
|
||||
ydash = ydash*(*_mat);
|
||||
|
||||
Vec3 zdash = _bsphere._center;
|
||||
zdash.y() += _bsphere._radius;
|
||||
zdash = zdash*(*_mat);
|
||||
|
||||
_bsphere._center = _bsphere._center*(*_mat);
|
||||
|
||||
xdash -= _bsphere._center;
|
||||
float len_xdash = xdash.length();
|
||||
|
||||
ydash -= _bsphere._center;
|
||||
float len_ydash = ydash.length();
|
||||
|
||||
zdash -= _bsphere._center;
|
||||
float len_zdash = zdash.length();
|
||||
|
||||
_bsphere._radius = len_xdash;
|
||||
if (_bsphere._radius<len_ydash) _bsphere._radius = len_ydash;
|
||||
if (_bsphere._radius<len_zdash) _bsphere._radius = len_zdash;
|
||||
|
||||
return true;
|
||||
}
|
||||
66
src/osg/DynamicLibrary.cpp
Normal file
66
src/osg/DynamicLibrary.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifdef WIN32
|
||||
#include <Io.h>
|
||||
#include <Windows.h>
|
||||
#include <Winbase.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifndef OSG_USE_IO_DOT_H
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
#include "osg/DynamicLibrary"
|
||||
#include "osg/OSG"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
DynamicLibrary::DynamicLibrary(const std::string& name,HANDLE handle)
|
||||
{
|
||||
_name = name;
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
DynamicLibrary::~DynamicLibrary()
|
||||
{
|
||||
if (_handle)
|
||||
{
|
||||
#ifdef WIN32
|
||||
FreeLibrary((HMODULE)_handle);
|
||||
#else
|
||||
dlclose(_handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
DynamicLibrary* DynamicLibrary::loadLibrary(const std::string& libraryName)
|
||||
{
|
||||
|
||||
char* fullLibraryName = osg::findDSO( libraryName.c_str() );
|
||||
if (fullLibraryName==NULL) return NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
HANDLE handle = LoadLibrary( fullLibraryName );
|
||||
if (handle) return new DynamicLibrary(libraryName,handle);
|
||||
notify(WARN) << "DynamicLibrary::failed loading "<<fullLibraryName<<endl;
|
||||
#else
|
||||
HANDLE handle = dlopen( fullLibraryName, RTLD_LAZY );
|
||||
if (handle) return new DynamicLibrary(libraryName,handle);
|
||||
notify(WARN) << "DynamicLibrary::failed loading "<<fullLibraryName<<endl;
|
||||
notify(WARN) << "DynamicLibrary::error "<<dlerror()<<endl;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DynamicLibrary::PROC_ADDRESS DynamicLibrary::getProcAddress(const std::string& procName)
|
||||
{
|
||||
if (_handle==NULL) return NULL;
|
||||
#ifdef WIN32
|
||||
return GetProcAddress( (HMODULE)_handle, procName.c_str() );
|
||||
#else
|
||||
return dlsym( _handle, procName.c_str() );
|
||||
#endif
|
||||
}
|
||||
45
src/osg/ExtensionSupported.cpp
Normal file
45
src/osg/ExtensionSupported.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/ExtensionSupported"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// copied form glut_ext.c
|
||||
// to be rewritten... Robert Osfield, November 2000.
|
||||
bool osg::ExtensionSupported(const char *extension)
|
||||
{
|
||||
static const GLubyte *extensions = NULL;
|
||||
const GLubyte *start;
|
||||
GLubyte *where, *terminator;
|
||||
|
||||
/* Extension names should not have spaces. */
|
||||
where = (GLubyte *) strchr(extension, ' ');
|
||||
if (where || *extension == '\0')
|
||||
return 0;
|
||||
|
||||
if (!extensions) {
|
||||
extensions = glGetString(GL_EXTENSIONS);
|
||||
}
|
||||
/* It takes a bit of care to be fool-proof about parsing the
|
||||
OpenGL extensions string. Don't be fooled by sub-strings,
|
||||
etc. */
|
||||
start = extensions;
|
||||
for (;;) {
|
||||
/* If your application crashes in the strstr routine below,
|
||||
you are probably calling glutExtensionSupported without
|
||||
having a current window. Calling glGetString without
|
||||
a current OpenGL context has unpredictable results.
|
||||
Please fix your program. */
|
||||
where = (GLubyte *) strstr((const char *) start, extension);
|
||||
if (!where)
|
||||
break;
|
||||
terminator = where + strlen(extension);
|
||||
if (where == start || *(where - 1) == ' ') {
|
||||
if (*terminator == ' ' || *terminator == '\0') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
start = terminator;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
422
src/osg/Field.cpp
Normal file
422
src/osg/Field.cpp
Normal file
@@ -0,0 +1,422 @@
|
||||
#include "osg/Field"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Field::Field()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
Field::Field(const Field& ic)
|
||||
{
|
||||
_copy(ic);
|
||||
}
|
||||
|
||||
|
||||
Field::~Field()
|
||||
{
|
||||
_free();
|
||||
}
|
||||
|
||||
|
||||
Field& Field::operator = (const Field& ic)
|
||||
{
|
||||
if (this==&ic) return *this;
|
||||
_free();
|
||||
_copy(ic);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Field::_free()
|
||||
{
|
||||
// free all data
|
||||
if (_fieldCache) delete [] _fieldCache;
|
||||
|
||||
_init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Field::_init()
|
||||
{
|
||||
|
||||
_fieldCacheCapacity = 256;
|
||||
_fieldCacheSize = 0;
|
||||
_fieldCache = NULL;
|
||||
|
||||
_fieldType = UNINTIALISED;
|
||||
|
||||
_withinQuotes = false;
|
||||
|
||||
_noNestedBrackets = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Field::_copy(const Field& ic)
|
||||
{
|
||||
|
||||
// copy string cache.
|
||||
if (ic._fieldCache)
|
||||
{
|
||||
_fieldCacheCapacity = ic._fieldCacheCapacity;
|
||||
_fieldCacheSize = ic._fieldCacheSize;
|
||||
_fieldCache = new char [_fieldCacheCapacity];
|
||||
strncpy(_fieldCache,ic._fieldCache,_fieldCacheCapacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fieldCacheCapacity = 0;
|
||||
_fieldCacheSize = 0;
|
||||
_fieldCache = NULL;
|
||||
}
|
||||
|
||||
_fieldType = ic._fieldType;
|
||||
|
||||
_withinQuotes = ic._withinQuotes;
|
||||
|
||||
_noNestedBrackets = ic._noNestedBrackets;
|
||||
}
|
||||
|
||||
|
||||
void Field::setWithinQuotes(bool withinQuotes)
|
||||
{
|
||||
_withinQuotes=withinQuotes;
|
||||
_fieldType = UNINTIALISED;
|
||||
}
|
||||
|
||||
|
||||
bool Field::getWithinQuotes()
|
||||
{
|
||||
return _withinQuotes;
|
||||
}
|
||||
|
||||
|
||||
void Field::setNoNestedBrackets(int no)
|
||||
{
|
||||
_noNestedBrackets=no;
|
||||
}
|
||||
|
||||
|
||||
int Field::getNoNestedBrackets()
|
||||
{
|
||||
return _noNestedBrackets;
|
||||
}
|
||||
|
||||
|
||||
const char* Field::getStr() const
|
||||
{
|
||||
if (_fieldCacheSize!=0) return _fieldCache;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
||||
char* Field::takeStr()
|
||||
{
|
||||
char* field = _fieldCache;
|
||||
|
||||
_fieldCache = NULL;
|
||||
_fieldCacheSize = 0;
|
||||
|
||||
_fieldType = UNINTIALISED;
|
||||
_withinQuotes = false;
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
void Field::reset()
|
||||
{
|
||||
_fieldCacheSize = 0;
|
||||
if (_fieldCache)
|
||||
{
|
||||
_fieldCache[_fieldCacheSize] = 0;
|
||||
}
|
||||
|
||||
_withinQuotes = false;
|
||||
_noNestedBrackets = 0;
|
||||
}
|
||||
|
||||
|
||||
void Field::addChar(char c)
|
||||
{
|
||||
if (_fieldCache==NULL)
|
||||
{
|
||||
if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE;
|
||||
_fieldCache = new char[_fieldCacheCapacity];
|
||||
_fieldCacheSize = 0;
|
||||
}
|
||||
else if (_fieldCacheSize>=_fieldCacheCapacity-1)
|
||||
{
|
||||
if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE;
|
||||
while (_fieldCacheSize>=_fieldCacheCapacity-1) _fieldCacheCapacity *= 2;
|
||||
char* tmp_str = _fieldCache;
|
||||
_fieldCache = new char[_fieldCacheCapacity];
|
||||
strncpy(_fieldCache,tmp_str,_fieldCacheSize);
|
||||
delete [] tmp_str;
|
||||
|
||||
}
|
||||
_fieldCache[_fieldCacheSize++] = c;
|
||||
_fieldCache[_fieldCacheSize] = 0;
|
||||
_fieldType = UNINTIALISED;
|
||||
}
|
||||
|
||||
|
||||
Field::FieldType Field::getFieldType() const
|
||||
{
|
||||
if (_fieldType==UNINTIALISED && _fieldCache)
|
||||
{
|
||||
_fieldType = calculateFieldType(_fieldCache,_withinQuotes);
|
||||
}
|
||||
return _fieldType;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isValid() const
|
||||
{
|
||||
if (_fieldCacheSize>0 && !_withinQuotes) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isOpenBracket() const
|
||||
{
|
||||
if (_fieldCacheSize==1) return _fieldCache[0]=='{';
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isCloseBracket() const
|
||||
{
|
||||
if (_fieldCacheSize==1) return _fieldCache[0]=='}';
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isWord() const
|
||||
{
|
||||
getFieldType();
|
||||
return (_fieldType==WORD);
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchWord(const char* str) const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==WORD && strcmp(_fieldCache,str)==0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchWord(const char* str,int noCharacters) const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==WORD && strncmp(_fieldCache,str,noCharacters)==0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isString() const
|
||||
{
|
||||
return getNoCharacters()!=0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchString(const char* str) const
|
||||
{
|
||||
return strcmp(_fieldCache,str)==0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchString(const char* str,int noCharacters) const
|
||||
{
|
||||
return strncmp(_fieldCache,str,noCharacters)==0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isQuotedString() const
|
||||
{
|
||||
return _withinQuotes;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isInt() const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==INTEGER;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchInt(int i) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==INTEGER)
|
||||
{
|
||||
return atoi(_fieldCache)==i;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::getInt(int& i) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==INTEGER)
|
||||
{
|
||||
i = atoi(_fieldCache);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::isFloat() const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==REAL || _fieldType==INTEGER;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchFloat(float f) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==REAL || _fieldType==INTEGER)
|
||||
{
|
||||
return (float)atof(_fieldCache)==f;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::getFloat(float& f) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==REAL || _fieldType==INTEGER)
|
||||
{
|
||||
f = (float)atof(_fieldCache);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::isDouble() const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==REAL || _fieldType==INTEGER;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchDouble(double d) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==REAL || _fieldType==INTEGER)
|
||||
{
|
||||
return atof(_fieldCache)==d;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::getDouble(double& d) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==REAL || _fieldType==INTEGER)
|
||||
{
|
||||
d = atof(_fieldCache);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Field::FieldType Field::calculateFieldType(const char* str,bool withinQuotes)
|
||||
{
|
||||
if (str==NULL) return BLANK;
|
||||
if (*str==0) return BLANK;
|
||||
|
||||
if (withinQuotes) return STRING;
|
||||
|
||||
bool hadPlusMinus = false;
|
||||
bool hadDecimalPlace = false;
|
||||
bool hadExponent = false;
|
||||
bool couldBeInt = true;
|
||||
bool couldBeFloat = true;
|
||||
int noZeroToNine = 0;
|
||||
|
||||
const char* ptr = str;
|
||||
while (*ptr!=0 && couldBeFloat)
|
||||
{
|
||||
if (*ptr=='+' || *ptr=='-')
|
||||
{
|
||||
if (hadPlusMinus)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
} else hadPlusMinus = true;
|
||||
}
|
||||
else if (*ptr>='0' && *ptr<='9')
|
||||
{
|
||||
noZeroToNine++;
|
||||
}
|
||||
else if (*ptr=='.')
|
||||
{
|
||||
if (hadDecimalPlace)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hadDecimalPlace = true;
|
||||
couldBeInt = false;
|
||||
}
|
||||
}
|
||||
else if (*ptr=='e' || *ptr=='E')
|
||||
{
|
||||
if (hadExponent || noZeroToNine==0)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hadExponent = true;
|
||||
couldBeInt = false;
|
||||
hadDecimalPlace = false;
|
||||
hadPlusMinus = false;
|
||||
noZeroToNine=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
++ptr;
|
||||
}
|
||||
|
||||
if (couldBeInt && noZeroToNine>0) return INTEGER;
|
||||
if (couldBeFloat && noZeroToNine>0) return REAL;
|
||||
if (str[0]=='{') return OPEN_BRACKET;
|
||||
if (str[0]=='}') return CLOSE_BRACKET;
|
||||
return WORD;
|
||||
}
|
||||
269
src/osg/FieldReader.cpp
Normal file
269
src/osg/FieldReader.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
#include "osg/FieldReader"
|
||||
#include "osg/Field"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
FieldReader::FieldReader()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
FieldReader::FieldReader(const FieldReader& ic)
|
||||
{
|
||||
_copy(ic);
|
||||
}
|
||||
|
||||
|
||||
FieldReader::~FieldReader()
|
||||
{
|
||||
_free();
|
||||
}
|
||||
|
||||
|
||||
FieldReader& FieldReader::operator = (const FieldReader& ic)
|
||||
{
|
||||
if (this==&ic) return *this;
|
||||
_free();
|
||||
_copy(ic);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::_free()
|
||||
{
|
||||
// free all data
|
||||
|
||||
_init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::_init()
|
||||
{
|
||||
_fin = NULL;
|
||||
_eof = true;
|
||||
|
||||
_noNestedBrackets = 0;
|
||||
|
||||
int i;
|
||||
for(i=0;i<256;++i) _delimatorEatLookUp[i]=false;
|
||||
_delimatorEatLookUp[' '] = true;
|
||||
_delimatorEatLookUp['\t'] = true;
|
||||
_delimatorEatLookUp['\n'] = true;
|
||||
_delimatorEatLookUp['\r'] = true;
|
||||
|
||||
for(i=0;i<256;++i) _delimatorKeepLookUp[i]=false;
|
||||
_delimatorKeepLookUp['{'] = true;
|
||||
_delimatorKeepLookUp['}'] = true;
|
||||
_delimatorKeepLookUp['"'] = true;
|
||||
_delimatorKeepLookUp['\''] = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::_copy(const FieldReader& ic)
|
||||
{
|
||||
|
||||
_fin = ic._fin;
|
||||
_eof = ic._eof;
|
||||
|
||||
_noNestedBrackets = ic._noNestedBrackets;
|
||||
|
||||
int i;
|
||||
for(i=0;i<256;++i) _delimatorEatLookUp[i]=ic._delimatorEatLookUp[i];
|
||||
for(i=0;i<256;++i) _delimatorKeepLookUp[i]=ic._delimatorKeepLookUp[i];
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::attach(istream* input)
|
||||
{
|
||||
_fin = input;
|
||||
|
||||
if (_fin)
|
||||
{
|
||||
_eof = _fin->eof()!=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_eof = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::detach()
|
||||
{
|
||||
_fin = NULL;
|
||||
_eof = true;
|
||||
}
|
||||
|
||||
|
||||
bool FieldReader::eof() const
|
||||
{
|
||||
return _eof;
|
||||
}
|
||||
|
||||
|
||||
bool FieldReader::findStartOfNextField()
|
||||
{
|
||||
int ch = 0;
|
||||
while (true)
|
||||
{
|
||||
ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
return false;
|
||||
}
|
||||
else if (_delimatorEatLookUp[ch])
|
||||
{
|
||||
_fin->ignore(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FieldReader::readField(Field& fieldPtr)
|
||||
{
|
||||
return _readField(&fieldPtr);
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::ignoreField()
|
||||
{
|
||||
_readField(NULL);
|
||||
}
|
||||
|
||||
|
||||
bool FieldReader::_readField(Field* fieldPtr)
|
||||
{
|
||||
if (fieldPtr) fieldPtr->reset();
|
||||
|
||||
if (!eof() && findStartOfNextField())
|
||||
{
|
||||
|
||||
int ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
else if (ch=='"')
|
||||
{
|
||||
if (fieldPtr)
|
||||
{
|
||||
fieldPtr->setWithinQuotes(true);
|
||||
fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
}
|
||||
_fin->ignore(1);
|
||||
char c;
|
||||
while (true)
|
||||
{
|
||||
ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
c = ch;
|
||||
if (ch=='"')
|
||||
{
|
||||
_fin->ignore(1);
|
||||
//return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
return fieldPtr!=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin->get(c);
|
||||
if (fieldPtr) fieldPtr->addChar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ch=='\'')
|
||||
{
|
||||
if (fieldPtr)
|
||||
{
|
||||
fieldPtr->setWithinQuotes(true);
|
||||
fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
}
|
||||
_fin->ignore(1);
|
||||
char c;
|
||||
while (true)
|
||||
{
|
||||
ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
c = ch;
|
||||
if (ch=='\'')
|
||||
{
|
||||
_fin->ignore(1);
|
||||
//return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
return fieldPtr!=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin->get(c);
|
||||
if (fieldPtr) fieldPtr->addChar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_delimatorKeepLookUp[ch])
|
||||
{
|
||||
char c;
|
||||
_fin->get(c);
|
||||
if (fieldPtr) fieldPtr->addChar(c);
|
||||
if (c=='{') ++_noNestedBrackets;
|
||||
else if (c=='}') --_noNestedBrackets;
|
||||
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
char c;
|
||||
while (true)
|
||||
{
|
||||
ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
c = ch;
|
||||
if (_delimatorEatLookUp[c])
|
||||
{
|
||||
_fin->ignore(1);
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
if (_delimatorKeepLookUp[c])
|
||||
{
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin->get(c);
|
||||
if (fieldPtr) fieldPtr->addChar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FieldReader::getNoNestedBrackets() const
|
||||
{
|
||||
return _noNestedBrackets;
|
||||
}
|
||||
361
src/osg/FieldReaderIterator.cpp
Normal file
361
src/osg/FieldReaderIterator.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
#include "osg/FieldReaderIterator"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
FieldReaderIterator::FieldReaderIterator()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator::FieldReaderIterator(const FieldReaderIterator& ic)
|
||||
{
|
||||
_copy(ic);
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator::~FieldReaderIterator()
|
||||
{
|
||||
_free();
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator& FieldReaderIterator::operator = (const FieldReaderIterator& ic)
|
||||
{
|
||||
if (this==&ic) return *this;
|
||||
_free();
|
||||
_copy(ic);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::_free()
|
||||
{
|
||||
// free all data
|
||||
if (_previousField)
|
||||
{
|
||||
delete _previousField;
|
||||
}
|
||||
if (_fieldQueue)
|
||||
{
|
||||
for(int i=0;i<_fieldQueueCapacity;++i)
|
||||
{
|
||||
if (_fieldQueue[i]) delete _fieldQueue[i];
|
||||
_fieldQueue[i] = NULL;
|
||||
}
|
||||
delete [] _fieldQueue;
|
||||
}
|
||||
_init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::_init()
|
||||
{
|
||||
_previousField = NULL;
|
||||
_fieldQueue = NULL;
|
||||
_fieldQueueSize = 0;
|
||||
_fieldQueueCapacity = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::_copy(const FieldReaderIterator& ic)
|
||||
{
|
||||
_reader = ic._reader;
|
||||
|
||||
if (ic._previousField)
|
||||
{
|
||||
_previousField = new Field(*ic._previousField);
|
||||
}
|
||||
|
||||
if (ic._fieldQueue && ic._fieldQueueCapacity>0)
|
||||
{
|
||||
_fieldQueue = new Field* [ic._fieldQueueCapacity];
|
||||
for(int i=0;i<ic._fieldQueueCapacity;++i)
|
||||
{
|
||||
if (ic._fieldQueue[i])
|
||||
{
|
||||
_fieldQueue[i] = new Field(*ic._fieldQueue[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fieldQueue[i] = NULL;
|
||||
}
|
||||
}
|
||||
_fieldQueueSize = ic._fieldQueueSize;
|
||||
_fieldQueueCapacity = ic._fieldQueueCapacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fieldQueue = NULL;
|
||||
_fieldQueueSize = 0;
|
||||
_fieldQueueCapacity = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::attach(istream* input)
|
||||
{
|
||||
_reader.attach(input);
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::detach()
|
||||
{
|
||||
_reader.detach();
|
||||
}
|
||||
|
||||
|
||||
bool FieldReaderIterator::eof() const
|
||||
{
|
||||
return _fieldQueueSize==0 && _reader.eof();
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::insert(int pos,Field* field)
|
||||
{
|
||||
if (field==NULL) return;
|
||||
|
||||
if (pos<0) pos=0;
|
||||
if (pos>_fieldQueueSize) pos=_fieldQueueSize;
|
||||
|
||||
int i;
|
||||
if (_fieldQueueSize>=_fieldQueueCapacity) // need to reallocate the stack
|
||||
{
|
||||
int newCapacity = _fieldQueueCapacity*2;
|
||||
if (newCapacity<MINIMUM_FIELD_READER_QUEUE_SIZE) newCapacity = MINIMUM_FIELD_READER_QUEUE_SIZE;
|
||||
while(_fieldQueueSize>=newCapacity) newCapacity*=2;
|
||||
Field** newFieldStack = new Field* [newCapacity];
|
||||
for(i=0;i<_fieldQueueCapacity;++i)
|
||||
{
|
||||
newFieldStack[i] = _fieldQueue[i];
|
||||
}
|
||||
for(;i<newCapacity;++i)
|
||||
{
|
||||
newFieldStack[i] = NULL;
|
||||
}
|
||||
_fieldQueue = newFieldStack;
|
||||
_fieldQueueCapacity = newCapacity;
|
||||
}
|
||||
|
||||
for(i=_fieldQueueSize-1;i>=pos;++i)
|
||||
{
|
||||
_fieldQueue[i+1]=_fieldQueue[i];
|
||||
}
|
||||
_fieldQueue[pos] = field;
|
||||
++_fieldQueueSize;
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::insert(int pos,const char* str)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
Field* field = new Field;
|
||||
while(*str!=0)
|
||||
{
|
||||
field->addChar(*str);
|
||||
++str;
|
||||
}
|
||||
insert(pos,field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Field& FieldReaderIterator::operator [] (int pos)
|
||||
{
|
||||
return field(pos);
|
||||
}
|
||||
|
||||
|
||||
Field& FieldReaderIterator::field (int pos)
|
||||
{
|
||||
if (pos<0)
|
||||
{
|
||||
_blank.setNoNestedBrackets(_reader.getNoNestedBrackets());
|
||||
return _blank;
|
||||
} // can directly access field
|
||||
else if (pos<_fieldQueueSize)
|
||||
{
|
||||
return *_fieldQueue[pos];
|
||||
} // need to read the new fields.
|
||||
else
|
||||
{
|
||||
if (pos>=_fieldQueueCapacity) // need to reallocate the stack
|
||||
{
|
||||
int newCapacity = _fieldQueueCapacity*2;
|
||||
if (newCapacity<MINIMUM_FIELD_READER_QUEUE_SIZE) newCapacity = MINIMUM_FIELD_READER_QUEUE_SIZE;
|
||||
while(_fieldQueueSize>=newCapacity) newCapacity*=2;
|
||||
Field** newFieldStack = new Field* [newCapacity];
|
||||
int i;
|
||||
for(i=0;i<_fieldQueueCapacity;++i)
|
||||
{
|
||||
newFieldStack[i] = _fieldQueue[i];
|
||||
}
|
||||
for(;i<newCapacity;++i)
|
||||
{
|
||||
newFieldStack[i] = NULL;
|
||||
}
|
||||
_fieldQueue = newFieldStack;
|
||||
_fieldQueueCapacity = newCapacity;
|
||||
}
|
||||
while(!_reader.eof() && pos>=_fieldQueueSize)
|
||||
{
|
||||
if (_fieldQueue[_fieldQueueSize]==NULL) _fieldQueue[_fieldQueueSize] = new Field;
|
||||
if (_reader.readField(*_fieldQueue[_fieldQueueSize]))
|
||||
{
|
||||
++_fieldQueueSize;
|
||||
}
|
||||
}
|
||||
if (pos<_fieldQueueSize)
|
||||
{
|
||||
return *_fieldQueue[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
_blank.setNoNestedBrackets(_reader.getNoNestedBrackets());
|
||||
return _blank;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator& FieldReaderIterator::operator ++ ()
|
||||
{
|
||||
return (*this)+=1;
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator& FieldReaderIterator::operator += (int no)
|
||||
{
|
||||
if (no>_fieldQueueSize)
|
||||
{
|
||||
while (!_reader.eof() && no>_fieldQueueSize)
|
||||
{
|
||||
_reader.ignoreField();
|
||||
--no;
|
||||
}
|
||||
_fieldQueueSize=0;
|
||||
}
|
||||
else if (no>0)
|
||||
{
|
||||
Field** tmpFields = new Field* [no];
|
||||
int i;
|
||||
for(i=0;i<no;++i)
|
||||
{
|
||||
tmpFields[i] = _fieldQueue[i];
|
||||
}
|
||||
for(i=no;i<_fieldQueueSize;++i)
|
||||
{
|
||||
_fieldQueue[i-no] = _fieldQueue[i];
|
||||
}
|
||||
_fieldQueueSize -= no;
|
||||
for(i=0;i<no;++i)
|
||||
{
|
||||
_fieldQueue[_fieldQueueSize+i] = tmpFields[i];
|
||||
}
|
||||
delete [] tmpFields;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// increments the itetor of the next simple field or
|
||||
// whole block if the current field[0] is an open bracket
|
||||
void FieldReaderIterator::advanceOverCurrentFieldOrBlock()
|
||||
{
|
||||
if (field(0).isOpenBracket()) advanceToEndOfCurrentBlock();
|
||||
else ++(*this);
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::advanceToEndOfCurrentBlock()
|
||||
{
|
||||
int entry = field(0).getNoNestedBrackets();
|
||||
while(!eof() && field(0).getNoNestedBrackets()>=entry)
|
||||
{
|
||||
++(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::advanceToEndOfBlock(int noNestedBrackets)
|
||||
{
|
||||
while(!eof() && field(0).getNoNestedBrackets()>=noNestedBrackets)
|
||||
{
|
||||
++(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FieldReaderIterator::matchSequence(const char* str)
|
||||
{
|
||||
if (str==NULL) return false;
|
||||
if (*str==0) return false;
|
||||
int fieldCount = 0;
|
||||
const char* end = str;
|
||||
while((*end)!=0 && (*end)==' ') ++end;
|
||||
const char* start = end;
|
||||
while((*start)!=0)
|
||||
{
|
||||
if (*end!=' ' && *end!=0)
|
||||
{
|
||||
++end;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (start!=end)
|
||||
{
|
||||
if (end-start>1 && *start=='%')
|
||||
{
|
||||
const char type = *(start+1);
|
||||
switch(type)
|
||||
{
|
||||
case('i') : // expecting an integer
|
||||
{
|
||||
if (!field(fieldCount).isInt()) return false;
|
||||
break;
|
||||
}
|
||||
case('f') : // expecting an floating point number
|
||||
{
|
||||
if (!field(fieldCount).isFloat()) return false;
|
||||
break;
|
||||
}
|
||||
case('s') : // expecting an quoted string
|
||||
{
|
||||
if (!field(fieldCount).isQuotedString()) return false;
|
||||
break;
|
||||
}
|
||||
default : // expecting an word
|
||||
{
|
||||
if (!field(fieldCount).isWord()) return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*start=='{')
|
||||
{
|
||||
if (!field(fieldCount).isOpenBracket()) return false;
|
||||
}
|
||||
else if (*start=='}')
|
||||
{
|
||||
if (!field(fieldCount).isCloseBracket()) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!field(fieldCount).matchWord(start,end-start)) return false;
|
||||
}
|
||||
}
|
||||
fieldCount++;
|
||||
}
|
||||
while((*end)==' ') ++end;
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
50
src/osg/FileNameUtils.cpp
Normal file
50
src/osg/FileNameUtils.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "osg/FileNameUtils"
|
||||
|
||||
std::string osg::getFilePath(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type slash = fileName.find_last_of('/');
|
||||
if (slash==std::string::npos) return std::string("");
|
||||
return std::string(fileName.begin(),fileName.begin()+slash+1);
|
||||
}
|
||||
|
||||
std::string osg::getSimpleFileName(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type slash = fileName.find_last_of('/');
|
||||
if (slash==std::string::npos) return fileName;
|
||||
return std::string(fileName.begin()+slash+1,fileName.end());
|
||||
}
|
||||
|
||||
std::string osg::getFileExtension(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type dot = fileName.find_last_of('.');
|
||||
if (dot==std::string::npos) return std::string("");
|
||||
return std::string(fileName.begin()+dot+1,fileName.end());
|
||||
}
|
||||
|
||||
std::string osg::getLowerCaseFileExtension(const std::string& filename)
|
||||
{
|
||||
std::string ext = osg::getFileExtension(filename);
|
||||
for(std::string::iterator itr=ext.begin();
|
||||
itr!=ext.end();
|
||||
++itr)
|
||||
{
|
||||
*itr = (char)tolower(*itr);
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
std::string osg::getStrippedName(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type slash = fileName.find_last_of('/');
|
||||
std::string::size_type dot = fileName.find_last_of('.');
|
||||
if (slash==std::string::npos) {
|
||||
if (dot==std::string::npos) return fileName;
|
||||
else return std::string(fileName.begin(),fileName.begin()+dot);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dot==std::string::npos) return std::string(fileName.begin()+slash+1,fileName.end());
|
||||
else return std::string(fileName.begin()+slash+1,fileName.begin()+dot);
|
||||
}
|
||||
}
|
||||
|
||||
47
src/osg/Fog.cpp
Normal file
47
src/osg/Fog.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/Fog"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Fog::Fog( void )
|
||||
{
|
||||
_mode = EXP;
|
||||
_density = 1.0f;
|
||||
_start = 0.0f;
|
||||
_end = 1.0f;
|
||||
_color.set( 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
Fog::~Fog( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
glFogi( GL_FOG_MODE, _mode );
|
||||
glFogf( GL_FOG_DENSITY, _density );
|
||||
glFogf( GL_FOG_START, _start );
|
||||
glFogf( GL_FOG_END, _end );
|
||||
glFogfv( GL_FOG_COLOR, (GLfloat*)_color.ptr() );
|
||||
}
|
||||
1778
src/osg/GeoSet.cpp
Normal file
1778
src/osg/GeoSet.cpp
Normal file
File diff suppressed because it is too large
Load Diff
427
src/osg/GeoSet_ogl.cpp
Normal file
427
src/osg/GeoSet_ogl.cpp
Normal file
@@ -0,0 +1,427 @@
|
||||
#include <stdio.h>
|
||||
#include "osg/GL"
|
||||
#include "osg/GeoSet"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#define DO_SHADING 1
|
||||
|
||||
#define I_ON (1<<4)
|
||||
#define C_ON (1<<3)
|
||||
#define N_ON (1<<2)
|
||||
#define T_ON (1<<1)
|
||||
#define V_ON (1<<0)
|
||||
|
||||
void GeoSet::set_fast_path( void )
|
||||
{
|
||||
if( _iaformat != IA_OFF )
|
||||
{
|
||||
_fast_path = I_ON;
|
||||
}
|
||||
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;
|
||||
else
|
||||
{
|
||||
_fast_path = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
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( _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( _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_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;
|
||||
if( _normal_binding == BIND_PERVERTEX )
|
||||
_fast_path |= N_ON;
|
||||
if( _texture_binding == BIND_PERVERTEX )
|
||||
_fast_path |= T_ON;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
notify(INFO) << "GeoSet - fast path = " << _fast_path << "\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
void GeoSet::draw_fast_path( void )
|
||||
{
|
||||
ushort *ocindex = _cindex;
|
||||
|
||||
switch( _fast_path )
|
||||
{
|
||||
case (I_ON) :
|
||||
_cindex = _iaindex;
|
||||
glInterleavedArrays( (GLenum)_ogliaformat, 0, _iarray );
|
||||
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;
|
||||
|
||||
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|T_ON|V_ON) :
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if( _color_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _colindex != 0L )
|
||||
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( _needprimlen ) // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
{
|
||||
int index = 0;
|
||||
if( _primLengths == (int *)0 )
|
||||
{
|
||||
notify(WARN) << "GeoSet->draw() : " "Primitive lengths required\n";
|
||||
return;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
else // POINTS, LINES, TRIANGLES, QUADS
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _numindices, GL_UNSIGNED_SHORT, _cindex );
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, 0, _numcoords );
|
||||
}
|
||||
|
||||
_cindex = ocindex;
|
||||
}
|
||||
|
||||
void GeoSet::draw_alternate_path( void )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_cindex == 0L) && (_flat_shaded_skip == 0) )
|
||||
{
|
||||
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( (_normal_binding == BIND_PERVERTEX) && (_nindex == 0L) && (_flat_shaded_skip == 0) )
|
||||
{
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
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( (_texture_binding == BIND_PERVERTEX) && (_tindex == 0L) )
|
||||
{
|
||||
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
|
||||
{
|
||||
int i, j;
|
||||
int index = 0;
|
||||
int ai = 0;
|
||||
int ci = 0;
|
||||
int ni = 0;
|
||||
int ti = 0;
|
||||
|
||||
if( _primLengths == (int *)0 )
|
||||
{
|
||||
notify(WARN) << "GeoSet->draw() : " "Primitive lengths required\n";
|
||||
return;
|
||||
}
|
||||
|
||||
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( _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( _normal_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if(_nindex != 0L)
|
||||
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( _cindex )
|
||||
glArrayElement( _cindex[ai++] );
|
||||
else
|
||||
glArrayElement( ai++ );
|
||||
}
|
||||
glEnd();
|
||||
|
||||
#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++]] );
|
||||
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex != 0L) )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ci++]] );
|
||||
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex != 0L) )
|
||||
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];
|
||||
}
|
||||
}
|
||||
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] );
|
||||
}
|
||||
|
||||
for( j = 0; j < _primlength; j++ )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_colindex != 0L ) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[i*_primlength+j]] );
|
||||
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex != 0L ) )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[i*_primlength+j]] );
|
||||
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex != 0L ) )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[i*_primlength+j]] );
|
||||
|
||||
glArrayElement( i*_primlength+j );
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _numindices, GL_UNSIGNED_SHORT, _cindex );
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, 0, _numcoords );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
850
src/osg/GeoState.cpp
Normal file
850
src/osg/GeoState.cpp
Normal file
@@ -0,0 +1,850 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "osg/GeoState"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
GeoState::GeoState()
|
||||
{
|
||||
|
||||
_transparencing = INHERIT;
|
||||
_face_culling = INHERIT;
|
||||
_lighting = INHERIT;
|
||||
_texturing = INHERIT;
|
||||
_fogging = INHERIT;
|
||||
_texgening = INHERIT;
|
||||
_antialiasing = INHERIT;
|
||||
_colortable = INHERIT;
|
||||
_pointSmoothing = INHERIT;
|
||||
_polygonOffsetting = INHERIT;
|
||||
_alphaTesting = INHERIT;
|
||||
|
||||
_transparency = 0L;
|
||||
_cullFace = 0L;
|
||||
_texture = 0L;
|
||||
_fog = 0L;
|
||||
_texgen = 0L;
|
||||
_material = 0L;
|
||||
_texenv = 0L;
|
||||
_texmat = 0L;
|
||||
_point = 0L;
|
||||
_polygonOffset = 0L;
|
||||
_alphaFunc = 0L;
|
||||
}
|
||||
|
||||
|
||||
GeoState::~GeoState()
|
||||
{
|
||||
// note, all attached state attributes will be automatically
|
||||
// unreferenced by ref_ptr<> and therefore there is now need to
|
||||
// delete the memory manually.
|
||||
}
|
||||
|
||||
|
||||
GeoState* GeoState::instance()
|
||||
{
|
||||
static ref_ptr<GeoState> s_geostate(new GeoState);
|
||||
return s_geostate.get();
|
||||
}
|
||||
|
||||
void GeoState::setGlobalDefaults()
|
||||
{
|
||||
_transparencing = OFF;
|
||||
_face_culling = ON;
|
||||
_lighting = OFF;
|
||||
_texturing = OFF;
|
||||
_fogging = OFF;
|
||||
_texgening = OFF;
|
||||
_antialiasing = OFF;
|
||||
_colortable = OFF;
|
||||
_pointSmoothing = OFF;
|
||||
_polygonOffsetting = OFF;
|
||||
_alphaTesting = OFF;
|
||||
|
||||
_transparency = new Transparency;
|
||||
_cullFace = new CullFace;
|
||||
_texture = 0L;
|
||||
_fog = 0L;
|
||||
_texgen = 0L;
|
||||
_material = new Material;
|
||||
_material->setColorMode(Material::AMBIENT_AND_DIFFUSE);
|
||||
_texenv = 0L;
|
||||
_texmat = 0L;
|
||||
_point = 0L;
|
||||
_polygonOffset = 0L;
|
||||
_alphaFunc = new AlphaFunc;
|
||||
|
||||
}
|
||||
|
||||
void GeoState::setAllToInherit()
|
||||
{
|
||||
_transparencing = INHERIT;
|
||||
_face_culling = INHERIT;
|
||||
_lighting = INHERIT;
|
||||
_texturing = INHERIT;
|
||||
_fogging = INHERIT;
|
||||
_texgening = INHERIT;
|
||||
_antialiasing = INHERIT;
|
||||
_colortable = INHERIT;
|
||||
_pointSmoothing = INHERIT;
|
||||
_polygonOffsetting = INHERIT;
|
||||
_alphaTesting = INHERIT;
|
||||
|
||||
_transparency = 0L;
|
||||
_cullFace = 0L;
|
||||
_texture = 0L;
|
||||
_fog = 0L;
|
||||
_texgen = 0L;
|
||||
_material = 0L;
|
||||
_texenv = 0L;
|
||||
_texmat = 0L;
|
||||
_point = 0L;
|
||||
_polygonOffset = 0L;
|
||||
_alphaFunc = 0L;
|
||||
}
|
||||
|
||||
bool GeoState::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
AttributeMode mode;
|
||||
if (fr[0].matchWord("transparency") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_transparencing = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (Transparency* transTmp = static_cast<Transparency*>(Transparency::instance()->readClone(fr)))
|
||||
{
|
||||
_transparency = transTmp;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("antialiasing") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_antialiasing = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("face_culling") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_face_culling = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (CullFace* cullTmp = static_cast<CullFace*>(CullFace::instance()->readClone(fr)))
|
||||
{
|
||||
_cullFace = cullTmp;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("lighting") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_lighting = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("texturing") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_texturing = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (Texture* textTmp = static_cast<Texture*>(Texture::instance()->readClone(fr)))
|
||||
{
|
||||
_texture = textTmp;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("fogging") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_fogging = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (Fog* fogTmp = static_cast<Fog*>(Fog::instance()->readClone(fr)))
|
||||
{
|
||||
_fog = fogTmp;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("colortable") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_colortable = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("texgening") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_texgening = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (TexGen* tmpTexgen = static_cast<TexGen*>(TexGen::instance()->readClone(fr)))
|
||||
{
|
||||
_texgen = tmpTexgen;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("point_smoothing") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_pointSmoothing = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (Point* tmpPoint = static_cast<Point*>(Point::instance()->readClone(fr)))
|
||||
{
|
||||
_point = tmpPoint;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("polygon_offset") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_polygonOffsetting = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (PolygonOffset* tmpPolygonOffset = static_cast<PolygonOffset*>(PolygonOffset::instance()->readClone(fr)))
|
||||
{
|
||||
_polygonOffset = tmpPolygonOffset;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
|
||||
if (fr[0].matchWord("alpha_test") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_alphaTesting = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (AlphaFunc* tmpAlphaFunc = static_cast<AlphaFunc*>(AlphaFunc::instance()->readClone(fr)))
|
||||
{
|
||||
_alphaFunc = tmpAlphaFunc;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
|
||||
if (Material* tmpMaterial = static_cast<Material*>(Material::instance()->readClone(fr)))
|
||||
{
|
||||
_material = tmpMaterial;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decided that texmatting does not make sense. If a Texture matrix
|
||||
* is present, just apply it. No need for a mode. Don.
|
||||
*
|
||||
if (fr[0].matchWord("texmating") && matchModeStr(fr[1].getStr(),mode)) {
|
||||
_texmating = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
*/
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool GeoState::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "transparency " << getModeStr(_transparencing) << endl;
|
||||
if (_transparency.valid()) _transparency->write(fw);
|
||||
|
||||
fw.indent() << "antialiasing " << getModeStr(_antialiasing) << endl;
|
||||
|
||||
fw.indent() << "face_culling " << getModeStr(_face_culling) << endl;
|
||||
if (_cullFace.valid()) _cullFace->write(fw);
|
||||
|
||||
fw.indent() << "lighting " << getModeStr(_lighting) << endl;
|
||||
|
||||
fw.indent() << "texturing " << getModeStr(_texturing) << endl;
|
||||
if (_texture.valid()) _texture->write(fw);
|
||||
|
||||
fw.indent() << "fogging " << getModeStr(_fogging) << endl;
|
||||
if (_fog.valid()) _fog->write(fw);
|
||||
|
||||
fw.indent() << "colortable " << getModeStr(_colortable) << endl;
|
||||
|
||||
fw.indent() << "texgening " << getModeStr(_texgening) << endl;
|
||||
if (_texgen.valid()) _texgen->write(fw);
|
||||
|
||||
if (_texenv.valid()) _texenv->write(fw);
|
||||
|
||||
fw.indent() << "point_smoothing " << getModeStr(_pointSmoothing) << endl;
|
||||
if (_point.valid()) _point->write(fw);
|
||||
|
||||
fw.indent() << "polygon_offset " << getModeStr(_polygonOffsetting) << endl;
|
||||
if (_polygonOffset.valid()) _polygonOffset->write(fw);
|
||||
|
||||
fw.indent() << "alpha_test " << getModeStr(_alphaTesting) << endl;
|
||||
if (_alphaFunc.valid()) _alphaFunc->write(fw);
|
||||
|
||||
if (_material.valid()) _material->write(fw);
|
||||
|
||||
/*
|
||||
fw.indent() << "texmating " << getModeStr(_texmating) << endl;
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoState::matchModeStr(const char* str,AttributeMode& mode)
|
||||
{
|
||||
if (strcmp(str,"INHERIT")==0) mode = INHERIT;
|
||||
else if (strcmp(str,"ON")==0) mode = ON;
|
||||
else if (strcmp(str,"OFF")==0) mode = OFF;
|
||||
else if (strcmp(str,"OVERRIDE_ON")==0) mode = OVERRIDE_ON;
|
||||
else if (strcmp(str,"OVERRIDE_OFF")==0) mode = OVERRIDE_OFF;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* GeoState::getModeStr(AttributeMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(INHERIT): return "INHERIT";
|
||||
case(ON): return "ON";
|
||||
case(OFF): return "OFF";
|
||||
case(OVERRIDE_ON): return "OVERRIDE_ON";
|
||||
case(OVERRIDE_OFF): return "OVERRIDE_OFF";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
void GeoState::setMode( AttributeType type, AttributeMode mode )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case ANTIALIAS : _antialiasing = mode; break;
|
||||
case FACE_CULL: _face_culling = mode; break;
|
||||
case FOG : _fogging = mode; break;
|
||||
case LIGHTING: _lighting = mode; break;
|
||||
case POINT : _pointSmoothing = mode; break;
|
||||
case POLYGON_OFFSET : _polygonOffsetting = mode; break;
|
||||
case TEXGEN : _texgening = mode; break;
|
||||
case TEXTURE : _texturing = mode; break;
|
||||
case TRANSPARENCY: _transparencing = mode; break;
|
||||
case ALPHAFUNC: _alphaTesting = mode; break;
|
||||
default : notify(WARN) << "GeoState::setMode("<<(int)type<<","<<(int)mode<<") not handled."<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
GeoState::AttributeMode GeoState::getMode( AttributeType type) const
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case ANTIALIAS : return _antialiasing;
|
||||
case FACE_CULL: return _face_culling;
|
||||
case FOG : return _fogging;
|
||||
case LIGHTING: return _lighting;
|
||||
case POINT : return _pointSmoothing;
|
||||
case POLYGON_OFFSET : return _polygonOffsetting;
|
||||
case TEXTURE : return _texturing;
|
||||
case TEXGEN : return _texgening;
|
||||
case TRANSPARENCY: return _transparencing;
|
||||
case ALPHAFUNC: return _alphaTesting;
|
||||
default : notify(WARN) << "GeoState::getMode("<<(int)type<<") not handled."<<endl;
|
||||
}
|
||||
return INHERIT;
|
||||
}
|
||||
|
||||
void GeoState::setAttribute( AttributeType type, Object *attribute )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case FACE_CULL : _cullFace = dynamic_cast<CullFace*>(attribute); break;
|
||||
case FOG : _fog = dynamic_cast<Fog*>(attribute); break;
|
||||
case LIGHTING: break; /*_light = (Light *)attribute;*/
|
||||
case MATERIAL: _material = dynamic_cast<Material*>(attribute); break;
|
||||
case POINT : _point = dynamic_cast<Point*>(attribute); break;
|
||||
case POLYGON_OFFSET: _polygonOffset = dynamic_cast<PolygonOffset*>(attribute); break;
|
||||
case TEXENV : _texenv = dynamic_cast<TexEnv*>(attribute); break;
|
||||
case TEXGEN : _texgen = dynamic_cast<TexGen*>(attribute); break;
|
||||
case TEXMAT : _texmat = dynamic_cast<TexMat*>(attribute); break;
|
||||
case TEXTURE : _texture = dynamic_cast<Texture*>(attribute); break;
|
||||
case TRANSPARENCY: _transparency = dynamic_cast<Transparency*>(attribute); break;
|
||||
case ALPHAFUNC: _alphaFunc = dynamic_cast<AlphaFunc*>(attribute); break;
|
||||
default : notify(WARN) << "GeoState::setAttribute("<<(int)type<<","<<attribute<<") not handled."<<endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object* GeoState::getAttribute( AttributeType type) const
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case FOG : return _fog.get();
|
||||
case LIGHTING: return NULL; /*_light*/
|
||||
case MATERIAL: return _material.get();
|
||||
case POINT : return _point.get();
|
||||
case POLYGON_OFFSET: return _polygonOffset.get();
|
||||
case TEXENV : return _texenv.get();
|
||||
case TEXGEN : return _texgen.get();
|
||||
case TEXMAT : return _texmat.get();
|
||||
case TEXTURE : return _texture.get();
|
||||
case TRANSPARENCY: return _transparency.get();
|
||||
case ALPHAFUNC: return _alphaFunc.get();
|
||||
default : notify(WARN) << "GeoState::getAttribute("<<(int)type<<") not handled."<<endl;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GeoState::apply()
|
||||
{
|
||||
switch(_transparencing)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Transparency::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Transparency::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_face_culling)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
CullFace::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
CullFace::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_lighting)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Lighting::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Lighting::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_texturing)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Texture::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Texture::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_texgening)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
TexGen::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
TexGen::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_fogging)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Fog::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Fog::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_pointSmoothing)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Point::enableSmooth();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Point::disableSmooth();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_polygonOffsetting)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
PolygonOffset::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
PolygonOffset::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_alphaTesting)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
AlphaFunc::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
AlphaFunc::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
if( _transparency.valid())
|
||||
_transparency->apply();
|
||||
|
||||
if( _cullFace.valid())
|
||||
_cullFace->apply();
|
||||
|
||||
if( _texenv.valid())
|
||||
_texenv->apply();
|
||||
|
||||
if( _texgen.valid())
|
||||
_texgen->apply();
|
||||
|
||||
if( _texture.valid())
|
||||
_texture->apply();
|
||||
|
||||
if( _material.valid())
|
||||
_material->apply();
|
||||
|
||||
if( _fog.valid())
|
||||
_fog->apply();
|
||||
|
||||
if( _texmat.valid())
|
||||
_texmat->apply();
|
||||
|
||||
if( _point.valid())
|
||||
_point->apply();
|
||||
|
||||
if( _polygonOffset.valid())
|
||||
_polygonOffset->apply();
|
||||
|
||||
if( _alphaFunc.valid())
|
||||
_alphaFunc->apply();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GeoState::apply(GeoState* global,GeoState* prev)
|
||||
{
|
||||
if (global==NULL || prev==NULL)
|
||||
{
|
||||
apply();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_transparencing,prev->_transparencing,_transparencing))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Transparency::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Transparency::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch(GeoState::combineMode(global->_face_culling,prev->_face_culling,_face_culling))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
CullFace::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
CullFace::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_lighting,prev->_lighting,_lighting))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Lighting::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Lighting::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_texturing,prev->_texturing,_texturing))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Texture::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Texture::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_texgening,prev->_texgening,_texgening))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
TexGen::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
TexGen::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_fogging,prev->_fogging,_fogging))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Fog::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Fog::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_pointSmoothing,prev->_pointSmoothing,_pointSmoothing))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Point::enableSmooth();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Point::disableSmooth();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_polygonOffsetting,prev->_polygonOffsetting,_polygonOffsetting))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
PolygonOffset::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
PolygonOffset::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_alphaTesting,prev->_alphaTesting,_alphaTesting))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
AlphaFunc::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
AlphaFunc::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
if (prev->_transparency!=_transparency)
|
||||
{
|
||||
osg::Transparency* new_transparency;
|
||||
if (_transparency.valid()) new_transparency = _transparency.get();
|
||||
else new_transparency = global->_transparency.get();
|
||||
if (new_transparency) new_transparency->apply();
|
||||
}
|
||||
|
||||
if (prev->_cullFace!=_cullFace)
|
||||
{
|
||||
osg::CullFace* new_cullFace;
|
||||
if (_cullFace.valid()) new_cullFace = _cullFace.get();
|
||||
else new_cullFace = global->_cullFace.get();
|
||||
if (new_cullFace) new_cullFace->apply();
|
||||
}
|
||||
|
||||
if (prev->_texenv!=_texenv)
|
||||
{
|
||||
osg::TexEnv* new_texenv;
|
||||
if (_texenv.valid()) new_texenv = _texenv.get();
|
||||
else new_texenv = global->_texenv.get();
|
||||
if (new_texenv) new_texenv->apply();
|
||||
}
|
||||
|
||||
if (prev->_texgen!=_texgen)
|
||||
{
|
||||
osg::TexGen* new_texgen;
|
||||
if (_texgen.valid()) new_texgen = _texgen.get();
|
||||
else new_texgen = global->_texgen.get();
|
||||
if (new_texgen) new_texgen->apply();
|
||||
}
|
||||
|
||||
if (prev->_texture!=_texture)
|
||||
{
|
||||
osg::Texture* new_texture;
|
||||
if (_texture.valid()) new_texture = _texture.get();
|
||||
else new_texture = global->_texture.get();
|
||||
if (new_texture) new_texture->apply();
|
||||
}
|
||||
|
||||
if (prev->_material!=_material)
|
||||
{
|
||||
osg::Material* new_material;
|
||||
if (_material.valid()) new_material = _material.get();
|
||||
else new_material = global->_material.get();
|
||||
if (new_material) new_material->apply();
|
||||
}
|
||||
|
||||
if (prev->_fog!=_fog)
|
||||
{
|
||||
osg::Fog* new_fog;
|
||||
if (_fog.valid()) new_fog = _fog.get();
|
||||
else new_fog = global->_fog.get();
|
||||
if (new_fog) new_fog->apply();
|
||||
}
|
||||
|
||||
if (prev->_texmat!=_texmat)
|
||||
{
|
||||
osg::TexMat* new_texmat;
|
||||
if (_texmat.valid()) new_texmat = _texmat.get();
|
||||
else new_texmat = global->_texmat.get();
|
||||
if (new_texmat) new_texmat->apply();
|
||||
}
|
||||
|
||||
if (prev->_point!=_point)
|
||||
{
|
||||
osg::Point* new_point;
|
||||
if (_point.valid()) new_point = _point.get();
|
||||
else new_point = global->_point.get();
|
||||
if (new_point) new_point->apply();
|
||||
}
|
||||
|
||||
if (prev->_polygonOffset!=_polygonOffset)
|
||||
{
|
||||
osg::PolygonOffset* new_polygonOffset;
|
||||
if (_polygonOffset.valid()) new_polygonOffset = _polygonOffset.get();
|
||||
else new_polygonOffset = global->_polygonOffset.get();
|
||||
if (new_polygonOffset) new_polygonOffset->apply();
|
||||
}
|
||||
|
||||
if (prev->_alphaFunc!=_alphaFunc)
|
||||
{
|
||||
osg::AlphaFunc* new_AlphaFunc;
|
||||
if (_alphaFunc.valid()) new_AlphaFunc = _alphaFunc.get();
|
||||
else new_AlphaFunc = global->_alphaFunc.get();
|
||||
if (new_AlphaFunc) new_AlphaFunc->apply();
|
||||
}
|
||||
}
|
||||
|
||||
bool GeoState::check()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#if 0 // [ NOTES on how apply should work
|
||||
|
||||
Each Scene must have a global initial GeoState, current GeoState, and current request state. The current definition of GeoState
|
||||
should really become an GeoState. The global initial State can have modes set to
|
||||
|
||||
SG_ON,
|
||||
SG_OFF,
|
||||
|
||||
and may be or'ed with
|
||||
|
||||
SG_OVERRIDE.
|
||||
|
||||
All attributes are set to the default. Defaults can be set at start up by querying hardware
|
||||
and determining best parameters (for example, do we have hardware texture mapping?, if so enable texture and create a texture environment).
|
||||
|
||||
The current GeoState and the request GeoState begin as a copy of the initial state. The request state is subsequently changed by each GeoState,
|
||||
during traversal. It is the current state that will actually issue the GL commands at apply time.
|
||||
|
||||
Attributes for the GeoStates may be
|
||||
|
||||
SG_ON -explicitely
|
||||
SG_OFF -explicitely
|
||||
SG_INHERIT
|
||||
|
||||
and may be or'ed with
|
||||
|
||||
SG_PERSIST
|
||||
|
||||
During traversal, each GeoState's attribute set to INHERIT does nothing. Each attribute set to ON or OFF sets the subsequent request state
|
||||
to the same before drawing and unsets it after. If the attribute is or'ed with SG_PERSIST, then the mode is not unset after drawing.
|
||||
Just before drawing the request state is compared to the current state. If an attribute or mode has changed, it is changed in the current
|
||||
state then applied. Only at this application will the actual GL calls be issued.
|
||||
|
||||
For exammple, if two subsequent geosets have lighting on the sequence will be as follows
|
||||
|
||||
geostate 1 sets lighting on in request state
|
||||
at draw:
|
||||
if current state has lighting off it is changed to on and applied.
|
||||
geostate1 unsets lighting in request state.
|
||||
|
||||
geosate2 resets lighting to on in request state
|
||||
at draw:
|
||||
current state has lighting set to on from previous draw therefore nothing changes
|
||||
|
||||
geostate2
|
||||
|
||||
Addendum 10/22 - Use this method for traversal. Currently we shall do dumb apply().
|
||||
Upon implementation of a CULL traversal, which creates a DRAW display list, then we
|
||||
shall implement the "smart" state change described above.
|
||||
|
||||
#endif // ]
|
||||
*/
|
||||
161
src/osg/Geode.cpp
Normal file
161
src/osg/Geode.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "osg/Geode"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef __sgi
|
||||
using std::find;
|
||||
using std::for_each;
|
||||
#endif
|
||||
|
||||
#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.
|
||||
}
|
||||
|
||||
|
||||
bool Geode::readLocalData(Input& fr)
|
||||
{
|
||||
|
||||
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))
|
||||
{
|
||||
// note ref_ptr<> automatically handles incrementing gset's reference count.
|
||||
_geosets.push_back(gset);
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Geode::removeGeoSet( GeoSet *gset )
|
||||
{
|
||||
GeoSetList::iterator itr = findGeoSet(gset);
|
||||
if (itr!=_geosets.end())
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing gset's reference count.
|
||||
_geosets.erase(itr);
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Geode::replaceGeoSet( GeoSet *origGset, GeoSet *newGset )
|
||||
{
|
||||
if (newGset==NULL || origGset==newGset) return false;
|
||||
|
||||
GeoSetList::iterator itr = findGeoSet(origGset);
|
||||
if (itr!=_geosets.end())
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing origGset's reference count,
|
||||
// and inccrementing newGset's reference count.
|
||||
*itr = newGset;
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Geode::computeBound( void )
|
||||
{
|
||||
BoundingBox bb;
|
||||
GeoSetList::iterator itr;
|
||||
for(itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
{
|
||||
bb.expandBy((*itr)->getBound());
|
||||
}
|
||||
|
||||
_bsphere._center = bb.center();
|
||||
_bsphere._radius = 0.0f;
|
||||
|
||||
for(itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
{
|
||||
const BoundingBox& bbox = (*itr)->getBound();
|
||||
for(unsigned int c=0;c<8;++c)
|
||||
{
|
||||
_bsphere.expandRadiusBy(bbox.corner(c));
|
||||
}
|
||||
}
|
||||
|
||||
_bsphere_computed=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Geode::compileGeoSets( void )
|
||||
{
|
||||
for(GeoSetList::iterator itr = _geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->compile();
|
||||
}
|
||||
}
|
||||
180
src/osg/Group.cpp
Normal file
180
src/osg/Group.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "osg/Group"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
#include "osg/BoundingBox"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// #ifdef __sgi
|
||||
// using std::find;
|
||||
// using std::for_each;
|
||||
// using std::string;
|
||||
// #endif
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Group> g_GroupProxy;
|
||||
|
||||
Group::Group()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Group::~Group()
|
||||
{
|
||||
|
||||
for(ChildList::iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
Node* child = itr->get();
|
||||
ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),this);
|
||||
if (pitr!=child->_parents.end()) child->_parents.erase(pitr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Group::traverse(NodeVisitor& nv)
|
||||
{
|
||||
for(ChildList::iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->accept(nv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Group::addChild( Node *child )
|
||||
{
|
||||
if (child && !containsNode(child))
|
||||
{
|
||||
// note ref_ptr<> automatically handles incrementing child's reference count.
|
||||
_children.push_back(child);
|
||||
|
||||
// register as parent of child.
|
||||
child->_parents.push_back(this);
|
||||
|
||||
dirtyBound();
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Group::removeChild( Node *child )
|
||||
{
|
||||
ChildList::iterator itr = findNode(child);
|
||||
if (itr!=_children.end())
|
||||
{
|
||||
// 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;
|
||||
|
||||
ChildList::iterator itr = findNode(origNode);
|
||||
if (itr!=_children.end())
|
||||
{
|
||||
ParentList::iterator pitr = std::find(origNode->_parents.begin(),origNode->_parents.end(),origNode);
|
||||
if (pitr!=origNode->_parents.end()) origNode->_parents.erase(pitr);
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing origNode's reference count,
|
||||
// and inccrementing newNode's reference count.
|
||||
*itr = newNode;
|
||||
|
||||
// register as parent of child.
|
||||
newNode->_parents.push_back(this);
|
||||
|
||||
dirtyBound();
|
||||
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()
|
||||
{
|
||||
|
||||
_bsphere_computed = true;
|
||||
|
||||
_bsphere.init();
|
||||
if (_children.empty()) return false;
|
||||
|
||||
BoundingBox bb;
|
||||
bb.init();
|
||||
ChildList::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();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
_bsphere.expandRadiusBy((*itr)->getBound());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
224
src/osg/Image.cpp
Normal file
224
src/osg/Image.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#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/Texture>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Image::Image()
|
||||
{
|
||||
_fileName = NULL;
|
||||
_s = _t = _r = 0;
|
||||
_internalFormat = 0;
|
||||
_pixelFormat = (unsigned int)0;
|
||||
_dataType = (unsigned int)0;
|
||||
_packing = 4;
|
||||
|
||||
_data = (unsigned char *)0L;
|
||||
}
|
||||
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
if (_fileName) ::free(_fileName);
|
||||
if (_data) ::free(_data);
|
||||
}
|
||||
|
||||
|
||||
void Image::setFileName(const char* fileName)
|
||||
{
|
||||
if (_fileName) ::free(_fileName);
|
||||
|
||||
if (fileName) _fileName = strdup(fileName);
|
||||
else _fileName = NULL;
|
||||
}
|
||||
|
||||
|
||||
void Image::setImage(int s,int t,int r,
|
||||
int internalFormat,
|
||||
unsigned int pixelFormat,
|
||||
unsigned int dataType,
|
||||
unsigned char *data,
|
||||
int packing)
|
||||
{
|
||||
if (_data) ::free(_data);
|
||||
|
||||
_s = s;
|
||||
_t = t;
|
||||
_r = r;
|
||||
|
||||
_internalFormat = internalFormat;
|
||||
_pixelFormat = pixelFormat;
|
||||
_dataType = dataType;
|
||||
|
||||
_data = data;
|
||||
|
||||
|
||||
if (packing<0)
|
||||
{
|
||||
if (_s%4==0)
|
||||
_packing = 4;
|
||||
else
|
||||
_packing = 1;
|
||||
}
|
||||
else
|
||||
_packing = packing;
|
||||
|
||||
// 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*/)
|
||||
{
|
||||
if (_data==NULL) return;
|
||||
|
||||
unsigned char* newData = (unsigned char *)malloc(2 * (s+1)*(t+1)*4);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT,_packing);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,_packing);
|
||||
|
||||
GLint status = gluScaleImage((GLenum)_pixelFormat,
|
||||
_s,
|
||||
_t,
|
||||
(GLenum)_dataType,
|
||||
_data,
|
||||
s,
|
||||
t,
|
||||
(GLenum)_dataType,
|
||||
newData);
|
||||
|
||||
if (status==0) {
|
||||
|
||||
// free old image.
|
||||
::free(_data);
|
||||
|
||||
_s = s;
|
||||
_t = t;
|
||||
_data = newData;
|
||||
}
|
||||
else
|
||||
{
|
||||
::free(newData);
|
||||
|
||||
notify(WARN) << "Error Image::scaleImage() do not succeed : errorString = "<<gluErrorString((GLenum)status)<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
if (s>0 && t>0)
|
||||
{
|
||||
|
||||
float y = 1.0;
|
||||
float x = y*(s/t);
|
||||
|
||||
// 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 geoset.
|
||||
osg::GeoSet* gset = new osg::GeoSet;
|
||||
gset->setGeoState(gstate);
|
||||
|
||||
osg::Vec3* coords = new Vec3 [4];
|
||||
coords[0].set(-x,0.0f,y);
|
||||
coords[1].set(-x,0.0f,-y);
|
||||
coords[2].set(x,0.0f,-y);
|
||||
coords[3].set(x,0.0f,y);
|
||||
gset->setCoords(coords);
|
||||
|
||||
osg::Vec2* tcoords = new Vec2 [4];
|
||||
tcoords[0].set(0.0f,1.0f);
|
||||
tcoords[1].set(0.0f,0.0f);
|
||||
tcoords[2].set(1.0f,0.0f);
|
||||
tcoords[3].set(1.0f,1.0f);
|
||||
gset->setTextureCoords(tcoords);
|
||||
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
|
||||
osg::Vec4* colours = new Vec4;
|
||||
colours->set(1.0f,1.0f,1.0,0.0f);
|
||||
gset->setColors(colours);
|
||||
gset->setColorBinding(osg::GeoSet::BIND_OVERALL);
|
||||
|
||||
gset->setNumPrims(1);
|
||||
gset->setPrimType(osg::GeoSet::QUADS);
|
||||
|
||||
// set up the geode.
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addGeoSet(gset);
|
||||
|
||||
return geode;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
69
src/osg/Input.cpp
Normal file
69
src/osg/Input.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "osg/Input"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Object"
|
||||
|
||||
#ifdef __sgi
|
||||
using std::string;
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
// Will extend to handle #DEF and use
|
||||
// functionality similar to Inventor,
|
||||
// and add the ability to handle #include
|
||||
// from within the OSG file format.
|
||||
Input::Input()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Input::~Input()
|
||||
{
|
||||
}
|
||||
|
||||
Object* Input::getObjectForUniqueID(const std::string& uniqueID)
|
||||
{
|
||||
UniqueIDToObjectMapping::iterator fitr = _uniqueIDToObjectMap.find(uniqueID);
|
||||
if (fitr != _uniqueIDToObjectMap.end()) return (*fitr).second;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
void Input::regisiterUniqueIDForObject(const std::string& uniqueID,Object* obj)
|
||||
{
|
||||
_uniqueIDToObjectMap[uniqueID] = obj;
|
||||
}
|
||||
|
||||
Object* Input::readObject()
|
||||
{
|
||||
return Registry::instance()->readObject(*this);
|
||||
}
|
||||
|
||||
|
||||
Object* Input::readObject(const string& fileName)
|
||||
{
|
||||
return Registry::instance()->readObject(fileName);
|
||||
}
|
||||
|
||||
|
||||
Image* Input::readImage()
|
||||
{
|
||||
return Registry::instance()->readImage(*this);
|
||||
}
|
||||
|
||||
|
||||
Image* Input::readImage(const string& fileName)
|
||||
{
|
||||
return Registry::instance()->readImage(fileName);
|
||||
}
|
||||
|
||||
|
||||
Node* Input::readNode()
|
||||
{
|
||||
return Registry::instance()->readNode(*this);
|
||||
}
|
||||
|
||||
|
||||
Node* Input::readNode(const string& fileName)
|
||||
{
|
||||
return Registry::instance()->readNode(fileName);
|
||||
}
|
||||
130
src/osg/LOD.cpp
Normal file
130
src/osg/LOD.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#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())
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (index<_rangeList.size()) _rangeList[index] = range;
|
||||
else while (index>=_rangeList.size()) _rangeList.push_back(range);
|
||||
|
||||
if (index<_rangeList2.size()) _rangeList2[index] = range*range;
|
||||
else while (index>=_rangeList2.size()) _rangeList2.push_back(range*range);
|
||||
}
|
||||
|
||||
int LOD::evaluate(const Vec3& eye_local, float bias)
|
||||
{
|
||||
// For cache coherency, use _rangeList2 exclusively
|
||||
if (_rangeList2.size()==0) return -1;
|
||||
|
||||
// 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]) {
|
||||
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;
|
||||
}
|
||||
97
src/osg/Light.cpp
Normal file
97
src/osg/Light.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "osg/Light"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
int Light::_currentLightNum = -1;
|
||||
|
||||
Light::Light( void )
|
||||
{
|
||||
_lightnum = ++_currentLightNum;
|
||||
_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;
|
||||
}
|
||||
|
||||
|
||||
Light::~Light( void )
|
||||
{
|
||||
}
|
||||
|
||||
Light* Light::instance()
|
||||
{
|
||||
static ref_ptr<Light> s_Light(new Light);
|
||||
return s_Light.get();
|
||||
}
|
||||
|
||||
void Light::init( void )
|
||||
{
|
||||
_ambient.set(0.05f,0.05f,0.05f,1.0f);
|
||||
_diffuse.set(0.8f,0.8f,0.8f,1.0f);
|
||||
_specular.set(0.05f,0.05f,0.05f,1.0f);
|
||||
_position.set(0.0f,0.0f,1.0f,0.0f);
|
||||
_direction.set(0.0f,0.0f,-1.0f);
|
||||
_spot_exponent = 0.0f;
|
||||
_spot_cutoff = 180.0f;
|
||||
_constant_attenuation = 1.0f;
|
||||
_linear_attenuation = 0.0f;
|
||||
_quadratic_attenuation = 0.0f;
|
||||
}
|
||||
|
||||
void Light::captureLightState()
|
||||
{
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_AMBIENT, _ambient.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_DIFFUSE, _diffuse.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPECULAR, _specular.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_POSITION, _position.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_DIRECTION, _direction.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_EXPONENT, &_spot_exponent );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_CUTOFF, &_spot_cutoff );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_CONSTANT_ATTENUATION, &_constant_attenuation );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_LINEAR_ATTENUATION, &_linear_attenuation );
|
||||
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 )
|
||||
{
|
||||
if( _on )
|
||||
{
|
||||
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() );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPECULAR, _specular.ptr() );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_POSITION, _position.ptr() );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_DIRECTION, _direction.ptr() );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_EXPONENT, _spot_exponent );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_CUTOFF, _spot_cutoff );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_CONSTANT_ATTENUATION, _constant_attenuation );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_LINEAR_ATTENUATION, _linear_attenuation );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_QUADRATIC_ATTENUATION, _quadratic_attenuation );
|
||||
}
|
||||
else
|
||||
glDisable( (GLenum)((int)GL_LIGHT0 + _lightnum) );
|
||||
}
|
||||
59
src/osg/LightSource.cpp
Normal file
59
src/osg/LightSource.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "osg/LightSource"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<LightSource> g_LightSourceProxy;
|
||||
|
||||
LightSource::LightSource()
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
}
|
||||
|
||||
|
||||
LightSource::~LightSource()
|
||||
{
|
||||
// ref_ptr<> automactially decrements the reference count of attached lights.
|
||||
}
|
||||
|
||||
|
||||
bool LightSource::readLocalData(Input& fr)
|
||||
{
|
||||
|
||||
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;
|
||||
}
|
||||
15
src/osg/Lighting.cpp
Normal file
15
src/osg/Lighting.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/Lighting"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
void Lighting::enable( void )
|
||||
{
|
||||
glEnable( GL_LIGHTING );
|
||||
}
|
||||
|
||||
|
||||
void Lighting::disable( void )
|
||||
{
|
||||
glDisable( GL_LIGHTING );
|
||||
}
|
||||
0
src/osg/Makedepend
Normal file
0
src/osg/Makedepend
Normal file
148
src/osg/Makefile
Normal file
148
src/osg/Makefile
Normal file
@@ -0,0 +1,148 @@
|
||||
#!smake
|
||||
include ../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
Registry.cpp\
|
||||
OSG.cpp\
|
||||
AlphaFunc.cpp\
|
||||
Group.cpp\
|
||||
Field.cpp\
|
||||
FieldReader.cpp\
|
||||
FieldReaderIterator.cpp\
|
||||
GeoSet.cpp\
|
||||
GeoSet_ogl.cpp\
|
||||
GeoState.cpp\
|
||||
Geode.cpp\
|
||||
Input.cpp\
|
||||
FileNameUtils.cpp\
|
||||
Light.cpp\
|
||||
LightSource.cpp\
|
||||
Lighting.cpp\
|
||||
Material.cpp\
|
||||
Matrix.cpp\
|
||||
Quat.cpp\
|
||||
Seg.cpp\
|
||||
Node.cpp\
|
||||
NodeVisitor.cpp\
|
||||
Object.cpp\
|
||||
Output.cpp\
|
||||
DynamicLibrary.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\
|
||||
Timer.cpp\
|
||||
Fog.cpp\
|
||||
ReaderWriterOSG.cpp\
|
||||
ReaderWriterRGB.cpp\
|
||||
Camera.cpp\
|
||||
Notify.cpp\
|
||||
ExtensionSupported.cpp\
|
||||
Point.cpp\
|
||||
PolygonOffset.cpp\
|
||||
Version.cpp\
|
||||
|
||||
|
||||
TARGET_BASENAME = osg
|
||||
|
||||
TARGET_LIB_FILES = lib$(TARGET_BASENAME).so
|
||||
|
||||
TARGET_INCLUDE_FILES = \
|
||||
osg/AlphaFunc\
|
||||
osg/Billboard\
|
||||
osg/BoundingBox\
|
||||
osg/BoundingSphere\
|
||||
osg/Camera\
|
||||
osg/CullFace\
|
||||
osg/DCS\
|
||||
osg/DynamicLibrary\
|
||||
osg/Export\
|
||||
osg/Field\
|
||||
osg/FieldReader\
|
||||
osg/FieldReaderIterator\
|
||||
osg/FileNameUtils\
|
||||
osg/Fog\
|
||||
osg/GeoSet\
|
||||
osg/GeoState\
|
||||
osg/Geode\
|
||||
osg/Group\
|
||||
osg/GL\
|
||||
osg/Image\
|
||||
osg/Input\
|
||||
osg/LOD\
|
||||
osg/Light\
|
||||
osg/LightSource\
|
||||
osg/Lighting\
|
||||
osg/Material\
|
||||
osg/Matrix\
|
||||
osg/Node\
|
||||
osg/Notify\
|
||||
osg/NodeVisitor\
|
||||
osg/OSG\
|
||||
osg/Object\
|
||||
osg/Output\
|
||||
osg/Point\
|
||||
osg/PolygonOffset\
|
||||
osg/Quat\
|
||||
osg/Referenced\
|
||||
osg/Registry\
|
||||
osg/Scene\
|
||||
osg/Seg\
|
||||
osg/Sequence\
|
||||
osg/State\
|
||||
osg/Switch\
|
||||
osg/TexEnv\
|
||||
osg/TexGen\
|
||||
osg/TexMat\
|
||||
osg/Texture\
|
||||
osg/Transparency\
|
||||
osg/Timer\
|
||||
osg/Types\
|
||||
osg/Vec2\
|
||||
osg/Vec3\
|
||||
osg/Vec4\
|
||||
osg/Version\
|
||||
|
||||
|
||||
TARGET_DATA_FILES = \
|
||||
cessna.osg\
|
||||
cow.osg\
|
||||
dumptruck.osg\
|
||||
e-s-bike.osg\
|
||||
flight_park.fly\
|
||||
glider.osg\
|
||||
ncc1701d.osg\
|
||||
paraglider.osg\
|
||||
torus.osg\
|
||||
turtle.osg\
|
||||
Test/CullFace.osg\
|
||||
Test/Point.osg\
|
||||
Test/PolygonOffset.osg\
|
||||
Images/lz.rgb\
|
||||
Images/reflect.rgb\
|
||||
Images/tank.rgb\
|
||||
Images/tree0.rgba\
|
||||
Images/water.rgb\
|
||||
Images/white.rgb\
|
||||
|
||||
|
||||
LIBS = -ldl
|
||||
|
||||
LIB = ../../lib/lib$(TARGET_BASENAME).so
|
||||
#LIB = ../../lib/lib$(TARGET_BASENAME).a
|
||||
|
||||
C++FLAGS += -I ../../include
|
||||
|
||||
include ../../Make/makerules
|
||||
|
||||
560
src/osg/Material.cpp
Normal file
560
src/osg/Material.cpp
Normal file
@@ -0,0 +1,560 @@
|
||||
#include "osg/Material"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Material::Material( void )
|
||||
{
|
||||
_colorMode = OFF;
|
||||
|
||||
_ambientFrontAndBack = true;
|
||||
_ambientFront.set(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
_ambientBack.set(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
|
||||
_diffuseFrontAndBack = true;
|
||||
_diffuseFront.set(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
_diffuseBack.set(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
|
||||
_specularFrontAndBack = true;
|
||||
_specularFront.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_specularBack.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
_emissionFrontAndBack = true;
|
||||
_emissionFront.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_emissionBack.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
_shininessFrontAndBack = true;
|
||||
_shininessFront = 0.0f;
|
||||
_shininessBack = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
Material::~Material( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Material* Material::instance()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getAmbient(MaterialFace 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;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getAmbient()."<<endl;
|
||||
return _ambientFront;
|
||||
}
|
||||
|
||||
void Material::setDiffuse( MaterialFace 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;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getDiffuse(MaterialFace 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;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getDiffuse()."<<endl;
|
||||
return _diffuseFront;
|
||||
}
|
||||
|
||||
void Material::setSpecular( MaterialFace 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;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getSpecular(MaterialFace 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;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getSpecular()."<<endl;
|
||||
return _specularFront;
|
||||
}
|
||||
|
||||
void Material::setEmission( MaterialFace 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;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getEmission(MaterialFace 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;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getEmission()."<<endl;
|
||||
return _emissionFront;
|
||||
}
|
||||
|
||||
void Material::setShininess( MaterialFace 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;
|
||||
}
|
||||
}
|
||||
|
||||
float Material::getShininess(MaterialFace 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;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getShininess()."<<endl;
|
||||
return _shininessFront;
|
||||
}
|
||||
|
||||
|
||||
bool Material::matchFaceAndColor(Input& fr,const char* name,MaterialFace& mf,Vec4& color)
|
||||
{
|
||||
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))
|
||||
{
|
||||
|
||||
_ambientFront[3] = 1.0f-transparency;
|
||||
_diffuseFront[3] = 1.0f-transparency;
|
||||
_specularFront[3] = 1.0f-transparency;
|
||||
_emissionFront[3] = 1.0f-transparency;
|
||||
|
||||
_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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (_ambientFrontAndBack)
|
||||
{
|
||||
fw.indent() << "ambientColor " << _ambientFront << endl;
|
||||
}
|
||||
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 )
|
||||
{
|
||||
if (_colorMode==OFF)
|
||||
{
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (_colorMode!=AMBIENT && _colorMode!=AMBIENT_AND_DIFFUSE)
|
||||
{
|
||||
if (_ambientFrontAndBack)
|
||||
{
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, _ambientFront.ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialfv( GL_FRONT, GL_AMBIENT, _ambientFront.ptr() );
|
||||
glMaterialfv( GL_BACK, GL_AMBIENT, _ambientBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
if (_colorMode!=DIFFUSE && _colorMode!=AMBIENT_AND_DIFFUSE)
|
||||
{
|
||||
if (_diffuseFrontAndBack)
|
||||
{
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, _diffuseFront.ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialfv( GL_FRONT, GL_DIFFUSE, _diffuseFront.ptr() );
|
||||
glMaterialfv( GL_BACK, GL_DIFFUSE, _diffuseBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
if (_colorMode!=SPECULAR)
|
||||
{
|
||||
if (_specularFrontAndBack)
|
||||
{
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, _specularFront.ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialfv( GL_FRONT, GL_SPECULAR, _specularFront.ptr() );
|
||||
glMaterialfv( GL_BACK, GL_SPECULAR, _specularBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
if (_colorMode!=EMISSION)
|
||||
{
|
||||
if (_emissionFrontAndBack)
|
||||
{
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, _emissionFront.ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialfv( GL_FRONT, GL_EMISSION, _emissionFront.ptr() );
|
||||
glMaterialfv( GL_BACK, GL_EMISSION, _emissionBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
if (_shininessFrontAndBack)
|
||||
{
|
||||
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, _shininessFront* 128.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialf( GL_FRONT, GL_SHININESS, _shininessFront* 128.0f );
|
||||
glMaterialf( GL_BACK, GL_SHININESS, _shininessBack* 128.0f );
|
||||
}
|
||||
|
||||
}
|
||||
512
src/osg/Matrix.cpp
Normal file
512
src/osg/Matrix.cpp
Normal file
@@ -0,0 +1,512 @@
|
||||
#include <math.h>
|
||||
#include "osg/Matrix"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
|
||||
using namespace osg;
|
||||
|
||||
typedef struct quaternion_
|
||||
{
|
||||
double x ;
|
||||
double y ;
|
||||
double z ;
|
||||
double w ;
|
||||
} quaternion ;
|
||||
|
||||
/* C = a(row).b(row) */
|
||||
|
||||
#define matrix_inner_product( a, b, row, col, C ) \
|
||||
{ \
|
||||
(C)[row][col] = (a)[row][0] * (b)[0][col] + \
|
||||
(a)[row][1] * (b)[1][col] + \
|
||||
(a)[row][2] * (b)[2][col] + \
|
||||
(a)[row][3] * (b)[3][col]; \
|
||||
}
|
||||
|
||||
/* C = a.b */
|
||||
|
||||
#define matrix_mult( a, b, C ) \
|
||||
{ \
|
||||
matrix_inner_product( a, b, 0, 0, C ); \
|
||||
matrix_inner_product( a, b, 0, 1, C ); \
|
||||
matrix_inner_product( a, b, 0, 2, C ); \
|
||||
matrix_inner_product( a, b, 0, 3, C ); \
|
||||
matrix_inner_product( a, b, 1, 0, C ); \
|
||||
matrix_inner_product( a, b, 1, 1, C ); \
|
||||
matrix_inner_product( a, b, 1, 2, C ); \
|
||||
matrix_inner_product( a, b, 1, 3, C ); \
|
||||
matrix_inner_product( a, b, 2, 0, C ); \
|
||||
matrix_inner_product( a, b, 2, 1, C ); \
|
||||
matrix_inner_product( a, b, 2, 2, C ); \
|
||||
matrix_inner_product( a, b, 2, 3, C ); \
|
||||
matrix_inner_product( a, b, 3, 0, C ); \
|
||||
matrix_inner_product( a, b, 3, 1, C ); \
|
||||
matrix_inner_product( a, b, 3, 2, C ); \
|
||||
matrix_inner_product( a, b, 3, 3, C ); \
|
||||
}
|
||||
|
||||
static void quaternion_matrix( quaternion *q, double mat[4][4] )
|
||||
{
|
||||
/* copied from Shoemake/ACM SIGGRAPH 89 */
|
||||
double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz ;
|
||||
|
||||
xs = q->x + q->x;
|
||||
ys = q->y + q->y;
|
||||
zs = q->z + q->z;
|
||||
|
||||
wx = q->w * xs ; wy = q->w * ys ; wz = q->w * zs ;
|
||||
xx = q->x * xs ; xy = q->x * ys ; xz = q->x * zs ;
|
||||
yy = q->y * ys ; yz = q->y * zs ; zz = q->z * zs ;
|
||||
|
||||
mat[0][0] = 1.0 - ( yy + zz ) ;
|
||||
mat[0][1] = xy - wz ;
|
||||
mat[0][2] = xz + wy ;
|
||||
mat[1][0] = xy + wz ;
|
||||
mat[1][1] = 1.0 - ( xx + zz ) ;
|
||||
mat[1][2] = yz - wx ;
|
||||
mat[2][0] = xz - wy ;
|
||||
mat[2][1] = yz + wx ;
|
||||
mat[2][2] = 1.0 - ( xx + yy ) ;
|
||||
|
||||
mat[0][3] = 0.0;
|
||||
mat[1][3] = 0.0;
|
||||
mat[2][3] = 0.0;
|
||||
|
||||
mat[3][0] = 0.0;
|
||||
mat[3][1] = 0.0;
|
||||
mat[3][2] = 0.0;
|
||||
mat[3][3] = 1.0;
|
||||
}
|
||||
|
||||
|
||||
Matrix::Matrix()
|
||||
{
|
||||
makeIdent();
|
||||
}
|
||||
|
||||
|
||||
Matrix::Matrix(const Matrix& matrix) : Object()
|
||||
{
|
||||
memcpy(_mat,matrix._mat,sizeof(_mat));
|
||||
}
|
||||
|
||||
|
||||
Matrix& Matrix::operator = (const Matrix& matrix)
|
||||
{
|
||||
if (&matrix==this) return *this;
|
||||
memcpy(_mat,matrix._mat,sizeof(_mat));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Matrix::Matrix(
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
_mat[0][1] = 0.0f;
|
||||
_mat[0][2] = 0.0f;
|
||||
_mat[0][3] = 0.0f;
|
||||
|
||||
_mat[1][0] = 0.0f;
|
||||
_mat[1][1] = 1.0f;
|
||||
_mat[1][2] = 0.0f;
|
||||
_mat[1][3] = 0.0f;
|
||||
|
||||
_mat[2][0] = 0.0f;
|
||||
_mat[2][1] = 0.0f;
|
||||
_mat[2][2] = 1.0f;
|
||||
_mat[2][3] = 0.0f;
|
||||
|
||||
_mat[3][0] = 0.0f;
|
||||
_mat[3][1] = 0.0f;
|
||||
_mat[3][2] = 0.0f;
|
||||
_mat[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
void Matrix::copy(const Matrix& matrix)
|
||||
{
|
||||
memcpy(_mat,matrix._mat,sizeof(_mat));
|
||||
}
|
||||
|
||||
void Matrix::makeScale(float sx, float sy, float sz)
|
||||
{
|
||||
makeIdent();
|
||||
_mat[0][0] = sx;
|
||||
_mat[1][1] = sy;
|
||||
_mat[2][2] = sz;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preScale( float sx, float sy, float sz, const Matrix& m )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeScale(sx, sy, sz);
|
||||
mult(transMat,m);
|
||||
}
|
||||
|
||||
void Matrix::postScale( const Matrix& m, float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeScale(sx, sy, sz);
|
||||
mult(m,transMat);
|
||||
}
|
||||
|
||||
void Matrix::preScale( float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeScale(sx, sy, sz);
|
||||
preMult(transMat);
|
||||
}
|
||||
|
||||
void Matrix::postScale( float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeScale(sx, sy, sz);
|
||||
postMult(transMat);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Matrix::makeTrans( float tx, float ty, float tz )
|
||||
{
|
||||
makeIdent();
|
||||
_mat[3][0] = tx;
|
||||
_mat[3][1] = ty;
|
||||
_mat[3][2] = tz;
|
||||
}
|
||||
|
||||
void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeTrans(tx, ty, tz);
|
||||
mult(transMat,m);
|
||||
}
|
||||
|
||||
void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeTrans(tx, ty, 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];
|
||||
_mat[3][1] = (tx * _mat[0][1]) + (ty * _mat[1][1]) + (tz * _mat[2][1]) + _mat[3][1];
|
||||
_mat[3][2] = (tx * _mat[0][2]) + (ty * _mat[1][2]) + (tz * _mat[2][2]) + _mat[3][2];
|
||||
_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;
|
||||
transMat.makeTrans(tx, ty, tz);
|
||||
postMult(transMat);
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float deg, float x, float y, float z )
|
||||
{
|
||||
double __mat[4][4];
|
||||
quaternion q;
|
||||
float d = sqrtf( square(x) + square(y) + square(z) );
|
||||
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
|
||||
float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
|
||||
|
||||
q.x = sin_HalfAngle * (x/d);
|
||||
q.y = sin_HalfAngle * (y/d);
|
||||
q.z = sin_HalfAngle * (z/d);
|
||||
q.w = cos_HalfAngle;
|
||||
|
||||
quaternion_matrix( &q, __mat );
|
||||
|
||||
for(int i=0;i<4;++i)
|
||||
{
|
||||
for(int j=0;j<4;++j)
|
||||
{
|
||||
_mat[i][j]=__mat[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m )
|
||||
{
|
||||
Matrix rotMat;
|
||||
rotMat.makeRot( deg, x, y, z );
|
||||
mult(rotMat,m);
|
||||
}
|
||||
|
||||
void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z )
|
||||
{
|
||||
Matrix rotMat;
|
||||
rotMat.makeRot( deg, x, y, z );
|
||||
mult(m,rotMat);
|
||||
}
|
||||
|
||||
void Matrix::preRot( float deg, float x, float y, float z )
|
||||
{
|
||||
quaternion q;
|
||||
double __mat[4][4];
|
||||
float res_mat[4][4];
|
||||
|
||||
float d = sqrtf( square(x) + square(y) + square(z) );
|
||||
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
|
||||
float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
|
||||
|
||||
q.x = sin_HalfAngle * (x/d);
|
||||
q.y = sin_HalfAngle * (y/d);
|
||||
q.z = sin_HalfAngle * (z/d);
|
||||
q.w = cos_HalfAngle;
|
||||
|
||||
quaternion_matrix( &q, __mat );
|
||||
matrix_mult( __mat, _mat, res_mat );
|
||||
memcpy( _mat, res_mat, sizeof( _mat ) );
|
||||
}
|
||||
|
||||
void Matrix::postRot( float deg, float x, float y, float z )
|
||||
{
|
||||
quaternion q;
|
||||
double __mat[4][4];
|
||||
float res_mat[4][4];
|
||||
|
||||
float d = sqrtf( square(x) + square(y) + square(z) );
|
||||
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
|
||||
float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
|
||||
|
||||
q.x = sin_HalfAngle * (x/d);
|
||||
q.y = sin_HalfAngle * (y/d);
|
||||
q.z = sin_HalfAngle * (z/d);
|
||||
q.w = cos_HalfAngle;
|
||||
|
||||
quaternion_matrix( &q, __mat );
|
||||
matrix_mult( _mat, __mat , res_mat );
|
||||
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][2] = tz;
|
||||
}
|
||||
void Matrix::setTrans( const Vec3& v )
|
||||
{
|
||||
_mat[3][0] = v[0];
|
||||
_mat[3][1] = v[1];
|
||||
_mat[3][2] = v[2];
|
||||
}
|
||||
|
||||
void Matrix::preMult(const Matrix& m)
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( m._mat, _mat, tm._mat );
|
||||
*this = tm;
|
||||
}
|
||||
|
||||
void Matrix::postMult(const Matrix& m)
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( _mat, m._mat, tm._mat );
|
||||
*this = tm;
|
||||
}
|
||||
|
||||
void Matrix::mult(const Matrix& lhs,const Matrix& rhs)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::invert(const Matrix& _m)
|
||||
{
|
||||
// code lifted from VR Juggler.
|
||||
// not cleanly added, but seems to work. RO.
|
||||
|
||||
const float* a = reinterpret_cast<const float*>(_m._mat);
|
||||
float* b = reinterpret_cast<float*>(_mat);
|
||||
|
||||
int n = 4;
|
||||
int i, j, k;
|
||||
int r[ 4], c[ 4], row[ 4], col[ 4];
|
||||
float m[ 4][ 4*2], pivot, max_m, tmp_m, fac;
|
||||
|
||||
/* Initialization */
|
||||
for ( i = 0; i < n; i ++ )
|
||||
{
|
||||
r[ i] = c[ i] = 0;
|
||||
row[ i] = col[ i] = 0;
|
||||
}
|
||||
|
||||
/* Set working matrix */
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
for ( j = 0; j < n; j++ )
|
||||
{
|
||||
m[ i][ j] = a[ i * n + j];
|
||||
m[ i][ j + n] = ( i == j ) ? 1.0 : 0.0 ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Begin of loop */
|
||||
for ( k = 0; k < n; k++ )
|
||||
{
|
||||
/* Choosing the pivot */
|
||||
for ( i = 0, max_m = 0; i < n; i++ )
|
||||
{
|
||||
if ( row[ i] ) continue;
|
||||
for ( j = 0; j < n; j++ )
|
||||
{
|
||||
if ( col[ j] ) continue;
|
||||
tmp_m = fabs( m[ i][j]);
|
||||
if ( tmp_m > max_m)
|
||||
{
|
||||
max_m = tmp_m;
|
||||
r[ k] = i;
|
||||
c[ k] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
row[ r[k] ] = col[ c[k] ] = 1;
|
||||
pivot = m[ r[ k] ][ c[ k] ];
|
||||
|
||||
if ( fabs( pivot) <= 1e-20)
|
||||
{
|
||||
notify(WARN) << "*** pivot = %f in mat_inv. ***\n";
|
||||
//exit( 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Normalization */
|
||||
for ( j = 0; j < 2*n; j++ )
|
||||
{
|
||||
if ( j == c[ k] )
|
||||
m[ r[ k]][ j] = 1.0;
|
||||
else
|
||||
m[ r[ k]][ j] /=pivot;
|
||||
}
|
||||
|
||||
/* Reduction */
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
if ( i == r[ k] )
|
||||
continue;
|
||||
|
||||
for ( j=0, fac = m[ i][ c[k]];j < 2*n; j++ )
|
||||
{
|
||||
if ( j == c[ k] )
|
||||
m[ i][ j] =0.0;
|
||||
else
|
||||
m[ i][ j] -=fac * m[ r[k]][ j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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];
|
||||
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = 0; j < n; j++ )
|
||||
b[ i * n + j] = m[ row[ i]][j + n];
|
||||
|
||||
return true; // It worked
|
||||
}
|
||||
168
src/osg/Node.cpp
Normal file
168
src/osg/Node.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#include "osg/Node"
|
||||
#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;
|
||||
_userData = NULL;
|
||||
_nodeMask = 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
if (_userData && _memoryAdapter.valid()) _memoryAdapter->decrementReference(_userData);
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
{
|
||||
_bsphere.init();
|
||||
return false;
|
||||
}
|
||||
|
||||
const BoundingSphere& Node::getBound()
|
||||
{
|
||||
if(!_bsphere_computed) computeBound();
|
||||
return _bsphere;
|
||||
}
|
||||
|
||||
void Node::dirtyBound()
|
||||
{
|
||||
if (_bsphere_computed)
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
|
||||
// dirty parent bounding sphere's to ensure that all are valid.
|
||||
for(ParentList::iterator itr=_parents.begin();
|
||||
itr!=_parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->dirtyBound();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
40
src/osg/NodeVisitor.cpp
Normal file
40
src/osg/NodeVisitor.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "osg/NodeVisitor"
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
NodeVisitor::NodeVisitor(TraversalMode tm)
|
||||
{
|
||||
_traverseVisitor = NULL;
|
||||
_traverseMode = tm;
|
||||
}
|
||||
|
||||
NodeVisitor::~NodeVisitor()
|
||||
{
|
||||
// if (_traverseVisitor) detach from _traverseVisitor;
|
||||
}
|
||||
|
||||
void NodeVisitor::setTraverseMode(TraversalMode mode)
|
||||
{
|
||||
if (_traverseMode==mode) return;
|
||||
if (mode==TRAVERSE_VISITOR)
|
||||
{
|
||||
if (_traverseVisitor==NULL) _traverseMode = TRAVERSE_NONE;
|
||||
else _traverseMode = TRAVERSE_VISITOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_traverseVisitor) _traverseVisitor=NULL;
|
||||
_traverseMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeVisitor::setTraverseVisitor(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;
|
||||
}
|
||||
87
src/osg/Notify.cpp
Normal file
87
src/osg/Notify.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "osg/Notify"
|
||||
#include <string>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
int osg::NotifyInit::count_ = 0;
|
||||
NotifySeverity osg::g_NotifyLevel = osg::NOTICE;
|
||||
ofstream *osg::g_absorbStreamPtr = NULL;
|
||||
|
||||
void osg::setNotifyLevel(NotifySeverity severity)
|
||||
{
|
||||
g_NotifyLevel = severity;
|
||||
}
|
||||
|
||||
int osg::getNotifyLevel()
|
||||
{
|
||||
return g_NotifyLevel;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
ostream& osg::notify(NotifySeverity severity)
|
||||
{
|
||||
if (severity<=g_NotifyLevel || g_absorbStreamPtr==NULL)
|
||||
{
|
||||
if (severity<=osg::WARN) return cerr;
|
||||
else return cout;
|
||||
}
|
||||
return *g_absorbStreamPtr;
|
||||
}
|
||||
#endif
|
||||
|
||||
NotifyInit::NotifyInit()
|
||||
{
|
||||
if (count_++ == 0) {
|
||||
|
||||
// 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)
|
||||
{
|
||||
g_absorbStreamPtr=new ofstream(OSGNOTIFYABSORBFILE);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
254
src/osg/OSG.cpp
Normal file
254
src/osg/OSG.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <Io.h>
|
||||
#include <Windows.h>
|
||||
#include <Winbase.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "osg/Notify"
|
||||
#include "osg/OSG"
|
||||
#include "osg/Node"
|
||||
#include "osg/Geode"
|
||||
#include "osg/Group"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#ifdef WIN32
|
||||
char *PathDelimitor = ";";
|
||||
static const char *s_default_file_path = ".;D:/OpenSceneGraph/Data;D:/OpenSceneGraph/Data/Images;D:/OpenSceneGraph/lib";
|
||||
//static char *s_filePath = (char *)s_default_file_path;
|
||||
static char *s_filePath = ".;";
|
||||
#else
|
||||
char *PathDelimitor = ":";
|
||||
static const char *s_default_file_path = ".:";
|
||||
#ifdef __sgi
|
||||
static const char *s_default_dso_path = "/usr/lib32/osgPlugins/";
|
||||
#else
|
||||
static const char *s_default_dso_path = "/usr/lib/osgPlugins/";
|
||||
#endif
|
||||
static char *s_filePath = ".:";
|
||||
//static char *s_filePath = s_default_file_path;
|
||||
#endif
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using std::vector;
|
||||
using std::find_if;
|
||||
|
||||
void osg::Init( void )
|
||||
{
|
||||
char *ptr;
|
||||
if( (ptr = getenv( "OSGFILEPATH" )) )
|
||||
{
|
||||
notify(DEBUG) << "osg::Init("<<ptr<<")"<<endl;
|
||||
SetFilePath( ptr );
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(DEBUG) << "osg::Init(NULL)"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void osg::SetFilePath( const char *_path )
|
||||
{
|
||||
char buff[1024];
|
||||
|
||||
notify(DEBUG) << "In osg::SetFilePath("<<_path<<")"<<endl;
|
||||
|
||||
buff[0] = 0;
|
||||
|
||||
/* notify(DEBUG) << "filePath " << s_filePath << endl;
|
||||
notify(DEBUG) << "defPath " << s_default_file_path << endl;
|
||||
notify(DEBUG) << "&filePath " << &s_filePath << endl;
|
||||
notify(DEBUG) << "&defPath " << &s_default_file_path << endl;
|
||||
*/
|
||||
if( s_filePath != s_default_file_path )
|
||||
{
|
||||
strcpy( buff, s_filePath );
|
||||
// delete s_filePath;
|
||||
}
|
||||
// if (strcmp(s_filePath, s_default_file_path) != 0)
|
||||
// {
|
||||
// strcpy( buff, s_filePath );
|
||||
// delete s_filePath;
|
||||
// }
|
||||
|
||||
strcat( buff, PathDelimitor );
|
||||
strcat( buff, _path );
|
||||
|
||||
s_filePath = strdup( buff );
|
||||
|
||||
notify(DEBUG) << "Out osg::SetFilePath("<<_path<<")"<<endl;
|
||||
}
|
||||
|
||||
|
||||
static char *FindFileInPath( const char *_file, const char * filePath )
|
||||
{
|
||||
char pathbuff[1024];
|
||||
char *tptr, *tmppath;
|
||||
char *path = 0L;
|
||||
|
||||
notify(DEBUG) << "FindFileInPath() : trying " << _file << " ...\n";
|
||||
#ifdef WIN32
|
||||
if( _access( _file, 4 ) == 0 ) return (char *)_file;
|
||||
#else
|
||||
if( access( _file, F_OK ) == 0 ) return (char *)_file;
|
||||
#endif
|
||||
|
||||
tptr = strdup( filePath );
|
||||
tmppath = strtok( tptr, PathDelimitor );
|
||||
|
||||
do
|
||||
{
|
||||
sprintf( pathbuff, "%s/%s", tmppath, _file );
|
||||
notify(DEBUG) << "FindFileInPath() : trying " << pathbuff << " ...\n";
|
||||
#ifdef WIN32
|
||||
if( _access( pathbuff, 4 ) == 0 ) break;
|
||||
#else
|
||||
if( access( pathbuff, F_OK ) == 0 ) break;
|
||||
#endif
|
||||
} while( (tmppath = strtok( 0, PathDelimitor )) );
|
||||
|
||||
if( tmppath != (char *)0L )
|
||||
path = strdup( pathbuff );
|
||||
|
||||
::free(tptr);
|
||||
|
||||
notify( DEBUG ) << "FindFileInPath() : returning " << path << "\n";
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
char *osg::FindFile( const char *file )
|
||||
{
|
||||
return FindFileInPath( file, s_filePath );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Order of precedence for
|
||||
|
||||
./
|
||||
OSG_LD_LIBRARY_PATH
|
||||
s_default_dso_path
|
||||
LD_LIBRARY*_PATH
|
||||
|
||||
* DO NOT USE PATH or OSGFILEPATH
|
||||
*/
|
||||
|
||||
char *osg::findDSO( const char *name )
|
||||
{
|
||||
char path[1024];
|
||||
char *ptr;
|
||||
|
||||
strcpy( path, "./" );
|
||||
|
||||
if((ptr = getenv( "OSG_LD_LIBRARY_PATH" )))
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, s_default_dso_path );
|
||||
|
||||
#ifdef __sgi
|
||||
|
||||
// bloody mess see rld(1) man page
|
||||
# if (_MIPS_SIM == _MIPS_SIM_ABI32)
|
||||
|
||||
if( (ptr = getenv( "LD_LIBRARY_PATH" )))
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
|
||||
# elif (_MIPS_SIM == _MIPS_SIM_NABI32)
|
||||
|
||||
if( !(ptr = getenv( "LD_LIBRARYN32_PATH" )))
|
||||
ptr = getenv( "LD_LIBRARY_PATH" );
|
||||
|
||||
if( ptr )
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
|
||||
# elif (_MIPS_SIM == _MIPS_SIM_ABI64)
|
||||
|
||||
if( !(ptr = getenv( "LD_LIBRARYN32_PATH" )))
|
||||
ptr = getenv( "LD_LIBRARY_PATH" );
|
||||
|
||||
if( ptr )
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
#if 0 // DO NOT USE PATH or OSGFILEPATH
|
||||
# ifdef WIN32
|
||||
if ((ptr = getenv( "PATH" )))
|
||||
{
|
||||
notify(DEBUG) << "PATH = "<<ptr<<endl;
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
# else
|
||||
if( (ptr = getenv( "LD_LIBRARY_PATH" )))
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
// #ifdef __sgi
|
||||
// strcat( path, PathDelimitor );
|
||||
// strcat( path, "/usr/lib32/osgPlugins" );
|
||||
// #else
|
||||
// strcat( path, PathDelimitor );
|
||||
// strcat( path, "/usr/lib/osgPlugins" );
|
||||
// #endif
|
||||
|
||||
#endif
|
||||
|
||||
strcat( path ,PathDelimitor );
|
||||
strcat( path, s_filePath );
|
||||
|
||||
char* fileFound = NULL;
|
||||
fileFound = FindFileInPath( name , path );
|
||||
if (fileFound) return fileFound;
|
||||
|
||||
// now try prepending the filename with "osgPlugins/"
|
||||
char* prependosgPlugins = new char[strlen(name)+12];
|
||||
strcpy(prependosgPlugins,"osgPlugins/");
|
||||
strcat(prependosgPlugins,name);
|
||||
|
||||
fileFound = FindFileInPath( prependosgPlugins , path );
|
||||
|
||||
delete prependosgPlugins;
|
||||
|
||||
return fileFound;
|
||||
#endif
|
||||
|
||||
return FindFileInPath( name, path );
|
||||
}
|
||||
|
||||
|
||||
78
src/osg/Object.cpp
Normal file
78
src/osg/Object.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#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;
|
||||
}
|
||||
75
src/osg/Output.cpp
Normal file
75
src/osg/Output.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "osg/Output"
|
||||
#include "osg/Object"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Output::Output()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
Output::~Output()
|
||||
{
|
||||
_free();
|
||||
}
|
||||
|
||||
void Output::_init()
|
||||
{
|
||||
_indent = 0;
|
||||
_indentStep = 2;
|
||||
_numIndicesPerLine = 10;
|
||||
}
|
||||
|
||||
|
||||
void Output::_free()
|
||||
{
|
||||
// should I be calling ofstream's free as well???
|
||||
}
|
||||
|
||||
|
||||
Output& Output::indent()
|
||||
{
|
||||
for(int i=0;i<_indent;++i) *this<<' ';
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Output::moveIn()
|
||||
{
|
||||
_indent += _indentStep;
|
||||
}
|
||||
|
||||
|
||||
void Output::moveOut()
|
||||
{
|
||||
_indent -= _indentStep;
|
||||
if (_indent<0) _indent=0;
|
||||
}
|
||||
|
||||
bool Output::getUniqueIDForObject(Object* obj,std::string& uniqueID)
|
||||
{
|
||||
UniqueIDToLabelMapping::iterator fitr = _objectToUniqueIDMap.find(obj);
|
||||
if (fitr != _objectToUniqueIDMap.end())
|
||||
{
|
||||
uniqueID = (*fitr).second;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Output::createUniqueIDForObject(Object* obj,std::string& uniqueID)
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str,"%s_%i",obj->className(),_objectToUniqueIDMap.size());
|
||||
uniqueID = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Output::registerUniqueIDForObject(Object* obj,std::string& uniqueID)
|
||||
{
|
||||
_objectToUniqueIDMap[obj] = uniqueID;
|
||||
return true;
|
||||
}
|
||||
|
||||
178
src/osg/Point.cpp
Normal file
178
src/osg/Point.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
// Ideas and code borrowed from GLUT pointburst demo
|
||||
// written by Mark J. Kilgard
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "osg/GL"
|
||||
#include "osg/Point"
|
||||
#include "osg/ExtensionSupported"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#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
|
||||
|
||||
#if !defined(GL_EXT_point_parameters)
|
||||
# define GL_POINT_SIZE_MIN_EXT 0x8126
|
||||
# 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
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
PFNGLPOINTPARAMETERFEXTPROC glPointParameterfEXT;
|
||||
PFNGLPOINTPARAMETERFVEXTPROC glPointParameterfvEXT;
|
||||
#endif
|
||||
|
||||
static int s_hasPointParameters;
|
||||
|
||||
|
||||
Point::Point( void )
|
||||
{
|
||||
_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
|
||||
}
|
||||
|
||||
|
||||
Point::~Point( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)
|
||||
wglGetProcAddress("glPointParameterfEXT");
|
||||
glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)
|
||||
wglGetProcAddress("glPointParameterfvEXT");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Point::enableSmooth( void )
|
||||
{
|
||||
glEnable( GL_POINT_SMOOTH );
|
||||
}
|
||||
|
||||
|
||||
void Point::disableSmooth( void )
|
||||
{
|
||||
glDisable( GL_POINT_SMOOTH );
|
||||
}
|
||||
|
||||
|
||||
void Point::setSize( float size )
|
||||
{
|
||||
_size = size;
|
||||
}
|
||||
|
||||
void Point::setFadeThresholdSize(float fadeThresholdSize)
|
||||
{
|
||||
_fadeThresholdSize = fadeThresholdSize;
|
||||
}
|
||||
|
||||
void Point::setDistanceAttenuation(const Vec3& distanceAttenuation)
|
||||
{
|
||||
_distanceAttenuation = distanceAttenuation;
|
||||
}
|
||||
|
||||
void Point::apply( void )
|
||||
{
|
||||
glPointSize(_size);
|
||||
|
||||
#if GL_EXT_point_parameters
|
||||
static bool s_gl_ext_init=false;
|
||||
|
||||
if (!s_gl_ext_init)
|
||||
{
|
||||
s_gl_ext_init = true;
|
||||
init_GL_EXT();
|
||||
}
|
||||
|
||||
if (s_hasPointParameters)
|
||||
{
|
||||
glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, (const GLfloat*)&_distanceAttenuation);
|
||||
glPointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, _fadeThresholdSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
85
src/osg/PolygonOffset.cpp
Normal file
85
src/osg/PolygonOffset.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/PolygonOffset"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
PolygonOffset::PolygonOffset( void )
|
||||
{
|
||||
_factor = 0.0f; // are these sensible defaut values?
|
||||
_units = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
PolygonOffset::~PolygonOffset( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
272
src/osg/Quat.cpp
Normal file
272
src/osg/Quat.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
#include "osg/Quat"
|
||||
#include "osg/Vec4"
|
||||
#include "osg/Vec3"
|
||||
#include "osg/Types"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/// Good introductions to Quaternions at:
|
||||
/// http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
/// http://mathworld.wolfram.com/Quaternion.html
|
||||
|
||||
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 )
|
||||
{
|
||||
float inversenorm = 1.0/sqrt( x*x + y*y + z*z );
|
||||
float coshalfangle = cos( 0.5*angle );
|
||||
float sinhalfangle = sin( 0.5*angle );
|
||||
|
||||
_fv[0] = x * sinhalfangle * inversenorm;
|
||||
_fv[1] = y * sinhalfangle * inversenorm;
|
||||
_fv[2] = z * sinhalfangle * inversenorm;
|
||||
_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
|
||||
// Watch out for the two special cases of when the vectors
|
||||
// are co-incident or opposite in direction.
|
||||
void Quat::makeRot( const Vec3& vec1, const Vec3& vec2 )
|
||||
{
|
||||
const float epsilon = 0.00001f;
|
||||
|
||||
float length1 = vec1.length();
|
||||
float length2 = vec2.length();
|
||||
float cosangle = vec1*vec2/(2*length1*length2); // dot product vec1*vec2
|
||||
|
||||
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 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get the angle of rotation and axis of this Quat object.
|
||||
// Won't give very meaningful results if the Quat is not associated
|
||||
// with a rotation!
|
||||
void Quat::getRot( float& angle, Vec3& vec ) const
|
||||
{
|
||||
float sinhalfangle = sqrt( _fv[0]*_fv[0] + _fv[1]*_fv[1] + _fv[2]*_fv[2] );
|
||||
/// float coshalfangle = _fv[3];
|
||||
|
||||
/// These are not checked for performance reasons ? (cop out!)
|
||||
/// Point for discussion - how do one handle errors in the osg?
|
||||
/// if ( abs(sinhalfangle) > 1.0 ) { error };
|
||||
/// if ( abs(coshalfangle) > 1.0 ) { error };
|
||||
|
||||
// *angle = atan2( sinhalfangle, coshalfangle ); // see man atan2
|
||||
angle = 2 * atan2( sinhalfangle, _fv[3] ); // -pi < angle < pi
|
||||
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] );
|
||||
|
||||
angle = 2 * atan2( sinhalfangle, _fv[3] );
|
||||
x = _fv[0] / sinhalfangle;
|
||||
y = _fv[1] / sinhalfangle;
|
||||
z = _fv[2] / sinhalfangle;
|
||||
}
|
||||
|
||||
|
||||
/// Spherical Linear Interpolation
|
||||
/// As t goes from 0 to 1, the Quat object goes from "from" to "to"
|
||||
/// Reference: Shoemake at SIGGRAPH 89
|
||||
/// See also
|
||||
/// http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
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
|
||||
|
||||
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 ;
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
|
||||
_fv = (from._fv*scale_from) + (to._fv*scale_to); // use Vec4 arithmetic
|
||||
// so that we get a Vec4
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define QX _fv[0]
|
||||
#define QY _fv[1]
|
||||
#define QZ _fv[2]
|
||||
#define QW _fv[3]
|
||||
|
||||
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;
|
||||
float tq[4];
|
||||
int i, j, k;
|
||||
|
||||
int nxt[3] = {1, 2, 0};
|
||||
|
||||
tr = m._mat[0][0] + m._mat[1][1] + m._mat[2][2];
|
||||
|
||||
// check the diagonal
|
||||
if (tr > 0.0)
|
||||
{
|
||||
s = (float)sqrt (tr + 1.0);
|
||||
QW = s / 2.0f;
|
||||
s = 0.5f / s;
|
||||
QX = (m._mat[1][2] - m._mat[2][1]) * s;
|
||||
QY = (m._mat[2][0] - m._mat[0][2]) * s;
|
||||
QZ = (m._mat[0][1] - m._mat[1][0]) * s;
|
||||
}
|
||||
else
|
||||
{
|
||||
// diagonal is negative
|
||||
i = 0;
|
||||
if (m._mat[1][1] > m._mat[0][0])
|
||||
i = 1;
|
||||
if (m._mat[2][2] > m._mat[i][i])
|
||||
i = 2;
|
||||
j = nxt[i];
|
||||
k = nxt[j];
|
||||
|
||||
s = (float)sqrt ((m._mat[i][i] - (m._mat[j][j] + m._mat[k][k])) + 1.0);
|
||||
|
||||
tq[i] = s * 0.5f;
|
||||
|
||||
if (s != 0.0f)
|
||||
s = 0.5f / s;
|
||||
|
||||
tq[3] = (m._mat[j][k] - m._mat[k][j]) * s;
|
||||
tq[j] = (m._mat[i][j] + m._mat[j][i]) * s;
|
||||
tq[k] = (m._mat[i][k] + m._mat[k][i]) * s;
|
||||
|
||||
QX = tq[0];
|
||||
QY = tq[1];
|
||||
QZ = tq[2];
|
||||
QW = tq[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
// calculate coefficients
|
||||
x2 = QX + QX;
|
||||
y2 = QY + QY;
|
||||
z2 = QZ + QZ;
|
||||
|
||||
xx = QX * x2;
|
||||
xy = QX * y2;
|
||||
xz = QX * z2;
|
||||
|
||||
yy = QY * y2;
|
||||
yz = QY * z2;
|
||||
zz = QZ * z2;
|
||||
|
||||
wx = QW * x2;
|
||||
wy = QW * y2;
|
||||
wz = QW * z2;
|
||||
|
||||
m._mat[0][0] = 1.0f - (yy + zz);
|
||||
m._mat[0][1] = xy - wz;
|
||||
m._mat[0][2] = xz + wy;
|
||||
m._mat[0][3] = 0.0f;
|
||||
|
||||
m._mat[1][0] = xy + wz;
|
||||
m._mat[1][1] = 1.0f - (xx + zz);
|
||||
m._mat[1][2] = yz - wx;
|
||||
m._mat[1][3] = 0.0f;
|
||||
|
||||
m._mat[2][0] = xz - wy;
|
||||
m._mat[2][1] = yz + wx;
|
||||
m._mat[2][2] = 1.0f - (xx + yy);
|
||||
m._mat[2][3] = 0.0f;
|
||||
|
||||
m._mat[3][0] = 0;
|
||||
m._mat[3][1] = 0;
|
||||
m._mat[3][2] = 0;
|
||||
m._mat[3][3] = 1;
|
||||
}
|
||||
101
src/osg/ReaderWriterOSG.cpp
Normal file
101
src/osg/ReaderWriterOSG.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "osg/Registry"
|
||||
|
||||
#include "osg/Object"
|
||||
#include "osg/Image"
|
||||
#include "osg/Node"
|
||||
#include "osg/Group"
|
||||
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#ifdef __sgi
|
||||
using std::string;
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
class DefaultReaderWriter : public ReaderWriter
|
||||
{
|
||||
public:
|
||||
virtual const char* className() { return "Default OSG Reader/Writer"; }
|
||||
virtual bool acceptsExtension(const string& extension) { return extension=="osg" || extension=="OSG"; }
|
||||
|
||||
virtual Object* readObject(const string& fileName) { return readNode(fileName); }
|
||||
virtual Node* readNode(const string& fileName)
|
||||
{
|
||||
ifstream fin(fileName.c_str());
|
||||
if (fin)
|
||||
{
|
||||
Input fr;
|
||||
fr.attach(&fin);
|
||||
|
||||
Group* group = new Group;
|
||||
group->setName("import group");
|
||||
|
||||
// load all nodes in file, placing them in a group.
|
||||
while(!fr.eof())
|
||||
{
|
||||
Node *node = fr.readNode();
|
||||
if (node) group->addChild(node);
|
||||
else fr.advanceOverCurrentFieldOrBlock();
|
||||
}
|
||||
|
||||
if (group->getNumChildren()>1)
|
||||
{
|
||||
return group;
|
||||
}
|
||||
else if (group->getNumChildren()==1)
|
||||
{
|
||||
// only one node loaded so just return that one node,
|
||||
// and delete the redundent group. Note, the
|
||||
// child must be referenced before defrencing
|
||||
// the group so to avoid delete its children.
|
||||
Node* node = group->getChild(0);
|
||||
node->ref();
|
||||
group->unref();
|
||||
return node;
|
||||
} // group->getNumChildren()==0
|
||||
else
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool writeObject(Object& obj,const string& fileName)
|
||||
{
|
||||
Output fout;
|
||||
fout.open(fileName.c_str());
|
||||
if (fout)
|
||||
{
|
||||
obj.write(fout);
|
||||
fout.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool writeNode(Node& node,const string& fileName)
|
||||
{
|
||||
Output fout;
|
||||
fout.open(fileName.c_str());
|
||||
if (fout)
|
||||
{
|
||||
|
||||
node.write(fout);
|
||||
fout.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
RegisterReaderWriterProxy<DefaultReaderWriter> g_defaultReaderWriterProxy;
|
||||
380
src/osg/ReaderWriterRGB.cpp
Normal file
380
src/osg/ReaderWriterRGB.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
#include "osg/Image"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
#include "osg/FileNameUtils"
|
||||
|
||||
#include "osg/Registry"
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/GeoState>
|
||||
#include <osg/Texture>
|
||||
|
||||
#include "osg/GL"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
typedef struct _rawImageRec
|
||||
{
|
||||
unsigned short imagic;
|
||||
unsigned short type;
|
||||
unsigned short dim;
|
||||
unsigned short sizeX, sizeY, sizeZ;
|
||||
unsigned long min, max;
|
||||
unsigned long wasteBytes;
|
||||
char name[80];
|
||||
unsigned long colorMap;
|
||||
FILE *file;
|
||||
unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
|
||||
unsigned long rleEnd;
|
||||
GLuint *rowStart;
|
||||
GLint *rowSize;
|
||||
} rawImageRec;
|
||||
|
||||
static void ConvertShort(unsigned short *array, long length)
|
||||
{
|
||||
unsigned long b1, b2;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = (unsigned char *)array;
|
||||
while (length--)
|
||||
{
|
||||
b1 = *ptr++;
|
||||
b2 = *ptr++;
|
||||
*array++ = (unsigned short) ((b1 << 8) | (b2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ConvertLong(GLuint *array, long length)
|
||||
{
|
||||
unsigned long b1, b2, b3, b4;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = (unsigned char *)array;
|
||||
while (length--)
|
||||
{
|
||||
b1 = *ptr++;
|
||||
b2 = *ptr++;
|
||||
b3 = *ptr++;
|
||||
b4 = *ptr++;
|
||||
*array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static rawImageRec *RawImageOpen(const char *fileName)
|
||||
{
|
||||
union
|
||||
{
|
||||
int testWord;
|
||||
char testByte[4];
|
||||
} endianTest;
|
||||
rawImageRec *raw;
|
||||
GLenum swapFlag;
|
||||
int x;
|
||||
|
||||
endianTest.testWord = 1;
|
||||
if (endianTest.testByte[0] == 1)
|
||||
{
|
||||
swapFlag = GL_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
swapFlag = GL_FALSE;
|
||||
}
|
||||
|
||||
raw = (rawImageRec *)malloc(sizeof(rawImageRec));
|
||||
if (raw == NULL)
|
||||
{
|
||||
notify(WARN)<< "Out of memory!"<<endl;
|
||||
return NULL;
|
||||
}
|
||||
if ((raw->file = fopen(fileName, "rb")) == NULL)
|
||||
{
|
||||
perror(fileName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fread(raw, 1, 12, raw->file);
|
||||
|
||||
if (swapFlag)
|
||||
{
|
||||
ConvertShort(&raw->imagic, 6);
|
||||
}
|
||||
|
||||
raw->tmp = raw->tmpR = raw->tmpG = raw->tmpB = raw->tmpA = 0L;
|
||||
|
||||
raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
|
||||
if (raw->tmp == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( raw->sizeZ >= 1 )
|
||||
{
|
||||
if( (raw->tmpR = (unsigned char *)malloc(raw->sizeX)) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
free( raw->tmp );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( raw->sizeZ >= 2 )
|
||||
{
|
||||
if( (raw->tmpG = (unsigned char *)malloc(raw->sizeX)) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
free( raw->tmp );
|
||||
free( raw->tmpR );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( raw->sizeZ >= 3 )
|
||||
{
|
||||
if( (raw->tmpB = (unsigned char *)malloc(raw->sizeX)) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
free( raw->tmp );
|
||||
free( raw->tmpR );
|
||||
free( raw->tmpG );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (raw->sizeZ >= 4)
|
||||
{
|
||||
if( (raw->tmpA = (unsigned char *)malloc(raw->sizeX)) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
free( raw->tmp );
|
||||
free( raw->tmpR );
|
||||
free( raw->tmpG );
|
||||
free( raw->tmpB );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((raw->type & 0xFF00) == 0x0100)
|
||||
{
|
||||
x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
|
||||
raw->rowStart = (GLuint *)malloc(x);
|
||||
raw->rowSize = (GLint *)malloc(x);
|
||||
if (raw->rowStart == NULL || raw->rowSize == NULL)
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
return NULL;
|
||||
}
|
||||
raw->rleEnd = 512 + (2 * x);
|
||||
fseek(raw->file, 512, SEEK_SET);
|
||||
fread(raw->rowStart, 1, x, raw->file);
|
||||
fread(raw->rowSize, 1, x, raw->file);
|
||||
if (swapFlag)
|
||||
{
|
||||
ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
|
||||
ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
|
||||
}
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
||||
|
||||
static void RawImageClose(rawImageRec *raw)
|
||||
{
|
||||
fclose(raw->file);
|
||||
free(raw->tmp);
|
||||
if( raw->tmpR )
|
||||
free(raw->tmpR);
|
||||
if( raw->tmpG )
|
||||
free(raw->tmpG);
|
||||
if( raw->tmpB )
|
||||
free(raw->tmpB);
|
||||
if( raw->tmpA )
|
||||
free(raw->tmpA);
|
||||
|
||||
free(raw);
|
||||
}
|
||||
|
||||
|
||||
static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
|
||||
{
|
||||
unsigned char *iPtr, *oPtr, pixel;
|
||||
int count, done = 0;
|
||||
|
||||
if ((raw->type & 0xFF00) == 0x0100)
|
||||
{
|
||||
fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
|
||||
fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
|
||||
raw->file);
|
||||
|
||||
iPtr = raw->tmp;
|
||||
oPtr = buf;
|
||||
while (!done)
|
||||
{
|
||||
pixel = *iPtr++;
|
||||
count = (int)(pixel & 0x7F);
|
||||
if (!count)
|
||||
{
|
||||
done = 1;
|
||||
return;
|
||||
}
|
||||
if (pixel & 0x80)
|
||||
{
|
||||
while (count--)
|
||||
{
|
||||
*oPtr++ = *iPtr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel = *iPtr++;
|
||||
while (count--)
|
||||
{
|
||||
*oPtr++ = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
|
||||
SEEK_SET);
|
||||
fread(buf, 1, raw->sizeX, raw->file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void RawImageGetData(rawImageRec *raw, unsigned char **data )
|
||||
{
|
||||
unsigned char *ptr;
|
||||
int i, j;
|
||||
|
||||
// // round the width to a factor 4
|
||||
// int width = (int)(floorf((float)raw->sizeX/4.0f)*4.0f);
|
||||
// if (width!=raw->sizeX) width += 4;
|
||||
|
||||
*data = (unsigned char *)malloc(2 * (raw->sizeX+1)*(raw->sizeY+1)*4);
|
||||
// *data = (unsigned char *)malloc(2 * (width+1)*(raw->sizeY+1)*4);
|
||||
|
||||
ptr = *data;
|
||||
for (i = 0; i < (int)(raw->sizeY); i++)
|
||||
{
|
||||
if( raw->sizeZ >= 1 )
|
||||
RawImageGetRow(raw, raw->tmpR, i, 0);
|
||||
if( raw->sizeZ >= 2 )
|
||||
RawImageGetRow(raw, raw->tmpG, i, 1);
|
||||
if( raw->sizeZ >= 3 )
|
||||
RawImageGetRow(raw, raw->tmpB, i, 2);
|
||||
if( raw->sizeZ >= 4 )
|
||||
RawImageGetRow(raw, raw->tmpA, i, 3);
|
||||
for (j = 0; j < (int)(raw->sizeX); j++)
|
||||
{
|
||||
if( raw->sizeZ >= 1 )
|
||||
*ptr++ = *(raw->tmpR + j);
|
||||
if( raw->sizeZ >= 2 )
|
||||
*ptr++ = *(raw->tmpG + j);
|
||||
if( raw->sizeZ >= 3 )
|
||||
*ptr++ = *(raw->tmpB + j);
|
||||
if( raw->sizeZ >= 4 )
|
||||
*ptr++ = *(raw->tmpA + j);
|
||||
}
|
||||
// // pad the image width with blanks to bring it up to the rounded width.
|
||||
// for(;j<width;++j) *ptr++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ReaderWriterRGB : public ReaderWriter
|
||||
{
|
||||
public:
|
||||
virtual const char* className() { return "Default RGB Image Reader/Writer"; }
|
||||
virtual bool acceptsExtension(const std::string& extension)
|
||||
{
|
||||
return extension=="rgb" || extension=="rgba" ||
|
||||
extension=="int" || extension=="inta" ||
|
||||
extension=="bw";
|
||||
}
|
||||
|
||||
|
||||
virtual Node* readNode(const std::string& fileName)
|
||||
{
|
||||
Image* image = readImage(fileName);
|
||||
if (image)
|
||||
{
|
||||
Geode* geode = createGeodeForImage(image);
|
||||
if (geode==NULL) image->unref();
|
||||
return geode;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual Image* readImage(const std::string& fileName)
|
||||
{
|
||||
std::string ext = getLowerCaseFileExtension(fileName);
|
||||
if (!acceptsExtension(ext)) return NULL;
|
||||
|
||||
rawImageRec *raw;
|
||||
|
||||
if( (raw = RawImageOpen(fileName.c_str())) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Unable to open \""<<fileName<<"\""<<endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int s = raw->sizeX;
|
||||
int t = raw->sizeY;
|
||||
int r = 1;
|
||||
|
||||
#if 0
|
||||
int internalFormat = raw->sizeZ == 3 ? GL_RGB5 :
|
||||
raw->sizeZ == 4 ? GL_RGB5_A1 : GL_RGB;
|
||||
#else
|
||||
int internalFormat = raw->sizeZ;
|
||||
#endif
|
||||
unsigned int pixelFormat =
|
||||
raw->sizeZ == 1 ? GL_LUMINANCE :
|
||||
raw->sizeZ == 2 ? GL_LUMINANCE_ALPHA :
|
||||
raw->sizeZ == 3 ? GL_RGB :
|
||||
raw->sizeZ == 4 ? GL_RGBA : (GLenum)-1;
|
||||
|
||||
unsigned int dataType = GL_UNSIGNED_BYTE;
|
||||
|
||||
unsigned char *data;
|
||||
RawImageGetData(raw, &data);
|
||||
RawImageClose(raw);
|
||||
|
||||
Image* image = new Image();
|
||||
image->setFileName(fileName.c_str());
|
||||
image->setImage(s,t,r,
|
||||
internalFormat,
|
||||
pixelFormat,
|
||||
dataType,
|
||||
data);
|
||||
|
||||
notify(INFO) << "image read ok "<<s<<" "<<t<<endl;
|
||||
return image;
|
||||
|
||||
}
|
||||
|
||||
virtual bool writeImage(Image& ,const std::string& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
RegisterReaderWriterProxy<ReaderWriterRGB> g_readerWriter_RGB_Proxy;
|
||||
543
src/osg/Registry.cpp
Normal file
543
src/osg/Registry.cpp
Normal file
@@ -0,0 +1,543 @@
|
||||
#include "osg/Registry"
|
||||
|
||||
#include "osg/Notify"
|
||||
#include "osg/Object"
|
||||
#include "osg/Image"
|
||||
#include "osg/Node"
|
||||
#include "osg/Group"
|
||||
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/FileNameUtils"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Object* osg::loadObjectFile(const char *name)
|
||||
{
|
||||
return Registry::instance()->readObject(name);
|
||||
}
|
||||
Image* osg::loadImageFile(const char *name)
|
||||
{
|
||||
return Registry::instance()->readImage(name);
|
||||
}
|
||||
|
||||
Node* osg::loadNodeFile(const char *name)
|
||||
{
|
||||
return Registry::instance()->readNode(name);
|
||||
}
|
||||
|
||||
bool osg::saveObjectFile(Object& object,const char *name)
|
||||
{
|
||||
return Registry::instance()->writeObject(object,name);
|
||||
}
|
||||
|
||||
bool osg::saveImageFile(Image& image,const char *name)
|
||||
{
|
||||
return Registry::instance()->writeImage(image,name);
|
||||
}
|
||||
|
||||
bool osg::saveNodeFile(Node& node,const char *name)
|
||||
{
|
||||
return Registry::instance()->writeNode(node,name);
|
||||
}
|
||||
|
||||
// definition of the Registry
|
||||
Registry::Registry()
|
||||
{
|
||||
notify(INFO) << "Constructing osg::Registry"<<endl;
|
||||
_openingLibrary = false;
|
||||
osg::Init();
|
||||
}
|
||||
|
||||
|
||||
Registry::~Registry()
|
||||
{
|
||||
// Don't write to notify() in here. Destruction order is indeterminate
|
||||
// (I think) and the notify stream may have been destroyed before this
|
||||
// is called.
|
||||
|
||||
// note, do not need to unregister attached prototype and reader/writers
|
||||
// as they will be automatically unreferenced by the std::vector
|
||||
// destructor & ref_ptr combination.
|
||||
|
||||
}
|
||||
|
||||
Registry* Registry::instance()
|
||||
{
|
||||
static Registry s_nodeFactory;
|
||||
return &s_nodeFactory;
|
||||
}
|
||||
|
||||
|
||||
void Registry::addPrototype(Object* obj)
|
||||
{
|
||||
if (obj==0L) return;
|
||||
|
||||
// works under win32, good old C :-)
|
||||
if (_openingLibrary) notify(INFO) << "Opening Library : ";
|
||||
notify(INFO) << "osg::Registry::addPrototype("<<obj->className()<<")"<<endl;
|
||||
|
||||
int newPos = _nodeProtoList.size();
|
||||
|
||||
_protoList.push_back(obj);
|
||||
|
||||
if (dynamic_cast<Node*>(obj))
|
||||
{
|
||||
_nodeProtoList.push_back(newPos);
|
||||
}
|
||||
if (dynamic_cast<Image*>(obj))
|
||||
{
|
||||
_imageProtoList.push_back(newPos);
|
||||
}
|
||||
}
|
||||
|
||||
void Registry::removePrototype(Object* obj)
|
||||
{
|
||||
if (obj==0L) return;
|
||||
|
||||
notify(INFO) << "osg::Registry::removePrototype()"<<endl;
|
||||
|
||||
PrototypeList::iterator pitr = std::find(_protoList.begin(),_protoList.end(),obj);
|
||||
if (pitr!=_protoList.end())
|
||||
{
|
||||
_protoList.erase(pitr);
|
||||
|
||||
// note need to handle the node and image lists,
|
||||
// to be implemented...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Registry::addReaderWriter(ReaderWriter* rw)
|
||||
{
|
||||
if (rw==0L) return;
|
||||
|
||||
if (_openingLibrary) notify(INFO) << "Opening Library : "<<endl;
|
||||
|
||||
notify(INFO) << "osg::Registry::addReaderWriter("<<rw->className()<<")"<<endl;
|
||||
|
||||
_rwList.push_back(rw);
|
||||
|
||||
}
|
||||
|
||||
void Registry::removeReaderWriter(ReaderWriter* rw)
|
||||
{
|
||||
if (rw==0L) return;
|
||||
|
||||
notify(INFO) << "osg::Registry::removeReaderWriter();"<<endl;
|
||||
|
||||
ReaderWriterList::iterator rwitr = std::find(_rwList.begin(),_rwList.end(),rw);
|
||||
if (rwitr!=_rwList.end())
|
||||
{
|
||||
_rwList.erase(rwitr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string Registry::createLibraryNameForFile(const std::string& fileName)
|
||||
{
|
||||
std::string ext = getLowerCaseFileExtension(fileName);
|
||||
return createLibraryNameForExt(ext);
|
||||
}
|
||||
|
||||
std::string Registry::createLibraryNameForExt(const std::string& ext)
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef _DEBUG
|
||||
return "osgdb_"+ext+"d.dll";
|
||||
# else
|
||||
return "osgdb_"+ext+".dll";
|
||||
# endif
|
||||
#else
|
||||
return "osgdb_"+ext+".so";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool Registry::loadLibrary(const std::string& fileName)
|
||||
{
|
||||
DynamicLibrary* dl = getLibrary(fileName);
|
||||
if (dl) return false;
|
||||
|
||||
_openingLibrary=true;
|
||||
|
||||
|
||||
dl = DynamicLibrary::loadLibrary(fileName);
|
||||
_openingLibrary=false;
|
||||
|
||||
if (dl)
|
||||
{
|
||||
dl->ref();
|
||||
_dlList.push_back(dl);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Registry::closeLibrary(const std::string& fileName)
|
||||
{
|
||||
DynamicLibraryList::iterator ditr = getLibraryItr(fileName);
|
||||
if (ditr!=_dlList.end())
|
||||
{
|
||||
(*ditr)->unref();
|
||||
_dlList.erase(ditr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Registry::DynamicLibraryList::iterator Registry::getLibraryItr(const std::string& fileName)
|
||||
{
|
||||
DynamicLibraryList::iterator ditr = _dlList.begin();
|
||||
for(;ditr!=_dlList.end();++ditr)
|
||||
{
|
||||
if ((*ditr)->getName()==fileName) return ditr;
|
||||
}
|
||||
return _dlList.end();
|
||||
}
|
||||
|
||||
DynamicLibrary* Registry::getLibrary(const std::string& fileName)
|
||||
{
|
||||
DynamicLibraryList::iterator ditr = getLibraryItr(fileName);
|
||||
if (ditr!=_dlList.end()) return ditr->get();
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
||||
Object* Registry::readObject(Input& fr)
|
||||
{
|
||||
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString()) {
|
||||
Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
|
||||
if (obj) fr+=2;
|
||||
return obj;
|
||||
}
|
||||
else return NULL;
|
||||
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<_protoList.size();++i)
|
||||
{
|
||||
Object* obj = _protoList[i]->readClone(fr);
|
||||
if (obj) return obj;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
Object* Registry::readObject(const std::string& fileName)
|
||||
{
|
||||
char *file = FindFile( fileName.c_str() );
|
||||
if (file==NULL) return NULL;
|
||||
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
Object* obj = (*itr)->readObject(file);
|
||||
if (obj) return obj;
|
||||
}
|
||||
|
||||
// now look for a plug-in to load the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (Registry::instance()->loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
Object* obj = (*itr)->readObject(file);
|
||||
if (obj) return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to read file "<<fileName<<endl;
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool Registry::writeObject(Object& obj,const std::string& fileName)
|
||||
{
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
if ((*itr)->writeObject(obj,fileName)) return true;
|
||||
}
|
||||
|
||||
// now look for a plug-in to save the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
if ((*itr)->writeObject(obj,fileName)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to write file "<<fileName<<endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Image* Registry::readImage(Input& fr)
|
||||
{
|
||||
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString()) {
|
||||
Image* image = dynamic_cast<Image*>(fr.getObjectForUniqueID(fr[1].getStr()));
|
||||
if (image) fr+=2;
|
||||
return image;
|
||||
}
|
||||
else return NULL;
|
||||
|
||||
}
|
||||
|
||||
for(std::vector<int>::iterator itr=_imageProtoList.begin();
|
||||
itr!=_imageProtoList.end();
|
||||
++itr)
|
||||
{
|
||||
int i=*itr;
|
||||
Object* obj = _protoList[i]->readClone(fr);
|
||||
if (obj)
|
||||
{
|
||||
Image* image = static_cast<Image*>(obj);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
Image* Registry::readImage(const std::string& fileName)
|
||||
{
|
||||
char *file = FindFile( fileName.c_str() );
|
||||
if (file==NULL) return NULL;
|
||||
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
Image* image = (*itr)->readImage(file);
|
||||
if (image) return image;
|
||||
}
|
||||
|
||||
// now look for a plug-in to load the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
Image* image = (*itr)->readImage(file);
|
||||
if (image) return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to read file "<<fileName<<endl;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool Registry::writeImage(Image& image,const std::string& fileName)
|
||||
{
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
if ((*itr)->writeImage(image,fileName)) return true;
|
||||
}
|
||||
|
||||
// now look for a plug-in to save the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
if ((*itr)->writeImage(image,fileName)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to write file "<<fileName<<endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Node* Registry::readNode(Input& fr)
|
||||
{
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString()) {
|
||||
Node* node = dynamic_cast<Node*>(fr.getObjectForUniqueID(fr[1].getStr()));
|
||||
if (node) fr+=2;
|
||||
return node;
|
||||
}
|
||||
else return NULL;
|
||||
|
||||
}
|
||||
|
||||
std::vector<int>::iterator itr=_nodeProtoList.begin();
|
||||
for(;itr!=_nodeProtoList.end();++itr)
|
||||
{
|
||||
int i=*itr;
|
||||
Object* obj = _protoList[i]->readClone(fr);
|
||||
if (obj)
|
||||
{
|
||||
Node* node = static_cast<Node*>(obj);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
Node* Registry::readNode(const std::string& fileName)
|
||||
{
|
||||
|
||||
char *file = FindFile( fileName.c_str() );
|
||||
if (file==NULL) return NULL;
|
||||
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
Node* node = (*itr)->readNode(file);
|
||||
if (node) return node;
|
||||
}
|
||||
|
||||
// now look for a plug-in to load the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
notify(INFO) << "Now checking for plug-in "<<libraryName<<endl;
|
||||
if (loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
Node* node = (*itr)->readNode(file);
|
||||
if (node) return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to read file "<<fileName<<endl;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool Registry::writeNode(Node& node,const std::string& fileName)
|
||||
{
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
if ((*itr)->writeNode(node,fileName)) return true;
|
||||
}
|
||||
|
||||
// now look for a plug-in to save the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (Registry::instance()->loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
if ((*itr)->writeNode(node,fileName)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to write file "<<fileName<<endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
69
src/osg/Scene.cpp
Normal file
69
src/osg/Scene.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "osg/Scene"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Scene> g_SceneProxy;
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
_gstate = NULL;
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
if (_gstate) _gstate->unref();
|
||||
}
|
||||
|
||||
void Scene::setGState(osg::GeoState* gstate)
|
||||
{
|
||||
if (gstate==_gstate) return;
|
||||
|
||||
if (_gstate) _gstate->unref();
|
||||
|
||||
_gstate = gstate;
|
||||
if (_gstate) _gstate->ref();
|
||||
}
|
||||
|
||||
bool Scene::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString()) {
|
||||
GeoState* geostate = dynamic_cast<GeoState*>(fr.getObjectForUniqueID(fr[1].getStr()));
|
||||
if (geostate) {
|
||||
fr+=2;
|
||||
_gstate = geostate;
|
||||
_gstate->ref();
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GeoState* readState = static_cast<GeoState*>(GeoState::instance()->readClone(fr)))
|
||||
{
|
||||
_gstate = readState;
|
||||
_gstate->ref();
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (Group::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
bool Scene::writeLocalData(Output& fw)
|
||||
{
|
||||
if (_gstate)
|
||||
{
|
||||
_gstate->write(fw);
|
||||
}
|
||||
|
||||
Group::writeLocalData(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
270
src/osg/Seg.cpp
Normal file
270
src/osg/Seg.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
#include "osg/Seg"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
bool Seg::intersectAndClip(Vec3& s,Vec3& e,const BoundingBox& bb)
|
||||
{
|
||||
// compate s and e against the xMin to xMax range of bb.
|
||||
if (s.x()<=e.x())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.x()<bb.xMin()) return false;
|
||||
if (s.x()>bb.xMax()) return false;
|
||||
|
||||
if (s.x()<bb.xMin())
|
||||
{
|
||||
// clip s to xMin.
|
||||
s = s+(e-s)*(bb.xMin()-s.x())/(e.x()-s.x());
|
||||
}
|
||||
|
||||
if (e.x()>bb.xMax())
|
||||
{
|
||||
// clip e to xMax.
|
||||
e = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.x()<bb.xMin()) return false;
|
||||
if (e.x()>bb.xMax()) return false;
|
||||
|
||||
if (e.x()<bb.xMin())
|
||||
{
|
||||
// clip s to xMin.
|
||||
e = s+(e-s)*(bb.xMin()-s.x())/(e.x()-s.x());
|
||||
}
|
||||
|
||||
if (s.x()>bb.xMax())
|
||||
{
|
||||
// clip e to xMax.
|
||||
s = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x());
|
||||
}
|
||||
}
|
||||
|
||||
// compate s and e against the yMin to yMax range of bb.
|
||||
if (s.y()<=e.y())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.y()<bb.yMin()) return false;
|
||||
if (s.y()>bb.yMax()) return false;
|
||||
|
||||
if (s.y()<bb.yMin())
|
||||
{
|
||||
// clip s to yMin.
|
||||
s = s+(e-s)*(bb.yMin()-s.y())/(e.y()-s.y());
|
||||
}
|
||||
|
||||
if (e.y()>bb.yMax())
|
||||
{
|
||||
// clip e to yMax.
|
||||
e = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.y()<bb.yMin()) return false;
|
||||
if (e.y()>bb.yMax()) return false;
|
||||
|
||||
if (e.y()<bb.yMin())
|
||||
{
|
||||
// clip s to yMin.
|
||||
e = s+(e-s)*(bb.yMin()-s.y())/(e.y()-s.y());
|
||||
}
|
||||
|
||||
if (s.y()>bb.yMax())
|
||||
{
|
||||
// clip e to yMax.
|
||||
s = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y());
|
||||
}
|
||||
}
|
||||
|
||||
// compate s and e against the zMin to zMax range of bb.
|
||||
if (s.z()<=e.z())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.z()<bb.zMin()) return false;
|
||||
if (s.z()>bb.zMax()) return false;
|
||||
|
||||
if (s.z()<bb.zMin())
|
||||
{
|
||||
// clip s to zMin.
|
||||
s = s+(e-s)*(bb.zMin()-s.z())/(e.z()-s.z());
|
||||
}
|
||||
|
||||
if (e.z()>bb.zMax())
|
||||
{
|
||||
// clip e to zMax.
|
||||
e = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.z()<bb.zMin()) return false;
|
||||
if (e.z()>bb.zMax()) return false;
|
||||
|
||||
if (e.z()<bb.zMin())
|
||||
{
|
||||
// clip s to zMin.
|
||||
e = s+(e-s)*(bb.zMin()-s.z())/(e.z()-s.z());
|
||||
}
|
||||
|
||||
if (s.z()>bb.zMax())
|
||||
{
|
||||
// clip e to zMax.
|
||||
s = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seg::intersect(const BoundingBox& bb) const
|
||||
{
|
||||
if (!bb.isValid()) return false;
|
||||
|
||||
Vec3 s=_s,e=_e;
|
||||
return intersectAndClip(s,e,bb);
|
||||
}
|
||||
|
||||
bool Seg::intersect(const BoundingBox& bb,float& r1,float& r2) const
|
||||
{
|
||||
if (!bb.isValid()) return false;
|
||||
|
||||
Vec3 s=_s,e=_e;
|
||||
return intersectAndClip(s,e,bb);
|
||||
}
|
||||
|
||||
bool Seg::intersect(const BoundingSphere& bs,float& r1,float& r2) const
|
||||
{
|
||||
Vec3 sm = _s-bs._center;
|
||||
float c = sm.length2()-bs._radius*bs._radius;
|
||||
|
||||
Vec3 se = _e-_s;
|
||||
float a = se.length2();
|
||||
|
||||
float b = sm*se*2.0f;
|
||||
|
||||
float d = b*b-4.0f*a*c;
|
||||
|
||||
if (d<0.0f) return false;
|
||||
|
||||
d = sqrtf(d);
|
||||
|
||||
float div = 1.0f/(2.0f*a);
|
||||
|
||||
r1 = (-b-d)*div;
|
||||
r2 = (-b+d)*div;
|
||||
|
||||
if (r1<=0.0f && r2<=0.0f) return false;
|
||||
|
||||
if (r1>=1.0f && r2>=1.0f) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seg::intersect(const BoundingSphere& bs) const
|
||||
{
|
||||
Vec3 sm = _s-bs._center;
|
||||
float c = sm.length2()-bs._radius*bs._radius;
|
||||
if (c<0.0f) return true;
|
||||
|
||||
Vec3 se = _e-_s;
|
||||
float a = se.length2();
|
||||
|
||||
float b = (sm*se)*2.0f;
|
||||
|
||||
float d = b*b-4.0f*a*c;
|
||||
|
||||
if (d<0.0f) return false;
|
||||
|
||||
d = sqrtf(d);
|
||||
|
||||
float div = 1.0f/(2.0f*a);
|
||||
|
||||
float r1 = (-b-d)*div;
|
||||
float r2 = (-b+d)*div;
|
||||
|
||||
if (r1<=0.0f && r2<=0.0f) return false;
|
||||
|
||||
if (r1>=1.0f && r2>=1.0f) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seg::intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r)
|
||||
{
|
||||
if (v1==v2 || v2==v3 || v1==v3) return false;
|
||||
|
||||
Vec3 vse = _e-_s;
|
||||
|
||||
Vec3 v12 = v2-v1;
|
||||
Vec3 n12 = v12^vse;
|
||||
float ds12 = (_s-v1)*n12;
|
||||
float d312 = (v3-v1)*n12;
|
||||
if (d312>=0.0f)
|
||||
{
|
||||
if (ds12<0.0f) return false;
|
||||
if (ds12>d312) return false;
|
||||
}
|
||||
else // d312 < 0
|
||||
{
|
||||
if (ds12>0.0f) return false;
|
||||
if (ds12<d312) return false;
|
||||
}
|
||||
|
||||
|
||||
Vec3 v23 = v3-v2;
|
||||
Vec3 n23 = v23^vse;
|
||||
float ds23 = (_s-v2)*n23;
|
||||
float d123 = (v1-v2)*n23;
|
||||
if (d123>=0.0f)
|
||||
{
|
||||
if (ds23<0.0f) return false;
|
||||
if (ds23>d123) return false;
|
||||
}
|
||||
else // d123 < 0
|
||||
{
|
||||
if (ds23>0.0f) return false;
|
||||
if (ds23<d123) return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vec3 v31 = v1-v3;
|
||||
Vec3 n31 = v31^vse;
|
||||
float ds31 = (_s-v3)*n31;
|
||||
float d231 = (v2-v3)*n31;
|
||||
if (d231>=0.0f)
|
||||
{
|
||||
if (ds31<0.0f) return false;
|
||||
if (ds31>d231) return false;
|
||||
}
|
||||
else // d231 < 0
|
||||
{
|
||||
if (ds31>0.0f) return false;
|
||||
if (ds31<d231) return false;
|
||||
}
|
||||
|
||||
float r3 = ds12/d312;
|
||||
float r1 = ds23/d123;
|
||||
float r2 = ds31/d231;
|
||||
|
||||
// float rt = r1+r2+r3;
|
||||
|
||||
Vec3 in = v1*r1+v2*r2+v3*r3;
|
||||
|
||||
float length = vse.length();
|
||||
vse /= length;
|
||||
float d = (in-_s)*vse;
|
||||
|
||||
|
||||
if (d<0.0f) return false;
|
||||
if (d>length) return false;
|
||||
|
||||
r = d/length;
|
||||
|
||||
return true;
|
||||
}
|
||||
8
src/osg/Sequence.cpp
Normal file
8
src/osg/Sequence.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "osg/Sequence"
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Sequence> g_SequenceProxy;
|
||||
|
||||
// to be written :-)
|
||||
87
src/osg/Switch.cpp
Normal file
87
src/osg/Switch.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "osg/Switch"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Switch> g_SwitchProxy;
|
||||
|
||||
Switch::Switch()
|
||||
{
|
||||
_value = ALL_CHILDREN_OFF;
|
||||
}
|
||||
|
||||
void Switch::traverse(NodeVisitor& nv)
|
||||
{
|
||||
switch(nv.getTraverseMode())
|
||||
{
|
||||
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):
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
78
src/osg/TexEnv.cpp
Normal file
78
src/osg/TexEnv.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "osg/TexEnv"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexEnv::TexEnv( void )
|
||||
{
|
||||
_mode = MODULATE;
|
||||
}
|
||||
|
||||
TexEnv::~TexEnv( void )
|
||||
{
|
||||
}
|
||||
|
||||
TexEnv* TexEnv::instance()
|
||||
{
|
||||
static ref_ptr<TexEnv> s_TexEnv(new TexEnv);
|
||||
return s_TexEnv.get();
|
||||
}
|
||||
|
||||
|
||||
void TexEnv::setMode( TexEnvMode mode )
|
||||
{
|
||||
_mode = (mode == DECAL ||
|
||||
mode == MODULATE ||
|
||||
mode == BLEND ) ?
|
||||
mode : MODULATE;
|
||||
}
|
||||
|
||||
void TexEnv::apply( void )
|
||||
{
|
||||
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;
|
||||
}
|
||||
89
src/osg/TexGen.cpp
Normal file
89
src/osg/TexGen.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
#include "osg/TexGen"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexGen::TexGen( void )
|
||||
{
|
||||
_mode = OBJECT_LINEAR;
|
||||
}
|
||||
|
||||
|
||||
TexGen::~TexGen( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TexGen* TexGen::instance()
|
||||
{
|
||||
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))
|
||||
{
|
||||
_mode = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
25
src/osg/TexMat.cpp
Normal file
25
src/osg/TexMat.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/TexMat"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexMat::TexMat( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TexMat::~TexMat( void )
|
||||
{
|
||||
}
|
||||
|
||||
TexMat* TexMat::instance()
|
||||
{
|
||||
static ref_ptr<TexMat> s_texmat(new TexMat);
|
||||
return s_texmat.get();
|
||||
}
|
||||
|
||||
void TexMat::apply( void )
|
||||
{
|
||||
glMatrixMode( GL_TEXTURE );
|
||||
glLoadMatrixf( (GLfloat *)_mat );
|
||||
}
|
||||
257
src/osg/Texture.cpp
Normal file
257
src/osg/Texture.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
#include "osg/Texture"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Image"
|
||||
#include "osg/Referenced"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Texture::Texture()
|
||||
{
|
||||
_handle = 0;
|
||||
|
||||
_wrap_s = CLAMP;
|
||||
_wrap_t = CLAMP;
|
||||
_wrap_r = CLAMP;
|
||||
_min_filter = NEAREST_MIPMAP_LINEAR;
|
||||
_mag_filter = LINEAR;
|
||||
}
|
||||
|
||||
|
||||
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 "";
|
||||
}
|
||||
|
||||
void Texture::setImage(Image* image)
|
||||
{
|
||||
if (_handle!=0) glDeleteTextures( 1, &_handle );
|
||||
_handle = 0;
|
||||
_image = image;
|
||||
}
|
||||
|
||||
void Texture::setWrap(WrapParameter which, WrapMode wrap)
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case WRAP_S : _wrap_s = wrap; break;
|
||||
case WRAP_T : _wrap_t = wrap; break;
|
||||
case WRAP_R : _wrap_r = wrap; break;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed Texture::setWrap("<<(unsigned int)which<<","<<(unsigned int)wrap<<")"<<endl; break;
|
||||
}
|
||||
}
|
||||
|
||||
Texture::WrapMode Texture::getWrap(WrapParameter which) const
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case WRAP_S : return _wrap_s;
|
||||
case WRAP_T : return _wrap_t;
|
||||
case WRAP_R : return _wrap_r;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed Texture::getWrap(which)"<<endl; return _wrap_s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Texture::setFilter(FilterParameter which, FilterMode filter)
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case MIN_FILTER : _min_filter = filter; break;
|
||||
case MAG_FILTER : _mag_filter = filter; break;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed Texture::setFilter("<<(unsigned int)which<<","<<(unsigned int)filter<<")"<<endl; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Texture::FilterMode Texture::getFilter(FilterParameter which) const
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case MIN_FILTER : return _min_filter;
|
||||
case MAG_FILTER : return _mag_filter;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed Texture::getFilter(which)"<<endl; return _min_filter;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::enable( void )
|
||||
{
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
|
||||
void Texture::disable( void )
|
||||
{
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
|
||||
void Texture::apply( void )
|
||||
{
|
||||
if(_handle!=0)
|
||||
{
|
||||
glBindTexture( GL_TEXTURE_2D, _handle );
|
||||
}
|
||||
else if (_image.valid())
|
||||
{
|
||||
|
||||
_image->ensureDimensionsArePowerOfTwo();
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,_image->packing());
|
||||
|
||||
|
||||
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);
|
||||
if( _min_filter == LINEAR || _min_filter == NEAREST )
|
||||
{
|
||||
|
||||
|
||||
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(),
|
||||
_image->s(),_image->t(),
|
||||
(GLenum)_image->pixelFormat(), (GLenum)_image->dataType(),
|
||||
_image->data() );
|
||||
}
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, _handle );
|
||||
|
||||
}
|
||||
}
|
||||
205
src/osg/Timer.cpp
Normal file
205
src/osg/Timer.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#ifdef WIN32 // [
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
|
||||
int Timer::inited = 0;
|
||||
double Timer::cpu_mhz = 0.0;
|
||||
|
||||
void Timer::init( void )
|
||||
{
|
||||
Timer_t start_time = tick();
|
||||
Sleep (1000);
|
||||
Timer_t end_time = tick();
|
||||
cpu_mhz = (double)(end_time-start_time)*1e-6;
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
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 __linux // [
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int Timer::inited = 0;
|
||||
double Timer::cpu_mhz = 0.0;
|
||||
|
||||
void Timer::init( void )
|
||||
{
|
||||
char buff[128];
|
||||
FILE *fp = fopen( "/proc/cpuinfo", "r" );
|
||||
|
||||
while( fgets( buff, sizeof( buff ), fp ) > 0 )
|
||||
{
|
||||
if( !strncmp( buff, "cpu MHz", strlen( "cpu MHz" )))
|
||||
{
|
||||
char *ptr = buff;
|
||||
|
||||
while( ptr && *ptr != ':' ) ptr++;
|
||||
if( ptr )
|
||||
{
|
||||
ptr++;
|
||||
sscanf( ptr, "%lf", &cpu_mhz );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
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 // [
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/syssgi.h>
|
||||
#include <sys/immu.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
unsigned long Timer::dummy = 0;
|
||||
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
__psunsigned_t phys_addr, raddr;
|
||||
unsigned int cycleval;
|
||||
volatile unsigned long counter_value, *iotimer_addr;
|
||||
int fd, poffmask;
|
||||
|
||||
poffmask = getpagesize() - 1;
|
||||
phys_addr = syssgi( SGI_QUERY_CYCLECNTR, &cycleval );
|
||||
microseconds_per_click = (double)cycleval/1e6;
|
||||
nanoseconds_per_click = (double)cycleval/1e3;
|
||||
raddr = phys_addr & ~poffmask;
|
||||
|
||||
clk = &dummy;
|
||||
|
||||
if( (fd = open( "/dev/mmem", O_RDONLY )) < 0 )
|
||||
{
|
||||
perror( "/dev/mmem" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
iotimer_addr = (volatile unsigned long *)mmap(
|
||||
(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)
|
||||
);
|
||||
|
||||
|
||||
cycleCntrSize = syssgi( SGI_CYCLECNTR_SIZE );
|
||||
|
||||
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 // ]
|
||||
46
src/osg/Transparency.cpp
Normal file
46
src/osg/Transparency.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "osg/OSG"
|
||||
#include "osg/Transparency"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Transparency::Transparency( void )
|
||||
{
|
||||
_source_factor = SRC_ALPHA;
|
||||
_destination_factor = ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
|
||||
|
||||
Transparency::~Transparency( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Transparency* Transparency::instance()
|
||||
{
|
||||
static ref_ptr<Transparency> s_transparency(new Transparency);
|
||||
return s_transparency.get();
|
||||
}
|
||||
|
||||
void Transparency::enable( void )
|
||||
{
|
||||
glEnable( GL_BLEND );
|
||||
}
|
||||
|
||||
|
||||
void Transparency::disable( void )
|
||||
{
|
||||
glDisable( GL_BLEND );
|
||||
}
|
||||
|
||||
|
||||
void Transparency::apply( void )
|
||||
{
|
||||
glBlendFunc( (GLenum)_source_factor, (GLenum)_destination_factor );
|
||||
}
|
||||
|
||||
|
||||
void Transparency::setFunction( int source, int destination )
|
||||
{
|
||||
_source_factor = source;
|
||||
_destination_factor = destination;
|
||||
}
|
||||
11
src/osg/Version.cpp
Normal file
11
src/osg/Version.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "osg/Version"
|
||||
|
||||
const char* osgGetVersion()
|
||||
{
|
||||
return "0.8.34";
|
||||
}
|
||||
|
||||
const char* osgGetLibraryName()
|
||||
{
|
||||
return "Open Scene Graph Library";
|
||||
}
|
||||
144
src/osgGLUT/GLUTEventAdapter.cpp
Normal file
144
src/osgGLUT/GLUTEventAdapter.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#include "osgGLUT/GLUTEventAdapter"
|
||||
#include "GL/glut.h"
|
||||
|
||||
using namespace osgGLUT;
|
||||
|
||||
// default to no mouse buttons being pressed.
|
||||
unsigned int GLUTEventAdapter::_s_accumulatedButtonMask = 0;
|
||||
|
||||
int GLUTEventAdapter::_s_Xmin = 0;
|
||||
int GLUTEventAdapter::_s_Xmax = 1280;
|
||||
int GLUTEventAdapter::_s_Ymin = 0;
|
||||
int GLUTEventAdapter::_s_Ymax = 1024;
|
||||
int GLUTEventAdapter::_s_mx = 0;
|
||||
int GLUTEventAdapter::_s_my = 0;
|
||||
|
||||
GLUTEventAdapter::GLUTEventAdapter()
|
||||
{
|
||||
_eventType = NONE; // adaptor does not encapsulate any events.
|
||||
_key = -1; // set to 'invalid' key value.
|
||||
_button = -1; // set to 'invalid' button value.
|
||||
_mx = -1; // set to 'invalid' position value.
|
||||
_my = -1; // set to 'invalid' position value.
|
||||
_buttonMask = 0; // default to no mouse buttons being pressed.
|
||||
_time = 0.0f; // default to no time has been set.
|
||||
|
||||
copyStaticVariables();
|
||||
|
||||
}
|
||||
|
||||
void GLUTEventAdapter::copyStaticVariables()
|
||||
{
|
||||
_buttonMask = _s_accumulatedButtonMask;
|
||||
_Xmin = _s_Xmin;
|
||||
_Xmax = _s_Xmax;
|
||||
_Ymin = _s_Ymin;
|
||||
_Ymax = _s_Ymax;
|
||||
_mx = _s_mx;
|
||||
_my = _s_my;
|
||||
}
|
||||
|
||||
void GLUTEventAdapter::setWindowSize(int Xmin, int Ymin, int Xmax, int Ymax)
|
||||
{
|
||||
_s_Xmin = Xmin;
|
||||
_s_Xmax = Xmax;
|
||||
_s_Ymin = Ymin;
|
||||
_s_Ymax = Ymax;
|
||||
}
|
||||
|
||||
void GLUTEventAdapter::setButtonMask(unsigned int buttonMask)
|
||||
{
|
||||
_s_accumulatedButtonMask = buttonMask;
|
||||
}
|
||||
|
||||
|
||||
void GLUTEventAdapter::adaptResize(float time, int Xmin, int Ymin, int Xmax, int Ymax)
|
||||
{
|
||||
setWindowSize(Xmin,Ymin,Xmax,Ymax);
|
||||
_eventType = RESIZE;
|
||||
_time = time;
|
||||
copyStaticVariables();
|
||||
}
|
||||
|
||||
/** method for adapting mouse motion events whilst mouse buttons are pressed.*/
|
||||
void GLUTEventAdapter::adaptMouseMotion(float time, int x, int y)
|
||||
{
|
||||
_eventType = DRAG;
|
||||
_time = time;
|
||||
_s_mx = x;
|
||||
_s_my = y;
|
||||
copyStaticVariables();
|
||||
}
|
||||
|
||||
/** method for adapting mouse motion events whilst no mouse button are pressed.*/
|
||||
void GLUTEventAdapter::adaptMousePassiveMotion(float time, int x, int y)
|
||||
{
|
||||
_eventType = MOVE;
|
||||
_time = time;
|
||||
_s_mx = x;
|
||||
_s_my = y;
|
||||
copyStaticVariables();
|
||||
}
|
||||
|
||||
/** method for adapting mouse button pressed/released events.*/
|
||||
void GLUTEventAdapter::adaptMouse(float time, int button, int state, int x, int y)
|
||||
{
|
||||
_time = time;
|
||||
|
||||
|
||||
if( state == GLUT_DOWN )
|
||||
{
|
||||
|
||||
_eventType = PUSH;
|
||||
_button = button;
|
||||
|
||||
switch(button)
|
||||
{
|
||||
case(GLUT_LEFT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | LEFT_BUTTON; break;
|
||||
case(GLUT_MIDDLE_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | MIDDLE_BUTTON; break;
|
||||
case(GLUT_RIGHT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask | RIGHT_BUTTON; break;
|
||||
}
|
||||
|
||||
}
|
||||
else if( state == GLUT_UP )
|
||||
{
|
||||
|
||||
_eventType = RELEASE;
|
||||
_button = button;
|
||||
|
||||
switch(button)
|
||||
{
|
||||
case(GLUT_LEFT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~LEFT_BUTTON; break;
|
||||
case(GLUT_MIDDLE_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~MIDDLE_BUTTON; break;
|
||||
case(GLUT_RIGHT_BUTTON): _s_accumulatedButtonMask = _s_accumulatedButtonMask & ~RIGHT_BUTTON; break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_s_mx = x;
|
||||
_s_my = y;
|
||||
|
||||
copyStaticVariables();
|
||||
}
|
||||
|
||||
/** method for adapting keyboard events.*/
|
||||
void GLUTEventAdapter::adaptKeyboard(float time, unsigned char key, int x, int y )
|
||||
{
|
||||
_eventType = KEYBOARD;
|
||||
_time = time;
|
||||
_key = key;
|
||||
_s_mx = x;
|
||||
_s_my = y;
|
||||
|
||||
copyStaticVariables();
|
||||
}
|
||||
|
||||
/** method for adapting frame events, i.e. iddle/display callback.*/
|
||||
void GLUTEventAdapter::adaptFrame(float time)
|
||||
{
|
||||
_eventType = FRAME;
|
||||
_time = time;
|
||||
|
||||
copyStaticVariables();
|
||||
}
|
||||
|
||||
0
src/osgGLUT/Makedepend
Normal file
0
src/osgGLUT/Makedepend
Normal file
26
src/osgGLUT/Makefile
Normal file
26
src/osgGLUT/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
#!smake
|
||||
include ../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
GLUTEventAdapter.cpp\
|
||||
Version.cpp\
|
||||
Viewer.cpp\
|
||||
|
||||
TARGET_BASENAME = osgGLUT
|
||||
|
||||
|
||||
LIBS = -ldl
|
||||
|
||||
LIB = ../../lib/lib$(TARGET_BASENAME).so
|
||||
#LIB = ../../lib/lib$(TARGET_BASENAME).a
|
||||
|
||||
TARGET_LIB_FILES = lib$(TARGET_BASENAME).so
|
||||
TARGET_INCLUDE_FILES = \
|
||||
osgGLUT/Export\
|
||||
osgGLUT/Viewer\
|
||||
osgGLUT/GLUTEventAdapter\
|
||||
|
||||
C++FLAGS += -I ../../include
|
||||
|
||||
include ../../Make/makerules
|
||||
|
||||
12
src/osgGLUT/Version.cpp
Executable file
12
src/osgGLUT/Version.cpp
Executable file
@@ -0,0 +1,12 @@
|
||||
#include "osgGLUT/Version"
|
||||
|
||||
|
||||
const char* osgGLUTGetVersion()
|
||||
{
|
||||
return "0.8.34";
|
||||
}
|
||||
|
||||
const char* osgGLUTGetLibraryName()
|
||||
{
|
||||
return "Open Scene Graph GLUT Library";
|
||||
}
|
||||
741
src/osgGLUT/Viewer.cpp
Normal file
741
src/osgGLUT/Viewer.cpp
Normal file
@@ -0,0 +1,741 @@
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "osgGLUT/Viewer"
|
||||
#include "osgGLUT/GLUTEventAdapter"
|
||||
|
||||
#include <osg/OSG>
|
||||
#include <osg/GeoState>
|
||||
#include <osg/Scene>
|
||||
#include <osg/Switch>
|
||||
#include <osg/Billboard>
|
||||
#include <osg/LOD>
|
||||
#include <osg/DCS>
|
||||
#include <osg/Light>
|
||||
#include <osg/LightSource>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Group>
|
||||
#include <osg/Output>
|
||||
#include <osg/Input>
|
||||
#include <osg/Registry>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Seg>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgUtil/RenderVisitor>
|
||||
#include <osgUtil/IntersectVisitor>
|
||||
#include <osgUtil/DisplayListVisitor>
|
||||
|
||||
#include <osgUtil/TrackballManipulator>
|
||||
#include <osgUtil/FlightManipulator>
|
||||
#include <osgUtil/DriveManipulator>
|
||||
|
||||
#include <osg/Version>
|
||||
#include <osgUtil/Version>
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define USE_FLTK
|
||||
#define USE_GLUT
|
||||
#endif
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <sys/timeb.h>
|
||||
#else
|
||||
#endif
|
||||
|
||||
#include <osg/Timer>
|
||||
osg::Timer g_timer;
|
||||
osg::Timer_t g_initTime;
|
||||
|
||||
static GLenum polymodes [] = { GL_FILL, GL_LINE, GL_POINT };
|
||||
|
||||
using namespace osgGLUT;
|
||||
|
||||
Viewer* Viewer::s_theViewer = 0;
|
||||
|
||||
Viewer::Viewer()
|
||||
{
|
||||
s_theViewer = this;
|
||||
|
||||
|
||||
fullscreen = false;
|
||||
_saved_ww = ww = 1024,
|
||||
_saved_wh = wh = 768;
|
||||
|
||||
mx = ww/2,
|
||||
my = wh/2;
|
||||
mbutton = 0;
|
||||
|
||||
|
||||
polymode = 0;
|
||||
texture = 1;
|
||||
backface = 1;
|
||||
lighting = 1;
|
||||
flat_shade = 0;
|
||||
|
||||
_printStats = false;
|
||||
|
||||
#ifdef SGV_USE_RTFS
|
||||
fs = new RTfs( RTFS_MODE_RTC_SPIN );
|
||||
frame_rate = 16;
|
||||
fs->setUpdateRate( frame_rate );
|
||||
#endif
|
||||
|
||||
_viewFrustumCullingActive = true;
|
||||
_smallFeatureCullingActive = true;
|
||||
|
||||
_two_sided_lighting=0;
|
||||
|
||||
_useDisplayLists = true;
|
||||
|
||||
_saveFileName = "saved_model.osg";
|
||||
|
||||
|
||||
_sceneView = new osgUtil::SceneView;
|
||||
_sceneView->setDefaults();
|
||||
|
||||
registerCameraManipulator(new osgUtil::TrackballManipulator);
|
||||
registerCameraManipulator(new osgUtil::FlightManipulator);
|
||||
registerCameraManipulator(new osgUtil::DriveManipulator);
|
||||
|
||||
osg::notify(osg::INFO)<<"Scene Graph Viewer (sgv)"<<endl;
|
||||
osg::notify(osg::INFO)<<" '"<<osgGetLibraryName()<<"' Version "<<osgGetVersion()<<endl;
|
||||
osg::notify(osg::INFO)<<" '"<<osgUtilGetLibraryName()<<"' Version "<<osgUtilGetVersion()<<endl;
|
||||
|
||||
_initialTick = _timer.tick();
|
||||
_frameTick = _initialTick;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Viewer::~Viewer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool Viewer::init(osg::Node* rootnode)
|
||||
{
|
||||
|
||||
bool saveModel = false;
|
||||
|
||||
GLUTEventAdapter::setWindowSize( 0,0,ww, wh );
|
||||
GLUTEventAdapter::setButtonMask(0);
|
||||
|
||||
_sceneView->setViewport(0,0,ww,wh);
|
||||
|
||||
glutInitWindowSize( ww, wh );
|
||||
//glutInit( &argc, argv ); // I moved this into main to avoid passing
|
||||
// argc and argv to the Viewer
|
||||
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
|
||||
glutCreateWindow( "OSG Viewer" );
|
||||
|
||||
glutReshapeFunc( reshapeCB );
|
||||
glutVisibilityFunc( visibilityCB );
|
||||
glutDisplayFunc( displayCB );
|
||||
glutKeyboardFunc( keyboardCB );
|
||||
|
||||
glutMouseFunc( mouseCB );
|
||||
glutMotionFunc( mouseMotionCB );
|
||||
glutPassiveMotionFunc( mousePassiveMotionCB );
|
||||
|
||||
#ifdef USE_FLTK
|
||||
// required to specify the idle function when using FLTK.
|
||||
// GLUT and FLTK GLUT differ in that GLUT implicitly calls visibilityFunc
|
||||
// on window creation, while FLTK calls it when the windows is iconised
|
||||
// or deiconsied but not on window creation.
|
||||
visibilityCB(GLUT_VISIBLE);
|
||||
#endif
|
||||
|
||||
if (_useDisplayLists)
|
||||
{
|
||||
// traverse the scene graph setting up all osg::GeoSet's so they will use
|
||||
// OpenGL display lists.
|
||||
osgUtil::DisplayListVisitor dlv(osgUtil::DisplayListVisitor::SWITCH_ON_DISPLAY_LISTS);
|
||||
rootnode->accept(dlv);
|
||||
}
|
||||
|
||||
_sceneView->setSceneData(rootnode);
|
||||
|
||||
if (saveModel)
|
||||
{
|
||||
osg::saveNodeFile(*rootnode, _saveFileName.c_str());
|
||||
}
|
||||
|
||||
selectCameraManipulator(0);
|
||||
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
_cameraManipulator->home(*ea,*this);
|
||||
|
||||
|
||||
// std::string name = Registry::instance()->createLibraryNameForExt("osg");
|
||||
// Registry::instance()->loadLibrary(name);
|
||||
// Registry::instance()->closeLibrary(name);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void Viewer::registerCameraManipulator(osgUtil::CameraManipulator* cm)
|
||||
{
|
||||
_cameraManipList.push_back(cm);
|
||||
}
|
||||
|
||||
void Viewer::selectCameraManipulator(unsigned int pos)
|
||||
{
|
||||
if (pos>=_cameraManipList.size()) return;
|
||||
|
||||
_cameraManipulator = _cameraManipList[pos];
|
||||
_cameraManipulator->setCamera(_sceneView->getCamera());
|
||||
_cameraManipulator->setNode(_sceneView->getSceneData());
|
||||
|
||||
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
_cameraManipulator->init(*ea,*this);
|
||||
}
|
||||
|
||||
void Viewer::needWarpPointer(int x,int y)
|
||||
{
|
||||
glutWarpPointer(x,y);
|
||||
}
|
||||
|
||||
bool Viewer::update()
|
||||
{
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
ea->adaptFrame(clockSeconds());
|
||||
|
||||
if (_cameraManipulator->update(*ea,*this))
|
||||
{
|
||||
// osg::notify(osg::INFO) << "Handled update frame"<<endl;
|
||||
}
|
||||
|
||||
updateFrameTick();
|
||||
|
||||
if (_printStats) osg::notify(osg::NOTICE) << "\033[0;0H";
|
||||
if (_printStats) osg::notify(osg::NOTICE) << "frameRate() = "<<frameRate()<<endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Viewer::traverse()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Viewer::draw()
|
||||
{
|
||||
// osg::notify(osg::INFO) << "Viewer::draw("<<mx<<","<<my<<") scale("<<bsphere._radius/(float)ww<<")"<<endl;
|
||||
|
||||
osg::Timer_t beforeTraversal = _timer.tick();
|
||||
|
||||
_sceneView->cull();
|
||||
|
||||
float timeTraversal = _timer.delta_m(beforeTraversal,_timer.tick());
|
||||
if (_printStats) osg::notify(osg::NOTICE) << "Time of Cull Traversal "<<timeTraversal<<"ms "<<endl;
|
||||
|
||||
|
||||
osg::Timer_t beforeDraw = _timer.tick();
|
||||
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,_two_sided_lighting);
|
||||
|
||||
_sceneView->draw();
|
||||
|
||||
float timeDraw = _timer.delta_m(beforeDraw,_timer.tick());
|
||||
if (_printStats) osg::notify(osg::NOTICE) << "Time of Draw "<<timeDraw<<"ms "<<endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Viewer::displayCB()
|
||||
{
|
||||
s_theViewer->display();
|
||||
}
|
||||
|
||||
|
||||
void Viewer::reshapeCB(GLint w, GLint h)
|
||||
{
|
||||
s_theViewer->reshape(w, h);
|
||||
}
|
||||
|
||||
|
||||
void Viewer::visibilityCB( int state )
|
||||
{
|
||||
s_theViewer->visibility(state);
|
||||
}
|
||||
|
||||
|
||||
void Viewer::mouseCB(int button, int state, int x, int y)
|
||||
{
|
||||
s_theViewer->mouse(button, state, x, y);
|
||||
}
|
||||
|
||||
|
||||
void Viewer::mouseMotionCB(int x, int y)
|
||||
{
|
||||
s_theViewer->mouseMotion(x,y);
|
||||
}
|
||||
|
||||
|
||||
void Viewer::mousePassiveMotionCB(int x, int y)
|
||||
{
|
||||
s_theViewer->mousePassiveMotion(x,y);
|
||||
}
|
||||
|
||||
|
||||
void Viewer::keyboardCB(unsigned char key, int x, int y)
|
||||
{
|
||||
s_theViewer->keyboard(key,x,y);
|
||||
}
|
||||
|
||||
|
||||
void Viewer::display()
|
||||
{
|
||||
// application traverasal.
|
||||
update();
|
||||
|
||||
draw();
|
||||
|
||||
glutSwapBuffers();
|
||||
|
||||
// cout << "Time elapsed "<<_timer.delta_s(_initialTick,_timer.tick())<<endl;
|
||||
|
||||
#ifdef SGV_USE_RTFS
|
||||
fs->frame();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Viewer::reshape(GLint w, GLint h)
|
||||
{
|
||||
ww = w;
|
||||
wh = h;
|
||||
|
||||
_sceneView->setViewport(0,0,ww,wh);
|
||||
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
ea->adaptResize(clockSeconds(),0,0,ww,wh);
|
||||
|
||||
if (_cameraManipulator->update(*ea,*this))
|
||||
{
|
||||
// osg::notify(osg::INFO) << "Handled reshape "<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Viewer::visibility(int state)
|
||||
{
|
||||
if (state == GLUT_VISIBLE)
|
||||
glutIdleFunc( displayCB );
|
||||
else
|
||||
glutIdleFunc(0L);
|
||||
}
|
||||
|
||||
|
||||
void Viewer::mouseMotion(int x, int y)
|
||||
{
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
ea->adaptMouseMotion(clockSeconds(),x,y);
|
||||
|
||||
if (_cameraManipulator->update(*ea,*this))
|
||||
{
|
||||
// osg::notify(osg::INFO) << "Handled mouseMotion "<<ea->_buttonMask<<" x="<<ea->_mx<<" y="<<ea->_my<<endl;
|
||||
}
|
||||
|
||||
|
||||
mx = x;
|
||||
my = y;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Viewer::mousePassiveMotion(int x, int y)
|
||||
{
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
ea->adaptMousePassiveMotion(clockSeconds(),x,y);
|
||||
|
||||
if (_cameraManipulator->update(*ea,*this))
|
||||
{
|
||||
// osg::notify(osg::INFO) << "Handled mousePassiveMotion "<<ea->_buttonMask<<" x="<<ea->_mx<<" y="<<ea->_my<<endl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Viewer::mouse(int button, int state, int x, int y)
|
||||
{
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
ea->adaptMouse(clockSeconds(),button,state,x,y);
|
||||
|
||||
if (_cameraManipulator->update(*ea,*this))
|
||||
{
|
||||
// osg::notify(osg::INFO) << "Handled mouse "<<ea->_buttonMask<<" x="<<ea->_mx<<" y="<<ea->_my<<endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Viewer::keyboard(unsigned char key, int x, int y)
|
||||
{
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
ea->adaptKeyboard(clockSeconds(),key,x,y);
|
||||
|
||||
if (_cameraManipulator->update(*ea,*this)) return;
|
||||
|
||||
if (key>='1' && key<='3')
|
||||
{
|
||||
int pos = key-'1';
|
||||
selectCameraManipulator(pos);
|
||||
}
|
||||
|
||||
switch( key )
|
||||
{
|
||||
|
||||
case '/' :
|
||||
if (_sceneView->getLODBias()>0.5) _sceneView->setLODBias(_sceneView->getLODBias()/1.5f);
|
||||
break;
|
||||
|
||||
case '*' :
|
||||
if (_sceneView->getLODBias()<30) _sceneView->setLODBias(_sceneView->getLODBias()*1.5f);
|
||||
break;
|
||||
|
||||
case '+' :
|
||||
#ifdef SGV_USE_RTFS
|
||||
frame_rate <<= 1;
|
||||
fs->stop();
|
||||
fs->setUpdateRate( frame_rate );
|
||||
fs->start();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case '-' :
|
||||
#ifdef SGV_USE_RTFS
|
||||
frame_rate >>= 1;
|
||||
if( frame_rate < 1 ) frame_rate = 1;
|
||||
fs->stop();
|
||||
fs->setUpdateRate( frame_rate );
|
||||
fs->start();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'd' :
|
||||
_useDisplayLists = !_useDisplayLists;
|
||||
if (_useDisplayLists)
|
||||
{
|
||||
// traverse the scene graph setting up all osg::GeoSet's so they will use
|
||||
// OpenGL display lists.
|
||||
osgUtil::DisplayListVisitor dlv(osgUtil::DisplayListVisitor::SWITCH_ON_DISPLAY_LISTS);
|
||||
_sceneView->getSceneData()->accept(dlv);
|
||||
osg::notify(osg::NOTICE) << "Switched on use of OpenGL Display Lists."<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// traverse the scene graph setting up all osg::GeoSet's so they will use
|
||||
// OpenGL display lists.
|
||||
osgUtil::DisplayListVisitor dlv(osgUtil::DisplayListVisitor::SWITCH_OFF_DISPLAY_LISTS);
|
||||
_sceneView->getSceneData()->accept(dlv);
|
||||
osg::notify(osg::NOTICE) << "Switched off use of OpenGL Display Lists."<<endl;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p' :
|
||||
_printStats = !_printStats;
|
||||
break;
|
||||
|
||||
case 's' :
|
||||
flat_shade = 1 - flat_shade ;
|
||||
if( flat_shade )
|
||||
glShadeModel( GL_FLAT );
|
||||
else
|
||||
glShadeModel( GL_SMOOTH );
|
||||
|
||||
break;
|
||||
|
||||
case 'b' :
|
||||
|
||||
backface = 1 - backface;
|
||||
if( backface )
|
||||
_sceneView->getGlobalState()->setMode(osg::GeoState::FACE_CULL,osg::GeoState::ON);
|
||||
else
|
||||
_sceneView->getGlobalState()->setMode(osg::GeoState::FACE_CULL,osg::GeoState::OVERRIDE_OFF);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 'l' :
|
||||
lighting = 1 - lighting ;
|
||||
if( lighting )
|
||||
_sceneView->getGlobalState()->setMode(osg::GeoState::LIGHTING,osg::GeoState::ON);
|
||||
else
|
||||
_sceneView->getGlobalState()->setMode(osg::GeoState::LIGHTING,osg::GeoState::OVERRIDE_OFF);
|
||||
break;
|
||||
|
||||
case 'L' :
|
||||
{
|
||||
osgUtil::SceneView::LightingMode lm= _sceneView->getLightingMode();
|
||||
switch(lm)
|
||||
{
|
||||
case(osgUtil::SceneView::HEADLIGHT) : lm = osgUtil::SceneView::SKY_LIGHT; break;
|
||||
case(osgUtil::SceneView::SKY_LIGHT) : lm = osgUtil::SceneView::NO_SCENEVIEW_LIGHT; break;
|
||||
case(osgUtil::SceneView::NO_SCENEVIEW_LIGHT) : lm = osgUtil::SceneView::HEADLIGHT; break;
|
||||
}
|
||||
_sceneView->setLightingMode(lm);
|
||||
break;
|
||||
}
|
||||
case 't' :
|
||||
texture = 1 - texture;
|
||||
if (texture)
|
||||
_sceneView->getGlobalState()->setMode(osg::GeoState::TEXTURE,osg::GeoState::INHERIT);
|
||||
else
|
||||
_sceneView->getGlobalState()->setMode(osg::GeoState::TEXTURE,osg::GeoState::OVERRIDE_OFF);
|
||||
break;
|
||||
|
||||
case 'T' :
|
||||
_two_sided_lighting = 1 - _two_sided_lighting;
|
||||
break;
|
||||
|
||||
case 'w' :
|
||||
polymode = (polymode+1)%3;
|
||||
glPolygonMode( GL_FRONT_AND_BACK, polymodes[polymode] );
|
||||
break;
|
||||
|
||||
case 'f' :
|
||||
fullscreen = !fullscreen;
|
||||
if (fullscreen)
|
||||
{
|
||||
_saved_ww = ww;
|
||||
_saved_wh = wh;
|
||||
glutFullScreen();
|
||||
} else
|
||||
{
|
||||
//glutPositionWindow(wx,wy);
|
||||
glutReshapeWindow(_saved_ww,_saved_wh);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o' :
|
||||
if (_sceneView->getSceneData() && osg::Registry::instance()->writeNode(*_sceneView->getSceneData(),_saveFileName))
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Saved scene to '"<<_saveFileName<<"'"<<endl;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c' :
|
||||
_smallFeatureCullingActive = !_smallFeatureCullingActive;
|
||||
if (_smallFeatureCullingActive)
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Small feature culling switched on "<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Small feature culling switched off "<<endl;
|
||||
}
|
||||
_sceneView->getRenderVisitor()->setCullingActive(osgUtil::RenderVisitor::SMALL_FEATURE_CULLING,_smallFeatureCullingActive);
|
||||
break;
|
||||
|
||||
case 'C' :
|
||||
_viewFrustumCullingActive = !_viewFrustumCullingActive;
|
||||
_sceneView->getRenderVisitor()->setCullingActive(osgUtil::RenderVisitor::VIEW_FRUSTUM_CULLING,_viewFrustumCullingActive);
|
||||
if (_viewFrustumCullingActive)
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "View frustum culling switched on "<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "View frustum culling switched off "<<endl;
|
||||
}
|
||||
break;
|
||||
|
||||
case '?' :
|
||||
case 'h' :
|
||||
help(osg::notify(osg::NOTICE));
|
||||
break;
|
||||
|
||||
case 'i' :
|
||||
case 'r' :
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "***** Intersecting **************"<< endl;
|
||||
|
||||
|
||||
osg::Vec3 near_point,far_point;
|
||||
if (!_sceneView->projectWindowXYIntoObject(x,wh-y,near_point,far_point))
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Failed to calculate intersection ray."<<endl;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Seg> seg = new osg::Seg;
|
||||
seg->set(near_point,far_point);
|
||||
osg::notify(osg::NOTICE) << "start("<<seg->start()<<") end("<<seg->end()<<")"<<endl;
|
||||
|
||||
osgUtil::IntersectVisitor iv;
|
||||
iv.addSeg(seg.get());
|
||||
|
||||
float startTime = clockSeconds();
|
||||
|
||||
_sceneView->getSceneData()->accept(iv);
|
||||
|
||||
float endTime = clockSeconds();
|
||||
|
||||
osg::notify(osg::NOTICE) << "Time for interesection = "<<(endTime-startTime)*1000<<"ms"<<endl;
|
||||
|
||||
if (iv.hits())
|
||||
{
|
||||
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(seg.get());
|
||||
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hitList.begin();
|
||||
hitr!=hitList.end();
|
||||
++hitr)
|
||||
{
|
||||
osg::Vec3 ip = hitr->_intersectPoint;
|
||||
osg::Vec3 in = hitr->_intersectNormal;
|
||||
osg::Geode* geode = hitr->_geode;
|
||||
osg::notify(osg::NOTICE) << " Itersection Point ("<<ip<<") Normal ("<<in<<")"<<endl;
|
||||
if (hitr->_matrix)
|
||||
{
|
||||
osg::Vec3 ipEye = ip*(*(hitr->_matrix));
|
||||
osg::Vec3 inEye = (in+ip)*(*(hitr->_matrix))-ipEye;
|
||||
inEye.normalize();
|
||||
if (geode) osg::notify(osg::NOTICE) << "Geode '"<<geode->getName()<<endl;
|
||||
osg::notify(osg::NOTICE) << " Eye Itersection Point ("<<ipEye<<") Normal ("<<inEye<<")"<<endl;
|
||||
|
||||
|
||||
}
|
||||
if (key=='r' && geode)
|
||||
{
|
||||
// remove geoset..
|
||||
osg::GeoSet* gset = hitr->_geoset;
|
||||
osg::notify(osg::NOTICE) << " geoset ("<<gset<<") "<<geode->removeGeoSet(gset)<<")"<<endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE) << endl << endl;
|
||||
}
|
||||
break;
|
||||
|
||||
case 27 : // Escape
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Viewer::help(ostream& fout)
|
||||
{
|
||||
|
||||
fout <<endl
|
||||
<<"Scene Graph Viewer (sgv) keyboard bindings:"<<endl
|
||||
<<endl
|
||||
<<"1 Select the trackball camera manipulator."<<endl
|
||||
<<" Left mouse button - rotate,"<<endl
|
||||
<<" Middle (or Left & Right) mouse button - pan,"<<endl
|
||||
<<" Right mouse button - zoom."<<endl
|
||||
<<"2 Select the flight camera manipulator."<<endl
|
||||
<<" Left mouse button - speed up,"<<endl
|
||||
<<" Middle (or Left & Right) mouse button - stop,"<<endl
|
||||
<<" Right mouse button - slow down, reverse."<<endl
|
||||
<<" Move mouse left to roll left, right to roll right."<<endl
|
||||
<<" Move mouse back (down) to pitch nose up, forward to pitch down."<<endl
|
||||
<<" In mode Q, the default, selected by pressing 'q'"<<endl
|
||||
<<" The flight path is yawed automatically into the turn to"<<endl
|
||||
<<" produce a similar effect as flying an aircaft."<<endl
|
||||
<<" In mode A, selected by pressing 'a'"<<endl
|
||||
<<" The flight path is not yawed automatically into the turn,"<<endl
|
||||
<<" producing a similar effect as space/marine flight."<<endl
|
||||
<<"3 Select the drive camera manipulator."<<endl
|
||||
<<" In mode Q, the default, selected by pressing 'q'"<<endl
|
||||
<<" Move mouse left to turn left, right to turn right."<<endl
|
||||
<<" Move mouse back (down) to reverse, forward to drive forward."<<endl
|
||||
<<" In mode A, selected by pressing 'a'"<<endl
|
||||
<<" Move mouse left to turn left, right to turn right."<<endl
|
||||
<<" Left mouse button - speed up,"<<endl
|
||||
<<" Middle (or Left & Right) mouse button - stop,"<<endl
|
||||
<<" Right mouse button - slow down, reverse."<<endl
|
||||
<<endl
|
||||
<<"+ Half the frame delay which speeds up the frame rate on Linux and Windows."<<endl
|
||||
<<"- Double the frame delay and therefore reduce the frame rate on Linux"<<endl
|
||||
<<" and Windows."<<endl
|
||||
<<endl
|
||||
<<"/ Divide the Level-Of-Detail (LOD) bias by 1.5, to encourage the"<<endl
|
||||
<<" selection of more complex LOD children."<<endl
|
||||
<<"* Multiple the Level-of-Detail (LOD) bias by 1.5, to encourage the"<<endl
|
||||
<<" selection of less complex LOD children."<<endl
|
||||
<<endl
|
||||
<<"c Toggle Small Feature Culling on or off."<<endl
|
||||
<<"C Toggle View Frustum Culling on or off."<<endl
|
||||
<<"d Toggle use of OpenGL's display lists."<<endl
|
||||
<<"b Toggle OpenGL's backface culling."<<endl
|
||||
<<"t Toggle OpenGL texturing on or off."<<endl
|
||||
<<"T Toggle OpenGL two-sided lighting on or off."<<endl
|
||||
<<"l Toggle OpenGL lighting on or off."<<endl
|
||||
<<"L Toggle SceneView lighting mode between HEADLIGHT, SKY_LIGHT"<<endl
|
||||
<<" and NO_SCENEVIEW_LIGHT."<<endl
|
||||
<<"s Toggle OpenGL shade model between flat and smooth shading."<<endl
|
||||
<<"w Toggle OpenGL polygon mode between solid, wireframe and points modes."<<endl
|
||||
<<endl
|
||||
<<"i Calculate and report the intersections with the scene under the"<<endl
|
||||
<<" current mouse x and mouse y position."<<endl
|
||||
<<endl
|
||||
<<"r Calculate and report the intersections with the scene under the"<<endl
|
||||
<<" current mouse x and mouse y position and delete the nearest"<<endl
|
||||
<<" interesected geoset."<<endl
|
||||
<<endl
|
||||
<<"p Print frame rate statistics on each frame."<<endl
|
||||
<<"o Output the loaded scene to 'saved_model.osg'."<<endl
|
||||
<<"?/h Print out sgv's keyboard bindings."<<endl
|
||||
<<"f Toggle between fullscreen and the previous window size. Note, GLUT"<<endl
|
||||
<<" fullscreen works properly on Windows and Irix, but on Linux"<<endl
|
||||
<<" it just maximizes the window and leaves the window's borders."<<endl
|
||||
<<"Space Reset scene to the default view."<<endl
|
||||
<<"Esc Exit sgv."<<endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
osg::Timer_t Viewer::clockTick()
|
||||
{
|
||||
return _timer.tick();
|
||||
}
|
||||
|
||||
|
||||
osg::Timer_t Viewer::frameTick()
|
||||
{
|
||||
return _frameTick;
|
||||
}
|
||||
|
||||
|
||||
// update time from the current frame update and the previous one.
|
||||
osg::Timer_t Viewer::updateFrameTick()
|
||||
{
|
||||
_lastFrameTick = _frameTick;
|
||||
_frameTick = _timer.tick();
|
||||
return _frameTick;
|
||||
}
|
||||
|
||||
bool Viewer::run()
|
||||
{
|
||||
updateFrameTick();
|
||||
#ifdef SGV_USE_RTFS
|
||||
fs->start();
|
||||
#endif
|
||||
glutMainLoop();
|
||||
return true;
|
||||
}
|
||||
32
src/osgPlugins/Makefile
Normal file
32
src/osgPlugins/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
#!smake
|
||||
SHELL=/bin/sh
|
||||
|
||||
|
||||
#DIRS = fly flt png
|
||||
#DIRS = fly flt pic png jpeg tga tiff gif png
|
||||
DIRS = fly osgtgz tgz zip flt pfb pic png jpeg tga tiff gif png
|
||||
|
||||
all :
|
||||
for f in $(DIRS) ; do cd $$f; make ; cd ..; done
|
||||
|
||||
clean :
|
||||
for f in $(DIRS) ; do cd $$f; make clean; cd ..; done
|
||||
|
||||
clobber :
|
||||
for f in $(DIRS) ; do cd $$f; make clobber; cd ..; done
|
||||
|
||||
depend :
|
||||
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
|
||||
|
||||
install :
|
||||
for f in $(DIRS) ; do cd $$f; make install; cd ..; done
|
||||
|
||||
instlinks :
|
||||
for f in $(DIRS) ; do cd $$f; make instlinks; cd ..; done
|
||||
|
||||
instclean :
|
||||
for f in $(DIRS) ; do cd $$f; make instclean; cd ..; done
|
||||
136
src/osgPlugins/flt/BoundingVolumeRecords.cpp
Normal file
136
src/osgPlugins/flt/BoundingVolumeRecords.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
// BoundingVolumeRecords.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "BoundingVolumeRecords.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingBoxRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<BoundingBoxRecord> g_BoundingBoxProxy;
|
||||
|
||||
|
||||
BoundingBoxRecord::BoundingBoxRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
BoundingBoxRecord::~BoundingBoxRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BoundingBoxRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingSphereRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<BoundingSphereRecord> g_BoundingSphereProxy;
|
||||
|
||||
|
||||
BoundingSphereRecord::BoundingSphereRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
BoundingSphereRecord::~BoundingSphereRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BoundingSphereRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingCylinderRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<BoundingCylinderRecord> g_BoundingCylinderProxy;
|
||||
|
||||
|
||||
BoundingCylinderRecord::BoundingCylinderRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
BoundingCylinderRecord::~BoundingCylinderRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BoundingCylinderRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingVolumeCenterRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<BoundingVolumeCenterRecord> g_BoundingVolumeCenterProxy;
|
||||
|
||||
|
||||
BoundingVolumeCenterRecord::BoundingVolumeCenterRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
BoundingVolumeCenterRecord::~BoundingVolumeCenterRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BoundingVolumeCenterRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingVolumeOrientationRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<BoundingVolumeOrientationRecord> g_BoundingVolumeOrientationProxy;
|
||||
|
||||
|
||||
BoundingVolumeOrientationRecord::BoundingVolumeOrientationRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
BoundingVolumeOrientationRecord::~BoundingVolumeOrientationRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BoundingVolumeOrientationRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
225
src/osgPlugins/flt/BoundingVolumeRecords.h
Normal file
225
src/osgPlugins/flt/BoundingVolumeRecords.h
Normal file
@@ -0,0 +1,225 @@
|
||||
// BoundingVolumeRecords.h
|
||||
|
||||
#ifndef __FLT_BOUNDING_VOLUME_RECORDS_H
|
||||
#define __FLT_BOUNDING_VOLUME_RECORDS_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingBoxRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef struct BoundingBoxTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
#if 0
|
||||
Int 4 Reserved
|
||||
Double 8 x coordinate of lowest corner
|
||||
Double 8 y coordinate of lowest corner
|
||||
Double 8 z coordinate of lowest corner
|
||||
Double 8 x coordinate of highest corner
|
||||
Double 8 y coordinate of highest corner
|
||||
Double 8 z coordinate of highest corner
|
||||
#endif
|
||||
} SBoundingBox;
|
||||
|
||||
|
||||
|
||||
class BoundingBoxRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
|
||||
BoundingBoxRecord();
|
||||
|
||||
virtual Record* clone() const { return new BoundingBoxRecord(); }
|
||||
virtual const char* className() const { return "BoundingBoxRecord"; }
|
||||
virtual int classOpcode() const { return BOUNDING_BOX_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~BoundingBoxRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingSphereRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef struct BoundingSphereTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
#if 0
|
||||
Unsigned Int 2 Length of the record
|
||||
Int 4 Reserved
|
||||
Double 8 Radius of the sphere
|
||||
#endif
|
||||
} SBoundingSphere;
|
||||
|
||||
|
||||
|
||||
class BoundingSphereRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
|
||||
BoundingSphereRecord();
|
||||
|
||||
virtual Record* clone() const { return new BoundingSphereRecord(); }
|
||||
virtual const char* className() const { return "BoundingSphereRecord"; }
|
||||
virtual int classOpcode() const { return BOUNDING_SPHERE_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~BoundingSphereRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingCylinderRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef struct BoundingCylinderTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
#if 0
|
||||
Int 4 Reserved
|
||||
Double 8 Radius of the cylinder base
|
||||
Double 8 Height of the cylinder
|
||||
#endif
|
||||
} SBoundingCylinder;
|
||||
|
||||
|
||||
|
||||
class BoundingCylinderRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
|
||||
BoundingCylinderRecord();
|
||||
|
||||
virtual Record* clone() const { return new BoundingCylinderRecord(); }
|
||||
virtual const char* className() const { return "BoundingCylinderRecord"; }
|
||||
virtual int classOpcode() const { return BOUNDING_CYLINDER_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~BoundingCylinderRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingVolumeCenterRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef struct BoundingVolumeCenterTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
#if 0
|
||||
Int 4 Reserved
|
||||
Double 8 x coordinate of center
|
||||
Double 8 y coordinate of center
|
||||
Double 8 z coordinate of center
|
||||
#endif
|
||||
} SBoundingVolumeCenter;
|
||||
|
||||
|
||||
|
||||
class BoundingVolumeCenterRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
|
||||
BoundingVolumeCenterRecord();
|
||||
|
||||
virtual Record* clone() const { return new BoundingVolumeCenterRecord(); }
|
||||
virtual const char* className() const { return "BoundingVolumeCenterRecord"; }
|
||||
virtual int classOpcode() const { return BOUNDING_VOLUME_CENTER_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~BoundingVolumeCenterRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BoundingVolumeOrientationRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef struct BoundingVolumeOrientationTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
#if 0
|
||||
Int 2 Bounding Volume Orientation Opcode 109
|
||||
Unsigned Int 2 Length of the record
|
||||
Int 4 Reserved
|
||||
Double 8 Yaw angle
|
||||
Double 8 Pitch angle
|
||||
Double 8 Roll angle
|
||||
#endif
|
||||
} SBoundingVolumeOrientation;
|
||||
|
||||
|
||||
|
||||
class BoundingVolumeOrientationRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
|
||||
BoundingVolumeOrientationRecord();
|
||||
|
||||
virtual Record* clone() const { return new BoundingVolumeOrientationRecord(); }
|
||||
virtual const char* className() const { return "BoundingVolumeOrientationRecord"; }
|
||||
virtual int classOpcode() const { return BOUNDING_VOLUME_ORIENTATION_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~BoundingVolumeOrientationRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
55
src/osgPlugins/flt/ColorPaletteRecord.cpp
Normal file
55
src/osgPlugins/flt/ColorPaletteRecord.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// ColorPaletteRecord.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "Input.h"
|
||||
#include "Registry.h"
|
||||
#include "ColorPaletteRecord.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MaterialPaletteRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
RegisterRecordProxy<ColorPaletteRecord> g_ColorPaletteRecordProxy;
|
||||
|
||||
|
||||
ColorPaletteRecord::ColorPaletteRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
ColorPaletteRecord::~ColorPaletteRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void ColorPaletteRecord::endian()
|
||||
{
|
||||
SColorPalette* pSColor = (SColorPalette*)getData();
|
||||
int nOffset = sizeof(SColorPalette);
|
||||
|
||||
if (nOffset < getSize())
|
||||
{
|
||||
int n = 0;
|
||||
ENDIAN( pSColor->nNames );
|
||||
|
||||
while ((n++ < pSColor->nNames) && (nOffset < getSize()))
|
||||
{
|
||||
SColorName* pName = (SColorName*)((char*)getData())+nOffset;
|
||||
ENDIAN( pName->swSize );
|
||||
ENDIAN( pName->nIndex );
|
||||
nOffset += pName->swSize;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
62
src/osgPlugins/flt/ColorPaletteRecord.h
Normal file
62
src/osgPlugins/flt/ColorPaletteRecord.h
Normal file
@@ -0,0 +1,62 @@
|
||||
// ColorPaletteRecord.h
|
||||
|
||||
#ifndef __FLT_COLOR_PALETTE_RECORD_H
|
||||
#define __FLT_COLOR_PALETTE_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ColorPaletteRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
struct SColorName
|
||||
{
|
||||
uint16 swSize; // Length of color name entry
|
||||
int16 Reserved1;
|
||||
int16 nIndex; // Color entry index
|
||||
int16 Reserved2;
|
||||
char szName[1]; // Color name string (variable length, up to 80 bytes)
|
||||
};
|
||||
|
||||
|
||||
struct SColorPalette
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
char szReserved[128]; // Reserved
|
||||
color32 Colors[1024]; // Color 0 - 1023
|
||||
int32 nNames;
|
||||
// Followed by SColorName. SColorName is of valiable length!
|
||||
};
|
||||
|
||||
|
||||
class ColorPaletteRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
ColorPaletteRecord();
|
||||
|
||||
virtual Record* clone() const { return new ColorPaletteRecord(); }
|
||||
virtual const char* className() const { return "ColorPaletteRecord"; }
|
||||
virtual int classOpcode() const { return COLOR_PALETTE_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
SColorPalette* getData() const { return (SColorPalette*)_pData; }
|
||||
|
||||
protected:
|
||||
virtual ~ColorPaletteRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif // __FLT_COLOR_PALETTE_RECORD_H
|
||||
37
src/osgPlugins/flt/CommentRecord.cpp
Normal file
37
src/osgPlugins/flt/CommentRecord.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// CommentRecord.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "CommentRecord.h"
|
||||
|
||||
|
||||
using namespace flt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CommentRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<CommentRecord> g_CommentRecordProxy;
|
||||
|
||||
|
||||
CommentRecord::CommentRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
CommentRecord::~CommentRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void CommentRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
53
src/osgPlugins/flt/CommentRecord.h
Normal file
53
src/osgPlugins/flt/CommentRecord.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// CommentRecord.h
|
||||
|
||||
#ifndef __FLT_COMMENT_RECORD_H
|
||||
#define __FLT_COMMENT_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CommentRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct CommentTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
// TODO
|
||||
} SComment;
|
||||
|
||||
|
||||
|
||||
class CommentRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
|
||||
CommentRecord();
|
||||
|
||||
virtual Record* clone() const { return new CommentRecord(); }
|
||||
virtual const char* className() const { return "CommentRecord"; }
|
||||
virtual int classOpcode() const { return COMMENT_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~CommentRecord();
|
||||
|
||||
virtual void endian();
|
||||
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
21
src/osgPlugins/flt/ControlRecord.cpp
Normal file
21
src/osgPlugins/flt/ControlRecord.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// ControlRecord.cpp
|
||||
|
||||
|
||||
|
||||
#include "Registry.h"
|
||||
#include "ControlRecord.h"
|
||||
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
|
||||
RegisterRecordProxy<PushLevelRecord> g_PushLevelProxy;
|
||||
RegisterRecordProxy<PopLevelRecord> g_PopLevelProxy;
|
||||
|
||||
RegisterRecordProxy<PushSubfaceRecord> g_PushSubfaceProxy;
|
||||
RegisterRecordProxy<PopSubfaceRecord> g_PopSubfaceProxy;
|
||||
|
||||
RegisterRecordProxy<PushExtensionRecord> g_PushExtensionProxy;
|
||||
RegisterRecordProxy<PopExtensionRecord> g_PopExtensionProxy;
|
||||
|
||||
125
src/osgPlugins/flt/ControlRecord.h
Normal file
125
src/osgPlugins/flt/ControlRecord.h
Normal file
@@ -0,0 +1,125 @@
|
||||
// ControlRecord.h
|
||||
|
||||
#ifndef __FLT_CONTROL_RECORD_H
|
||||
#define __FLT_CONTROL_RECORD_H
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PushLevelRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class PushLevelRecord : public ControlRecord
|
||||
{
|
||||
public:
|
||||
PushLevelRecord() {}
|
||||
|
||||
virtual Record* clone() const { return new PushLevelRecord(); }
|
||||
virtual const char* className() const { return "PushLevelRecord"; }
|
||||
virtual int classOpcode() const { return PUSH_LEVEL_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
virtual ~PushLevelRecord() {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PopLevelRecord : public ControlRecord
|
||||
{
|
||||
public:
|
||||
PopLevelRecord() {}
|
||||
|
||||
virtual Record* clone() const { return new PopLevelRecord(); }
|
||||
virtual const char* className() const { return "PopLevelRecord"; }
|
||||
virtual int classOpcode() const { return POP_LEVEL_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
virtual ~PopLevelRecord() {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PushSubfaceRecord : public ControlRecord
|
||||
{
|
||||
public:
|
||||
PushSubfaceRecord() {}
|
||||
|
||||
virtual Record* clone() const { return new PushSubfaceRecord(); }
|
||||
virtual const char* className() const { return "PushSubfaceRecord"; }
|
||||
virtual int classOpcode() const { return PUSH_SUBFACE_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
virtual ~PushSubfaceRecord() {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PopSubfaceRecord : public ControlRecord
|
||||
{
|
||||
public:
|
||||
PopSubfaceRecord() {}
|
||||
|
||||
virtual Record* clone() const { return new PopSubfaceRecord(); }
|
||||
virtual const char* className() const { return "PopSubfaceRecord"; }
|
||||
virtual int classOpcode() const { return POP_SUBFACE_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
virtual ~PopSubfaceRecord() {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PushExtensionRecord : public ControlRecord
|
||||
{
|
||||
public:
|
||||
PushExtensionRecord() {}
|
||||
|
||||
virtual Record* clone() const { return new PushExtensionRecord(); }
|
||||
virtual const char* className() const { return "PushExtensionRecord"; }
|
||||
virtual int classOpcode() const { return PUSH_EXTENSION_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
virtual ~PushExtensionRecord() {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PopExtensionRecord : public ControlRecord
|
||||
{
|
||||
public:
|
||||
PopExtensionRecord() {}
|
||||
|
||||
virtual Record* clone() const { return new PopExtensionRecord(); }
|
||||
virtual const char* className() const { return "PopExtensionRecord"; }
|
||||
virtual int classOpcode() const { return POP_EXTENSION_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
virtual ~PopExtensionRecord() {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif // __FLT_CONTROL_RECORD_H
|
||||
|
||||
52
src/osgPlugins/flt/DofRecord.cpp
Normal file
52
src/osgPlugins/flt/DofRecord.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// DofRecord.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "DofRecord.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DofRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<DofRecord> g_DofProxy;
|
||||
|
||||
|
||||
DofRecord::DofRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
DofRecord::~DofRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DofRecord::endian()
|
||||
{
|
||||
SDegreeOfFreedom *pSDof = (SDegreeOfFreedom*)getData();
|
||||
|
||||
ENDIAN( pSDof->diReserved );
|
||||
pSDof->OriginLocalDOF.endian();
|
||||
pSDof->PointOnXaxis.endian();
|
||||
pSDof->PointInXYplane.endian();
|
||||
pSDof->dfZ.endian();
|
||||
pSDof->dfY.endian();
|
||||
pSDof->dfX.endian();
|
||||
pSDof->dfPitch.endian();
|
||||
pSDof->dfRoll.endian();
|
||||
pSDof->dfYaw.endian();
|
||||
pSDof->dfZscale.endian();
|
||||
pSDof->dfYscale.endian();
|
||||
pSDof->dfXscale.endian();
|
||||
ENDIAN( pSDof->dwFlags );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
87
src/osgPlugins/flt/DofRecord.h
Normal file
87
src/osgPlugins/flt/DofRecord.h
Normal file
@@ -0,0 +1,87 @@
|
||||
// DofRecord.h
|
||||
|
||||
|
||||
|
||||
#ifndef __FLT_DOF_RECORD_H
|
||||
#define __FLT_DOF_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
struct SRange
|
||||
{
|
||||
float64 _dfMin; // Minimum value with respect to the local coord system
|
||||
float64 _dfMax; // Maximum value with respect to the local coordsystem
|
||||
float64 _dfCurrent; // Current value with respect to the local coord system
|
||||
float64 _dfIncrement; // Increment
|
||||
|
||||
inline float64 minRange() { return _dfMin; }
|
||||
inline float64 maxRange() { return _dfMax; }
|
||||
inline float64 current() { return _dfCurrent; }
|
||||
inline float64 increment() { return _dfIncrement; }
|
||||
void endian() {
|
||||
ENDIAN( _dfMin );
|
||||
ENDIAN( _dfMax );
|
||||
ENDIAN( _dfCurrent );
|
||||
ENDIAN( _dfIncrement );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef struct DegreeOfFreedomTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
char szIdent[8]; // 7 char ASCII ID; 0 terminates
|
||||
int32 diReserved; // Reserved
|
||||
float64x3 OriginLocalDOF; // Origin (x,y,z) of the DOF's local coordinate system
|
||||
float64x3 PointOnXaxis; // Point (x,y,z) on the x-axis of the DOF's local coord system
|
||||
float64x3 PointInXYplane; // Point (x,y,z) in xy plane of the DOF's local coord system
|
||||
SRange dfZ; // Legal z values with respect to the local coord system
|
||||
SRange dfY; // Legal y values with respect to the local coord system
|
||||
SRange dfX; // Legal x values with respect to the local coord system
|
||||
SRange dfPitch; // Legal pitch values (rotation about the x-axis)
|
||||
SRange dfRoll; // Legal roll values( rotation about the y-axis)
|
||||
SRange dfYaw; // Legal yaw values (rotation about the z-axis)
|
||||
SRange dfZscale; // Legal z scale values (about local origin)
|
||||
SRange dfYscale; // Legal y scale values about local origin)
|
||||
SRange dfXscale; // Legal x scale values (about local origin)
|
||||
uint32 dwFlags; // Flags, bits from left to right (see OF doc)
|
||||
} SDegreeOfFreedom;
|
||||
|
||||
|
||||
|
||||
class DofRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
DofRecord();
|
||||
|
||||
virtual Record* clone() const { return new DofRecord(); }
|
||||
virtual const char* className() const { return "DofRecord"; }
|
||||
virtual int classOpcode() const { return DOF_OP; }
|
||||
virtual int sizeofData() const { return sizeof(SDegreeOfFreedom); }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
SDegreeOfFreedom* getData() const { return (SDegreeOfFreedom*)_pData; }
|
||||
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
|
||||
|
||||
protected:
|
||||
virtual ~DofRecord();
|
||||
|
||||
virtual void endian();
|
||||
|
||||
// virtual bool readLocalData(Input& fr);
|
||||
// virtual bool writeLocalData(Output& fw);
|
||||
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
39
src/osgPlugins/flt/ExtensionRecord.cpp
Normal file
39
src/osgPlugins/flt/ExtensionRecord.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// ExtensionRecord.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "ExtensionRecord.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ExtensionRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<ExtensionRecord> g_ExtensionProxy;
|
||||
|
||||
|
||||
ExtensionRecord::ExtensionRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
ExtensionRecord::~ExtensionRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ExtensionRecord::endian()
|
||||
{
|
||||
SExtension *pExtension = (SExtension*)getData();
|
||||
|
||||
// VALID_RECORD(SHeader, pRecHdr)
|
||||
ENDIAN( pExtension->code );
|
||||
}
|
||||
|
||||
|
||||
|
||||
59
src/osgPlugins/flt/ExtensionRecord.h
Normal file
59
src/osgPlugins/flt/ExtensionRecord.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// ExtensionRecord.h
|
||||
|
||||
#ifndef __FLT_EXTENSION_RECORD_H
|
||||
#define __FLT_EXTENSION_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
namespace flt {
|
||||
class Input;
|
||||
};
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ExtensionRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct ExtensionTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
|
||||
char szIdent[8]; // 7 char ASCII ID; 0 terminates
|
||||
char site[8]; // Site ID - Unique site name
|
||||
char reserved; // Reserved
|
||||
char revision; // Revision - site specific
|
||||
uint16 code; // Record code - site specific
|
||||
// char n/a; // Extended data - site specific
|
||||
}SExtension;
|
||||
|
||||
|
||||
class ExtensionRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
ExtensionRecord();
|
||||
|
||||
virtual Record* clone() const { return new ExtensionRecord(); }
|
||||
virtual const char* className() const { return "ExtensionRecord"; }
|
||||
virtual int classOpcode() const { return EXTENSION_OP; }
|
||||
virtual int sizeofData() const { return sizeof(SExtension); }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
virtual ~ExtensionRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
52
src/osgPlugins/flt/ExternalRecord.cpp
Normal file
52
src/osgPlugins/flt/ExternalRecord.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// ExternalRecord.cpp
|
||||
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "FltFile.h"
|
||||
#include "ExternalRecord.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ExternalRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<ExternalRecord> g_ExternalProxy;
|
||||
|
||||
|
||||
ExternalRecord::ExternalRecord()
|
||||
{
|
||||
_pExternal = NULL;
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
ExternalRecord::~ExternalRecord()
|
||||
{
|
||||
if (_pExternal)
|
||||
_pExternal->unref();
|
||||
}
|
||||
|
||||
|
||||
void ExternalRecord::setExternal(FltFile* pExternal)
|
||||
{
|
||||
if (_pExternal)
|
||||
_pExternal->unref();
|
||||
|
||||
_pExternal = pExternal;
|
||||
_pExternal->ref();
|
||||
}
|
||||
|
||||
|
||||
void ExternalRecord::endian()
|
||||
{
|
||||
SExternalReference *pSExternal = (SExternalReference*)getData();
|
||||
|
||||
ENDIAN( pSExternal->diFlags );
|
||||
}
|
||||
|
||||
|
||||
|
||||
63
src/osgPlugins/flt/ExternalRecord.h
Normal file
63
src/osgPlugins/flt/ExternalRecord.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// ExternalRecord.h
|
||||
|
||||
#ifndef __FLT_EXTERNAL_RECORD_H
|
||||
#define __FLT_EXTERNAL_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
struct SExternalReference
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
char szPath[200]; // 199 char ASCII Path; 0 terminates
|
||||
uint8 swReserved[4]; // Reserved
|
||||
int32 diFlags; // Flags (bits from left to right)
|
||||
// 0 = Color Palette Override
|
||||
// 1 = Material Palette Override
|
||||
// 2 = Texture Palette Override
|
||||
// 3 = Line Palette Override
|
||||
// 4 = Sound Palette Override
|
||||
// 5 = Light source Palette Override
|
||||
// 6-31 Spare
|
||||
int16 iReserved; // Reserved
|
||||
};
|
||||
|
||||
|
||||
class ExternalRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
ExternalRecord();
|
||||
|
||||
virtual Record* clone() const { return new ExternalRecord(); }
|
||||
virtual const char* className() const { return "ExternalRecord"; }
|
||||
virtual int classOpcode() const { return EXTERNAL_REFERENCE_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
SExternalReference* getData() const { return (SExternalReference*)_pData; }
|
||||
|
||||
void setExternal(FltFile* pExternal);
|
||||
FltFile* getExternal() { return _pExternal; }
|
||||
const std::string getFilename( void ) const { return std::string(getData()->szPath); }
|
||||
|
||||
protected:
|
||||
virtual ~ExternalRecord();
|
||||
|
||||
// virtual bool readLocalData(Input& fr);
|
||||
// virtual bool writeLocalData(Output& fw);
|
||||
|
||||
virtual void endian();
|
||||
|
||||
FltFile* _pExternal;
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
292
src/osgPlugins/flt/FaceRecord.cpp
Normal file
292
src/osgPlugins/flt/FaceRecord.cpp
Normal file
@@ -0,0 +1,292 @@
|
||||
// FaceRecord.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "FaceRecord.h"
|
||||
#include "Input.h"
|
||||
|
||||
|
||||
using namespace flt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FaceRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<FaceRecord> g_FaceProxy;
|
||||
|
||||
|
||||
FaceRecord::FaceRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
FaceRecord::~FaceRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int FaceRecord::numberOfVertices()
|
||||
{
|
||||
for (int n=0; n < getNumChildren(); n++)
|
||||
{
|
||||
VertexListRecord* pSVertexList = (VertexListRecord*)getChild(n);
|
||||
if (pSVertexList && pSVertexList->isOfType(VERTEX_LIST_OP))
|
||||
return pSVertexList->numberOfVertices();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int FaceRecord::getVertexPoolOffset(int index)
|
||||
{
|
||||
for (int n=0; n < getNumChildren(); n++)
|
||||
{
|
||||
VertexListRecord* pSVertexList = (VertexListRecord*)getChild(n);
|
||||
if (pSVertexList && pSVertexList->isOfType(VERTEX_LIST_OP))
|
||||
return pSVertexList->getVertexPoolOffset(index);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void FaceRecord::endian()
|
||||
{
|
||||
SFace *pSFace = (SFace*)getData();
|
||||
|
||||
ENDIAN( pSFace->diIRColor );
|
||||
ENDIAN( pSFace->iObjectRelPriority );
|
||||
ENDIAN( pSFace->wPrimaryNameIndex );
|
||||
ENDIAN( pSFace->wSecondaryNameIndex );
|
||||
ENDIAN( pSFace->iDetailTexturePattern );
|
||||
ENDIAN( pSFace->iTexturePattern );
|
||||
ENDIAN( pSFace->iMaterial );
|
||||
ENDIAN( pSFace->iSurfaceMaterial );
|
||||
ENDIAN( pSFace->iFeature );
|
||||
ENDIAN( pSFace->diIRMaterial );
|
||||
ENDIAN( pSFace->wTransparency );
|
||||
ENDIAN( pSFace->diFlags );
|
||||
// ENDIAN( pSFace->PrimaryPackedColor );
|
||||
// ENDIAN( pSFace->SecondaryPackedColor );
|
||||
ENDIAN( pSFace->iTextureMapIndex );
|
||||
ENDIAN( pSFace->dwPrimaryColorIndex );
|
||||
ENDIAN( pSFace->dwAlternateColorIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// virtual
|
||||
bool FaceRecord::readLocalData(Input& fr)
|
||||
{
|
||||
if (!PrimNodeRecord::readLocalData(fr))
|
||||
return false;
|
||||
|
||||
//
|
||||
// Check for subfaces
|
||||
//
|
||||
|
||||
Record* pRec;
|
||||
|
||||
if (!(pRec=fr.readCreateRecord())) return false;
|
||||
|
||||
if (pRec->getOpcode() != PUSH_SUBFACE_OP)
|
||||
return fr.rewindLast();
|
||||
|
||||
while ((pRec=fr.readCreateRecord()))
|
||||
{
|
||||
if (pRec->getOpcode()==POP_SUBFACE_OP) return true;
|
||||
|
||||
if (pRec->isPrimaryNode())
|
||||
{
|
||||
addChild(pRec);
|
||||
|
||||
if (!((PrimNodeRecord*)pRec)->readLocalData(fr))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (pRec != NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VertexListRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<VertexListRecord> g_VertexListProxy;
|
||||
|
||||
|
||||
VertexListRecord::VertexListRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
VertexListRecord::~VertexListRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int VertexListRecord::numberOfVertices()
|
||||
{
|
||||
return getBodyLength()/4;
|
||||
}
|
||||
|
||||
|
||||
int VertexListRecord::getVertexPoolOffset(int index)
|
||||
{
|
||||
SSingleVertexList *pSVertexList = (SSingleVertexList*)getData();
|
||||
|
||||
if ((index >= 0) && (index < numberOfVertices()))
|
||||
return pSVertexList->diSOffset[index];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void VertexListRecord::endian()
|
||||
{
|
||||
SSingleVertexList *pSVertexList = (SSingleVertexList*)getData();
|
||||
int nNumberOfVertices = numberOfVertices();
|
||||
|
||||
for(int i=0; i < nNumberOfVertices; i++)
|
||||
{
|
||||
ENDIAN( pSVertexList->diSOffset[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// virtual
|
||||
bool VertexListRecord::readLocalData(Input& fr)
|
||||
{
|
||||
// A vertex node is a leaf node in the database and
|
||||
// therefore cannot have any children.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MorphVertexListRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<MorphVertexListRecord> g_MorphVertexListRecordProxy;
|
||||
|
||||
|
||||
MorphVertexListRecord::MorphVertexListRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
MorphVertexListRecord::~MorphVertexListRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int MorphVertexListRecord::numberOfVertices()
|
||||
{
|
||||
return getBodyLength()/8;
|
||||
}
|
||||
|
||||
|
||||
void MorphVertexListRecord::endian()
|
||||
{
|
||||
// SMorphVertexList *pSMorpVertexList = (SMorphVertexList*)getData();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// virtual
|
||||
bool MorphVertexListRecord::readLocalData(Input& fr)
|
||||
{
|
||||
// A vertex node is a leaf node in the database and
|
||||
// therefore cannot have any children.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UnknownListRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
//RegisterRecordProxy<UnknownListRecord> g_UnknownListProxy;
|
||||
|
||||
|
||||
UnknownListRecord::UnknownListRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
UnknownListRecord::~UnknownListRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void UnknownListRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// virtual
|
||||
bool UnknownListRecord::readLocalData(Input& fr)
|
||||
{
|
||||
// A vertex node is a leaf node in the database and
|
||||
// therefore cannot have any children.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VectorRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<VectorRecord> g_VectorProxy;
|
||||
|
||||
|
||||
VectorRecord::VectorRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
VectorRecord::~VectorRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void VectorRecord::endian()
|
||||
{
|
||||
SVector *pSVector = (SVector*)getData();
|
||||
|
||||
pSVector->Vec.endian();
|
||||
}
|
||||
|
||||
|
||||
|
||||
288
src/osgPlugins/flt/FaceRecord.h
Normal file
288
src/osgPlugins/flt/FaceRecord.h
Normal file
@@ -0,0 +1,288 @@
|
||||
// FaceRecord.h
|
||||
|
||||
#ifndef __FLT_FACE_RECORD_H
|
||||
#define __FLT_FACE_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FaceRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
struct SFace
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
char szIdent[8]; // 7 char ASCII ID; 0 terminates
|
||||
int32 diIRColor; // IR Color Code
|
||||
int16 iObjectRelPriority; // Polygon relative priority
|
||||
uint8 swDrawFlag; // How to draw the polygon
|
||||
// = 0 Draw solid backfaced
|
||||
// = 1 Draw solid no backface
|
||||
// = 2 Draw wireframe and not closed
|
||||
// = 3 Draw closed wireframe
|
||||
// = 4 Surround with wireframe in alternate color
|
||||
// = 8 Omni-directional light
|
||||
// = 9 Unidirectional light
|
||||
// = 10 Bidirectional light
|
||||
uint8 swTexWhite; // if TRUE, draw textured polygon white (see note 1 below)
|
||||
uint16 wPrimaryNameIndex; // Color name index
|
||||
uint16 wSecondaryNameIndex; // Alternate color name index
|
||||
uint8 swNotUsed; // Not used
|
||||
uint8 swTemplateTrans; // Set template transparency
|
||||
// = 0 None
|
||||
// = 1 Fixed
|
||||
// = 2 Axis type rotate
|
||||
// = 4 Point rotate
|
||||
int16 iDetailTexturePattern; // Detail texture pattern no. -1 if none
|
||||
int16 iTexturePattern; // Texture pattern no. -1 if none
|
||||
int16 iMaterial; // Material code [0-63]. -1 if none
|
||||
int16 iSurfaceMaterial; // Surface material code (for DFAD)
|
||||
int16 iFeature; // Feature ID (for DFAD)
|
||||
int32 diIRMaterial; // IR Material codes
|
||||
uint16 wTransparency; // Transparency
|
||||
// = 0 opaque
|
||||
// = 65535 for totally clear
|
||||
uint8 swInfluenceLODGen; // LOD Generation Control
|
||||
uint8 swLinestyle; // Linestyle Index
|
||||
int32 diFlags; // Flags (bits from to right)
|
||||
// 0 = Terrain
|
||||
// 1 = No Color
|
||||
// 2 = No Alt Color
|
||||
// 3 = Packed color
|
||||
// 4 = Terrain culture cutout (footprint)
|
||||
// 5 = Hidden (not drawn)
|
||||
// 6-31 Spare
|
||||
uint8 swLightMode; // Lightmode
|
||||
// = 0 use face color, not illuminated
|
||||
// = 1 use vertex color, not illuminated
|
||||
// = 2 use face color and vertex normal
|
||||
// = 3 use vertex color and vertex normal
|
||||
|
||||
uint8 swReserved1[7]; // Reserved
|
||||
color32 PrimaryPackedColor; // Packed Color Primary (A, B, G, R)
|
||||
color32 SecondaryPackedColor; // Packed Color Secondary (A, B, G, R)
|
||||
int16 iTextureMapIndex; // Texture mapping index
|
||||
int16 iReserved2;
|
||||
uint32 dwPrimaryColorIndex;
|
||||
uint32 dwAlternateColorIndex;
|
||||
int16 iReserved3[2];
|
||||
};
|
||||
|
||||
|
||||
class FaceRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
|
||||
enum DrawFlag {
|
||||
SOLID_BACKFACED = 0,
|
||||
SOLID_NO_BACKFACE = 1,
|
||||
WIREFRAME_NOT_CLOSED = 2,
|
||||
WIREFRAME_CLOSED = 3,
|
||||
SURROUND_ALTERNATE_COLOR = 4,
|
||||
OMNIDIRECTIONAL_LIGHT = 8,
|
||||
UNIDIRECTIONAL_LIGHT = 9,
|
||||
BIDIRECTIONAL_LIGHT = 10
|
||||
};
|
||||
|
||||
enum LightMode {
|
||||
FACE_COLOR = 0,
|
||||
VERTEX_COLOR = 1,
|
||||
FACE_COLOR_LIGHTING = 2,
|
||||
VERTEX_COLOR_LIGHTING = 3,
|
||||
};
|
||||
|
||||
FaceRecord();
|
||||
|
||||
virtual Record* clone() const { return new FaceRecord(); }
|
||||
virtual const char* className() const { return "FaceRecord"; }
|
||||
virtual int classOpcode() const { return FACE_OP; }
|
||||
virtual int sizeofData() const { return sizeof(SFace); }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
virtual SFace* getData() const { return (SFace*)_pData; }
|
||||
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
|
||||
|
||||
int numberOfVertices();
|
||||
int getVertexPoolOffset(int index);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~FaceRecord();
|
||||
|
||||
virtual void endian();
|
||||
|
||||
virtual bool readLocalData(Input& fr);
|
||||
// virtual bool writeLocalData(Output& fw);
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VertexListRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct SingleVertexListTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
int32 diSOffset[1]; // Byte offset to this vertex record in vertex table,
|
||||
// the actual vertex of the face
|
||||
} SSingleVertexList;
|
||||
|
||||
|
||||
|
||||
class VertexListRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
VertexListRecord();
|
||||
|
||||
virtual Record* clone() const { return new VertexListRecord(); }
|
||||
virtual const char* className() const { return "VertexListRecord"; }
|
||||
virtual int classOpcode() const { return VERTEX_LIST_OP; }
|
||||
virtual int sizeofData() const { return sizeof(SSingleVertexList); }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
virtual SSingleVertexList* getData() const { return (SSingleVertexList*)_pData; }
|
||||
|
||||
int numberOfVertices();
|
||||
int getVertexPoolOffset(int index);
|
||||
|
||||
protected:
|
||||
virtual ~VertexListRecord();
|
||||
|
||||
virtual bool readLocalData(Input& fr);
|
||||
// virtual bool writeLocalData(Output& fw);
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MorphVertexListRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct MorphVertexListTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
uint32 dwOffset0; // Byte offset into vertex palette of the 0% vertex
|
||||
uint32 dwOffset100; // Byte offset into vertex palette of the 100% vertex
|
||||
} SMorphVertexList;
|
||||
|
||||
|
||||
|
||||
class MorphVertexListRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
MorphVertexListRecord();
|
||||
|
||||
virtual Record* clone() const { return new MorphVertexListRecord(); }
|
||||
virtual const char* className() const { return "MorphVertexListRecord"; }
|
||||
virtual int classOpcode() const { return MORPH_VERTEX_LIST_OP; }
|
||||
virtual int sizeofData() const { return sizeof(SMorphVertexList); }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
virtual SMorphVertexList* getData() const { return (SMorphVertexList*)_pData; }
|
||||
|
||||
int numberOfVertices();
|
||||
|
||||
protected:
|
||||
virtual ~MorphVertexListRecord();
|
||||
|
||||
virtual bool readLocalData(Input& fr);
|
||||
// virtual bool writeLocalData(Output& fw);
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UnknownListRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
class UnknownListRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
UnknownListRecord();
|
||||
|
||||
virtual Record* clone() const { return new UnknownListRecord(); }
|
||||
virtual const char* className() const { return "UnknownListRecord"; }
|
||||
virtual int classOpcode() const { return 53; }
|
||||
// virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
virtual ~UnknownListRecord();
|
||||
|
||||
virtual bool readLocalData(Input& fr);
|
||||
// virtual bool writeLocalData(Output& fw);
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VectorRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// A vector record is an ancillary record of the (pre V15.4) face node.
|
||||
// Its only use is to provide the direction vector for old-style
|
||||
// unidirectional and bidirectional light point faces.
|
||||
|
||||
typedef struct VectorTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
float32x3 Vec;
|
||||
} SVector;
|
||||
|
||||
|
||||
|
||||
class VectorRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
VectorRecord();
|
||||
|
||||
virtual Record* clone() const { return new VectorRecord(); }
|
||||
virtual const char* className() const { return "VectorRecord"; }
|
||||
virtual int classOpcode() const { return VECTOR_OP; }
|
||||
virtual int sizeofData() const { return sizeof(SVector); }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
virtual SVector* getData() const { return (SVector*)_pData; }
|
||||
|
||||
protected:
|
||||
virtual ~VectorRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
166
src/osgPlugins/flt/FltFile.cpp
Normal file
166
src/osgPlugins/flt/FltFile.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
// FltFile.cpp
|
||||
|
||||
#include <osg/OSG>
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include "FltFile.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
#include "ExternalRecord.h"
|
||||
#include "flt2osg.h" // ConvertFromFLT
|
||||
#include "Input.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
FltFile::FltFile(
|
||||
ColorPool* pColorPool,
|
||||
TexturePool* pTexturePool,
|
||||
MaterialPool* pMaterialPool)
|
||||
|
||||
{
|
||||
if (pColorPool)
|
||||
_pColorPool = pColorPool;
|
||||
else
|
||||
_pColorPool = &_colorPool;
|
||||
|
||||
if (pTexturePool)
|
||||
_pTexturePool = pTexturePool;
|
||||
else
|
||||
_pTexturePool = &_texturePool;
|
||||
|
||||
if (pMaterialPool)
|
||||
_pMaterialPool = pMaterialPool;
|
||||
else
|
||||
_pMaterialPool = &_materialPool;
|
||||
|
||||
_pHeaderRecord = NULL;
|
||||
}
|
||||
|
||||
|
||||
FltFile::~FltFile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
osg::Object* FltFile::readObject(const std::string& fileName)
|
||||
{
|
||||
return readNode(fileName);
|
||||
}
|
||||
|
||||
|
||||
osg::Node* FltFile::readNode(const std::string& fileName)
|
||||
{
|
||||
osg::Node* node = NULL;
|
||||
Record* pRootRec = readModel(fileName);
|
||||
|
||||
if (pRootRec == NULL)
|
||||
return NULL;
|
||||
|
||||
// Convert record tree to osg scene graph
|
||||
node = convert();
|
||||
|
||||
pRootRec->unref(); // delete record tree
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
osg::Node* FltFile::convert()
|
||||
{
|
||||
ConvertFromFLT visit(this);
|
||||
return visit.convert(getHeaderRecord());
|
||||
}
|
||||
|
||||
|
||||
// Read flight model (include externals)
|
||||
Record* FltFile::readModel(const std::string& fileName)
|
||||
{
|
||||
Record* pRec = readFile(fileName);
|
||||
if (pRec == NULL) return NULL;
|
||||
|
||||
readExternals(pRec);
|
||||
return pRec;
|
||||
}
|
||||
|
||||
|
||||
Record* FltFile::readFile(const std::string& fileName)
|
||||
{
|
||||
FileInput fin;
|
||||
|
||||
if (!fin.open(fileName)) return NULL;
|
||||
|
||||
osg::notify(osg::INFO) << "Loading " << fileName << " ... " << endl;
|
||||
|
||||
Record* pRec = fin.readCreateRecord();
|
||||
_pHeaderRecord = pRec;
|
||||
if (pRec == NULL)
|
||||
{
|
||||
osg::notify(osg::WARN) << "File not found " << fileName << endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pRec->isPrimaryNode()) // Header
|
||||
pRec->readLocalData(fin); // Read rest of file
|
||||
|
||||
fin.close();
|
||||
|
||||
|
||||
return pRec;
|
||||
}
|
||||
|
||||
|
||||
class ReadExternal : public RecordVisitor
|
||||
{
|
||||
public:
|
||||
ReadExternal(FltFile* fltFile)
|
||||
{
|
||||
_fltFile = fltFile;
|
||||
setTraverseMode(RecordVisitor::TRAVERSE_ALL_CHILDREN);
|
||||
}
|
||||
|
||||
virtual void apply(ExternalRecord& rec)
|
||||
{
|
||||
SExternalReference* pSExternal = (SExternalReference*)rec.getData();
|
||||
|
||||
osg::notify(osg::INFO) << "External=" << pSExternal->szPath << endl;
|
||||
|
||||
ColorPool* pColorPool = NULL;
|
||||
TexturePool* pTexturePool = NULL;
|
||||
MaterialPool* pMaterialPool = NULL;
|
||||
|
||||
if (pSExternal->diFlags & BIT0)
|
||||
pColorPool = _fltFile->getColorPool();
|
||||
|
||||
if (pSExternal->diFlags & BIT2)
|
||||
pTexturePool = _fltFile->getTexturePool();
|
||||
|
||||
if (pSExternal->diFlags & BIT1)
|
||||
pMaterialPool = _fltFile->getMaterialPool();
|
||||
|
||||
FltFile* flt = new FltFile(pColorPool, pTexturePool, pMaterialPool);
|
||||
if (flt)
|
||||
{
|
||||
flt->readModel(pSExternal->szPath);
|
||||
rec.setExternal(flt);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
FltFile* _fltFile;
|
||||
};
|
||||
|
||||
void FltFile::readExternals(Record* pRec)
|
||||
{
|
||||
|
||||
if (pRec)
|
||||
{
|
||||
ReadExternal visitor(this);
|
||||
pRec->accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
60
src/osgPlugins/flt/FltFile.h
Normal file
60
src/osgPlugins/flt/FltFile.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// FltFile.h
|
||||
|
||||
#ifndef __FLT_FILE_H
|
||||
#define __FLT_FILE_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <osg/Referenced>
|
||||
|
||||
#include "Pool.h"
|
||||
|
||||
namespace flt {
|
||||
|
||||
class Record;
|
||||
|
||||
|
||||
class FltFile : public osg::Referenced
|
||||
{
|
||||
|
||||
public:
|
||||
FltFile(
|
||||
ColorPool* pColorPool = NULL,
|
||||
TexturePool* pTexturePool = NULL,
|
||||
MaterialPool* pMaterialPool = NULL);
|
||||
virtual ~FltFile();
|
||||
|
||||
virtual osg::Object* readObject(const std::string& fileName);
|
||||
virtual osg::Node* readNode(const std::string& fileName);
|
||||
osg::Node* convert();
|
||||
Record* getHeaderRecord() { return _pHeaderRecord; }
|
||||
Record* readModel(const std::string& fileName);
|
||||
|
||||
ColorPool* getColorPool() { return _pColorPool; }
|
||||
TexturePool* getTexturePool() { return _pTexturePool; }
|
||||
MaterialPool* getMaterialPool() { return _pMaterialPool; }
|
||||
|
||||
protected:
|
||||
|
||||
Record* readFile(const std::string& fileName);
|
||||
void readExternals(Record* pRec);
|
||||
|
||||
private:
|
||||
|
||||
Record* _pHeaderRecord;
|
||||
|
||||
ColorPool _colorPool;
|
||||
TexturePool _texturePool;
|
||||
MaterialPool _materialPool;
|
||||
|
||||
ColorPool* _pColorPool;
|
||||
TexturePool* _pTexturePool;
|
||||
MaterialPool* _pMaterialPool;
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
95
src/osgPlugins/flt/FltRecords.h
Normal file
95
src/osgPlugins/flt/FltRecords.h
Normal file
@@ -0,0 +1,95 @@
|
||||
// FltRecords.h
|
||||
|
||||
|
||||
#ifndef __FLT_RECORDS_H
|
||||
#define __FLT_RECORDS_H
|
||||
|
||||
#include "flt.h"
|
||||
|
||||
namespace flt {
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct MorphingVertexListTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
int32 diAOffset; // Byte offset to the actual vertex record in the vertex table.
|
||||
int32 diMOffset; // Byte offset to the morph vertex record in the vertex table.
|
||||
} SMorphingVertexList; // see OF doc
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct ReplicateTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
int16 iNumber; // Number of replications
|
||||
int16 iSpare; // Spare for fullword alignment
|
||||
} SReplicate;
|
||||
|
||||
/*
|
||||
typedef struct ReferenceTag // OBSOLETE
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
int16 iSpare; // Spare
|
||||
int16 iNumber; // Instance definition number
|
||||
} SReference;
|
||||
|
||||
|
||||
typedef struct DefinitionTag // OBSOLETE
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
int16 iSpare; // Spare
|
||||
int16 iNumber; // Instance definition number
|
||||
} SDefinition;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
typedef struct ColorTableTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
char szReserved[128];// Reserved
|
||||
color32 Colors[1024]; // Array of brightest RGB of color 0 - 1024
|
||||
} SColorTable;
|
||||
|
||||
// this record is sometimes immediately followed by a: int32 numberOfColorNames
|
||||
// and then the specified number of ColorNames as described in the structure below
|
||||
// to check if such a list exist: compare RecHeaderBuff.wLength with sizeof(SColorTable)
|
||||
|
||||
typedef struct ColorNameListTag
|
||||
{
|
||||
uint16 wEntryLength;
|
||||
int16 iReserved_1;
|
||||
int16 iEntryIndex;
|
||||
int16 iReserved_2;
|
||||
char *szName; // calc length of string from wEntryLength
|
||||
} SColorNameList;
|
||||
*/
|
||||
|
||||
/*
|
||||
typedef struct ComponentTag
|
||||
{
|
||||
float32 sfRed; // red component of material
|
||||
float32 sfGreen; // green component of material
|
||||
float32 sfBlue; // blue component of material
|
||||
} SComponent;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif // __FLT_RECORDS_H
|
||||
|
||||
574
src/osgPlugins/flt/GeoSetBuilder.cpp
Normal file
574
src/osgPlugins/flt/GeoSetBuilder.cpp
Normal file
@@ -0,0 +1,574 @@
|
||||
// GeoSetBuilder.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "FltFile.h"
|
||||
#include "Pool.h"
|
||||
#include "opcodes.h"
|
||||
#include "VertexPoolRecords.h"
|
||||
#include "OldVertexRecords.h"
|
||||
#include "MaterialPaletteRecord.h"
|
||||
#include "GeoSetBuilder.h"
|
||||
|
||||
#include <osg/Object>
|
||||
#include <osg/LOD>
|
||||
#include <osg/GeoState>
|
||||
#include <osg/Transparency>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/GeoState>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Material>
|
||||
#include <osg/Texture>
|
||||
#include <osg/TexEnv>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GeoSetBuilder
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// OpenFlight don't save data in GeoSets. This class tries to find
|
||||
// existing GeoSets with matching state before creating a new GeoSet.
|
||||
|
||||
GeoSetBuilder::GeoSetBuilder(FltFile* pFltFile)
|
||||
{
|
||||
_pFltFile = pFltFile;
|
||||
initPrimData();
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
GeoSetBuilder::~GeoSetBuilder()
|
||||
{
|
||||
for(GeoSetList::iterator itr=_aGeoSet.begin();
|
||||
itr!=_aGeoSet.end();
|
||||
++itr)
|
||||
{
|
||||
delete *itr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GeoSetBuilder::initPrimData()
|
||||
{
|
||||
_appearance.init();
|
||||
_aVertex.erase(_aVertex.begin(), _aVertex.end());
|
||||
}
|
||||
|
||||
|
||||
// Convert flt::TmpGeoSet's to osg::GeoSet's and add to osg::Geode.
|
||||
// If geode parameter is NULL create new.
|
||||
// If geode created inside this function and no osg::GeoSet's
|
||||
// added free geode.
|
||||
osg::Geode* GeoSetBuilder::createOsgGeoSets(osg::Geode* geode)
|
||||
{
|
||||
bool bInternalGeodeAllocation = false;
|
||||
|
||||
if (geode == NULL)
|
||||
{
|
||||
geode = new osg::Geode;
|
||||
bInternalGeodeAllocation = true;
|
||||
}
|
||||
|
||||
for(GeoSetList::iterator itr=_aGeoSet.begin();
|
||||
itr!=_aGeoSet.end();
|
||||
++itr)
|
||||
{
|
||||
osg::GeoSet* gset = (*itr)->createOsgGeoSet();
|
||||
if (gset)
|
||||
geode->addGeoSet(gset);
|
||||
}
|
||||
|
||||
if (bInternalGeodeAllocation && (geode->getNumGeosets() == 0))
|
||||
{
|
||||
geode->unref();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
|
||||
void GeoSetBuilder::addVertex(Record* vertex)
|
||||
{
|
||||
_aVertex.push_back(vertex);
|
||||
_appearance.setVertexOp(vertex->getOpcode());
|
||||
}
|
||||
|
||||
|
||||
bool GeoSetBuilder::addPrimitive()
|
||||
{
|
||||
int nVertices = _aVertex.size();
|
||||
|
||||
if (nVertices == 0) return false;
|
||||
|
||||
if (_appearance.getPrimType() == osg::GeoSet::NO_TYPE)
|
||||
_appearance.setPrimType(findPrimType(nVertices));
|
||||
|
||||
TmpGeoSet* gset = findMatchingGeoSet();
|
||||
if (gset)
|
||||
{
|
||||
addTo(gset);
|
||||
if (_appearance.getMaterial())
|
||||
{
|
||||
_appearance.getMaterial()->unref();
|
||||
_appearance.setMaterial(NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
addToNew();
|
||||
|
||||
initPrimData();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////// protected /////////////////////////////////
|
||||
|
||||
|
||||
TmpGeoSet* GeoSetBuilder::findMatchingGeoSet()
|
||||
{
|
||||
|
||||
for(std::vector<TmpGeoSet*>::iterator itr=_aGeoSet.begin();
|
||||
itr!=_aGeoSet.end();
|
||||
++itr)
|
||||
{
|
||||
if (_appearance == (*itr)->_appearance)
|
||||
return *itr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void GeoSetBuilder::addTo(TmpGeoSet* gset)
|
||||
{
|
||||
int nVertices = _aVertex.size();
|
||||
gset->addPrimLen(nVertices);
|
||||
|
||||
for(std::vector<Record*>::iterator itr=_aVertex.begin();
|
||||
itr!=_aVertex.end();
|
||||
++itr)
|
||||
{
|
||||
gset->addVertex(*itr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GeoSetBuilder::addToNew()
|
||||
{
|
||||
TmpGeoSet* gset = new TmpGeoSet(_pFltFile);
|
||||
if (gset == NULL) return;
|
||||
|
||||
// Transfer data to TmpGeoSet
|
||||
gset->_appearance = _appearance;
|
||||
addTo(gset);
|
||||
|
||||
_aGeoSet.push_back(gset);
|
||||
}
|
||||
|
||||
|
||||
PrimitiveType GeoSetBuilder::findPrimType( int nVertices)
|
||||
{
|
||||
PrimitiveType primtype = osg::GeoSet::NO_TYPE;
|
||||
|
||||
switch (nVertices)
|
||||
{
|
||||
case 1:
|
||||
primtype = osg::GeoSet::POINTS;
|
||||
break;
|
||||
case 2:
|
||||
primtype = osg::GeoSet::LINES;
|
||||
break;
|
||||
case 3:
|
||||
primtype = osg::GeoSet::TRIANGLES;
|
||||
break;
|
||||
case 4:
|
||||
primtype = osg::GeoSet::QUADS;
|
||||
break;
|
||||
default:
|
||||
if (nVertices >= 5) primtype = osg::GeoSet::POLYGON;
|
||||
break;
|
||||
}
|
||||
|
||||
return primtype;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TmpGeoSet
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// GeoSet with dynamic size. Used by GeoSetBuilder as a temp. buffer.
|
||||
|
||||
|
||||
TmpGeoSet::TmpGeoSet(FltFile* pFltFile)
|
||||
{
|
||||
_pFltFile = pFltFile;
|
||||
}
|
||||
|
||||
|
||||
TmpGeoSet::~TmpGeoSet()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TmpGeoSet::addVertex(Record* vertex)
|
||||
{
|
||||
_appearance.setVertexOp(vertex->getOpcode());
|
||||
_aVertex.push_back(vertex);
|
||||
}
|
||||
|
||||
|
||||
void TmpGeoSet::addPrimLen(int len)
|
||||
{
|
||||
_aPrimLen.push_back(len);
|
||||
}
|
||||
|
||||
|
||||
osg::GeoSet* TmpGeoSet::createOsgGeoSet()
|
||||
{
|
||||
int prims = _aPrimLen.size();
|
||||
int indices = _aVertex.size();
|
||||
|
||||
if (prims==0 || indices==0)
|
||||
return NULL;
|
||||
|
||||
osg::GeoSet* gset = new osg::GeoSet;
|
||||
|
||||
gset->setNumPrims(prims);
|
||||
gset->setPrimType(_appearance.getPrimType());
|
||||
|
||||
osg::GeoState* gstate = new osg::GeoState;
|
||||
gset->setGeoState(gstate);
|
||||
|
||||
// Material
|
||||
osg::Material* osgMaterial = _appearance.getMaterial();
|
||||
if (osgMaterial)
|
||||
{
|
||||
gstate->setAttribute(osg::GeoState::MATERIAL, osgMaterial);
|
||||
}
|
||||
|
||||
// Color BIND_OVERALL
|
||||
if (_appearance.getColorBinding() == osg::GeoSet::BIND_OVERALL)
|
||||
{
|
||||
osg::Vec4* color = new osg::Vec4[1];
|
||||
*color = _appearance.getColor();
|
||||
gset->setColorBinding(_appearance.getColorBinding());
|
||||
gset->setColors(color);
|
||||
}
|
||||
|
||||
// Color BIND_PERVERTEX
|
||||
if (_appearance.getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
|
||||
{
|
||||
gset->setColorBinding(_appearance.getColorBinding());
|
||||
gset->setColors(new osg::Vec4[indices]);
|
||||
}
|
||||
|
||||
// Transparency
|
||||
if (_appearance.getTransparency())
|
||||
{
|
||||
gstate->setMode(osg::GeoState::TRANSPARENCY, osg::GeoState::ON);
|
||||
gstate->setAttribute(osg::GeoState::TRANSPARENCY, new osg::Transparency);
|
||||
}
|
||||
|
||||
// Cull face
|
||||
if (_appearance.getCullface())
|
||||
{
|
||||
osg::CullFace* cullface = new osg::CullFace;
|
||||
if (cullface)
|
||||
{
|
||||
gstate->setMode(osg::GeoState::FACE_CULL, osg::GeoState::ON);
|
||||
cullface->setMode(osg::CullFace::BACK);
|
||||
gstate->setAttribute(osg::GeoState::FACE_CULL, cullface);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gstate->setMode(osg::GeoState::FACE_CULL, osg::GeoState::OFF);
|
||||
}
|
||||
|
||||
// Texture
|
||||
if (_appearance.getTexture())
|
||||
{
|
||||
gstate->setMode( osg::GeoState::TEXTURE, osg::GeoState::ON );
|
||||
gstate->setAttribute( osg::GeoState::TEXTURE, _appearance.getTexture() );
|
||||
gstate->setAttribute( osg::GeoState::TEXENV, new osg::TexEnv );
|
||||
}
|
||||
|
||||
// Lighting
|
||||
if (_appearance.getLighting())
|
||||
gstate->setMode( osg::GeoState::LIGHTING, osg::GeoState::ON );
|
||||
else
|
||||
gstate->setMode( osg::GeoState::LIGHTING, osg::GeoState::OFF );
|
||||
|
||||
// Subface
|
||||
if (_appearance.getSubface() > 0)
|
||||
{
|
||||
osg::PolygonOffset* polyoffset = new osg::PolygonOffset;
|
||||
if (polyoffset)
|
||||
{
|
||||
int level = _appearance.getSubface();
|
||||
gstate->setMode(osg::GeoState::POLYGON_OFFSET,osg::GeoState::ON);
|
||||
polyoffset->setOffset(-1*level, -20*level);
|
||||
gstate->setAttribute(osg::GeoState::POLYGON_OFFSET, polyoffset);
|
||||
}
|
||||
}
|
||||
|
||||
// Point
|
||||
if (_appearance.getPrimType() == osg::GeoSet::POINTS)
|
||||
{
|
||||
osg::Point* point = new osg::Point;
|
||||
if (point)
|
||||
{
|
||||
gstate->setMode(osg::GeoState::POINT,osg::GeoState::ON);
|
||||
point->setSize(8);
|
||||
point->enableSmooth();
|
||||
gstate->setAttribute(osg::GeoState::POINT, point);
|
||||
}
|
||||
}
|
||||
|
||||
// PrimLengths
|
||||
|
||||
int nPrimLenSize = 1;
|
||||
if (_appearance.getPrimType() == osg::GeoSet::POLYGON)
|
||||
nPrimLenSize = prims;
|
||||
int *lens = new int[nPrimLenSize];
|
||||
gset->setPrimLengths( lens );
|
||||
for (int n=0; n < nPrimLenSize; n++)
|
||||
lens[n] = _aPrimLen[n];
|
||||
|
||||
// Vertices
|
||||
switch(_appearance.getVertexOp())
|
||||
{
|
||||
case VERTEX_C_OP:
|
||||
gset->setCoords(new osg::Vec3[indices]);
|
||||
break;
|
||||
case VERTEX_CN_OP:
|
||||
gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
gset->setCoords(new osg::Vec3[indices]);
|
||||
gset->setNormals(new osg::Vec3[indices]);
|
||||
break;
|
||||
case VERTEX_CT_OP:
|
||||
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
gset->setCoords(new osg::Vec3[indices]);
|
||||
gset->setTextureCoords(new osg::Vec2[indices]);
|
||||
break;
|
||||
case VERTEX_CNT_OP:
|
||||
gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
gset->setCoords(new osg::Vec3[indices]);
|
||||
gset->setNormals(new osg::Vec3[indices]);
|
||||
gset->setTextureCoords(new osg::Vec2[indices]);
|
||||
break;
|
||||
case OLD_VERTEX_OP:
|
||||
gset->setCoords(new osg::Vec3[indices]);
|
||||
break;
|
||||
case OLD_VERTEX_COLOR_OP:
|
||||
gset->setCoords(new osg::Vec3[indices]);
|
||||
break;
|
||||
case OLD_VERTEX_COLOR_NORMAL_OP:
|
||||
gset->setCoords(new osg::Vec3[indices]);
|
||||
// gset->setNormals(new osg::Vec3[indices]);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Copy vertices
|
||||
{
|
||||
int index;
|
||||
std::vector<Record*>::iterator itr;
|
||||
for(index=0, itr=_aVertex.begin();
|
||||
itr!=_aVertex.end();
|
||||
++index, ++itr)
|
||||
{
|
||||
setVertex(gset, index, *itr);
|
||||
}
|
||||
}
|
||||
|
||||
return gset;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////// private //////////////////////////////////
|
||||
|
||||
|
||||
void TmpGeoSet::setVertex(osg::GeoSet* gset, int index, Record* vertex)
|
||||
{
|
||||
bool bColorBindPerVertex = _appearance.getColorBinding() == osg::GeoSet::BIND_PERVERTEX;
|
||||
|
||||
switch(_appearance.getVertexOp())
|
||||
{
|
||||
case VERTEX_C_OP:
|
||||
{
|
||||
SVertex* pVert = (SVertex*)vertex->getData();
|
||||
osg::Vec3* coords = gset->getCoords();
|
||||
|
||||
coords[index].set(
|
||||
(float)pVert->Coord.x(),
|
||||
(float)pVert->Coord.y(),
|
||||
(float)pVert->Coord.z());
|
||||
if (bColorBindPerVertex)
|
||||
{
|
||||
osg::Vec4* colors = gset->getColors();
|
||||
|
||||
if (pVert->swFlags & BIT3)
|
||||
colors[index] = pVert->PackedColor.get();
|
||||
else
|
||||
{
|
||||
ColorPool* pColorPool = _pFltFile->getColorPool();
|
||||
if (pColorPool)
|
||||
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VERTEX_CN_OP:
|
||||
{
|
||||
SNormalVertex* pVert = (SNormalVertex*)vertex->getData();
|
||||
osg::Vec3* coords = gset->getCoords();
|
||||
osg::Vec3* normals = gset->getNormals();
|
||||
|
||||
coords[index].set(
|
||||
(float)pVert->Coord.x(),
|
||||
(float)pVert->Coord.y(),
|
||||
(float)pVert->Coord.z());
|
||||
normals[index].set(
|
||||
(float)pVert->Normal.x(),
|
||||
(float)pVert->Normal.y(),
|
||||
(float)pVert->Normal.z());
|
||||
if (bColorBindPerVertex)
|
||||
{
|
||||
osg::Vec4* colors = gset->getColors();
|
||||
|
||||
if (pVert->swFlags & BIT3)
|
||||
colors[index] = pVert->PackedColor.get();
|
||||
else
|
||||
{
|
||||
ColorPool* pColorPool = _pFltFile->getColorPool();
|
||||
if (pColorPool)
|
||||
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VERTEX_CNT_OP:
|
||||
{
|
||||
SNormalTextureVertex* pVert = (SNormalTextureVertex*)vertex->getData();
|
||||
osg::Vec3* coords = gset->getCoords();
|
||||
osg::Vec3* normals = gset->getNormals();
|
||||
osg::Vec2* texuv = gset->getTCoords();
|
||||
|
||||
coords[index].set(
|
||||
(float)pVert->Coord.x(),
|
||||
(float)pVert->Coord.y(),
|
||||
(float)pVert->Coord.z());
|
||||
normals[index].set(
|
||||
(float)pVert->Normal.x(),
|
||||
(float)pVert->Normal.y(),
|
||||
(float)pVert->Normal.z());
|
||||
texuv[index].set(
|
||||
(float)pVert->Texture.x(),
|
||||
(float)pVert->Texture.y());
|
||||
if (bColorBindPerVertex)
|
||||
{
|
||||
osg::Vec4* colors = gset->getColors();
|
||||
|
||||
if (pVert->swFlags & BIT3)
|
||||
colors[index] = pVert->PackedColor.get();
|
||||
else
|
||||
{
|
||||
ColorPool* pColorPool = _pFltFile->getColorPool();
|
||||
if (pColorPool)
|
||||
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VERTEX_CT_OP:
|
||||
{
|
||||
STextureVertex* pVert = (STextureVertex*)vertex->getData();
|
||||
osg::Vec3* coords = gset->getCoords();
|
||||
osg::Vec2* texuv = gset->getTCoords();
|
||||
|
||||
coords[index].set(
|
||||
(float)pVert->Coord.x(),
|
||||
(float)pVert->Coord.y(),
|
||||
(float)pVert->Coord.z());
|
||||
texuv[index].set(
|
||||
(float)pVert->Texture.x(),
|
||||
(float)pVert->Texture.y());
|
||||
if (bColorBindPerVertex)
|
||||
{
|
||||
osg::Vec4* colors = gset->getColors();
|
||||
|
||||
if (pVert->swFlags & BIT3)
|
||||
colors[index] = pVert->PackedColor.get();
|
||||
else
|
||||
{
|
||||
ColorPool* pColorPool = _pFltFile->getColorPool();
|
||||
if (pColorPool)
|
||||
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OLD_VERTEX_OP:
|
||||
{
|
||||
SOldVertex* pVert = (SOldVertex*)vertex->getData();
|
||||
osg::Vec3* coords = gset->getCoords();
|
||||
|
||||
coords[index].set(
|
||||
(float)pVert->v[0],
|
||||
(float)pVert->v[1],
|
||||
(float)pVert->v[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
case OLD_VERTEX_COLOR_OP:
|
||||
{
|
||||
SOldVertexColor* pVert = (SOldVertexColor*)vertex->getData();
|
||||
osg::Vec3* coords = gset->getCoords();
|
||||
|
||||
coords[index].set(
|
||||
(float)pVert->v[0],
|
||||
(float)pVert->v[1],
|
||||
(float)pVert->v[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
case OLD_VERTEX_COLOR_NORMAL_OP:
|
||||
{
|
||||
SOldVertexColorNormal* pVert = (SOldVertexColorNormal*)vertex->getData();
|
||||
osg::Vec3* coords = gset->getCoords();
|
||||
// osg::Vec3* normals = gset->getNormals();
|
||||
|
||||
coords[index].set(
|
||||
(float)pVert->Coord[0],
|
||||
(float)pVert->Coord[1],
|
||||
(float)pVert->Coord[2]);
|
||||
/*
|
||||
normals[index].set(
|
||||
(float)pVert->Normal[0],
|
||||
(float)pVert->Normal[1],
|
||||
(float)pVert->Normal[2]);
|
||||
*/
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
234
src/osgPlugins/flt/GeoSetBuilder.h
Normal file
234
src/osgPlugins/flt/GeoSetBuilder.h
Normal file
@@ -0,0 +1,234 @@
|
||||
// GeoSetBuilder.h
|
||||
|
||||
#ifndef __FLT_GEOSETS_H
|
||||
#define __FLT_GEOSETS_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/Vec2>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
|
||||
|
||||
namespace osg {
|
||||
class Node;
|
||||
class LOD;
|
||||
class GeoSet;
|
||||
class Geode;
|
||||
class GeoState;
|
||||
class Material;
|
||||
class Texture;
|
||||
}
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
class Record;
|
||||
class TmpGeoSet;
|
||||
|
||||
typedef osg::GeoSet::PrimitiveType PrimitiveType;
|
||||
typedef std::vector<osg::Vec3> CoordList;
|
||||
typedef std::vector<osg::Vec3> NormalList;
|
||||
typedef std::vector<osg::Vec2> TexUVList;
|
||||
typedef std::vector<osg::Vec4> ColorList;
|
||||
typedef std::vector<Record*> VertexList;
|
||||
typedef std::vector<int> PrimLenList;
|
||||
|
||||
|
||||
|
||||
class Appearance
|
||||
{
|
||||
public:
|
||||
|
||||
typedef osg::GeoSet::BindingType BindingType;
|
||||
|
||||
Appearance() { init(); }
|
||||
|
||||
void init()
|
||||
{
|
||||
_nVertexOp = 0;
|
||||
_primtype = osg::GeoSet::NO_TYPE;
|
||||
_material = NULL;
|
||||
_texture = NULL;
|
||||
_color = osg::Vec4(1,1,1,1);
|
||||
_color_binding = osg::GeoSet::BIND_OFF;
|
||||
_cullface = false;
|
||||
_transparency = false;
|
||||
_lighting = false;
|
||||
_subface = 0;
|
||||
}
|
||||
|
||||
void setVertexOp(int op) { _nVertexOp = op; }
|
||||
int getVertexOp() { return _nVertexOp; }
|
||||
|
||||
void setPrimType(PrimitiveType pt) { _primtype = pt; }
|
||||
PrimitiveType getPrimType() { return _primtype; }
|
||||
|
||||
void setColor(osg::Vec4 color) { _color = color; }
|
||||
osg::Vec4& getColor() { return _color; }
|
||||
|
||||
void setColorBinding( BindingType binding ) { _color_binding = binding; }
|
||||
BindingType getColorBinding() { return _color_binding; }
|
||||
|
||||
void setMaterial(osg::Material *material) { _material = material; }
|
||||
osg::Material* getMaterial() { return _material; }
|
||||
|
||||
void setTexture(osg::Texture *texture) { _texture = texture; }
|
||||
osg::Texture* getTexture() { return _texture; }
|
||||
|
||||
void setCullface(bool cullface) { _cullface = cullface; }
|
||||
bool getCullface() { return _cullface; }
|
||||
|
||||
void setTransparency(bool transp) { _transparency = transp; }
|
||||
bool getTransparency() { return _transparency; }
|
||||
|
||||
void setLighting(bool light) { _lighting = light; }
|
||||
bool getLighting() { return _lighting; }
|
||||
|
||||
void setSubface(int level) { _subface = level; }
|
||||
int getSubface() { return _subface; }
|
||||
|
||||
bool mat_equal(const void *m) const
|
||||
{
|
||||
if (_material && m)
|
||||
return !memcmp(_material, m, sizeof(osg::Material));
|
||||
return (!_material && !m);
|
||||
}
|
||||
|
||||
bool col_equal(const BindingType b, const osg::Vec4 c) const
|
||||
{
|
||||
if (_color_binding != b)
|
||||
return false;
|
||||
if (_color_binding == osg::GeoSet::BIND_OVERALL)
|
||||
return (_color == c);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*inline*/ bool operator == (const Appearance& a) const
|
||||
{
|
||||
return ((_nVertexOp == a._nVertexOp)
|
||||
&& (_primtype == a._primtype)
|
||||
&& mat_equal(a._material)
|
||||
&& col_equal(a._color_binding, a._color)
|
||||
&& (_texture == a._texture)
|
||||
&& (_cullface == a._cullface)
|
||||
&& (_transparency == a._transparency)
|
||||
&& (_lighting == a._lighting)
|
||||
&& (_subface == a._subface));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int _nVertexOp;
|
||||
PrimitiveType _primtype;
|
||||
osg::Material* _material;
|
||||
osg::Texture* _texture;
|
||||
osg::Vec4 _color; // BIND_OVERALL
|
||||
BindingType _color_binding;
|
||||
bool _cullface;
|
||||
bool _transparency;
|
||||
bool _lighting;
|
||||
int _subface;
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GeoSetBuilder
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
class GeoSetBuilder
|
||||
{
|
||||
public:
|
||||
|
||||
typedef osg::GeoSet::BindingType BindingType;
|
||||
|
||||
GeoSetBuilder(FltFile* pFltFile);
|
||||
virtual ~GeoSetBuilder();
|
||||
|
||||
void addVertex(Record* vertex);
|
||||
void setPrimType(PrimitiveType pt) { _appearance.setPrimType(pt); }
|
||||
void setColor(osg::Vec4 color) { _appearance.setColor(color); }
|
||||
void setColorBinding(BindingType binding ) { _appearance.setColorBinding(binding); }
|
||||
void setMaterial(osg::Material *material) { _appearance.setMaterial(material); }
|
||||
void setTexture(osg::Texture *texture) { _appearance.setTexture(texture); }
|
||||
void setCullface(bool cullface) { _appearance.setCullface(cullface); }
|
||||
void setTransparency(bool transp) { _appearance.setTransparency(transp); }
|
||||
void setLighting(bool light) { _appearance.setLighting(light); }
|
||||
void setSubface(int level) { _appearance.setSubface(level); }
|
||||
|
||||
PrimitiveType getPrimType() { return _appearance.getPrimType(); }
|
||||
osg::Vec4& getColor() { return _appearance.getColor(); }
|
||||
BindingType getColorBinding() { return _appearance.getColorBinding(); }
|
||||
osg::Material* getMaterial() { return _appearance.getMaterial(); }
|
||||
osg::Texture* getTexture() { return _appearance.getTexture(); }
|
||||
bool getCullface() { return _appearance.getCullface(); }
|
||||
bool getTransparency() { return _appearance.getTransparency(); }
|
||||
bool getLighting() { return _appearance.getLighting(); }
|
||||
int getSubface() { return _appearance.getSubface(); }
|
||||
|
||||
bool addPrimitive();
|
||||
osg::Geode* createOsgGeoSets(osg::Geode* geode=NULL);
|
||||
|
||||
protected:
|
||||
|
||||
void initPrimData();
|
||||
TmpGeoSet* findMatchingGeoSet();
|
||||
void addTo(TmpGeoSet* gset);
|
||||
void addToNew();
|
||||
PrimitiveType findPrimType( int nVertices);
|
||||
|
||||
private:
|
||||
|
||||
VertexList _aVertex;
|
||||
Appearance _appearance;
|
||||
|
||||
typedef std::vector<TmpGeoSet*> GeoSetList;
|
||||
GeoSetList _aGeoSet;
|
||||
|
||||
FltFile* _pFltFile;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TmpGeoSet
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class TmpGeoSet
|
||||
{
|
||||
public:
|
||||
|
||||
TmpGeoSet(FltFile* pFltFile);
|
||||
virtual ~TmpGeoSet();
|
||||
|
||||
void addVertex(Record* vertex);
|
||||
void addPrimLen(int len);
|
||||
osg::GeoSet* createOsgGeoSet();
|
||||
|
||||
Appearance _appearance;
|
||||
|
||||
private:
|
||||
|
||||
void setVertex(osg::GeoSet* gset, int index, Record* vertex);
|
||||
|
||||
PrimLenList _aPrimLen;
|
||||
VertexList _aVertex;
|
||||
|
||||
FltFile* _pFltFile;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end of namespace flt
|
||||
|
||||
|
||||
|
||||
#endif // __FLT_GEOSETS_H
|
||||
|
||||
44
src/osgPlugins/flt/GroupRecord.cpp
Normal file
44
src/osgPlugins/flt/GroupRecord.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// GroupRecord.cpp
|
||||
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "GroupRecord.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GroupRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<GroupRecord> g_GroupProxy;
|
||||
|
||||
|
||||
GroupRecord::GroupRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
GroupRecord::~GroupRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GroupRecord::endian()
|
||||
{
|
||||
SGroup *pSGroup = (SGroup*)getData();
|
||||
|
||||
ENDIAN( pSGroup->iGroupRelPriority );
|
||||
ENDIAN( pSGroup->dwFlags );
|
||||
ENDIAN( pSGroup->iSpecialId_1 );
|
||||
ENDIAN( pSGroup->iSpecialId_2 );
|
||||
ENDIAN( pSGroup->iSignificance );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
64
src/osgPlugins/flt/GroupRecord.h
Normal file
64
src/osgPlugins/flt/GroupRecord.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// GroupRecord.h
|
||||
|
||||
#ifndef __FLT_GROUP_RECORD_H
|
||||
#define __FLT_GROUP_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
struct SGroup
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
char szIdent[8]; // 7 char ASCII ID; 0 terminates
|
||||
int16 iGroupRelPriority; // Group relative priority
|
||||
int16 iSpare; // Spare for fullword alignment
|
||||
uint32 dwFlags; // Flags (bits, from left to right)
|
||||
// 0 = Reserved
|
||||
// 1 = Forward animation
|
||||
// 2 = Cycling animation
|
||||
// 3 = Bounding box follows
|
||||
// 4 = Freeze bounding box
|
||||
// 5 = Default parent
|
||||
// 6-31 Spare
|
||||
int16 iSpecialId_1; // Special effects ID 1 - defined by real time
|
||||
int16 iSpecialId_2; // Special effects ID 2 - defined by real time
|
||||
int16 iSignificance; // Significance Flags
|
||||
uint8 swLayer; // Layer Number
|
||||
uint8 swReserved[5]; // Reserved
|
||||
};
|
||||
|
||||
|
||||
class GroupRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
GroupRecord();
|
||||
|
||||
virtual Record* clone() const { return new GroupRecord(); }
|
||||
virtual const char* className() const { return "GroupRecord"; }
|
||||
virtual int classOpcode() const { return GROUP_OP; }
|
||||
virtual int sizeofData() const { return sizeof(SGroup); }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
SGroup* getData() const { return (SGroup*)_pData; }
|
||||
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
|
||||
|
||||
int childLODs();
|
||||
|
||||
protected:
|
||||
virtual ~GroupRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
197
src/osgPlugins/flt/HeaderRecord.cpp
Normal file
197
src/osgPlugins/flt/HeaderRecord.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
// HeaderRecord.cpp
|
||||
|
||||
#include "osg/Group"
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "HeaderRecord.h"
|
||||
#include "Input.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HeaderRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<HeaderRecord> g_HeaderProxy;
|
||||
|
||||
|
||||
HeaderRecord::HeaderRecord()
|
||||
{
|
||||
// _pNode = NULL;
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
HeaderRecord::~HeaderRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void HeaderRecord::endian()
|
||||
{
|
||||
SHeader *pHeader = (SHeader*)getData();
|
||||
|
||||
// VALID_RECORD(SHeader, pRecHdr)
|
||||
ENDIAN( pHeader->diFormatRevLev );
|
||||
ENDIAN( pHeader->diDatabaseRevLev );
|
||||
ENDIAN( pHeader->iNextGroup );
|
||||
ENDIAN( pHeader->iNextLOD );
|
||||
ENDIAN( pHeader->iNextObject );
|
||||
ENDIAN( pHeader->iNextPolygon );
|
||||
ENDIAN( pHeader->iMultDivUnit );
|
||||
ENDIAN( pHeader->diFlags );
|
||||
ENDIAN( pHeader->diProjection );
|
||||
ENDIAN( pHeader->iNextDegOfFreedom );
|
||||
ENDIAN( pHeader->iVertexStorage );
|
||||
ENDIAN( pHeader->diDatabaseSource );
|
||||
ENDIAN( pHeader->dfSWDatabaseCoordX );
|
||||
ENDIAN( pHeader->dfSWDatabaseCoordY );
|
||||
ENDIAN( pHeader->dfDatabaseOffsetX );
|
||||
ENDIAN( pHeader->dfDatabaseOffsetY );
|
||||
ENDIAN( pHeader->iNextSound );
|
||||
ENDIAN( pHeader->iNextPath );
|
||||
ENDIAN( pHeader->iNextClippingRegion );
|
||||
ENDIAN( pHeader->iNextText );
|
||||
ENDIAN( pHeader->iNextBSP );
|
||||
ENDIAN( pHeader->iNextSwitch );
|
||||
pHeader->SWCorner.endian();
|
||||
pHeader->NECorner.endian();
|
||||
pHeader->Origin.endian();
|
||||
ENDIAN( pHeader->dfLambertUpperLat );
|
||||
ENDIAN( pHeader->dfLambertLowerLat );
|
||||
ENDIAN( pHeader->iNextLightSource );
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void HeaderRecord::decode()
|
||||
{
|
||||
// SHeader *pHeader = (SHeader*)getData();
|
||||
|
||||
// Add node to scene graph
|
||||
// _pNode = new osg::Node;
|
||||
// _pNode->setName(pHeader->szIdent);
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
bool HeaderRecord::readLocalData(Input& fr)
|
||||
{
|
||||
return PrimNodeRecord::readLocalData(fr);
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
int HeaderRecord::decodeAncillary(int op)
|
||||
{
|
||||
/*
|
||||
switch (op)
|
||||
{
|
||||
case COLOUR_TABLE_OP:
|
||||
G_TRACE0( "\tCOLOUR_TABLE_R\n" );
|
||||
break;
|
||||
|
||||
case MATERIAL_PALETTE_OP:
|
||||
{
|
||||
fltMaterialPalette rec( _pFltFile );
|
||||
rec.readRecordBody();
|
||||
rec.decodeRecord();
|
||||
}
|
||||
break;
|
||||
|
||||
case LIGHT_SOURCE_PALETTE_R:
|
||||
G_TRACE0( "\tLIGHT_SOURCE_PALETTE_R\n" );
|
||||
break;
|
||||
|
||||
case VERTEX_PALETTE_R:
|
||||
{
|
||||
fltVertexPalette rec( _pFltFile );
|
||||
rec.readRecordBody();
|
||||
rec.decodeRecord();
|
||||
}
|
||||
break;
|
||||
|
||||
case VERTEX_COORD_R:
|
||||
{
|
||||
fltVertex rec( _pFltFile );
|
||||
rec.readRecordBody();
|
||||
rec.decodeRecord();
|
||||
}
|
||||
break;
|
||||
|
||||
case VERTEX_NORMAL_COORD_R:
|
||||
{
|
||||
fltNormalVertex rec( _pFltFile );
|
||||
rec.readRecordBody();
|
||||
rec.decodeRecord();
|
||||
}
|
||||
break;
|
||||
|
||||
case VERTEX_NORMAL_UV_COORD_R:
|
||||
{
|
||||
fltNormalTextureVertex rec( _pFltFile );
|
||||
rec.readRecordBody();
|
||||
rec.decodeRecord();
|
||||
}
|
||||
break;
|
||||
|
||||
case VERTEX_UV_COORD_R:
|
||||
{
|
||||
fltTextureVertex rec( _pFltFile );
|
||||
rec.readRecordBody();
|
||||
rec.decodeRecord();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
} // end-switch
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
int HeaderRecord::decodeLevel( int op )
|
||||
{
|
||||
/*
|
||||
switch (op)
|
||||
{
|
||||
case GROUP_OP:
|
||||
{
|
||||
fltGroup rec( _pFltFile, (csGroup*)_pContainer );
|
||||
rec.readRecordBody();
|
||||
rec.decodeRecord();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
void HeaderRecord::write()
|
||||
{
|
||||
SHeader *pHeader = (SHeader*)getData();
|
||||
|
||||
G_TRACE0("Header\n");
|
||||
G_TRACE1("\tFormatRevisionLevel %ld\n", pHeader->diFormatRevLev);
|
||||
G_TRACE1("\tDatabaseRevisionLevel %ld\n", pHeader->diDatabaseRevLev);
|
||||
G_TRACE1("\tDateAndTimeOfLastRev. %s\n", pHeader->szDaTimLastRev);
|
||||
G_TRACE1("\tProjection %ld\n", pHeader->diProjection);
|
||||
G_TRACE1("\tDatabase Source %ld\n", pHeader->diDatabaseSource);
|
||||
G_TRACE1("\tSWCorner,Lat %lf\n", pHeader->SWCorner.dfLat);
|
||||
G_TRACE1("\tSWCorner,Lon %lf\n", pHeader->SWCorner.dfLon);
|
||||
G_TRACE1("\tNECorner,Lat %lf\n", pHeader->NECorner.dfLat);
|
||||
G_TRACE1("\tNECorner,Lon %lf\n", pHeader->NECorner.dfLon);
|
||||
G_TRACE1("\tOrigin,Lat %lf\n", pHeader->Origin.dfLat);
|
||||
G_TRACE1("\tOrigin,Lon %lf\n", pHeader->Origin.dfLon);
|
||||
}
|
||||
*/
|
||||
|
||||
126
src/osgPlugins/flt/HeaderRecord.h
Normal file
126
src/osgPlugins/flt/HeaderRecord.h
Normal file
@@ -0,0 +1,126 @@
|
||||
// HeaderRecord.h
|
||||
|
||||
#ifndef __FLT_HEADER_RECORD_H
|
||||
#define __FLT_HEADER_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
//namespace flt {
|
||||
//class Node;
|
||||
//};
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
struct SHeader
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
char szIdent[8]; // ID field (Not curr used)
|
||||
int32 diFormatRevLev; // Format revision level
|
||||
int32 diDatabaseRevLev; // Edit rev. level
|
||||
char szDaTimLastRev[32]; // Date and time last rev.
|
||||
int16 iNextGroup; // Next group ID number
|
||||
int16 iNextLOD; // Next LOD ID number
|
||||
int16 iNextObject; // Next object ID number
|
||||
int16 iNextPolygon; // Next polygon ID number
|
||||
int16 iMultDivUnit; // Unit multiplier/divisor, always = 1
|
||||
uint8 swVertexCoordUnit; // Vertex coordinate units
|
||||
// 0 = Meters
|
||||
// 1 = Kilometers
|
||||
// 4 = Feet
|
||||
// 5 = Inches
|
||||
// 8 = Nautical miles
|
||||
uint8 swTexWhite; // if TRUE set texwhite on new polygons
|
||||
int32 diFlags; // Flags (bits, from left to right)
|
||||
// 0 = Save vertex normals
|
||||
// 1-31 Spare
|
||||
int32 diNotUsed_1[6]; // Not Used
|
||||
int32 diProjection; // Projection Type
|
||||
// 0 = Flat Earth
|
||||
// 1 = Trapezoidal
|
||||
// 2 = Round Earth
|
||||
// 3 = Lambert
|
||||
// 4 = UTM
|
||||
// 5 = Geodetic
|
||||
// 6 = Geocentric
|
||||
int32 diNotUsed_2[7]; // Not Used
|
||||
int16 iNextDegOfFreedom; // Next degree of freedom ID number
|
||||
int16 iVertexStorage; // Vertex Storage Type
|
||||
// 1 = Double Precision Float
|
||||
int32 diDatabaseSource; // Database Source
|
||||
// 100 = OpenFlight
|
||||
// 200 = DIG I/DIG II
|
||||
// 300 = Evans and Sutherland CT5A/CT6
|
||||
// 400 = PSP DIG
|
||||
// 600 = General Electric CIV/CV / PT2000
|
||||
// 700 = Evans and Sutherland GDF
|
||||
float64 dfSWDatabaseCoordX; // Southwest Database Coordinate (x,y)
|
||||
float64 dfSWDatabaseCoordY;
|
||||
float64 dfDatabaseOffsetX; // Delta (x,y) to Place Database
|
||||
float64 dfDatabaseOffsetY;
|
||||
int16 iNextSound; // Next Sound Bead Id
|
||||
int16 iNextPath; // Next Path Bead ID
|
||||
int32 diReserved_1[2]; // Reserved for MultiGen
|
||||
int16 iNextClippingRegion;// Next Clipping Region Bead ID
|
||||
int16 iNextText; // Next Text Bead ID
|
||||
int16 iNextBSP; // Next BSP ID
|
||||
int16 iNextSwitch; // Next Switch Bead ID
|
||||
int32 diReserved_2; // Reserved
|
||||
float64x2 SWCorner; // South West Corner Lat/Lon (NB: dec. degrees)
|
||||
float64x2 NECorner; // North East Corner Lat/Lon (NB: dec. degrees)
|
||||
float64x2 Origin; // Origin Lat/Lon (NB: dec. degrees, not radians)
|
||||
float64 dfLambertUpperLat; // Lambert Upper Latitude
|
||||
float64 dfLambertLowerLat; // Lambert Lower Latitude
|
||||
int16 iNextLightSource; // Next Light Source ID Number
|
||||
int16 iReserved_3; // Reserved
|
||||
int16 iNextRoad; // Next road bead ID number
|
||||
int16 iNextCat; // Next CAT bead ID number
|
||||
int16 iReserved_4[4]; // Reserved
|
||||
int32 diEllipsoid; // Earth ellipsoid model
|
||||
// 0 - WGS 1984
|
||||
// 1 - WGS 1972
|
||||
// 2 - Bessel
|
||||
// 3 - Clarke 1866
|
||||
// 4 - NAD 1927
|
||||
};
|
||||
|
||||
|
||||
class HeaderRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
HeaderRecord();
|
||||
|
||||
virtual Record* clone() const { return new HeaderRecord(); }
|
||||
virtual const char* className() const { return "HeaderRecord"; }
|
||||
virtual int classOpcode() const { return HEADER_OP; }
|
||||
virtual int sizeofData() const { return sizeof(SHeader); }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
SHeader* getData() const { return (SHeader*)_pData; }
|
||||
virtual const std::string getName( void ) const { return std::string(getData()->szIdent); }
|
||||
|
||||
protected:
|
||||
virtual ~HeaderRecord();
|
||||
|
||||
virtual void endian();
|
||||
virtual void decode();
|
||||
|
||||
virtual bool readLocalData(Input& fr);
|
||||
// virtual bool writeLocalData(Output& fw);
|
||||
|
||||
virtual int decodeAncillary(int op);
|
||||
virtual int decodeLevel(int op);
|
||||
|
||||
private:
|
||||
// vertex pool
|
||||
// osg::Node* _pNode;
|
||||
|
||||
};
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
202
src/osgPlugins/flt/Input.cpp
Normal file
202
src/osgPlugins/flt/Input.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
// Input.cpp
|
||||
|
||||
#include <string>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <osg/Notify>
|
||||
|
||||
#include "Input.h"
|
||||
#include "Record.h"
|
||||
#include "Registry.h"
|
||||
|
||||
#ifdef __sgi
|
||||
using std::string;
|
||||
#endif
|
||||
|
||||
#ifdef OSG_USE_IO_DOT_H
|
||||
#include <iostream.h>
|
||||
#else
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
|
||||
|
||||
FileInput::FileInput()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
FileInput::~FileInput()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void FileInput::_init()
|
||||
{
|
||||
_lRecOffset = 0L;
|
||||
_file = NULL;
|
||||
_eof = true;
|
||||
}
|
||||
|
||||
|
||||
size_t FileInput::_read(void *buffer, size_t size)
|
||||
{
|
||||
if (_eof) return 0;
|
||||
|
||||
size_t nItemsRead = ::fread(buffer, size, 1, _file);
|
||||
if (nItemsRead != 1)
|
||||
_eof = true;
|
||||
|
||||
return nItemsRead;
|
||||
}
|
||||
|
||||
|
||||
bool FileInput::eof()
|
||||
{
|
||||
return _eof;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool FileInput::open(const std::string& fileName)
|
||||
{
|
||||
_file=::fopen( fileName.c_str(), "rb");
|
||||
if (_file == NULL) return false;
|
||||
_eof = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void FileInput::close()
|
||||
{
|
||||
if (_file) ::fclose(_file);
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
bool FileInput::rewindLast()
|
||||
{
|
||||
if (_file == NULL) return false;
|
||||
return (fseek(_file, _lRecOffset, SEEK_SET) == 0);
|
||||
}
|
||||
|
||||
|
||||
long FileInput::offset()
|
||||
{
|
||||
return _lRecOffset;
|
||||
}
|
||||
|
||||
|
||||
// read opcode and size
|
||||
|
||||
bool FileInput::_readHeader(SRecHeader* pHdr)
|
||||
{
|
||||
int nItemsRead;
|
||||
|
||||
_lRecOffset = ::ftell( _file ); // Save file position for rewind operation
|
||||
|
||||
// Read record header (4 bytes)
|
||||
nItemsRead = _read(pHdr, sizeof(SRecHeader));
|
||||
if (nItemsRead != 1)
|
||||
return false;
|
||||
|
||||
if (isLittleEndianMachine())
|
||||
pHdr->endian();
|
||||
|
||||
if ((unsigned)pHdr->length() < sizeof(SRecHeader))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FileInput::_readBody(SRecHeader* pData)
|
||||
{
|
||||
// Read record body
|
||||
int nBodySize = pData->length() - sizeof(SRecHeader);
|
||||
if (nBodySize > 0)
|
||||
{
|
||||
int nItemsRead = _read(pData+1, nBodySize);
|
||||
if (nItemsRead != 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SRecHeader* FileInput::readRecord()
|
||||
{
|
||||
SRecHeader hdr;
|
||||
SRecHeader* pData;
|
||||
|
||||
if (!_readHeader(&hdr))
|
||||
return NULL;
|
||||
|
||||
// Allocate buffer for record (including header)
|
||||
pData = (SRecHeader*)::malloc(hdr.length());
|
||||
if (pData == NULL)
|
||||
return NULL;
|
||||
|
||||
*pData = hdr;
|
||||
|
||||
// Some records contains only the header
|
||||
if (hdr.length() == sizeof(SRecHeader))
|
||||
return pData;
|
||||
|
||||
if (!_readBody(pData))
|
||||
return NULL;
|
||||
|
||||
return pData;
|
||||
}
|
||||
|
||||
|
||||
Record* Input::readCreateRecord()
|
||||
{
|
||||
SRecHeader* pData = readRecord();
|
||||
|
||||
if (pData == NULL) return NULL;
|
||||
|
||||
// find matching record prototype class
|
||||
Record* pProto = Registry::instance()->getRecordProto(pData->opcode());
|
||||
|
||||
if (pProto == NULL)
|
||||
pProto = Registry::instance()->getRecordProto(0);
|
||||
|
||||
if (pProto == NULL)
|
||||
{
|
||||
// Should not be possible to end up here!
|
||||
osg::notify(osg::INFO) << "UnknownRecord not in registry!" << endl;
|
||||
::free(pData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// clone protoype
|
||||
Record* pRec = pProto->cloneRecord(pData);
|
||||
if (pRec == NULL)
|
||||
{
|
||||
osg::notify(osg::INFO) << "Can't clone record!" << endl;
|
||||
::free(pData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
osg::notify(osg::INFO) << "class=" << pRec->className();
|
||||
osg::notify(osg::INFO) << " op=" << pRec->getOpcode();
|
||||
osg::notify(osg::INFO) << " name=" << pRec->getName();
|
||||
osg::notify(osg::INFO) << " offset=" << offset() << endl;
|
||||
#endif
|
||||
|
||||
if (isLittleEndianMachine()) // From Intel with love :-(
|
||||
pRec->endian();
|
||||
|
||||
return pRec;
|
||||
}
|
||||
|
||||
|
||||
108
src/osgPlugins/flt/Input.h
Normal file
108
src/osgPlugins/flt/Input.h
Normal file
@@ -0,0 +1,108 @@
|
||||
#ifndef __FLT_INPUT_H
|
||||
#define __FLT_INPUT_H
|
||||
|
||||
#include "Record.h"
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
namespace osg {
|
||||
class Object;
|
||||
class Image;
|
||||
class Node;
|
||||
};
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
|
||||
class Record;
|
||||
|
||||
|
||||
class Input
|
||||
{
|
||||
public:
|
||||
|
||||
Input() {}
|
||||
|
||||
virtual SRecHeader* readRecord() = 0;
|
||||
virtual bool eof() = 0;
|
||||
virtual bool rewindLast() = 0;
|
||||
virtual long offset() = 0;
|
||||
|
||||
Record* readCreateRecord();
|
||||
|
||||
protected:
|
||||
|
||||
/** disallow creation of Objects on the stack.*/
|
||||
virtual ~Input() {}
|
||||
|
||||
private:
|
||||
|
||||
virtual bool _readHeader(SRecHeader* pHdr) = 0;
|
||||
virtual bool _readBody(SRecHeader* pData) = 0;
|
||||
};
|
||||
|
||||
|
||||
/** Class for managing the reading of binary .flt files.*/
|
||||
class FileInput : public Input
|
||||
{
|
||||
public:
|
||||
|
||||
FileInput();
|
||||
virtual ~FileInput();
|
||||
|
||||
bool open(const std::string& fileName);
|
||||
void close();
|
||||
virtual bool eof();
|
||||
virtual bool rewindLast();
|
||||
virtual long offset();
|
||||
|
||||
virtual SRecHeader* readRecord();
|
||||
|
||||
private:
|
||||
virtual bool _readHeader(SRecHeader* pHdr);
|
||||
virtual bool _readBody(SRecHeader* pData);
|
||||
void _init();
|
||||
size_t _read(void *buffer, size_t size);
|
||||
|
||||
FILE* _file;
|
||||
bool _eof;
|
||||
long _lRecOffset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MemInput : public Input
|
||||
{
|
||||
public:
|
||||
|
||||
MemInput();
|
||||
virtual ~MemInput();
|
||||
|
||||
bool open(SRecHeader* pHdr);
|
||||
void close();
|
||||
virtual bool eof();
|
||||
virtual bool rewindLast();
|
||||
virtual long offset();
|
||||
|
||||
virtual SRecHeader* readRecord();
|
||||
|
||||
private:
|
||||
virtual bool _readHeader(SRecHeader* pHdr);
|
||||
virtual bool _readBody(SRecHeader* pData);
|
||||
void _init();
|
||||
size_t _read(void *buffer, size_t size);
|
||||
|
||||
bool _eof;
|
||||
long _lRecOffset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif // __FLT_INPUT_H
|
||||
62
src/osgPlugins/flt/InstanceRecords.cpp
Normal file
62
src/osgPlugins/flt/InstanceRecords.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// InstanceRecords.cpp
|
||||
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "InstanceRecords.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InstanceDefinitionRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<InstanceDefinitionRecord> g_InstanceDefinitionProxy;
|
||||
|
||||
|
||||
InstanceDefinitionRecord::InstanceDefinitionRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
InstanceDefinitionRecord::~InstanceDefinitionRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void InstanceDefinitionRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InstanceReferenceRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<InstanceReferenceRecord> g_InstanceReferenceProxy;
|
||||
|
||||
|
||||
InstanceReferenceRecord::InstanceReferenceRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
InstanceReferenceRecord::~InstanceReferenceRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void InstanceReferenceRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
85
src/osgPlugins/flt/InstanceRecords.h
Normal file
85
src/osgPlugins/flt/InstanceRecords.h
Normal file
@@ -0,0 +1,85 @@
|
||||
// InstanceRecords.h
|
||||
|
||||
|
||||
#ifndef __FLT_INSTANCE_RECORDS_H
|
||||
#define __FLT_INSTANCE_RECORDS_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InstanceDefinitionRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct InstanceDefinitionTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
}SInstanceDefinition;
|
||||
|
||||
|
||||
class InstanceDefinitionRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
InstanceDefinitionRecord();
|
||||
|
||||
virtual Record* clone() const { return new InstanceDefinitionRecord(); }
|
||||
virtual const char* className() const { return "InstanceDefinitionRecord"; }
|
||||
virtual int classOpcode() const { return INSTANCE_DEFINITION_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
SInstanceDefinition* getData() const { return (SInstanceDefinition*)_pData; }
|
||||
|
||||
protected:
|
||||
virtual ~InstanceDefinitionRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InstanceReferenceRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef struct InstanceReferenceTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
}SInstanceReference;
|
||||
|
||||
|
||||
|
||||
class InstanceReferenceRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
InstanceReferenceRecord();
|
||||
|
||||
virtual Record* clone() const { return new InstanceReferenceRecord(); }
|
||||
virtual const char* className() const { return "InstanceReferenceRecord"; }
|
||||
virtual int classOpcode() const { return INSTANCE_REFERENCE_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
SInstanceReference* getData() const { return (SInstanceReference*)_pData; }
|
||||
|
||||
protected:
|
||||
virtual ~InstanceReferenceRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
73
src/osgPlugins/flt/LightPointRecord.cpp
Normal file
73
src/osgPlugins/flt/LightPointRecord.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
// LightPointRecord.cpp
|
||||
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "LightPointRecord.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LightPointRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<LightPointRecord> g_LightPointProxy;
|
||||
|
||||
|
||||
LightPointRecord::LightPointRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
LightPointRecord::~LightPointRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LightPointRecord::endian()
|
||||
{
|
||||
SLightPoint *pSLightPoint = (SLightPoint*)getData();
|
||||
|
||||
ENDIAN( pSLightPoint->iMaterial );
|
||||
ENDIAN( pSLightPoint->iFeature );
|
||||
ENDIAN( pSLightPoint->diMode );
|
||||
ENDIAN( pSLightPoint->sfIntensityFront );
|
||||
ENDIAN( pSLightPoint->sfIntensityBack );
|
||||
ENDIAN( pSLightPoint->sfMinDefocus );
|
||||
ENDIAN( pSLightPoint->sfMaxDefocus );
|
||||
ENDIAN( pSLightPoint->diFadeMode );
|
||||
ENDIAN( pSLightPoint->diFogPunchMode );
|
||||
ENDIAN( pSLightPoint->diDirectionalMode );
|
||||
ENDIAN( pSLightPoint->diRangeMode );
|
||||
ENDIAN( pSLightPoint->sfMinPixelSize );
|
||||
ENDIAN( pSLightPoint->sfMaxPixelSize );
|
||||
ENDIAN( pSLightPoint->afActualPixelSize );
|
||||
ENDIAN( pSLightPoint->sfTranspFalloff );
|
||||
ENDIAN( pSLightPoint->sfTranspFalloffExponent );
|
||||
ENDIAN( pSLightPoint->sfTranspFalloffScalar );
|
||||
ENDIAN( pSLightPoint->sfTranspFalloffClamp );
|
||||
ENDIAN( pSLightPoint->sfFog );
|
||||
ENDIAN( pSLightPoint->sfReserved );
|
||||
ENDIAN( pSLightPoint->sfSize );
|
||||
ENDIAN( pSLightPoint->diDirection );
|
||||
ENDIAN( pSLightPoint->sfLobeHoriz );
|
||||
ENDIAN( pSLightPoint->sfLobeVert );
|
||||
ENDIAN( pSLightPoint->sfLobeRoll );
|
||||
ENDIAN( pSLightPoint->sfFalloff );
|
||||
ENDIAN( pSLightPoint->sfAmbientIntensity );
|
||||
ENDIAN( pSLightPoint->sfAnimPeriod );
|
||||
ENDIAN( pSLightPoint->sfAnimPhaseDelay );
|
||||
ENDIAN( pSLightPoint->sfAnimPeriodEnable );
|
||||
ENDIAN( pSLightPoint->sfSignificance );
|
||||
ENDIAN( pSLightPoint->sfDrawOrder );
|
||||
ENDIAN( pSLightPoint->sfFlags );
|
||||
pSLightPoint->animRot.endian();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
135
src/osgPlugins/flt/LightPointRecord.h
Normal file
135
src/osgPlugins/flt/LightPointRecord.h
Normal file
@@ -0,0 +1,135 @@
|
||||
// LightPointRecord.h
|
||||
|
||||
#ifndef __FLT_LIGHT_POINT_RECORD_H
|
||||
#define __FLT_LIGHT_POINT_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
struct SLightPoint
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
char szIdent[8]; // 7 char ASCII ID; 0 terminates
|
||||
int16 iMaterial; // Surface material code (for DFAD)
|
||||
int16 iFeature; // Feature ID (for DFAD)
|
||||
color32 dwBackColor; // Back color for all bidirectional points
|
||||
int32 diMode; // Display mode
|
||||
// 0 = RASTER
|
||||
// 1 = CALLIGRAPHIC
|
||||
// 2 = EITHER
|
||||
float32 sfIntensityFront; // Intensity - scalar for front colors
|
||||
float32 sfIntensityBack; // - scalar for back color
|
||||
float32 sfMinDefocus; // Minimum defocus - limit (0.0 - 1.0) for calligraphic points
|
||||
float32 sfMaxDefocus; // Maximum defocus - limit (0.0 - 1.0) for calligraphic points
|
||||
int32 diFadeMode; // Fading mode
|
||||
// 0 = enable perspective fading calculations
|
||||
// 1 = disable calculations
|
||||
int32 diFogPunchMode; // Fog Punch mode
|
||||
// 0 = enable fog punch through calculations
|
||||
// 1 = disable calculations
|
||||
int32 diDirectionalMode; // Directional mode
|
||||
// 0 = enable directional calculations
|
||||
// 1 = disable calculations
|
||||
int32 diRangeMode; // Range mode
|
||||
// 0 = use depth (Z) buffer calculation
|
||||
// 1 = use slant range calculation
|
||||
float32 sfMinPixelSize; // Minimum pixel size
|
||||
// Minimum diameter of points in pixels
|
||||
float32 sfMaxPixelSize; // Maximum pixel size
|
||||
// Maximum diameter of points in pixels
|
||||
float32 afActualPixelSize; // Actual size
|
||||
// Actual diameter of points in database coordinates
|
||||
float32 sfTranspFalloff; // Transparent falloff pixel size
|
||||
// Diameter in pixels when points become transparent
|
||||
float32 sfTranspFalloffExponent; // Transparent falloff exponent
|
||||
// >= 0 - falloff multiplier exponent (1.0 = linear falloff)
|
||||
float32 sfTranspFalloffScalar; // Transparent falloff scalar
|
||||
// > 0 - falloff multiplier scale factor
|
||||
float32 sfTranspFalloffClamp; // Transparent falloff clamp
|
||||
// Minimum permissible falloff multiplier result
|
||||
float32 sfFog; // Fog scalar
|
||||
// >= 0 - adjusts range of points for punch threw effect.
|
||||
float32 sfReserved;
|
||||
float32 sfSize; // Size difference threshold
|
||||
// Point size transition hint to renderer
|
||||
int32 diDirection; // Directional type
|
||||
// 0 = OMNIDIRECTIONAL
|
||||
// 1 = UNIDIRECTIONAL
|
||||
// 2 = BIDIRECTIONAL
|
||||
float32 sfLobeHoriz; // Horizontal lobe angle [degrees]
|
||||
float32 sfLobeVert; // Vertical lobe angle [degrees]
|
||||
float32 sfLobeRoll; // Rotation of lobe about local Y axis [degrees]
|
||||
float32 sfFalloff; // Directional falloff exponent
|
||||
// >= 0 - falloff multiplier exponent
|
||||
// (1.0 = linear falloff)
|
||||
float32 sfAmbientIntensity; // Directional ambient intensity
|
||||
float32 sfAnimPeriod; // Animation period [seconds]
|
||||
float32 sfAnimPhaseDelay; // Animation phase delay [seconds]
|
||||
float32 sfAnimPeriodEnable; // Animation enabled period [seconds]
|
||||
float32 sfSignificance; // Drop out priority for RASCAL lights (0.0 - 1.0)
|
||||
int32 sfDrawOrder; // Calligraphic draw order
|
||||
uint32 sfFlags; // Flags (bits, from left to right)
|
||||
// 0 = reserved
|
||||
// 1 = No back color
|
||||
// TRUE = don<6F>t use back color for
|
||||
// bidirectional points
|
||||
// FALSE = use back color for
|
||||
// bidirectional points
|
||||
// 2 = reserved
|
||||
// 3 = Calligraphic proximity occulting (Debunching)
|
||||
// 4 = Reflective, non-emissive point
|
||||
// 5-7 = Randomize intensity
|
||||
// 0 = never
|
||||
// 1 = low
|
||||
// 2 = medium
|
||||
// 3 = high
|
||||
// 8 = Perspective mode
|
||||
// 9 = Flashing
|
||||
// 10 = Rotating
|
||||
// 11 = Rotate Counter Clockwise
|
||||
// Direction of rotation about local Z axis
|
||||
// 12 = reserved
|
||||
// 13-14 = Quality
|
||||
// 0 = Low
|
||||
// 1 = Medium
|
||||
// 2 = High
|
||||
// 3 = Undefined
|
||||
// 15 = Visible during day
|
||||
// 16 = Visible during dusk
|
||||
// 17 = Visible during night
|
||||
// 18-31 = Spare
|
||||
float32x3 animRot; // Axis of rotation for rotating animation
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LightPointRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
LightPointRecord();
|
||||
|
||||
virtual Record* clone() const { return new LightPointRecord(); }
|
||||
virtual const char* className() const { return "LightPointRecord"; }
|
||||
virtual int classOpcode() const { return LIGHT_POINT_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
virtual SLightPoint* getData() const { return (SLightPoint*)_pData; }
|
||||
|
||||
protected:
|
||||
virtual ~LightPointRecord();
|
||||
|
||||
virtual void endian();
|
||||
};
|
||||
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
38
src/osgPlugins/flt/LightSourcePaletteRecord.cpp
Normal file
38
src/osgPlugins/flt/LightSourcePaletteRecord.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// LightSourcePaletteRecord.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "LightSourcePaletteRecord.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LightSourcePaletteRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
RegisterRecordProxy<LightSourcePaletteRecord> g_LightSourcePaletteProxy;
|
||||
|
||||
|
||||
LightSourcePaletteRecord::LightSourcePaletteRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
LightSourcePaletteRecord::~LightSourcePaletteRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void LightSourcePaletteRecord::endian()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
66
src/osgPlugins/flt/LightSourcePaletteRecord.h
Normal file
66
src/osgPlugins/flt/LightSourcePaletteRecord.h
Normal file
@@ -0,0 +1,66 @@
|
||||
// LightSourcePaletteRecord.h
|
||||
|
||||
#ifndef __FLT_LIGHT_SOURCE_PALETTE_RECORD_H
|
||||
#define __FLT_LIGHT_SOURCE_PALETTE_RECORD_H
|
||||
|
||||
|
||||
#include "opcodes.h"
|
||||
#include "Record.h"
|
||||
#include "RecordVisitor.h"
|
||||
|
||||
|
||||
namespace flt {
|
||||
|
||||
|
||||
typedef struct LightSourcePaletteTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
int32 diIndex; // Palette index
|
||||
int32 diReserved_1[2];
|
||||
char szName[20]; // Light source name
|
||||
int32 diReserved_2;
|
||||
float32 sfAmbientRGBA[4]; // Alpha comp. currently unused
|
||||
float32 sfDiffuseRGBA[4]; // Alpha comp. currently unused
|
||||
float32 sfSpecularRGBA[4]; // Alpha comp. currently unused
|
||||
int32 diLightType; // 0 = INFINITE
|
||||
// 1 = LOCAL
|
||||
// 2 = SPOT
|
||||
int32 diReserved_3[10];
|
||||
float32 sfDropoff; // Spot exponential dropoff term
|
||||
float32 sfCutoff; // Spot cutoff angle (radians)
|
||||
float32 sfYaw;
|
||||
float32 sfPitch;
|
||||
float32 sfConstantAttuenation;
|
||||
float32 sfLinearAttuenation;
|
||||
float32 sfQuadraticAttuenation;
|
||||
int32 diModelingLight; // TRUE/FALSE
|
||||
int32 diSpare[19];
|
||||
} SLightSourcePalette;
|
||||
|
||||
|
||||
|
||||
class LightSourcePaletteRecord : public AncillaryRecord
|
||||
{
|
||||
public:
|
||||
|
||||
LightSourcePaletteRecord();
|
||||
|
||||
virtual Record* clone() const { return new LightSourcePaletteRecord(); }
|
||||
virtual const char* className() const { return "LightSourcePaletteRecord"; }
|
||||
virtual int classOpcode() const { return LIGHT_SOURCE_PALETTE_OP; }
|
||||
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
|
||||
// virtual void traverse(RecordVisitor& rv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~LightSourcePaletteRecord();
|
||||
|
||||
virtual void endian();
|
||||
|
||||
};
|
||||
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
47
src/osgPlugins/flt/LightSourceRecord.cpp
Normal file
47
src/osgPlugins/flt/LightSourceRecord.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// LightSourceRecord.cpp
|
||||
|
||||
#include "flt.h"
|
||||
#include "Registry.h"
|
||||
#include "LightSourceRecord.h"
|
||||
|
||||
|
||||
using namespace flt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LightSourceRecord
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
RegisterRecordProxy<LightSourceRecord> g_LightSourceRecordProxy;
|
||||
|
||||
|
||||
LightSourceRecord::LightSourceRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
LightSourceRecord::~LightSourceRecord()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void LightSourceRecord::endian()
|
||||
{
|
||||
SLightSource *pSLightSource = (SLightSource*)getData();
|
||||
|
||||
ENDIAN( pSLightSource->diReserved_1 );
|
||||
ENDIAN( pSLightSource->diIndex );
|
||||
ENDIAN( pSLightSource->diReserved_2 );
|
||||
ENDIAN( pSLightSource->dwFlags );
|
||||
ENDIAN( pSLightSource->diReserved_3 );
|
||||
pSLightSource->Coord.endian();
|
||||
ENDIAN( pSLightSource->sfYaw );
|
||||
ENDIAN( pSLightSource->sfPitch );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user