Initial revision

This commit is contained in:
Don BURNS
2001-01-10 16:32:10 +00:00
parent 7c12eb9361
commit 70208ebc06
461 changed files with 70936 additions and 0 deletions

101
src/osg/AlphaFunc.cpp Normal file
View 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
View 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
View 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;
}

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

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

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

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

File diff suppressed because it is too large Load Diff

427
src/osg/GeoSet_ogl.cpp Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

148
src/osg/Makefile Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,11 @@
#include "osg/Version"
const char* osgGetVersion()
{
return "0.8.34";
}
const char* osgGetLibraryName()
{
return "Open Scene Graph Library";
}