Initial revision
This commit is contained in:
101
src/osg/AlphaFunc.cpp
Normal file
101
src/osg/AlphaFunc.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/AlphaFunc"
|
||||
#include "osg/Output"
|
||||
#include "osg/Input"
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
AlphaFunc::AlphaFunc()
|
||||
{
|
||||
_comparisonFunc = ALWAYS;
|
||||
_referenceValue = 1.0f;
|
||||
}
|
||||
|
||||
AlphaFunc::~AlphaFunc()
|
||||
{
|
||||
}
|
||||
|
||||
AlphaFunc* AlphaFunc::instance()
|
||||
{
|
||||
static ref_ptr<AlphaFunc> s_AlphaFunc(new AlphaFunc);
|
||||
return s_AlphaFunc.get();
|
||||
}
|
||||
|
||||
void AlphaFunc::enable()
|
||||
{
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
}
|
||||
|
||||
void AlphaFunc::disable()
|
||||
{
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
}
|
||||
|
||||
void AlphaFunc::apply()
|
||||
{
|
||||
glAlphaFunc((GLenum)_comparisonFunc,_referenceValue);
|
||||
}
|
||||
|
||||
|
||||
bool AlphaFunc::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
ComparisonFunction func;
|
||||
if (fr[0].matchWord("comparisonFunc") && matchFuncStr(fr[1].getStr(),func))
|
||||
{
|
||||
_comparisonFunc = func;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
float ref;
|
||||
if (fr[0].matchWord("referenceValue") && fr[1].getFloat(ref))
|
||||
{
|
||||
_referenceValue = ref;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool AlphaFunc::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "comparisonFunc " << getFuncStr(_comparisonFunc) << endl;
|
||||
fw.indent() << "referenceValue " << _referenceValue << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AlphaFunc::matchFuncStr(const char* str,ComparisonFunction& func)
|
||||
{
|
||||
if (strcmp(str,"NEVER")==0) func = NEVER;
|
||||
else if (strcmp(str,"LESS")==0) func = LESS;
|
||||
else if (strcmp(str,"EQUAL")==0) func = EQUAL;
|
||||
else if (strcmp(str,"LEQUAL")==0) func = LEQUAL;
|
||||
else if (strcmp(str,"GREATER")==0) func = GREATER;
|
||||
else if (strcmp(str,"NOTEQUAL")==0) func = NOTEQUAL;
|
||||
else if (strcmp(str,"GEQUAL")==0) func = GEQUAL;
|
||||
else if (strcmp(str,"ALWAYS")==0) func = ALWAYS;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* AlphaFunc::getFuncStr(ComparisonFunction func)
|
||||
{
|
||||
switch(func)
|
||||
{
|
||||
case(NEVER): return "NEVER";
|
||||
case(LESS): return "LESS";
|
||||
case(EQUAL): return "EQUAL";
|
||||
case(LEQUAL): return "LEQUAL";
|
||||
case(GREATER): return "GREATER";
|
||||
case(NOTEQUAL): return "NOTEQUAL";
|
||||
case(GEQUAL): return "GEQUAL";
|
||||
case(ALWAYS): return "ALWAYS";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
272
src/osg/Billboard.cpp
Normal file
272
src/osg/Billboard.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "osg/Billboard"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Billboard> g_BillboardProxy;
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
Billboard::Billboard()
|
||||
{
|
||||
_mode = AXIAL_ROT;
|
||||
// _mode = POINT_ROT_WORLD;
|
||||
_axis.set(0.0f,0.0f,1.0f);
|
||||
}
|
||||
|
||||
|
||||
Billboard::~Billboard()
|
||||
{
|
||||
}
|
||||
|
||||
bool Billboard::addGeoSet(GeoSet *gset)
|
||||
{
|
||||
if (Geode::addGeoSet(gset))
|
||||
{
|
||||
Vec3 pos(0.0f,0.0f,0.0f);
|
||||
while (_positionList.size()<_geosets.size())
|
||||
{
|
||||
_positionList.push_back(pos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Billboard::addGeoSet(GeoSet *gset,const Vec3& pos)
|
||||
{
|
||||
if (Geode::addGeoSet(gset))
|
||||
{
|
||||
while (_positionList.size()<_geosets.size())
|
||||
{
|
||||
_positionList.push_back(pos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Billboard::removeGeoSet( GeoSet *gset )
|
||||
{
|
||||
PositionList::iterator pitr = _positionList.begin();
|
||||
for (GeoSetList::iterator itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr,++pitr)
|
||||
{
|
||||
if (itr->get()==gset)
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing gset's reference count.
|
||||
_geosets.erase(itr);
|
||||
_positionList.erase(pitr);
|
||||
_bsphere_computed = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Billboard::calcRotation(const Vec3& eye_local, const Vec3& pos_local,Matrix& mat)
|
||||
{
|
||||
switch(_mode)
|
||||
{
|
||||
case(AXIAL_ROT):
|
||||
{
|
||||
Vec3 ev = pos_local-eye_local;
|
||||
ev.z() = 0.0f;
|
||||
float ev_length = ev.length();
|
||||
if (ev_length>0.0f) {
|
||||
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
|
||||
//mat.makeRot(rotation_z*180.0f/M_PI,0.0f,0.0f,1.0f);
|
||||
float inv = 1.0f/ev_length;
|
||||
float c = ev.y()*inv;
|
||||
float s = ev.x()*inv;
|
||||
mat._mat[0][0] = c;
|
||||
mat._mat[0][1] = -s;
|
||||
mat._mat[1][0] = s;
|
||||
mat._mat[1][1] = c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(POINT_ROT_WORLD):
|
||||
case(POINT_ROT_EYE):
|
||||
{
|
||||
Vec3 ev = pos_local-eye_local;
|
||||
ev.normalize();
|
||||
|
||||
float ev_len = ev.length();
|
||||
if (ev_len != 0.0f)
|
||||
{
|
||||
ev /= ev_len;
|
||||
|
||||
Vec3 cp = ev^Vec3(0.0f,1.0f,0.0f);
|
||||
float dot = ev*Vec3(0.0f,1.0f,0.0f);
|
||||
|
||||
float cp_len = cp.length();
|
||||
if (cp_len != 0.0f)
|
||||
{
|
||||
cp /= cp_len;
|
||||
|
||||
float rotation_cp = acosf(dot);
|
||||
mat.makeRot(rotation_cp*180.0f/M_PI,cp[0],cp[1],cp[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Billboard::calcTransform(const Vec3& eye_local, const Vec3& pos_local,Matrix& mat)
|
||||
{
|
||||
// mat.makeTrans(pos_local[0],pos_local[1],pos_local[2]);
|
||||
// mat.makeIdent();
|
||||
calcRotation(eye_local,pos_local,mat);
|
||||
|
||||
// mat.postTrans(pos_local[0],pos_local[1],pos_local[2]);
|
||||
mat._mat[3][0] += pos_local[0];
|
||||
mat._mat[3][1] += pos_local[1];
|
||||
mat._mat[3][2] += pos_local[2];
|
||||
|
||||
}
|
||||
|
||||
bool Billboard::readLocalData(Input& fr)
|
||||
{
|
||||
// note, free done by Node::read(Input& fr)
|
||||
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr[0].matchWord("Mode"))
|
||||
{
|
||||
if (fr[1].matchWord("AXIAL_ROT"))
|
||||
{
|
||||
_mode = AXIAL_ROT;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("POINT_ROT_EYE"))
|
||||
{
|
||||
_mode = POINT_ROT_EYE;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("POINT_ROT_WORLD"))
|
||||
{
|
||||
_mode = POINT_ROT_WORLD;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
// read the position data.
|
||||
bool matchFirst = false;
|
||||
if ((matchFirst=fr.matchSequence("Positions {")) || fr.matchSequence("Positions %i {"))
|
||||
{
|
||||
|
||||
// set up coordinates.
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
|
||||
if (matchFirst)
|
||||
{
|
||||
fr += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//_positionList.(capacity);
|
||||
fr += 3;
|
||||
}
|
||||
|
||||
Vec3 pos;
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
{
|
||||
if (fr[0].getFloat(pos[0]) && fr[1].getFloat(pos[1]) && fr[2].getFloat(pos[2]))
|
||||
{
|
||||
fr += 3;
|
||||
_positionList.push_back(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
++fr;
|
||||
}
|
||||
}
|
||||
|
||||
iteratorAdvanced = true;
|
||||
++fr;
|
||||
|
||||
}
|
||||
|
||||
if (Geode::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
bool Billboard::writeLocalData(Output& fw)
|
||||
{
|
||||
|
||||
switch(_mode)
|
||||
{
|
||||
case(AXIAL_ROT): fw.indent() << "Mode AXIAL_ROT"<<endl; break;
|
||||
case(POINT_ROT_EYE): fw.indent() << "Mode POINT_ROT_EYE"<<endl; break;
|
||||
case(POINT_ROT_WORLD): fw.indent() << "Mode POINT_ROT_WORLD"<<endl; break;
|
||||
}
|
||||
|
||||
fw.indent() << "Axis " << _axis[0] << " "<<_axis[1]<<" "<<_axis[2]<<endl;
|
||||
|
||||
fw.indent() << "Positions {"<<endl;
|
||||
fw.moveIn();
|
||||
for(PositionList::iterator piter = _positionList.begin();
|
||||
piter != _positionList.end();
|
||||
++piter)
|
||||
{
|
||||
fw.indent() << (*piter)[0] << " "<<(*piter)[1]<<" "<<(*piter)[2]<<endl;
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent() << "}"<<endl;
|
||||
|
||||
Geode::writeLocalData(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Billboard::computeBound( void )
|
||||
{
|
||||
int i;
|
||||
int ngsets = _geosets.size();
|
||||
|
||||
if( ngsets == 0 ) return false;
|
||||
|
||||
_bsphere._center.set(0.0f,0.0f,0.0f);
|
||||
|
||||
for( i = 0; i < ngsets; i++ )
|
||||
{
|
||||
GeoSet *gset = _geosets[i].get();
|
||||
const BoundingBox& bbox = gset->getBound();
|
||||
|
||||
_bsphere._center += bbox.center();
|
||||
_bsphere._center += _positionList[i];
|
||||
}
|
||||
|
||||
_bsphere._center /= (float)(ngsets);
|
||||
|
||||
float maxd = 0.0;
|
||||
for( i = 0; i < ngsets; ++i )
|
||||
{
|
||||
GeoSet *gset = _geosets[i].get();
|
||||
const BoundingBox& bbox = gset->getBound();
|
||||
Vec3 local_center = _bsphere._center-_positionList[i];
|
||||
for(unsigned int c=0;c<8;++c)
|
||||
{
|
||||
float d = (bbox.corner(c)-local_center).length2();
|
||||
if( d > maxd ) maxd = d;
|
||||
}
|
||||
}
|
||||
_bsphere._radius = sqrtf(maxd);
|
||||
|
||||
_bsphere_computed=true;
|
||||
|
||||
return true;
|
||||
}
|
||||
44
src/osg/BoundingBox.cpp
Normal file
44
src/osg/BoundingBox.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "osg/BoundingBox"
|
||||
#include "osg/BoundingSphere"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
void BoundingBox::expandBy(const Vec3& v)
|
||||
{
|
||||
if(v.x()<_min.x()) _min.x() = v.x();
|
||||
if(v.x()>_max.x()) _max.x() = v.x();
|
||||
|
||||
if(v.y()<_min.y()) _min.y() = v.y();
|
||||
if(v.y()>_max.y()) _max.y() = v.y();
|
||||
|
||||
if(v.z()<_min.z()) _min.z() = v.z();
|
||||
if(v.z()>_max.z()) _max.z() = v.z();
|
||||
}
|
||||
|
||||
void BoundingBox::expandBy(const BoundingBox& bb)
|
||||
{
|
||||
if (!bb.isValid()) return;
|
||||
|
||||
if(bb._min.x()<_min.x()) _min.x() = bb._min.x();
|
||||
if(bb._max.x()>_max.x()) _max.x() = bb._max.x();
|
||||
|
||||
if(bb._min.y()<_min.y()) _min.y() = bb._min.y();
|
||||
if(bb._max.y()>_max.y()) _max.y() = bb._max.y();
|
||||
|
||||
if(bb._min.z()<_min.z()) _min.z() = bb._min.z();
|
||||
if(bb._max.z()>_max.z()) _max.z() = bb._max.z();
|
||||
}
|
||||
|
||||
void BoundingBox::expandBy(const BoundingSphere& sh)
|
||||
{
|
||||
if (!sh.isValid()) return;
|
||||
|
||||
if(sh._center.x()-sh._radius<_min.x()) _min.x() = sh._center.x()-sh._radius;
|
||||
if(sh._center.x()+sh._radius>_max.x()) _max.x() = sh._center.x()+sh._radius;
|
||||
|
||||
if(sh._center.y()-sh._radius<_min.y()) _min.y() = sh._center.y()-sh._radius;
|
||||
if(sh._center.y()+sh._radius>_max.y()) _max.y() = sh._center.y()+sh._radius;
|
||||
|
||||
if(sh._center.z()-sh._radius<_min.z()) _min.z() = sh._center.z()-sh._radius;
|
||||
if(sh._center.z()+sh._radius>_max.z()) _max.z() = sh._center.z()+sh._radius;
|
||||
}
|
||||
81
src/osg/BoundingSphere.cpp
Normal file
81
src/osg/BoundingSphere.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "osg/BoundingSphere"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
void BoundingSphere::expandBy(const Vec3& v)
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
Vec3 dv = v-_center;
|
||||
float r = dv.length();
|
||||
if (r>_radius)
|
||||
{
|
||||
float dr = (r-_radius)*0.5f;
|
||||
_center += dv*(dr/r);
|
||||
_radius += dr;
|
||||
} // else do nothing as vertex is within sphere.
|
||||
}
|
||||
else
|
||||
{
|
||||
_center = v;
|
||||
_radius = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BoundingSphere::expandRadiusBy(const Vec3& v)
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
float r = (v-_center).length();
|
||||
if (r>_radius) _radius = r;
|
||||
// else do nothing as vertex is within sphere.
|
||||
}
|
||||
else
|
||||
{
|
||||
_center = v;
|
||||
_radius = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BoundingSphere::expandBy(const BoundingSphere& sh)
|
||||
{
|
||||
if (sh.isValid())
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
Vec3 dv = sh._center-_center;
|
||||
float dv_len = dv.length();
|
||||
if (dv_len+sh._radius>_radius)
|
||||
{
|
||||
|
||||
Vec3 e1 = _center-(dv*(_radius/dv_len));
|
||||
Vec3 e2 = sh._center+(dv*(sh._radius/dv_len));
|
||||
_center = (e1+e2)*0.5f;
|
||||
_radius = (e2-_center).length();
|
||||
|
||||
} // else do nothing as vertex is within sphere.
|
||||
}
|
||||
else
|
||||
{
|
||||
_center = sh._center;
|
||||
_radius = sh._radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
void BoundingSphere::expandRadiusBy(const BoundingSphere& sh)
|
||||
{
|
||||
if (sh.isValid())
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
float r = (sh._center-_center).length()+sh._radius;
|
||||
if (r>_radius) _radius = r;
|
||||
// else do nothing as vertex is within sphere.
|
||||
}
|
||||
else
|
||||
{
|
||||
_center = sh._center;
|
||||
_radius = sh._radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
85
src/osg/Camera.cpp
Normal file
85
src/osg/Camera.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "osg/GL"
|
||||
#include <osg/Camera>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
_fovy = 60.0;
|
||||
_aspectRatio = 1.0;
|
||||
home();
|
||||
}
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
}
|
||||
|
||||
void Camera::home()
|
||||
{
|
||||
_eyePoint.set(0.0f,0.0f,0.0f);
|
||||
_lookPoint.set(0.0f,0.0f,-1.0f);
|
||||
_upVector.set(0.0f,1.0f,0.0f);
|
||||
_nearPlane = 1.0;
|
||||
_farPlane = 1000.0;
|
||||
}
|
||||
|
||||
void Camera::setView(osg::Vec3 eyePoint, osg::Vec3 lookPoint, osg::Vec3 upVector)
|
||||
{
|
||||
// Should do some checking here!
|
||||
_eyePoint = eyePoint;
|
||||
_lookPoint = lookPoint;
|
||||
_upVector = upVector;
|
||||
}
|
||||
|
||||
void Camera::draw_PROJECTION() const
|
||||
{
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
gluPerspective(_fovy, _aspectRatio, static_cast<GLdouble>(_nearPlane), static_cast<GLdouble>(_farPlane));
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
}
|
||||
|
||||
void Camera::draw_MODELVIEW() const
|
||||
{
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
gluLookAt( _eyePoint.x(), _eyePoint.y(), _eyePoint.z(),
|
||||
_lookPoint.x(), _lookPoint.y(), _lookPoint.z(),
|
||||
_upVector.x(), _upVector.y(), _upVector.z());
|
||||
|
||||
}
|
||||
|
||||
void Camera::ensureOrthogonalUpVector()
|
||||
{
|
||||
Vec3 lv = _lookPoint-_eyePoint;
|
||||
Vec3 sv = lv^_upVector;
|
||||
_upVector = sv^lv;
|
||||
_upVector.normalize();
|
||||
}
|
||||
|
||||
void Camera::mult(const Camera& camera,const Matrix& m)
|
||||
{
|
||||
// transform camera.
|
||||
_upVector = (camera._lookPoint+camera._upVector)*m;
|
||||
_eyePoint = camera._eyePoint*m;
|
||||
_lookPoint = camera._lookPoint*m;
|
||||
_upVector -= _lookPoint;
|
||||
|
||||
// now reset up vector so it remains at 90 degrees to look vector,
|
||||
// as it may drift during transformation.
|
||||
ensureOrthogonalUpVector();
|
||||
}
|
||||
|
||||
void Camera::mult(const Matrix& m,const Camera& camera)
|
||||
{
|
||||
// transform camera.
|
||||
_upVector = m*(camera._lookPoint+camera._upVector);
|
||||
_eyePoint = m*camera._eyePoint;
|
||||
_lookPoint = m*camera._lookPoint;
|
||||
_upVector -= _lookPoint;
|
||||
|
||||
// now reset up vector so it remains at 90 degrees to look vector,
|
||||
// as it may drift during transformation.
|
||||
ensureOrthogonalUpVector();
|
||||
}
|
||||
|
||||
80
src/osg/CullFace.cpp
Normal file
80
src/osg/CullFace.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/CullFace"
|
||||
#include "osg/Output"
|
||||
#include "osg/Input"
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
CullFace::CullFace()
|
||||
{
|
||||
_mode = BACK;
|
||||
}
|
||||
|
||||
CullFace::~CullFace()
|
||||
{
|
||||
}
|
||||
|
||||
CullFace* CullFace::instance()
|
||||
{
|
||||
static ref_ptr<CullFace> s_CullFace(new CullFace);
|
||||
return s_CullFace.get();
|
||||
}
|
||||
|
||||
void CullFace::enable( void )
|
||||
{
|
||||
glEnable( GL_CULL_FACE );
|
||||
}
|
||||
|
||||
|
||||
void CullFace::disable( void )
|
||||
{
|
||||
glDisable( GL_CULL_FACE );
|
||||
}
|
||||
|
||||
void CullFace::apply()
|
||||
{
|
||||
glCullFace((GLenum)_mode);
|
||||
}
|
||||
|
||||
|
||||
bool CullFace::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr[0].matchWord("mode"))
|
||||
{
|
||||
if (fr[1].matchWord("FRONT"))
|
||||
{
|
||||
_mode = FRONT;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("BACK"))
|
||||
{
|
||||
_mode = BACK;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("FRONT_AND_BACK"))
|
||||
{
|
||||
_mode = FRONT_AND_BACK;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool CullFace::writeLocalData(Output& fw)
|
||||
{
|
||||
switch(_mode)
|
||||
{
|
||||
case(FRONT): fw.indent() << "mode FRONT" << endl; break;
|
||||
case(BACK): fw.indent() << "mode BACK" << endl; break;
|
||||
case(FRONT_AND_BACK): fw.indent() << "mode FRONT_AND_BACK" << endl; break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
112
src/osg/DCS.cpp
Normal file
112
src/osg/DCS.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "osg/DCS"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<DCS> g_DCSProxy;
|
||||
|
||||
DCS::DCS()
|
||||
{
|
||||
_mat = new Matrix(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0 );
|
||||
|
||||
_mat->ref();
|
||||
}
|
||||
|
||||
|
||||
DCS::DCS(const Matrix& mat )
|
||||
{
|
||||
_mat = new Matrix(mat);
|
||||
_mat->ref();
|
||||
}
|
||||
|
||||
|
||||
DCS::~DCS()
|
||||
{
|
||||
_mat->unref();
|
||||
}
|
||||
|
||||
void DCS::setMatrix(const Matrix& mat )
|
||||
{
|
||||
*_mat = mat;
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
void DCS::preTranslate( float tx, float ty, float tz )
|
||||
{
|
||||
_mat->preTrans( tx, ty, tz );
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
void DCS::preRotate( float deg, float x, float y, float z )
|
||||
{
|
||||
_mat->preRot( deg, x, y, z );
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
bool DCS::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (Matrix* tmpMatrix = static_cast<Matrix*>(Matrix::instance()->readClone(fr)))
|
||||
{
|
||||
|
||||
if (_mat) _mat->unref();
|
||||
_mat = tmpMatrix;
|
||||
_mat->ref();
|
||||
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (Group::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool DCS::writeLocalData(Output& fw)
|
||||
{
|
||||
if (_mat) _mat->write(fw);
|
||||
|
||||
|
||||
return Group::writeLocalData(fw);
|
||||
}
|
||||
|
||||
bool DCS::computeBound( void )
|
||||
{
|
||||
if (!Group::computeBound()) return false;
|
||||
|
||||
Vec3 xdash = _bsphere._center;
|
||||
xdash.x() += _bsphere._radius;
|
||||
xdash = xdash*(*_mat);
|
||||
|
||||
Vec3 ydash = _bsphere._center;
|
||||
ydash.y() += _bsphere._radius;
|
||||
ydash = ydash*(*_mat);
|
||||
|
||||
Vec3 zdash = _bsphere._center;
|
||||
zdash.y() += _bsphere._radius;
|
||||
zdash = zdash*(*_mat);
|
||||
|
||||
_bsphere._center = _bsphere._center*(*_mat);
|
||||
|
||||
xdash -= _bsphere._center;
|
||||
float len_xdash = xdash.length();
|
||||
|
||||
ydash -= _bsphere._center;
|
||||
float len_ydash = ydash.length();
|
||||
|
||||
zdash -= _bsphere._center;
|
||||
float len_zdash = zdash.length();
|
||||
|
||||
_bsphere._radius = len_xdash;
|
||||
if (_bsphere._radius<len_ydash) _bsphere._radius = len_ydash;
|
||||
if (_bsphere._radius<len_zdash) _bsphere._radius = len_zdash;
|
||||
|
||||
return true;
|
||||
}
|
||||
66
src/osg/DynamicLibrary.cpp
Normal file
66
src/osg/DynamicLibrary.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifdef WIN32
|
||||
#include <Io.h>
|
||||
#include <Windows.h>
|
||||
#include <Winbase.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifndef OSG_USE_IO_DOT_H
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
#include "osg/DynamicLibrary"
|
||||
#include "osg/OSG"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
DynamicLibrary::DynamicLibrary(const std::string& name,HANDLE handle)
|
||||
{
|
||||
_name = name;
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
DynamicLibrary::~DynamicLibrary()
|
||||
{
|
||||
if (_handle)
|
||||
{
|
||||
#ifdef WIN32
|
||||
FreeLibrary((HMODULE)_handle);
|
||||
#else
|
||||
dlclose(_handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
DynamicLibrary* DynamicLibrary::loadLibrary(const std::string& libraryName)
|
||||
{
|
||||
|
||||
char* fullLibraryName = osg::findDSO( libraryName.c_str() );
|
||||
if (fullLibraryName==NULL) return NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
HANDLE handle = LoadLibrary( fullLibraryName );
|
||||
if (handle) return new DynamicLibrary(libraryName,handle);
|
||||
notify(WARN) << "DynamicLibrary::failed loading "<<fullLibraryName<<endl;
|
||||
#else
|
||||
HANDLE handle = dlopen( fullLibraryName, RTLD_LAZY );
|
||||
if (handle) return new DynamicLibrary(libraryName,handle);
|
||||
notify(WARN) << "DynamicLibrary::failed loading "<<fullLibraryName<<endl;
|
||||
notify(WARN) << "DynamicLibrary::error "<<dlerror()<<endl;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DynamicLibrary::PROC_ADDRESS DynamicLibrary::getProcAddress(const std::string& procName)
|
||||
{
|
||||
if (_handle==NULL) return NULL;
|
||||
#ifdef WIN32
|
||||
return GetProcAddress( (HMODULE)_handle, procName.c_str() );
|
||||
#else
|
||||
return dlsym( _handle, procName.c_str() );
|
||||
#endif
|
||||
}
|
||||
45
src/osg/ExtensionSupported.cpp
Normal file
45
src/osg/ExtensionSupported.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/ExtensionSupported"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// copied form glut_ext.c
|
||||
// to be rewritten... Robert Osfield, November 2000.
|
||||
bool osg::ExtensionSupported(const char *extension)
|
||||
{
|
||||
static const GLubyte *extensions = NULL;
|
||||
const GLubyte *start;
|
||||
GLubyte *where, *terminator;
|
||||
|
||||
/* Extension names should not have spaces. */
|
||||
where = (GLubyte *) strchr(extension, ' ');
|
||||
if (where || *extension == '\0')
|
||||
return 0;
|
||||
|
||||
if (!extensions) {
|
||||
extensions = glGetString(GL_EXTENSIONS);
|
||||
}
|
||||
/* It takes a bit of care to be fool-proof about parsing the
|
||||
OpenGL extensions string. Don't be fooled by sub-strings,
|
||||
etc. */
|
||||
start = extensions;
|
||||
for (;;) {
|
||||
/* If your application crashes in the strstr routine below,
|
||||
you are probably calling glutExtensionSupported without
|
||||
having a current window. Calling glGetString without
|
||||
a current OpenGL context has unpredictable results.
|
||||
Please fix your program. */
|
||||
where = (GLubyte *) strstr((const char *) start, extension);
|
||||
if (!where)
|
||||
break;
|
||||
terminator = where + strlen(extension);
|
||||
if (where == start || *(where - 1) == ' ') {
|
||||
if (*terminator == ' ' || *terminator == '\0') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
start = terminator;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
422
src/osg/Field.cpp
Normal file
422
src/osg/Field.cpp
Normal file
@@ -0,0 +1,422 @@
|
||||
#include "osg/Field"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Field::Field()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
Field::Field(const Field& ic)
|
||||
{
|
||||
_copy(ic);
|
||||
}
|
||||
|
||||
|
||||
Field::~Field()
|
||||
{
|
||||
_free();
|
||||
}
|
||||
|
||||
|
||||
Field& Field::operator = (const Field& ic)
|
||||
{
|
||||
if (this==&ic) return *this;
|
||||
_free();
|
||||
_copy(ic);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Field::_free()
|
||||
{
|
||||
// free all data
|
||||
if (_fieldCache) delete [] _fieldCache;
|
||||
|
||||
_init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Field::_init()
|
||||
{
|
||||
|
||||
_fieldCacheCapacity = 256;
|
||||
_fieldCacheSize = 0;
|
||||
_fieldCache = NULL;
|
||||
|
||||
_fieldType = UNINTIALISED;
|
||||
|
||||
_withinQuotes = false;
|
||||
|
||||
_noNestedBrackets = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Field::_copy(const Field& ic)
|
||||
{
|
||||
|
||||
// copy string cache.
|
||||
if (ic._fieldCache)
|
||||
{
|
||||
_fieldCacheCapacity = ic._fieldCacheCapacity;
|
||||
_fieldCacheSize = ic._fieldCacheSize;
|
||||
_fieldCache = new char [_fieldCacheCapacity];
|
||||
strncpy(_fieldCache,ic._fieldCache,_fieldCacheCapacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fieldCacheCapacity = 0;
|
||||
_fieldCacheSize = 0;
|
||||
_fieldCache = NULL;
|
||||
}
|
||||
|
||||
_fieldType = ic._fieldType;
|
||||
|
||||
_withinQuotes = ic._withinQuotes;
|
||||
|
||||
_noNestedBrackets = ic._noNestedBrackets;
|
||||
}
|
||||
|
||||
|
||||
void Field::setWithinQuotes(bool withinQuotes)
|
||||
{
|
||||
_withinQuotes=withinQuotes;
|
||||
_fieldType = UNINTIALISED;
|
||||
}
|
||||
|
||||
|
||||
bool Field::getWithinQuotes()
|
||||
{
|
||||
return _withinQuotes;
|
||||
}
|
||||
|
||||
|
||||
void Field::setNoNestedBrackets(int no)
|
||||
{
|
||||
_noNestedBrackets=no;
|
||||
}
|
||||
|
||||
|
||||
int Field::getNoNestedBrackets()
|
||||
{
|
||||
return _noNestedBrackets;
|
||||
}
|
||||
|
||||
|
||||
const char* Field::getStr() const
|
||||
{
|
||||
if (_fieldCacheSize!=0) return _fieldCache;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
||||
char* Field::takeStr()
|
||||
{
|
||||
char* field = _fieldCache;
|
||||
|
||||
_fieldCache = NULL;
|
||||
_fieldCacheSize = 0;
|
||||
|
||||
_fieldType = UNINTIALISED;
|
||||
_withinQuotes = false;
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
void Field::reset()
|
||||
{
|
||||
_fieldCacheSize = 0;
|
||||
if (_fieldCache)
|
||||
{
|
||||
_fieldCache[_fieldCacheSize] = 0;
|
||||
}
|
||||
|
||||
_withinQuotes = false;
|
||||
_noNestedBrackets = 0;
|
||||
}
|
||||
|
||||
|
||||
void Field::addChar(char c)
|
||||
{
|
||||
if (_fieldCache==NULL)
|
||||
{
|
||||
if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE;
|
||||
_fieldCache = new char[_fieldCacheCapacity];
|
||||
_fieldCacheSize = 0;
|
||||
}
|
||||
else if (_fieldCacheSize>=_fieldCacheCapacity-1)
|
||||
{
|
||||
if (_fieldCacheCapacity<MIN_CACHE_SIZE) _fieldCacheCapacity=MIN_CACHE_SIZE;
|
||||
while (_fieldCacheSize>=_fieldCacheCapacity-1) _fieldCacheCapacity *= 2;
|
||||
char* tmp_str = _fieldCache;
|
||||
_fieldCache = new char[_fieldCacheCapacity];
|
||||
strncpy(_fieldCache,tmp_str,_fieldCacheSize);
|
||||
delete [] tmp_str;
|
||||
|
||||
}
|
||||
_fieldCache[_fieldCacheSize++] = c;
|
||||
_fieldCache[_fieldCacheSize] = 0;
|
||||
_fieldType = UNINTIALISED;
|
||||
}
|
||||
|
||||
|
||||
Field::FieldType Field::getFieldType() const
|
||||
{
|
||||
if (_fieldType==UNINTIALISED && _fieldCache)
|
||||
{
|
||||
_fieldType = calculateFieldType(_fieldCache,_withinQuotes);
|
||||
}
|
||||
return _fieldType;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isValid() const
|
||||
{
|
||||
if (_fieldCacheSize>0 && !_withinQuotes) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isOpenBracket() const
|
||||
{
|
||||
if (_fieldCacheSize==1) return _fieldCache[0]=='{';
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isCloseBracket() const
|
||||
{
|
||||
if (_fieldCacheSize==1) return _fieldCache[0]=='}';
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isWord() const
|
||||
{
|
||||
getFieldType();
|
||||
return (_fieldType==WORD);
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchWord(const char* str) const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==WORD && strcmp(_fieldCache,str)==0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchWord(const char* str,int noCharacters) const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==WORD && strncmp(_fieldCache,str,noCharacters)==0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isString() const
|
||||
{
|
||||
return getNoCharacters()!=0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchString(const char* str) const
|
||||
{
|
||||
return strcmp(_fieldCache,str)==0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchString(const char* str,int noCharacters) const
|
||||
{
|
||||
return strncmp(_fieldCache,str,noCharacters)==0;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isQuotedString() const
|
||||
{
|
||||
return _withinQuotes;
|
||||
}
|
||||
|
||||
|
||||
bool Field::isInt() const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==INTEGER;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchInt(int i) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==INTEGER)
|
||||
{
|
||||
return atoi(_fieldCache)==i;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::getInt(int& i) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==INTEGER)
|
||||
{
|
||||
i = atoi(_fieldCache);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::isFloat() const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==REAL || _fieldType==INTEGER;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchFloat(float f) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==REAL || _fieldType==INTEGER)
|
||||
{
|
||||
return (float)atof(_fieldCache)==f;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::getFloat(float& f) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==REAL || _fieldType==INTEGER)
|
||||
{
|
||||
f = (float)atof(_fieldCache);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::isDouble() const
|
||||
{
|
||||
getFieldType();
|
||||
return _fieldType==REAL || _fieldType==INTEGER;
|
||||
}
|
||||
|
||||
|
||||
bool Field::matchDouble(double d) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==REAL || _fieldType==INTEGER)
|
||||
{
|
||||
return atof(_fieldCache)==d;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Field::getDouble(double& d) const
|
||||
{
|
||||
getFieldType();
|
||||
if (_fieldType==REAL || _fieldType==INTEGER)
|
||||
{
|
||||
d = atof(_fieldCache);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Field::FieldType Field::calculateFieldType(const char* str,bool withinQuotes)
|
||||
{
|
||||
if (str==NULL) return BLANK;
|
||||
if (*str==0) return BLANK;
|
||||
|
||||
if (withinQuotes) return STRING;
|
||||
|
||||
bool hadPlusMinus = false;
|
||||
bool hadDecimalPlace = false;
|
||||
bool hadExponent = false;
|
||||
bool couldBeInt = true;
|
||||
bool couldBeFloat = true;
|
||||
int noZeroToNine = 0;
|
||||
|
||||
const char* ptr = str;
|
||||
while (*ptr!=0 && couldBeFloat)
|
||||
{
|
||||
if (*ptr=='+' || *ptr=='-')
|
||||
{
|
||||
if (hadPlusMinus)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
} else hadPlusMinus = true;
|
||||
}
|
||||
else if (*ptr>='0' && *ptr<='9')
|
||||
{
|
||||
noZeroToNine++;
|
||||
}
|
||||
else if (*ptr=='.')
|
||||
{
|
||||
if (hadDecimalPlace)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hadDecimalPlace = true;
|
||||
couldBeInt = false;
|
||||
}
|
||||
}
|
||||
else if (*ptr=='e' || *ptr=='E')
|
||||
{
|
||||
if (hadExponent || noZeroToNine==0)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hadExponent = true;
|
||||
couldBeInt = false;
|
||||
hadDecimalPlace = false;
|
||||
hadPlusMinus = false;
|
||||
noZeroToNine=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
++ptr;
|
||||
}
|
||||
|
||||
if (couldBeInt && noZeroToNine>0) return INTEGER;
|
||||
if (couldBeFloat && noZeroToNine>0) return REAL;
|
||||
if (str[0]=='{') return OPEN_BRACKET;
|
||||
if (str[0]=='}') return CLOSE_BRACKET;
|
||||
return WORD;
|
||||
}
|
||||
269
src/osg/FieldReader.cpp
Normal file
269
src/osg/FieldReader.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
#include "osg/FieldReader"
|
||||
#include "osg/Field"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
FieldReader::FieldReader()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
FieldReader::FieldReader(const FieldReader& ic)
|
||||
{
|
||||
_copy(ic);
|
||||
}
|
||||
|
||||
|
||||
FieldReader::~FieldReader()
|
||||
{
|
||||
_free();
|
||||
}
|
||||
|
||||
|
||||
FieldReader& FieldReader::operator = (const FieldReader& ic)
|
||||
{
|
||||
if (this==&ic) return *this;
|
||||
_free();
|
||||
_copy(ic);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::_free()
|
||||
{
|
||||
// free all data
|
||||
|
||||
_init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::_init()
|
||||
{
|
||||
_fin = NULL;
|
||||
_eof = true;
|
||||
|
||||
_noNestedBrackets = 0;
|
||||
|
||||
int i;
|
||||
for(i=0;i<256;++i) _delimatorEatLookUp[i]=false;
|
||||
_delimatorEatLookUp[' '] = true;
|
||||
_delimatorEatLookUp['\t'] = true;
|
||||
_delimatorEatLookUp['\n'] = true;
|
||||
_delimatorEatLookUp['\r'] = true;
|
||||
|
||||
for(i=0;i<256;++i) _delimatorKeepLookUp[i]=false;
|
||||
_delimatorKeepLookUp['{'] = true;
|
||||
_delimatorKeepLookUp['}'] = true;
|
||||
_delimatorKeepLookUp['"'] = true;
|
||||
_delimatorKeepLookUp['\''] = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::_copy(const FieldReader& ic)
|
||||
{
|
||||
|
||||
_fin = ic._fin;
|
||||
_eof = ic._eof;
|
||||
|
||||
_noNestedBrackets = ic._noNestedBrackets;
|
||||
|
||||
int i;
|
||||
for(i=0;i<256;++i) _delimatorEatLookUp[i]=ic._delimatorEatLookUp[i];
|
||||
for(i=0;i<256;++i) _delimatorKeepLookUp[i]=ic._delimatorKeepLookUp[i];
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::attach(istream* input)
|
||||
{
|
||||
_fin = input;
|
||||
|
||||
if (_fin)
|
||||
{
|
||||
_eof = _fin->eof()!=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_eof = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::detach()
|
||||
{
|
||||
_fin = NULL;
|
||||
_eof = true;
|
||||
}
|
||||
|
||||
|
||||
bool FieldReader::eof() const
|
||||
{
|
||||
return _eof;
|
||||
}
|
||||
|
||||
|
||||
bool FieldReader::findStartOfNextField()
|
||||
{
|
||||
int ch = 0;
|
||||
while (true)
|
||||
{
|
||||
ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
return false;
|
||||
}
|
||||
else if (_delimatorEatLookUp[ch])
|
||||
{
|
||||
_fin->ignore(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FieldReader::readField(Field& fieldPtr)
|
||||
{
|
||||
return _readField(&fieldPtr);
|
||||
}
|
||||
|
||||
|
||||
void FieldReader::ignoreField()
|
||||
{
|
||||
_readField(NULL);
|
||||
}
|
||||
|
||||
|
||||
bool FieldReader::_readField(Field* fieldPtr)
|
||||
{
|
||||
if (fieldPtr) fieldPtr->reset();
|
||||
|
||||
if (!eof() && findStartOfNextField())
|
||||
{
|
||||
|
||||
int ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
else if (ch=='"')
|
||||
{
|
||||
if (fieldPtr)
|
||||
{
|
||||
fieldPtr->setWithinQuotes(true);
|
||||
fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
}
|
||||
_fin->ignore(1);
|
||||
char c;
|
||||
while (true)
|
||||
{
|
||||
ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
c = ch;
|
||||
if (ch=='"')
|
||||
{
|
||||
_fin->ignore(1);
|
||||
//return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
return fieldPtr!=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin->get(c);
|
||||
if (fieldPtr) fieldPtr->addChar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ch=='\'')
|
||||
{
|
||||
if (fieldPtr)
|
||||
{
|
||||
fieldPtr->setWithinQuotes(true);
|
||||
fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
}
|
||||
_fin->ignore(1);
|
||||
char c;
|
||||
while (true)
|
||||
{
|
||||
ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
c = ch;
|
||||
if (ch=='\'')
|
||||
{
|
||||
_fin->ignore(1);
|
||||
//return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
return fieldPtr!=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin->get(c);
|
||||
if (fieldPtr) fieldPtr->addChar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_delimatorKeepLookUp[ch])
|
||||
{
|
||||
char c;
|
||||
_fin->get(c);
|
||||
if (fieldPtr) fieldPtr->addChar(c);
|
||||
if (c=='{') ++_noNestedBrackets;
|
||||
else if (c=='}') --_noNestedBrackets;
|
||||
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fieldPtr) fieldPtr->setNoNestedBrackets(getNoNestedBrackets());
|
||||
char c;
|
||||
while (true)
|
||||
{
|
||||
ch = _fin->peek();
|
||||
if (ch==EOF)
|
||||
{
|
||||
_eof = true;
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
c = ch;
|
||||
if (_delimatorEatLookUp[c])
|
||||
{
|
||||
_fin->ignore(1);
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
if (_delimatorKeepLookUp[c])
|
||||
{
|
||||
return fieldPtr && fieldPtr->getNoCharacters()!=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fin->get(c);
|
||||
if (fieldPtr) fieldPtr->addChar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FieldReader::getNoNestedBrackets() const
|
||||
{
|
||||
return _noNestedBrackets;
|
||||
}
|
||||
361
src/osg/FieldReaderIterator.cpp
Normal file
361
src/osg/FieldReaderIterator.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
#include "osg/FieldReaderIterator"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
FieldReaderIterator::FieldReaderIterator()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator::FieldReaderIterator(const FieldReaderIterator& ic)
|
||||
{
|
||||
_copy(ic);
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator::~FieldReaderIterator()
|
||||
{
|
||||
_free();
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator& FieldReaderIterator::operator = (const FieldReaderIterator& ic)
|
||||
{
|
||||
if (this==&ic) return *this;
|
||||
_free();
|
||||
_copy(ic);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::_free()
|
||||
{
|
||||
// free all data
|
||||
if (_previousField)
|
||||
{
|
||||
delete _previousField;
|
||||
}
|
||||
if (_fieldQueue)
|
||||
{
|
||||
for(int i=0;i<_fieldQueueCapacity;++i)
|
||||
{
|
||||
if (_fieldQueue[i]) delete _fieldQueue[i];
|
||||
_fieldQueue[i] = NULL;
|
||||
}
|
||||
delete [] _fieldQueue;
|
||||
}
|
||||
_init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::_init()
|
||||
{
|
||||
_previousField = NULL;
|
||||
_fieldQueue = NULL;
|
||||
_fieldQueueSize = 0;
|
||||
_fieldQueueCapacity = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::_copy(const FieldReaderIterator& ic)
|
||||
{
|
||||
_reader = ic._reader;
|
||||
|
||||
if (ic._previousField)
|
||||
{
|
||||
_previousField = new Field(*ic._previousField);
|
||||
}
|
||||
|
||||
if (ic._fieldQueue && ic._fieldQueueCapacity>0)
|
||||
{
|
||||
_fieldQueue = new Field* [ic._fieldQueueCapacity];
|
||||
for(int i=0;i<ic._fieldQueueCapacity;++i)
|
||||
{
|
||||
if (ic._fieldQueue[i])
|
||||
{
|
||||
_fieldQueue[i] = new Field(*ic._fieldQueue[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
_fieldQueue[i] = NULL;
|
||||
}
|
||||
}
|
||||
_fieldQueueSize = ic._fieldQueueSize;
|
||||
_fieldQueueCapacity = ic._fieldQueueCapacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fieldQueue = NULL;
|
||||
_fieldQueueSize = 0;
|
||||
_fieldQueueCapacity = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::attach(istream* input)
|
||||
{
|
||||
_reader.attach(input);
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::detach()
|
||||
{
|
||||
_reader.detach();
|
||||
}
|
||||
|
||||
|
||||
bool FieldReaderIterator::eof() const
|
||||
{
|
||||
return _fieldQueueSize==0 && _reader.eof();
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::insert(int pos,Field* field)
|
||||
{
|
||||
if (field==NULL) return;
|
||||
|
||||
if (pos<0) pos=0;
|
||||
if (pos>_fieldQueueSize) pos=_fieldQueueSize;
|
||||
|
||||
int i;
|
||||
if (_fieldQueueSize>=_fieldQueueCapacity) // need to reallocate the stack
|
||||
{
|
||||
int newCapacity = _fieldQueueCapacity*2;
|
||||
if (newCapacity<MINIMUM_FIELD_READER_QUEUE_SIZE) newCapacity = MINIMUM_FIELD_READER_QUEUE_SIZE;
|
||||
while(_fieldQueueSize>=newCapacity) newCapacity*=2;
|
||||
Field** newFieldStack = new Field* [newCapacity];
|
||||
for(i=0;i<_fieldQueueCapacity;++i)
|
||||
{
|
||||
newFieldStack[i] = _fieldQueue[i];
|
||||
}
|
||||
for(;i<newCapacity;++i)
|
||||
{
|
||||
newFieldStack[i] = NULL;
|
||||
}
|
||||
_fieldQueue = newFieldStack;
|
||||
_fieldQueueCapacity = newCapacity;
|
||||
}
|
||||
|
||||
for(i=_fieldQueueSize-1;i>=pos;++i)
|
||||
{
|
||||
_fieldQueue[i+1]=_fieldQueue[i];
|
||||
}
|
||||
_fieldQueue[pos] = field;
|
||||
++_fieldQueueSize;
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::insert(int pos,const char* str)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
Field* field = new Field;
|
||||
while(*str!=0)
|
||||
{
|
||||
field->addChar(*str);
|
||||
++str;
|
||||
}
|
||||
insert(pos,field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Field& FieldReaderIterator::operator [] (int pos)
|
||||
{
|
||||
return field(pos);
|
||||
}
|
||||
|
||||
|
||||
Field& FieldReaderIterator::field (int pos)
|
||||
{
|
||||
if (pos<0)
|
||||
{
|
||||
_blank.setNoNestedBrackets(_reader.getNoNestedBrackets());
|
||||
return _blank;
|
||||
} // can directly access field
|
||||
else if (pos<_fieldQueueSize)
|
||||
{
|
||||
return *_fieldQueue[pos];
|
||||
} // need to read the new fields.
|
||||
else
|
||||
{
|
||||
if (pos>=_fieldQueueCapacity) // need to reallocate the stack
|
||||
{
|
||||
int newCapacity = _fieldQueueCapacity*2;
|
||||
if (newCapacity<MINIMUM_FIELD_READER_QUEUE_SIZE) newCapacity = MINIMUM_FIELD_READER_QUEUE_SIZE;
|
||||
while(_fieldQueueSize>=newCapacity) newCapacity*=2;
|
||||
Field** newFieldStack = new Field* [newCapacity];
|
||||
int i;
|
||||
for(i=0;i<_fieldQueueCapacity;++i)
|
||||
{
|
||||
newFieldStack[i] = _fieldQueue[i];
|
||||
}
|
||||
for(;i<newCapacity;++i)
|
||||
{
|
||||
newFieldStack[i] = NULL;
|
||||
}
|
||||
_fieldQueue = newFieldStack;
|
||||
_fieldQueueCapacity = newCapacity;
|
||||
}
|
||||
while(!_reader.eof() && pos>=_fieldQueueSize)
|
||||
{
|
||||
if (_fieldQueue[_fieldQueueSize]==NULL) _fieldQueue[_fieldQueueSize] = new Field;
|
||||
if (_reader.readField(*_fieldQueue[_fieldQueueSize]))
|
||||
{
|
||||
++_fieldQueueSize;
|
||||
}
|
||||
}
|
||||
if (pos<_fieldQueueSize)
|
||||
{
|
||||
return *_fieldQueue[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
_blank.setNoNestedBrackets(_reader.getNoNestedBrackets());
|
||||
return _blank;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator& FieldReaderIterator::operator ++ ()
|
||||
{
|
||||
return (*this)+=1;
|
||||
}
|
||||
|
||||
|
||||
FieldReaderIterator& FieldReaderIterator::operator += (int no)
|
||||
{
|
||||
if (no>_fieldQueueSize)
|
||||
{
|
||||
while (!_reader.eof() && no>_fieldQueueSize)
|
||||
{
|
||||
_reader.ignoreField();
|
||||
--no;
|
||||
}
|
||||
_fieldQueueSize=0;
|
||||
}
|
||||
else if (no>0)
|
||||
{
|
||||
Field** tmpFields = new Field* [no];
|
||||
int i;
|
||||
for(i=0;i<no;++i)
|
||||
{
|
||||
tmpFields[i] = _fieldQueue[i];
|
||||
}
|
||||
for(i=no;i<_fieldQueueSize;++i)
|
||||
{
|
||||
_fieldQueue[i-no] = _fieldQueue[i];
|
||||
}
|
||||
_fieldQueueSize -= no;
|
||||
for(i=0;i<no;++i)
|
||||
{
|
||||
_fieldQueue[_fieldQueueSize+i] = tmpFields[i];
|
||||
}
|
||||
delete [] tmpFields;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// increments the itetor of the next simple field or
|
||||
// whole block if the current field[0] is an open bracket
|
||||
void FieldReaderIterator::advanceOverCurrentFieldOrBlock()
|
||||
{
|
||||
if (field(0).isOpenBracket()) advanceToEndOfCurrentBlock();
|
||||
else ++(*this);
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::advanceToEndOfCurrentBlock()
|
||||
{
|
||||
int entry = field(0).getNoNestedBrackets();
|
||||
while(!eof() && field(0).getNoNestedBrackets()>=entry)
|
||||
{
|
||||
++(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FieldReaderIterator::advanceToEndOfBlock(int noNestedBrackets)
|
||||
{
|
||||
while(!eof() && field(0).getNoNestedBrackets()>=noNestedBrackets)
|
||||
{
|
||||
++(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FieldReaderIterator::matchSequence(const char* str)
|
||||
{
|
||||
if (str==NULL) return false;
|
||||
if (*str==0) return false;
|
||||
int fieldCount = 0;
|
||||
const char* end = str;
|
||||
while((*end)!=0 && (*end)==' ') ++end;
|
||||
const char* start = end;
|
||||
while((*start)!=0)
|
||||
{
|
||||
if (*end!=' ' && *end!=0)
|
||||
{
|
||||
++end;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (start!=end)
|
||||
{
|
||||
if (end-start>1 && *start=='%')
|
||||
{
|
||||
const char type = *(start+1);
|
||||
switch(type)
|
||||
{
|
||||
case('i') : // expecting an integer
|
||||
{
|
||||
if (!field(fieldCount).isInt()) return false;
|
||||
break;
|
||||
}
|
||||
case('f') : // expecting an floating point number
|
||||
{
|
||||
if (!field(fieldCount).isFloat()) return false;
|
||||
break;
|
||||
}
|
||||
case('s') : // expecting an quoted string
|
||||
{
|
||||
if (!field(fieldCount).isQuotedString()) return false;
|
||||
break;
|
||||
}
|
||||
default : // expecting an word
|
||||
{
|
||||
if (!field(fieldCount).isWord()) return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*start=='{')
|
||||
{
|
||||
if (!field(fieldCount).isOpenBracket()) return false;
|
||||
}
|
||||
else if (*start=='}')
|
||||
{
|
||||
if (!field(fieldCount).isCloseBracket()) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!field(fieldCount).matchWord(start,end-start)) return false;
|
||||
}
|
||||
}
|
||||
fieldCount++;
|
||||
}
|
||||
while((*end)==' ') ++end;
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
50
src/osg/FileNameUtils.cpp
Normal file
50
src/osg/FileNameUtils.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "osg/FileNameUtils"
|
||||
|
||||
std::string osg::getFilePath(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type slash = fileName.find_last_of('/');
|
||||
if (slash==std::string::npos) return std::string("");
|
||||
return std::string(fileName.begin(),fileName.begin()+slash+1);
|
||||
}
|
||||
|
||||
std::string osg::getSimpleFileName(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type slash = fileName.find_last_of('/');
|
||||
if (slash==std::string::npos) return fileName;
|
||||
return std::string(fileName.begin()+slash+1,fileName.end());
|
||||
}
|
||||
|
||||
std::string osg::getFileExtension(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type dot = fileName.find_last_of('.');
|
||||
if (dot==std::string::npos) return std::string("");
|
||||
return std::string(fileName.begin()+dot+1,fileName.end());
|
||||
}
|
||||
|
||||
std::string osg::getLowerCaseFileExtension(const std::string& filename)
|
||||
{
|
||||
std::string ext = osg::getFileExtension(filename);
|
||||
for(std::string::iterator itr=ext.begin();
|
||||
itr!=ext.end();
|
||||
++itr)
|
||||
{
|
||||
*itr = (char)tolower(*itr);
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
std::string osg::getStrippedName(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type slash = fileName.find_last_of('/');
|
||||
std::string::size_type dot = fileName.find_last_of('.');
|
||||
if (slash==std::string::npos) {
|
||||
if (dot==std::string::npos) return fileName;
|
||||
else return std::string(fileName.begin(),fileName.begin()+dot);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dot==std::string::npos) return std::string(fileName.begin()+slash+1,fileName.end());
|
||||
else return std::string(fileName.begin()+slash+1,fileName.begin()+dot);
|
||||
}
|
||||
}
|
||||
|
||||
47
src/osg/Fog.cpp
Normal file
47
src/osg/Fog.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/Fog"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Fog::Fog( void )
|
||||
{
|
||||
_mode = EXP;
|
||||
_density = 1.0f;
|
||||
_start = 0.0f;
|
||||
_end = 1.0f;
|
||||
_color.set( 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
Fog::~Fog( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Fog* Fog::instance()
|
||||
{
|
||||
static ref_ptr<Fog> s_fog(new Fog);
|
||||
return s_fog.get();
|
||||
}
|
||||
|
||||
|
||||
void Fog::enable( void )
|
||||
{
|
||||
glEnable( GL_FOG );
|
||||
}
|
||||
|
||||
|
||||
void Fog::disable( void )
|
||||
{
|
||||
glDisable( GL_FOG );
|
||||
}
|
||||
|
||||
|
||||
void Fog::apply( void )
|
||||
{
|
||||
glFogi( GL_FOG_MODE, _mode );
|
||||
glFogf( GL_FOG_DENSITY, _density );
|
||||
glFogf( GL_FOG_START, _start );
|
||||
glFogf( GL_FOG_END, _end );
|
||||
glFogfv( GL_FOG_COLOR, (GLfloat*)_color.ptr() );
|
||||
}
|
||||
1778
src/osg/GeoSet.cpp
Normal file
1778
src/osg/GeoSet.cpp
Normal file
File diff suppressed because it is too large
Load Diff
427
src/osg/GeoSet_ogl.cpp
Normal file
427
src/osg/GeoSet_ogl.cpp
Normal file
@@ -0,0 +1,427 @@
|
||||
#include <stdio.h>
|
||||
#include "osg/GL"
|
||||
#include "osg/GeoSet"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#define DO_SHADING 1
|
||||
|
||||
#define I_ON (1<<4)
|
||||
#define C_ON (1<<3)
|
||||
#define N_ON (1<<2)
|
||||
#define T_ON (1<<1)
|
||||
#define V_ON (1<<0)
|
||||
|
||||
void GeoSet::set_fast_path( void )
|
||||
{
|
||||
if( _iaformat != IA_OFF )
|
||||
{
|
||||
_fast_path = I_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( _normal_binding != BIND_PERPRIM) &&
|
||||
( _nindex == 0L ) &&
|
||||
( _color_binding != BIND_PERPRIM) &&
|
||||
( _colindex == 0L ) &&
|
||||
( _primtype != FLAT_LINE_STRIP ) &&
|
||||
( _primtype != FLAT_TRIANGLE_STRIP ) &&
|
||||
( _primtype != FLAT_TRIANGLE_FAN )
|
||||
)
|
||||
_fast_path = V_ON;
|
||||
else
|
||||
{
|
||||
_fast_path = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because NORMALS are bound PER_PRIM\n";
|
||||
|
||||
if( _nindex != 0L )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because NORMAL indeces are specified\n";
|
||||
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because COLORS are bound PER_PRIM\n";
|
||||
|
||||
if( _cindex != 0L )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because COLOR indeces are specified\n";
|
||||
|
||||
if( _primtype == FLAT_LINE_STRIP )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_LINE_STRIP\n";
|
||||
|
||||
if ( _primtype == FLAT_TRIANGLE_STRIP )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_TRIANGLE_STRIP\n";
|
||||
|
||||
if ( _primtype == FLAT_TRIANGLE_FAN )
|
||||
notify( DEBUG ) << "Geoset - Failed fast path because primitive is FLAT_TRIANGLE_FAN\n";
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
if( _fast_path )
|
||||
{
|
||||
if( _color_binding == BIND_PERVERTEX )
|
||||
_fast_path |= C_ON;
|
||||
if( _normal_binding == BIND_PERVERTEX )
|
||||
_fast_path |= N_ON;
|
||||
if( _texture_binding == BIND_PERVERTEX )
|
||||
_fast_path |= T_ON;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
notify(INFO) << "GeoSet - fast path = " << _fast_path << "\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
void GeoSet::draw_fast_path( void )
|
||||
{
|
||||
ushort *ocindex = _cindex;
|
||||
|
||||
switch( _fast_path )
|
||||
{
|
||||
case (I_ON) :
|
||||
_cindex = _iaindex;
|
||||
glInterleavedArrays( (GLenum)_ogliaformat, 0, _iarray );
|
||||
break;
|
||||
|
||||
case (V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (T_ON|V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (N_ON|V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (N_ON|T_ON|V_ON) :
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (C_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
|
||||
case (C_ON|T_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (C_ON|N_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
|
||||
case (C_ON|N_ON|T_ON|V_ON) :
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, (GLfloat *)_tcoords );
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
break;
|
||||
}
|
||||
|
||||
if( _color_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _colindex != 0L )
|
||||
glColor4fv( (GLfloat * )&_colors[_colindex[0]] );
|
||||
else
|
||||
glColor4fv( (GLfloat * )&_colors[0] );
|
||||
}
|
||||
|
||||
if( _normal_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _nindex != 0L )
|
||||
glNormal3fv( (GLfloat * )&_normals[_nindex[0]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat * )&_normals[0] );
|
||||
}
|
||||
|
||||
if( _needprimlen ) // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
{
|
||||
int index = 0;
|
||||
if( _primLengths == (int *)0 )
|
||||
{
|
||||
notify(WARN) << "GeoSet->draw() : " "Primitive lengths required\n";
|
||||
return;
|
||||
}
|
||||
|
||||
for( int i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _primLengths[i], GL_UNSIGNED_SHORT, &_cindex[index] );
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, index, _primLengths[i] );
|
||||
index += _primLengths[i];
|
||||
}
|
||||
}
|
||||
else // POINTS, LINES, TRIANGLES, QUADS
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _numindices, GL_UNSIGNED_SHORT, _cindex );
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, 0, _numcoords );
|
||||
}
|
||||
|
||||
_cindex = ocindex;
|
||||
}
|
||||
|
||||
void GeoSet::draw_alternate_path( void )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_cindex == 0L) && (_flat_shaded_skip == 0) )
|
||||
{
|
||||
glEnableClientState( GL_COLOR_ARRAY );
|
||||
glColorPointer( 4, GL_FLOAT, 0, (GLfloat *)_colors );
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisableClientState( GL_COLOR_ARRAY );
|
||||
if( _color_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _colindex )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[0]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[0] );
|
||||
}
|
||||
}
|
||||
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex == 0L) && (_flat_shaded_skip == 0) )
|
||||
{
|
||||
glEnableClientState( GL_NORMAL_ARRAY );
|
||||
glNormalPointer( GL_FLOAT, 0, (GLfloat *)_normals );
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisableClientState( GL_NORMAL_ARRAY );
|
||||
if( _normal_binding == BIND_OVERALL )
|
||||
{
|
||||
if( _nindex )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[0]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[0] );
|
||||
}
|
||||
}
|
||||
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex == 0L) )
|
||||
{
|
||||
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, _tcoords );
|
||||
}
|
||||
else
|
||||
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
glVertexPointer( 3, GL_FLOAT, 0, (GLfloat *)_coords );
|
||||
|
||||
if( _needprimlen ) // LINE_STRIP, LINE_LOOP, TRIANGLE_STRIP,
|
||||
// TRIANGLE_FAN, QUAD_STRIP, POLYGONS
|
||||
// FLAT_LINE_STRIP, FLAT_TRIANGLE_STRIP, FLAT_TRIANGLE_FAN
|
||||
{
|
||||
int i, j;
|
||||
int index = 0;
|
||||
int ai = 0;
|
||||
int ci = 0;
|
||||
int ni = 0;
|
||||
int ti = 0;
|
||||
|
||||
if( _primLengths == (int *)0 )
|
||||
{
|
||||
notify(WARN) << "GeoSet->draw() : " "Primitive lengths required\n";
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _colindex )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[ci++] );
|
||||
}
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _nindex )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ni++]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[ni++] );
|
||||
}
|
||||
|
||||
if( _flat_shaded_skip )
|
||||
{
|
||||
#ifdef DO_SHADING
|
||||
glShadeModel( GL_FLAT );
|
||||
#endif
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( j = 0; j < _primLengths[i]; j++ )
|
||||
{
|
||||
if( j >= _flat_shaded_skip )
|
||||
{
|
||||
if( _color_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if( (_colindex != 0L) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[ci++] );
|
||||
}
|
||||
|
||||
if( _normal_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if(_nindex != 0L)
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ni++]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[ni++] );
|
||||
}
|
||||
}
|
||||
|
||||
if( _texture_binding == BIND_PERVERTEX )
|
||||
{
|
||||
if( _tindex != 0L )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[ti++]] );
|
||||
else
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[ti++] );
|
||||
}
|
||||
|
||||
if( _cindex )
|
||||
glArrayElement( _cindex[ai++] );
|
||||
else
|
||||
glArrayElement( ai++ );
|
||||
}
|
||||
glEnd();
|
||||
|
||||
#ifdef DO_SHADING
|
||||
glShadeModel( GL_SMOOTH );
|
||||
#endif
|
||||
}
|
||||
|
||||
else
|
||||
if( ((_color_binding == BIND_PERVERTEX ) && (_colindex != 0L) ) ||
|
||||
((_normal_binding == BIND_PERVERTEX ) && (_nindex != 0L) ) ||
|
||||
((_texture_binding == BIND_PERVERTEX ) && (_tindex != 0L) ) )
|
||||
{
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( j = 0; j < _primLengths[i]; j++ )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_colindex != 0L) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[ci++]] );
|
||||
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex != 0L) )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[ci++]] );
|
||||
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex != 0L) )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[ti++]] );
|
||||
|
||||
if( _cindex )
|
||||
glArrayElement( _cindex[ai++] );
|
||||
else
|
||||
glArrayElement( ai++ );
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _primLengths[i], GL_UNSIGNED_SHORT, &_cindex[index] );
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, index, _primLengths[i] );
|
||||
}
|
||||
index += _primLengths[i];
|
||||
}
|
||||
}
|
||||
else // POINTS, LINES, TRIANGLES, QUADS
|
||||
{
|
||||
int i, j;
|
||||
if( _normal_binding == BIND_PERPRIM || _color_binding == BIND_PERPRIM ||
|
||||
((_color_binding == BIND_PERVERTEX ) && (_colindex != 0L) ) ||
|
||||
((_normal_binding == BIND_PERVERTEX ) && (_nindex != 0L) ) ||
|
||||
((_texture_binding == BIND_PERVERTEX ) && (_tindex != 0L) ) )
|
||||
{
|
||||
glBegin( (GLenum)_oglprimtype );
|
||||
for( i = 0; i < _numprims; i++ )
|
||||
{
|
||||
if( _color_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _colindex )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[i]] );
|
||||
else
|
||||
glColor4fv( (GLfloat *)&_colors[i] );
|
||||
}
|
||||
if( _normal_binding == BIND_PERPRIM )
|
||||
{
|
||||
if( _nindex )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[i]] );
|
||||
else
|
||||
glNormal3fv( (GLfloat *)&_normals[i] );
|
||||
}
|
||||
|
||||
for( j = 0; j < _primlength; j++ )
|
||||
{
|
||||
if( (_color_binding == BIND_PERVERTEX) && (_colindex != 0L ) )
|
||||
glColor4fv( (GLfloat *)&_colors[_colindex[i*_primlength+j]] );
|
||||
|
||||
if( (_normal_binding == BIND_PERVERTEX) && (_nindex != 0L ) )
|
||||
glNormal3fv( (GLfloat *)&_normals[_nindex[i*_primlength+j]] );
|
||||
|
||||
if( (_texture_binding == BIND_PERVERTEX) && (_tindex != 0L ) )
|
||||
glTexCoord2fv( (GLfloat *)&_tcoords[_tindex[i*_primlength+j]] );
|
||||
|
||||
glArrayElement( i*_primlength+j );
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( _cindex != (ushort *)0L )
|
||||
glDrawElements( (GLenum)_oglprimtype, _numindices, GL_UNSIGNED_SHORT, _cindex );
|
||||
else
|
||||
glDrawArrays( (GLenum)_oglprimtype, 0, _numcoords );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
850
src/osg/GeoState.cpp
Normal file
850
src/osg/GeoState.cpp
Normal file
@@ -0,0 +1,850 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "osg/GeoState"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
GeoState::GeoState()
|
||||
{
|
||||
|
||||
_transparencing = INHERIT;
|
||||
_face_culling = INHERIT;
|
||||
_lighting = INHERIT;
|
||||
_texturing = INHERIT;
|
||||
_fogging = INHERIT;
|
||||
_texgening = INHERIT;
|
||||
_antialiasing = INHERIT;
|
||||
_colortable = INHERIT;
|
||||
_pointSmoothing = INHERIT;
|
||||
_polygonOffsetting = INHERIT;
|
||||
_alphaTesting = INHERIT;
|
||||
|
||||
_transparency = 0L;
|
||||
_cullFace = 0L;
|
||||
_texture = 0L;
|
||||
_fog = 0L;
|
||||
_texgen = 0L;
|
||||
_material = 0L;
|
||||
_texenv = 0L;
|
||||
_texmat = 0L;
|
||||
_point = 0L;
|
||||
_polygonOffset = 0L;
|
||||
_alphaFunc = 0L;
|
||||
}
|
||||
|
||||
|
||||
GeoState::~GeoState()
|
||||
{
|
||||
// note, all attached state attributes will be automatically
|
||||
// unreferenced by ref_ptr<> and therefore there is now need to
|
||||
// delete the memory manually.
|
||||
}
|
||||
|
||||
|
||||
GeoState* GeoState::instance()
|
||||
{
|
||||
static ref_ptr<GeoState> s_geostate(new GeoState);
|
||||
return s_geostate.get();
|
||||
}
|
||||
|
||||
void GeoState::setGlobalDefaults()
|
||||
{
|
||||
_transparencing = OFF;
|
||||
_face_culling = ON;
|
||||
_lighting = OFF;
|
||||
_texturing = OFF;
|
||||
_fogging = OFF;
|
||||
_texgening = OFF;
|
||||
_antialiasing = OFF;
|
||||
_colortable = OFF;
|
||||
_pointSmoothing = OFF;
|
||||
_polygonOffsetting = OFF;
|
||||
_alphaTesting = OFF;
|
||||
|
||||
_transparency = new Transparency;
|
||||
_cullFace = new CullFace;
|
||||
_texture = 0L;
|
||||
_fog = 0L;
|
||||
_texgen = 0L;
|
||||
_material = new Material;
|
||||
_material->setColorMode(Material::AMBIENT_AND_DIFFUSE);
|
||||
_texenv = 0L;
|
||||
_texmat = 0L;
|
||||
_point = 0L;
|
||||
_polygonOffset = 0L;
|
||||
_alphaFunc = new AlphaFunc;
|
||||
|
||||
}
|
||||
|
||||
void GeoState::setAllToInherit()
|
||||
{
|
||||
_transparencing = INHERIT;
|
||||
_face_culling = INHERIT;
|
||||
_lighting = INHERIT;
|
||||
_texturing = INHERIT;
|
||||
_fogging = INHERIT;
|
||||
_texgening = INHERIT;
|
||||
_antialiasing = INHERIT;
|
||||
_colortable = INHERIT;
|
||||
_pointSmoothing = INHERIT;
|
||||
_polygonOffsetting = INHERIT;
|
||||
_alphaTesting = INHERIT;
|
||||
|
||||
_transparency = 0L;
|
||||
_cullFace = 0L;
|
||||
_texture = 0L;
|
||||
_fog = 0L;
|
||||
_texgen = 0L;
|
||||
_material = 0L;
|
||||
_texenv = 0L;
|
||||
_texmat = 0L;
|
||||
_point = 0L;
|
||||
_polygonOffset = 0L;
|
||||
_alphaFunc = 0L;
|
||||
}
|
||||
|
||||
bool GeoState::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
AttributeMode mode;
|
||||
if (fr[0].matchWord("transparency") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_transparencing = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (Transparency* transTmp = static_cast<Transparency*>(Transparency::instance()->readClone(fr)))
|
||||
{
|
||||
_transparency = transTmp;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("antialiasing") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_antialiasing = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("face_culling") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_face_culling = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (CullFace* cullTmp = static_cast<CullFace*>(CullFace::instance()->readClone(fr)))
|
||||
{
|
||||
_cullFace = cullTmp;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("lighting") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_lighting = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("texturing") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_texturing = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (Texture* textTmp = static_cast<Texture*>(Texture::instance()->readClone(fr)))
|
||||
{
|
||||
_texture = textTmp;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("fogging") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_fogging = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (Fog* fogTmp = static_cast<Fog*>(Fog::instance()->readClone(fr)))
|
||||
{
|
||||
_fog = fogTmp;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("colortable") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_colortable = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("texgening") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_texgening = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (TexGen* tmpTexgen = static_cast<TexGen*>(TexGen::instance()->readClone(fr)))
|
||||
{
|
||||
_texgen = tmpTexgen;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("point_smoothing") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_pointSmoothing = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (Point* tmpPoint = static_cast<Point*>(Point::instance()->readClone(fr)))
|
||||
{
|
||||
_point = tmpPoint;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("polygon_offset") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_polygonOffsetting = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (PolygonOffset* tmpPolygonOffset = static_cast<PolygonOffset*>(PolygonOffset::instance()->readClone(fr)))
|
||||
{
|
||||
_polygonOffset = tmpPolygonOffset;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
|
||||
if (fr[0].matchWord("alpha_test") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_alphaTesting = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
if (AlphaFunc* tmpAlphaFunc = static_cast<AlphaFunc*>(AlphaFunc::instance()->readClone(fr)))
|
||||
{
|
||||
_alphaFunc = tmpAlphaFunc;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
|
||||
if (Material* tmpMaterial = static_cast<Material*>(Material::instance()->readClone(fr)))
|
||||
{
|
||||
_material = tmpMaterial;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decided that texmatting does not make sense. If a Texture matrix
|
||||
* is present, just apply it. No need for a mode. Don.
|
||||
*
|
||||
if (fr[0].matchWord("texmating") && matchModeStr(fr[1].getStr(),mode)) {
|
||||
_texmating = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
*/
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool GeoState::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "transparency " << getModeStr(_transparencing) << endl;
|
||||
if (_transparency.valid()) _transparency->write(fw);
|
||||
|
||||
fw.indent() << "antialiasing " << getModeStr(_antialiasing) << endl;
|
||||
|
||||
fw.indent() << "face_culling " << getModeStr(_face_culling) << endl;
|
||||
if (_cullFace.valid()) _cullFace->write(fw);
|
||||
|
||||
fw.indent() << "lighting " << getModeStr(_lighting) << endl;
|
||||
|
||||
fw.indent() << "texturing " << getModeStr(_texturing) << endl;
|
||||
if (_texture.valid()) _texture->write(fw);
|
||||
|
||||
fw.indent() << "fogging " << getModeStr(_fogging) << endl;
|
||||
if (_fog.valid()) _fog->write(fw);
|
||||
|
||||
fw.indent() << "colortable " << getModeStr(_colortable) << endl;
|
||||
|
||||
fw.indent() << "texgening " << getModeStr(_texgening) << endl;
|
||||
if (_texgen.valid()) _texgen->write(fw);
|
||||
|
||||
if (_texenv.valid()) _texenv->write(fw);
|
||||
|
||||
fw.indent() << "point_smoothing " << getModeStr(_pointSmoothing) << endl;
|
||||
if (_point.valid()) _point->write(fw);
|
||||
|
||||
fw.indent() << "polygon_offset " << getModeStr(_polygonOffsetting) << endl;
|
||||
if (_polygonOffset.valid()) _polygonOffset->write(fw);
|
||||
|
||||
fw.indent() << "alpha_test " << getModeStr(_alphaTesting) << endl;
|
||||
if (_alphaFunc.valid()) _alphaFunc->write(fw);
|
||||
|
||||
if (_material.valid()) _material->write(fw);
|
||||
|
||||
/*
|
||||
fw.indent() << "texmating " << getModeStr(_texmating) << endl;
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeoState::matchModeStr(const char* str,AttributeMode& mode)
|
||||
{
|
||||
if (strcmp(str,"INHERIT")==0) mode = INHERIT;
|
||||
else if (strcmp(str,"ON")==0) mode = ON;
|
||||
else if (strcmp(str,"OFF")==0) mode = OFF;
|
||||
else if (strcmp(str,"OVERRIDE_ON")==0) mode = OVERRIDE_ON;
|
||||
else if (strcmp(str,"OVERRIDE_OFF")==0) mode = OVERRIDE_OFF;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* GeoState::getModeStr(AttributeMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(INHERIT): return "INHERIT";
|
||||
case(ON): return "ON";
|
||||
case(OFF): return "OFF";
|
||||
case(OVERRIDE_ON): return "OVERRIDE_ON";
|
||||
case(OVERRIDE_OFF): return "OVERRIDE_OFF";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
void GeoState::setMode( AttributeType type, AttributeMode mode )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case ANTIALIAS : _antialiasing = mode; break;
|
||||
case FACE_CULL: _face_culling = mode; break;
|
||||
case FOG : _fogging = mode; break;
|
||||
case LIGHTING: _lighting = mode; break;
|
||||
case POINT : _pointSmoothing = mode; break;
|
||||
case POLYGON_OFFSET : _polygonOffsetting = mode; break;
|
||||
case TEXGEN : _texgening = mode; break;
|
||||
case TEXTURE : _texturing = mode; break;
|
||||
case TRANSPARENCY: _transparencing = mode; break;
|
||||
case ALPHAFUNC: _alphaTesting = mode; break;
|
||||
default : notify(WARN) << "GeoState::setMode("<<(int)type<<","<<(int)mode<<") not handled."<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
GeoState::AttributeMode GeoState::getMode( AttributeType type) const
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case ANTIALIAS : return _antialiasing;
|
||||
case FACE_CULL: return _face_culling;
|
||||
case FOG : return _fogging;
|
||||
case LIGHTING: return _lighting;
|
||||
case POINT : return _pointSmoothing;
|
||||
case POLYGON_OFFSET : return _polygonOffsetting;
|
||||
case TEXTURE : return _texturing;
|
||||
case TEXGEN : return _texgening;
|
||||
case TRANSPARENCY: return _transparencing;
|
||||
case ALPHAFUNC: return _alphaTesting;
|
||||
default : notify(WARN) << "GeoState::getMode("<<(int)type<<") not handled."<<endl;
|
||||
}
|
||||
return INHERIT;
|
||||
}
|
||||
|
||||
void GeoState::setAttribute( AttributeType type, Object *attribute )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case FACE_CULL : _cullFace = dynamic_cast<CullFace*>(attribute); break;
|
||||
case FOG : _fog = dynamic_cast<Fog*>(attribute); break;
|
||||
case LIGHTING: break; /*_light = (Light *)attribute;*/
|
||||
case MATERIAL: _material = dynamic_cast<Material*>(attribute); break;
|
||||
case POINT : _point = dynamic_cast<Point*>(attribute); break;
|
||||
case POLYGON_OFFSET: _polygonOffset = dynamic_cast<PolygonOffset*>(attribute); break;
|
||||
case TEXENV : _texenv = dynamic_cast<TexEnv*>(attribute); break;
|
||||
case TEXGEN : _texgen = dynamic_cast<TexGen*>(attribute); break;
|
||||
case TEXMAT : _texmat = dynamic_cast<TexMat*>(attribute); break;
|
||||
case TEXTURE : _texture = dynamic_cast<Texture*>(attribute); break;
|
||||
case TRANSPARENCY: _transparency = dynamic_cast<Transparency*>(attribute); break;
|
||||
case ALPHAFUNC: _alphaFunc = dynamic_cast<AlphaFunc*>(attribute); break;
|
||||
default : notify(WARN) << "GeoState::setAttribute("<<(int)type<<","<<attribute<<") not handled."<<endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object* GeoState::getAttribute( AttributeType type) const
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case FOG : return _fog.get();
|
||||
case LIGHTING: return NULL; /*_light*/
|
||||
case MATERIAL: return _material.get();
|
||||
case POINT : return _point.get();
|
||||
case POLYGON_OFFSET: return _polygonOffset.get();
|
||||
case TEXENV : return _texenv.get();
|
||||
case TEXGEN : return _texgen.get();
|
||||
case TEXMAT : return _texmat.get();
|
||||
case TEXTURE : return _texture.get();
|
||||
case TRANSPARENCY: return _transparency.get();
|
||||
case ALPHAFUNC: return _alphaFunc.get();
|
||||
default : notify(WARN) << "GeoState::getAttribute("<<(int)type<<") not handled."<<endl;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GeoState::apply()
|
||||
{
|
||||
switch(_transparencing)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Transparency::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Transparency::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_face_culling)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
CullFace::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
CullFace::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_lighting)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Lighting::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Lighting::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_texturing)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Texture::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Texture::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_texgening)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
TexGen::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
TexGen::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_fogging)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Fog::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Fog::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_pointSmoothing)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Point::enableSmooth();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Point::disableSmooth();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_polygonOffsetting)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
PolygonOffset::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
PolygonOffset::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(_alphaTesting)
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
AlphaFunc::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
AlphaFunc::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
if( _transparency.valid())
|
||||
_transparency->apply();
|
||||
|
||||
if( _cullFace.valid())
|
||||
_cullFace->apply();
|
||||
|
||||
if( _texenv.valid())
|
||||
_texenv->apply();
|
||||
|
||||
if( _texgen.valid())
|
||||
_texgen->apply();
|
||||
|
||||
if( _texture.valid())
|
||||
_texture->apply();
|
||||
|
||||
if( _material.valid())
|
||||
_material->apply();
|
||||
|
||||
if( _fog.valid())
|
||||
_fog->apply();
|
||||
|
||||
if( _texmat.valid())
|
||||
_texmat->apply();
|
||||
|
||||
if( _point.valid())
|
||||
_point->apply();
|
||||
|
||||
if( _polygonOffset.valid())
|
||||
_polygonOffset->apply();
|
||||
|
||||
if( _alphaFunc.valid())
|
||||
_alphaFunc->apply();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GeoState::apply(GeoState* global,GeoState* prev)
|
||||
{
|
||||
if (global==NULL || prev==NULL)
|
||||
{
|
||||
apply();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_transparencing,prev->_transparencing,_transparencing))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Transparency::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Transparency::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch(GeoState::combineMode(global->_face_culling,prev->_face_culling,_face_culling))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
CullFace::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
CullFace::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_lighting,prev->_lighting,_lighting))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Lighting::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Lighting::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_texturing,prev->_texturing,_texturing))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Texture::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Texture::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_texgening,prev->_texgening,_texgening))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
TexGen::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
TexGen::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_fogging,prev->_fogging,_fogging))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Fog::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Fog::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_pointSmoothing,prev->_pointSmoothing,_pointSmoothing))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
Point::enableSmooth();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
Point::disableSmooth();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_polygonOffsetting,prev->_polygonOffsetting,_polygonOffsetting))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
PolygonOffset::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
PolygonOffset::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
switch(GeoState::combineMode(global->_alphaTesting,prev->_alphaTesting,_alphaTesting))
|
||||
{
|
||||
case(ON):
|
||||
case(OVERRIDE_ON):
|
||||
AlphaFunc::enable();
|
||||
break;
|
||||
case(OFF):
|
||||
case(OVERRIDE_OFF):
|
||||
AlphaFunc::disable();
|
||||
break;
|
||||
case(INHERIT):
|
||||
break;
|
||||
}
|
||||
|
||||
if (prev->_transparency!=_transparency)
|
||||
{
|
||||
osg::Transparency* new_transparency;
|
||||
if (_transparency.valid()) new_transparency = _transparency.get();
|
||||
else new_transparency = global->_transparency.get();
|
||||
if (new_transparency) new_transparency->apply();
|
||||
}
|
||||
|
||||
if (prev->_cullFace!=_cullFace)
|
||||
{
|
||||
osg::CullFace* new_cullFace;
|
||||
if (_cullFace.valid()) new_cullFace = _cullFace.get();
|
||||
else new_cullFace = global->_cullFace.get();
|
||||
if (new_cullFace) new_cullFace->apply();
|
||||
}
|
||||
|
||||
if (prev->_texenv!=_texenv)
|
||||
{
|
||||
osg::TexEnv* new_texenv;
|
||||
if (_texenv.valid()) new_texenv = _texenv.get();
|
||||
else new_texenv = global->_texenv.get();
|
||||
if (new_texenv) new_texenv->apply();
|
||||
}
|
||||
|
||||
if (prev->_texgen!=_texgen)
|
||||
{
|
||||
osg::TexGen* new_texgen;
|
||||
if (_texgen.valid()) new_texgen = _texgen.get();
|
||||
else new_texgen = global->_texgen.get();
|
||||
if (new_texgen) new_texgen->apply();
|
||||
}
|
||||
|
||||
if (prev->_texture!=_texture)
|
||||
{
|
||||
osg::Texture* new_texture;
|
||||
if (_texture.valid()) new_texture = _texture.get();
|
||||
else new_texture = global->_texture.get();
|
||||
if (new_texture) new_texture->apply();
|
||||
}
|
||||
|
||||
if (prev->_material!=_material)
|
||||
{
|
||||
osg::Material* new_material;
|
||||
if (_material.valid()) new_material = _material.get();
|
||||
else new_material = global->_material.get();
|
||||
if (new_material) new_material->apply();
|
||||
}
|
||||
|
||||
if (prev->_fog!=_fog)
|
||||
{
|
||||
osg::Fog* new_fog;
|
||||
if (_fog.valid()) new_fog = _fog.get();
|
||||
else new_fog = global->_fog.get();
|
||||
if (new_fog) new_fog->apply();
|
||||
}
|
||||
|
||||
if (prev->_texmat!=_texmat)
|
||||
{
|
||||
osg::TexMat* new_texmat;
|
||||
if (_texmat.valid()) new_texmat = _texmat.get();
|
||||
else new_texmat = global->_texmat.get();
|
||||
if (new_texmat) new_texmat->apply();
|
||||
}
|
||||
|
||||
if (prev->_point!=_point)
|
||||
{
|
||||
osg::Point* new_point;
|
||||
if (_point.valid()) new_point = _point.get();
|
||||
else new_point = global->_point.get();
|
||||
if (new_point) new_point->apply();
|
||||
}
|
||||
|
||||
if (prev->_polygonOffset!=_polygonOffset)
|
||||
{
|
||||
osg::PolygonOffset* new_polygonOffset;
|
||||
if (_polygonOffset.valid()) new_polygonOffset = _polygonOffset.get();
|
||||
else new_polygonOffset = global->_polygonOffset.get();
|
||||
if (new_polygonOffset) new_polygonOffset->apply();
|
||||
}
|
||||
|
||||
if (prev->_alphaFunc!=_alphaFunc)
|
||||
{
|
||||
osg::AlphaFunc* new_AlphaFunc;
|
||||
if (_alphaFunc.valid()) new_AlphaFunc = _alphaFunc.get();
|
||||
else new_AlphaFunc = global->_alphaFunc.get();
|
||||
if (new_AlphaFunc) new_AlphaFunc->apply();
|
||||
}
|
||||
}
|
||||
|
||||
bool GeoState::check()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#if 0 // [ NOTES on how apply should work
|
||||
|
||||
Each Scene must have a global initial GeoState, current GeoState, and current request state. The current definition of GeoState
|
||||
should really become an GeoState. The global initial State can have modes set to
|
||||
|
||||
SG_ON,
|
||||
SG_OFF,
|
||||
|
||||
and may be or'ed with
|
||||
|
||||
SG_OVERRIDE.
|
||||
|
||||
All attributes are set to the default. Defaults can be set at start up by querying hardware
|
||||
and determining best parameters (for example, do we have hardware texture mapping?, if so enable texture and create a texture environment).
|
||||
|
||||
The current GeoState and the request GeoState begin as a copy of the initial state. The request state is subsequently changed by each GeoState,
|
||||
during traversal. It is the current state that will actually issue the GL commands at apply time.
|
||||
|
||||
Attributes for the GeoStates may be
|
||||
|
||||
SG_ON -explicitely
|
||||
SG_OFF -explicitely
|
||||
SG_INHERIT
|
||||
|
||||
and may be or'ed with
|
||||
|
||||
SG_PERSIST
|
||||
|
||||
During traversal, each GeoState's attribute set to INHERIT does nothing. Each attribute set to ON or OFF sets the subsequent request state
|
||||
to the same before drawing and unsets it after. If the attribute is or'ed with SG_PERSIST, then the mode is not unset after drawing.
|
||||
Just before drawing the request state is compared to the current state. If an attribute or mode has changed, it is changed in the current
|
||||
state then applied. Only at this application will the actual GL calls be issued.
|
||||
|
||||
For exammple, if two subsequent geosets have lighting on the sequence will be as follows
|
||||
|
||||
geostate 1 sets lighting on in request state
|
||||
at draw:
|
||||
if current state has lighting off it is changed to on and applied.
|
||||
geostate1 unsets lighting in request state.
|
||||
|
||||
geosate2 resets lighting to on in request state
|
||||
at draw:
|
||||
current state has lighting set to on from previous draw therefore nothing changes
|
||||
|
||||
geostate2
|
||||
|
||||
Addendum 10/22 - Use this method for traversal. Currently we shall do dumb apply().
|
||||
Upon implementation of a CULL traversal, which creates a DRAW display list, then we
|
||||
shall implement the "smart" state change described above.
|
||||
|
||||
#endif // ]
|
||||
*/
|
||||
161
src/osg/Geode.cpp
Normal file
161
src/osg/Geode.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "osg/Geode"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef __sgi
|
||||
using std::find;
|
||||
using std::for_each;
|
||||
#endif
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Geode> g_GeodeProxy;
|
||||
|
||||
Geode::Geode()
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
}
|
||||
|
||||
|
||||
Geode::~Geode()
|
||||
{
|
||||
// ref_ptr<> automactially decrements the reference count of all geosets.
|
||||
}
|
||||
|
||||
|
||||
bool Geode::readLocalData(Input& fr)
|
||||
{
|
||||
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (Node::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
int num_geosets;
|
||||
if (fr[0].matchWord("num_geosets") &&
|
||||
fr[1].getInt(num_geosets))
|
||||
{
|
||||
// could allocate space for children here...
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
GeoSet* gset_read = NULL;
|
||||
do
|
||||
{
|
||||
if ((gset_read=static_cast<GeoSet*>(GeoSet::instance()->readClone(fr))))
|
||||
{
|
||||
addGeoSet(gset_read);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
} while(gset_read != NULL);
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Geode::writeLocalData(Output& fw)
|
||||
{
|
||||
Node::writeLocalData(fw);
|
||||
|
||||
fw.indent() << "num_geosets " << getNumGeosets() << endl;
|
||||
for(GeoSetList::iterator itr = _geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->write(fw);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Geode::addGeoSet( GeoSet *gset )
|
||||
{
|
||||
if (gset && !containsGeoSet(gset))
|
||||
{
|
||||
// note ref_ptr<> automatically handles incrementing gset's reference count.
|
||||
_geosets.push_back(gset);
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Geode::removeGeoSet( GeoSet *gset )
|
||||
{
|
||||
GeoSetList::iterator itr = findGeoSet(gset);
|
||||
if (itr!=_geosets.end())
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing gset's reference count.
|
||||
_geosets.erase(itr);
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Geode::replaceGeoSet( GeoSet *origGset, GeoSet *newGset )
|
||||
{
|
||||
if (newGset==NULL || origGset==newGset) return false;
|
||||
|
||||
GeoSetList::iterator itr = findGeoSet(origGset);
|
||||
if (itr!=_geosets.end())
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing origGset's reference count,
|
||||
// and inccrementing newGset's reference count.
|
||||
*itr = newGset;
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Geode::computeBound( void )
|
||||
{
|
||||
BoundingBox bb;
|
||||
GeoSetList::iterator itr;
|
||||
for(itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
{
|
||||
bb.expandBy((*itr)->getBound());
|
||||
}
|
||||
|
||||
_bsphere._center = bb.center();
|
||||
_bsphere._radius = 0.0f;
|
||||
|
||||
for(itr=_geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
{
|
||||
const BoundingBox& bbox = (*itr)->getBound();
|
||||
for(unsigned int c=0;c<8;++c)
|
||||
{
|
||||
_bsphere.expandRadiusBy(bbox.corner(c));
|
||||
}
|
||||
}
|
||||
|
||||
_bsphere_computed=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Geode::compileGeoSets( void )
|
||||
{
|
||||
for(GeoSetList::iterator itr = _geosets.begin();
|
||||
itr!=_geosets.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->compile();
|
||||
}
|
||||
}
|
||||
180
src/osg/Group.cpp
Normal file
180
src/osg/Group.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "osg/Group"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
#include "osg/BoundingBox"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// #ifdef __sgi
|
||||
// using std::find;
|
||||
// using std::for_each;
|
||||
// using std::string;
|
||||
// #endif
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Group> g_GroupProxy;
|
||||
|
||||
Group::Group()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Group::~Group()
|
||||
{
|
||||
|
||||
for(ChildList::iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
Node* child = itr->get();
|
||||
ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),this);
|
||||
if (pitr!=child->_parents.end()) child->_parents.erase(pitr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Group::traverse(NodeVisitor& nv)
|
||||
{
|
||||
for(ChildList::iterator itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->accept(nv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Group::addChild( Node *child )
|
||||
{
|
||||
if (child && !containsNode(child))
|
||||
{
|
||||
// note ref_ptr<> automatically handles incrementing child's reference count.
|
||||
_children.push_back(child);
|
||||
|
||||
// register as parent of child.
|
||||
child->_parents.push_back(this);
|
||||
|
||||
dirtyBound();
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Group::removeChild( Node *child )
|
||||
{
|
||||
ChildList::iterator itr = findNode(child);
|
||||
if (itr!=_children.end())
|
||||
{
|
||||
// note ref_ptr<> automatically handles decrementing child's reference count.
|
||||
_children.erase(itr);
|
||||
dirtyBound();
|
||||
|
||||
ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),child);
|
||||
if (pitr!=child->_parents.end()) child->_parents.erase(pitr);
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Group::replaceChild( Node *origNode, Node *newNode )
|
||||
{
|
||||
if (newNode==NULL || origNode==newNode) return false;
|
||||
|
||||
ChildList::iterator itr = findNode(origNode);
|
||||
if (itr!=_children.end())
|
||||
{
|
||||
ParentList::iterator pitr = std::find(origNode->_parents.begin(),origNode->_parents.end(),origNode);
|
||||
if (pitr!=origNode->_parents.end()) origNode->_parents.erase(pitr);
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing origNode's reference count,
|
||||
// and inccrementing newNode's reference count.
|
||||
*itr = newNode;
|
||||
|
||||
// register as parent of child.
|
||||
newNode->_parents.push_back(this);
|
||||
|
||||
dirtyBound();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
bool Group::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (Node::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
int num_children;
|
||||
if (fr[0].matchWord("num_children") &&
|
||||
fr[1].getInt(num_children))
|
||||
{
|
||||
// could allocate space for children here...
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
Node* node = NULL;
|
||||
while((node=fr.readNode())!=NULL)
|
||||
{
|
||||
addChild(node);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Group::writeLocalData(Output& fw)
|
||||
{
|
||||
Node::writeLocalData(fw);
|
||||
|
||||
fw.indent() << "num_children " << getNumChildren() << endl;
|
||||
for(int i=0;i<getNumChildren();++i)
|
||||
{
|
||||
getChild(i)->write(fw);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Group::computeBound()
|
||||
{
|
||||
|
||||
_bsphere_computed = true;
|
||||
|
||||
_bsphere.init();
|
||||
if (_children.empty()) return false;
|
||||
|
||||
BoundingBox bb;
|
||||
bb.init();
|
||||
ChildList::iterator itr;
|
||||
for(itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
bb.expandBy((*itr)->getBound());
|
||||
}
|
||||
|
||||
if (!bb.isValid()) return false;
|
||||
|
||||
_bsphere._center = bb.center();
|
||||
_bsphere._radius = 0.0f;
|
||||
for(itr=_children.begin();
|
||||
itr!=_children.end();
|
||||
++itr)
|
||||
{
|
||||
_bsphere.expandRadiusBy((*itr)->getBound());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
224
src/osg/Image.cpp
Normal file
224
src/osg/Image.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "osg/Image"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/GL"
|
||||
#include "osg/Notify"
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/GeoState>
|
||||
#include <osg/Texture>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Image::Image()
|
||||
{
|
||||
_fileName = NULL;
|
||||
_s = _t = _r = 0;
|
||||
_internalFormat = 0;
|
||||
_pixelFormat = (unsigned int)0;
|
||||
_dataType = (unsigned int)0;
|
||||
_packing = 4;
|
||||
|
||||
_data = (unsigned char *)0L;
|
||||
}
|
||||
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
if (_fileName) ::free(_fileName);
|
||||
if (_data) ::free(_data);
|
||||
}
|
||||
|
||||
|
||||
void Image::setFileName(const char* fileName)
|
||||
{
|
||||
if (_fileName) ::free(_fileName);
|
||||
|
||||
if (fileName) _fileName = strdup(fileName);
|
||||
else _fileName = NULL;
|
||||
}
|
||||
|
||||
|
||||
void Image::setImage(int s,int t,int r,
|
||||
int internalFormat,
|
||||
unsigned int pixelFormat,
|
||||
unsigned int dataType,
|
||||
unsigned char *data,
|
||||
int packing)
|
||||
{
|
||||
if (_data) ::free(_data);
|
||||
|
||||
_s = s;
|
||||
_t = t;
|
||||
_r = r;
|
||||
|
||||
_internalFormat = internalFormat;
|
||||
_pixelFormat = pixelFormat;
|
||||
_dataType = dataType;
|
||||
|
||||
_data = data;
|
||||
|
||||
|
||||
if (packing<0)
|
||||
{
|
||||
if (_s%4==0)
|
||||
_packing = 4;
|
||||
else
|
||||
_packing = 1;
|
||||
}
|
||||
else
|
||||
_packing = packing;
|
||||
|
||||
// scaleImageTo(16,16,_r);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Image::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (fr[0].matchWord("file") && fr[1].isString())
|
||||
{
|
||||
//loadFile(fr[1].getStr());
|
||||
fr += 2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Image::writeLocalData(Output& fw)
|
||||
{
|
||||
if (_fileName)
|
||||
{
|
||||
fw.indent() << "file \""<<_fileName<<"\""<<endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Image::scaleImage(int s,int t,int /*r*/)
|
||||
{
|
||||
if (_data==NULL) return;
|
||||
|
||||
unsigned char* newData = (unsigned char *)malloc(2 * (s+1)*(t+1)*4);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT,_packing);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,_packing);
|
||||
|
||||
GLint status = gluScaleImage((GLenum)_pixelFormat,
|
||||
_s,
|
||||
_t,
|
||||
(GLenum)_dataType,
|
||||
_data,
|
||||
s,
|
||||
t,
|
||||
(GLenum)_dataType,
|
||||
newData);
|
||||
|
||||
if (status==0) {
|
||||
|
||||
// free old image.
|
||||
::free(_data);
|
||||
|
||||
_s = s;
|
||||
_t = t;
|
||||
_data = newData;
|
||||
}
|
||||
else
|
||||
{
|
||||
::free(newData);
|
||||
|
||||
notify(WARN) << "Error Image::scaleImage() do not succeed : errorString = "<<gluErrorString((GLenum)status)<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Image::ensureDimensionsArePowerOfTwo()
|
||||
{
|
||||
float sp2 = logf((float)_s)/logf(2.0f);
|
||||
float rounded_sp2 = floorf(sp2+0.5f);
|
||||
int new_s = (int)(powf(2.0f,rounded_sp2));
|
||||
|
||||
float tp2 = logf((float)_t)/logf(2.0f);
|
||||
float rounded_tp2 = floorf(tp2+0.5f);
|
||||
int new_t = (int)(powf(2.0f,rounded_tp2));
|
||||
|
||||
if (new_s!=_s && new_t!=_t)
|
||||
{
|
||||
notify(NOTICE) << "Scaling image '"<<_fileName<<"' from ("<<_s<<","<<_t<<") to ("<<new_s<<","<<new_t<<")"<<endl;
|
||||
scaleImage(new_s,new_t,_r);
|
||||
}
|
||||
}
|
||||
|
||||
Geode* osg::createGeodeForImage(osg::Image* image)
|
||||
{
|
||||
return createGeodeForImage(image,image->s(),image->t());
|
||||
}
|
||||
|
||||
Geode* osg::createGeodeForImage(osg::Image* image,float s,float t)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
if (s>0 && t>0)
|
||||
{
|
||||
|
||||
float y = 1.0;
|
||||
float x = y*(s/t);
|
||||
|
||||
// set up the texture.
|
||||
osg::Texture* texture = new osg::Texture;
|
||||
texture->setImage(image);
|
||||
|
||||
// set up the geostate.
|
||||
osg::GeoState* gstate = new osg::GeoState;
|
||||
gstate->setMode(osg::GeoState::FACE_CULL,osg::GeoState::OFF);
|
||||
gstate->setMode(osg::GeoState::LIGHTING,osg::GeoState::OFF);
|
||||
gstate->setMode(osg::GeoState::TEXTURE,osg::GeoState::ON);
|
||||
gstate->setAttribute(osg::GeoState::TEXTURE,texture);
|
||||
|
||||
// set up the geoset.
|
||||
osg::GeoSet* gset = new osg::GeoSet;
|
||||
gset->setGeoState(gstate);
|
||||
|
||||
osg::Vec3* coords = new Vec3 [4];
|
||||
coords[0].set(-x,0.0f,y);
|
||||
coords[1].set(-x,0.0f,-y);
|
||||
coords[2].set(x,0.0f,-y);
|
||||
coords[3].set(x,0.0f,y);
|
||||
gset->setCoords(coords);
|
||||
|
||||
osg::Vec2* tcoords = new Vec2 [4];
|
||||
tcoords[0].set(0.0f,1.0f);
|
||||
tcoords[1].set(0.0f,0.0f);
|
||||
tcoords[2].set(1.0f,0.0f);
|
||||
tcoords[3].set(1.0f,1.0f);
|
||||
gset->setTextureCoords(tcoords);
|
||||
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
|
||||
|
||||
osg::Vec4* colours = new Vec4;
|
||||
colours->set(1.0f,1.0f,1.0,0.0f);
|
||||
gset->setColors(colours);
|
||||
gset->setColorBinding(osg::GeoSet::BIND_OVERALL);
|
||||
|
||||
gset->setNumPrims(1);
|
||||
gset->setPrimType(osg::GeoSet::QUADS);
|
||||
|
||||
// set up the geode.
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addGeoSet(gset);
|
||||
|
||||
return geode;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
69
src/osg/Input.cpp
Normal file
69
src/osg/Input.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "osg/Input"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Object"
|
||||
|
||||
#ifdef __sgi
|
||||
using std::string;
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
// Will extend to handle #DEF and use
|
||||
// functionality similar to Inventor,
|
||||
// and add the ability to handle #include
|
||||
// from within the OSG file format.
|
||||
Input::Input()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Input::~Input()
|
||||
{
|
||||
}
|
||||
|
||||
Object* Input::getObjectForUniqueID(const std::string& uniqueID)
|
||||
{
|
||||
UniqueIDToObjectMapping::iterator fitr = _uniqueIDToObjectMap.find(uniqueID);
|
||||
if (fitr != _uniqueIDToObjectMap.end()) return (*fitr).second;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
void Input::regisiterUniqueIDForObject(const std::string& uniqueID,Object* obj)
|
||||
{
|
||||
_uniqueIDToObjectMap[uniqueID] = obj;
|
||||
}
|
||||
|
||||
Object* Input::readObject()
|
||||
{
|
||||
return Registry::instance()->readObject(*this);
|
||||
}
|
||||
|
||||
|
||||
Object* Input::readObject(const string& fileName)
|
||||
{
|
||||
return Registry::instance()->readObject(fileName);
|
||||
}
|
||||
|
||||
|
||||
Image* Input::readImage()
|
||||
{
|
||||
return Registry::instance()->readImage(*this);
|
||||
}
|
||||
|
||||
|
||||
Image* Input::readImage(const string& fileName)
|
||||
{
|
||||
return Registry::instance()->readImage(fileName);
|
||||
}
|
||||
|
||||
|
||||
Node* Input::readNode()
|
||||
{
|
||||
return Registry::instance()->readNode(*this);
|
||||
}
|
||||
|
||||
|
||||
Node* Input::readNode(const string& fileName)
|
||||
{
|
||||
return Registry::instance()->readNode(fileName);
|
||||
}
|
||||
130
src/osg/LOD.cpp
Normal file
130
src/osg/LOD.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#include "osg/LOD"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<LOD> g_LODProxy;
|
||||
|
||||
void LOD::traverse(NodeVisitor& nv)
|
||||
{
|
||||
switch(nv.getTraverseMode())
|
||||
{
|
||||
case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
|
||||
if (_children.size()!=0) _children.front()->accept(nv);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LOD::setRange(unsigned int index, float range)
|
||||
{
|
||||
if (index<_rangeList.size()) _rangeList[index] = range;
|
||||
else while (index>=_rangeList.size()) _rangeList.push_back(range);
|
||||
|
||||
if (index<_rangeList2.size()) _rangeList2[index] = range*range;
|
||||
else while (index>=_rangeList2.size()) _rangeList2.push_back(range*range);
|
||||
}
|
||||
|
||||
int LOD::evaluate(const Vec3& eye_local, float bias)
|
||||
{
|
||||
// For cache coherency, use _rangeList2 exclusively
|
||||
if (_rangeList2.size()==0) return -1;
|
||||
|
||||
// Test distance-squared against the stored array of squared ranges
|
||||
float LODRange = (eye_local-_center).length2()*bias;
|
||||
if (LODRange<_rangeList2[0]) return -1;
|
||||
|
||||
for(unsigned int i=0;i<_rangeList2.size()-1;++i)
|
||||
{
|
||||
if (_rangeList2[i]<=LODRange && LODRange<_rangeList2[i+1]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool LOD::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr.matchSequence("Center %f %f %f"))
|
||||
{
|
||||
|
||||
fr[1].getFloat(_center[0]);
|
||||
fr[2].getFloat(_center[1]);
|
||||
fr[3].getFloat(_center[2]);
|
||||
|
||||
iteratorAdvanced = true;
|
||||
fr+=3;
|
||||
}
|
||||
|
||||
bool matchFirst = false;
|
||||
if ((matchFirst=fr.matchSequence("Ranges {")) || fr.matchSequence("Ranges %i {"))
|
||||
{
|
||||
|
||||
// set up coordinates.
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
|
||||
if (matchFirst)
|
||||
{
|
||||
fr += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//_rangeList.(capacity);
|
||||
fr += 3;
|
||||
}
|
||||
|
||||
float range;
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
{
|
||||
if (fr[0].getFloat(range))
|
||||
{
|
||||
++fr;
|
||||
_rangeList.push_back(range);
|
||||
_rangeList2.push_back(range*range);
|
||||
}
|
||||
else
|
||||
{
|
||||
++fr;
|
||||
}
|
||||
}
|
||||
|
||||
iteratorAdvanced = true;
|
||||
++fr;
|
||||
|
||||
}
|
||||
|
||||
if (Group::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool LOD::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "Center "<<_center[0] << " "<<_center[1] << " "<<_center[2] <<endl;
|
||||
|
||||
fw.indent() << "Ranges {"<<endl;
|
||||
fw.moveIn();
|
||||
for(RangeList::iterator riter = _rangeList.begin();
|
||||
riter != _rangeList.end();
|
||||
++riter)
|
||||
{
|
||||
fw.indent() << (*riter) <<endl;
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent() << "}"<<endl;
|
||||
|
||||
Group::writeLocalData(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
97
src/osg/Light.cpp
Normal file
97
src/osg/Light.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "osg/Light"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
int Light::_currentLightNum = -1;
|
||||
|
||||
Light::Light( void )
|
||||
{
|
||||
_lightnum = ++_currentLightNum;
|
||||
_on = 1;
|
||||
|
||||
init();
|
||||
|
||||
// notify(DEBUG) << "_ambient "<<_ambient<<endl;
|
||||
// notify(DEBUG) << "_diffuse "<<_diffuse<<endl;
|
||||
// notify(DEBUG) << "_specular "<<_specular<<endl;
|
||||
// notify(DEBUG) << "_position "<<_position<<endl;
|
||||
// notify(DEBUG) << "_direction "<<_direction<<endl;
|
||||
// notify(DEBUG) << "_spot_exponent "<<_spot_exponent<<endl;
|
||||
// notify(DEBUG) << "_spot_cutoff "<<_spot_cutoff<<endl;
|
||||
// notify(DEBUG) << "_constant_attenuation "<<_constant_attenuation<<endl;
|
||||
// notify(DEBUG) << "_linear_attenuation "<<_linear_attenuation<<endl;
|
||||
// notify(DEBUG) << "_quadratic_attenuation "<<_quadratic_attenuation<<endl;
|
||||
}
|
||||
|
||||
|
||||
Light::~Light( void )
|
||||
{
|
||||
}
|
||||
|
||||
Light* Light::instance()
|
||||
{
|
||||
static ref_ptr<Light> s_Light(new Light);
|
||||
return s_Light.get();
|
||||
}
|
||||
|
||||
void Light::init( void )
|
||||
{
|
||||
_ambient.set(0.05f,0.05f,0.05f,1.0f);
|
||||
_diffuse.set(0.8f,0.8f,0.8f,1.0f);
|
||||
_specular.set(0.05f,0.05f,0.05f,1.0f);
|
||||
_position.set(0.0f,0.0f,1.0f,0.0f);
|
||||
_direction.set(0.0f,0.0f,-1.0f);
|
||||
_spot_exponent = 0.0f;
|
||||
_spot_cutoff = 180.0f;
|
||||
_constant_attenuation = 1.0f;
|
||||
_linear_attenuation = 0.0f;
|
||||
_quadratic_attenuation = 0.0f;
|
||||
}
|
||||
|
||||
void Light::captureLightState()
|
||||
{
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_AMBIENT, _ambient.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_DIFFUSE, _diffuse.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPECULAR, _specular.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_POSITION, _position.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_DIRECTION, _direction.ptr() );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_EXPONENT, &_spot_exponent );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_CUTOFF, &_spot_cutoff );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_CONSTANT_ATTENUATION, &_constant_attenuation );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_LINEAR_ATTENUATION, &_linear_attenuation );
|
||||
glGetLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_QUADRATIC_ATTENUATION, &_quadratic_attenuation );
|
||||
}
|
||||
|
||||
|
||||
void Light::enable( void )
|
||||
{
|
||||
glEnable( GL_LIGHTING );
|
||||
}
|
||||
|
||||
|
||||
void Light::disable( void )
|
||||
{
|
||||
glDisable( GL_LIGHTING );
|
||||
}
|
||||
|
||||
|
||||
void Light::apply( void )
|
||||
{
|
||||
if( _on )
|
||||
{
|
||||
glEnable ( (GLenum)((int)GL_LIGHT0 + _lightnum) );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_AMBIENT, _ambient.ptr() );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_DIFFUSE, _diffuse.ptr() );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPECULAR, _specular.ptr() );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_POSITION, _position.ptr() );
|
||||
glLightfv( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_DIRECTION, _direction.ptr() );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_EXPONENT, _spot_exponent );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_SPOT_CUTOFF, _spot_cutoff );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_CONSTANT_ATTENUATION, _constant_attenuation );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_LINEAR_ATTENUATION, _linear_attenuation );
|
||||
glLightf ( (GLenum)((int)GL_LIGHT0 + _lightnum), GL_QUADRATIC_ATTENUATION, _quadratic_attenuation );
|
||||
}
|
||||
else
|
||||
glDisable( (GLenum)((int)GL_LIGHT0 + _lightnum) );
|
||||
}
|
||||
59
src/osg/LightSource.cpp
Normal file
59
src/osg/LightSource.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "osg/LightSource"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<LightSource> g_LightSourceProxy;
|
||||
|
||||
LightSource::LightSource()
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
}
|
||||
|
||||
|
||||
LightSource::~LightSource()
|
||||
{
|
||||
// ref_ptr<> automactially decrements the reference count of attached lights.
|
||||
}
|
||||
|
||||
|
||||
bool LightSource::readLocalData(Input& fr)
|
||||
{
|
||||
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (Node::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
Light* light = static_cast<Light*>(Light::instance()->readClone(fr));
|
||||
if (light)
|
||||
{
|
||||
_light = light;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool LightSource::writeLocalData(Output& fw)
|
||||
{
|
||||
Node::writeLocalData(fw);
|
||||
|
||||
if (_light.valid()) _light->write(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LightSource::computeBound( void )
|
||||
{
|
||||
// note, don't do anything right now as the light itself is not
|
||||
// visualised, just having an effect on the lighting of geodes.
|
||||
_bsphere.init();
|
||||
|
||||
_bsphere_computed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
15
src/osg/Lighting.cpp
Normal file
15
src/osg/Lighting.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/Lighting"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
void Lighting::enable( void )
|
||||
{
|
||||
glEnable( GL_LIGHTING );
|
||||
}
|
||||
|
||||
|
||||
void Lighting::disable( void )
|
||||
{
|
||||
glDisable( GL_LIGHTING );
|
||||
}
|
||||
0
src/osg/Makedepend
Normal file
0
src/osg/Makedepend
Normal file
148
src/osg/Makefile
Normal file
148
src/osg/Makefile
Normal file
@@ -0,0 +1,148 @@
|
||||
#!smake
|
||||
include ../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
Registry.cpp\
|
||||
OSG.cpp\
|
||||
AlphaFunc.cpp\
|
||||
Group.cpp\
|
||||
Field.cpp\
|
||||
FieldReader.cpp\
|
||||
FieldReaderIterator.cpp\
|
||||
GeoSet.cpp\
|
||||
GeoSet_ogl.cpp\
|
||||
GeoState.cpp\
|
||||
Geode.cpp\
|
||||
Input.cpp\
|
||||
FileNameUtils.cpp\
|
||||
Light.cpp\
|
||||
LightSource.cpp\
|
||||
Lighting.cpp\
|
||||
Material.cpp\
|
||||
Matrix.cpp\
|
||||
Quat.cpp\
|
||||
Seg.cpp\
|
||||
Node.cpp\
|
||||
NodeVisitor.cpp\
|
||||
Object.cpp\
|
||||
Output.cpp\
|
||||
DynamicLibrary.cpp\
|
||||
TexEnv.cpp\
|
||||
TexGen.cpp\
|
||||
Image.cpp\
|
||||
Texture.cpp\
|
||||
DCS.cpp\
|
||||
Scene.cpp\
|
||||
Switch.cpp\
|
||||
Sequence.cpp\
|
||||
LOD.cpp\
|
||||
Billboard.cpp\
|
||||
BoundingSphere.cpp\
|
||||
BoundingBox.cpp\
|
||||
Transparency.cpp\
|
||||
CullFace.cpp\
|
||||
TexMat.cpp\
|
||||
Timer.cpp\
|
||||
Fog.cpp\
|
||||
ReaderWriterOSG.cpp\
|
||||
ReaderWriterRGB.cpp\
|
||||
Camera.cpp\
|
||||
Notify.cpp\
|
||||
ExtensionSupported.cpp\
|
||||
Point.cpp\
|
||||
PolygonOffset.cpp\
|
||||
Version.cpp\
|
||||
|
||||
|
||||
TARGET_BASENAME = osg
|
||||
|
||||
TARGET_LIB_FILES = lib$(TARGET_BASENAME).so
|
||||
|
||||
TARGET_INCLUDE_FILES = \
|
||||
osg/AlphaFunc\
|
||||
osg/Billboard\
|
||||
osg/BoundingBox\
|
||||
osg/BoundingSphere\
|
||||
osg/Camera\
|
||||
osg/CullFace\
|
||||
osg/DCS\
|
||||
osg/DynamicLibrary\
|
||||
osg/Export\
|
||||
osg/Field\
|
||||
osg/FieldReader\
|
||||
osg/FieldReaderIterator\
|
||||
osg/FileNameUtils\
|
||||
osg/Fog\
|
||||
osg/GeoSet\
|
||||
osg/GeoState\
|
||||
osg/Geode\
|
||||
osg/Group\
|
||||
osg/GL\
|
||||
osg/Image\
|
||||
osg/Input\
|
||||
osg/LOD\
|
||||
osg/Light\
|
||||
osg/LightSource\
|
||||
osg/Lighting\
|
||||
osg/Material\
|
||||
osg/Matrix\
|
||||
osg/Node\
|
||||
osg/Notify\
|
||||
osg/NodeVisitor\
|
||||
osg/OSG\
|
||||
osg/Object\
|
||||
osg/Output\
|
||||
osg/Point\
|
||||
osg/PolygonOffset\
|
||||
osg/Quat\
|
||||
osg/Referenced\
|
||||
osg/Registry\
|
||||
osg/Scene\
|
||||
osg/Seg\
|
||||
osg/Sequence\
|
||||
osg/State\
|
||||
osg/Switch\
|
||||
osg/TexEnv\
|
||||
osg/TexGen\
|
||||
osg/TexMat\
|
||||
osg/Texture\
|
||||
osg/Transparency\
|
||||
osg/Timer\
|
||||
osg/Types\
|
||||
osg/Vec2\
|
||||
osg/Vec3\
|
||||
osg/Vec4\
|
||||
osg/Version\
|
||||
|
||||
|
||||
TARGET_DATA_FILES = \
|
||||
cessna.osg\
|
||||
cow.osg\
|
||||
dumptruck.osg\
|
||||
e-s-bike.osg\
|
||||
flight_park.fly\
|
||||
glider.osg\
|
||||
ncc1701d.osg\
|
||||
paraglider.osg\
|
||||
torus.osg\
|
||||
turtle.osg\
|
||||
Test/CullFace.osg\
|
||||
Test/Point.osg\
|
||||
Test/PolygonOffset.osg\
|
||||
Images/lz.rgb\
|
||||
Images/reflect.rgb\
|
||||
Images/tank.rgb\
|
||||
Images/tree0.rgba\
|
||||
Images/water.rgb\
|
||||
Images/white.rgb\
|
||||
|
||||
|
||||
LIBS = -ldl
|
||||
|
||||
LIB = ../../lib/lib$(TARGET_BASENAME).so
|
||||
#LIB = ../../lib/lib$(TARGET_BASENAME).a
|
||||
|
||||
C++FLAGS += -I ../../include
|
||||
|
||||
include ../../Make/makerules
|
||||
|
||||
560
src/osg/Material.cpp
Normal file
560
src/osg/Material.cpp
Normal file
@@ -0,0 +1,560 @@
|
||||
#include "osg/Material"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Material::Material( void )
|
||||
{
|
||||
_colorMode = OFF;
|
||||
|
||||
_ambientFrontAndBack = true;
|
||||
_ambientFront.set(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
_ambientBack.set(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
|
||||
_diffuseFrontAndBack = true;
|
||||
_diffuseFront.set(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
_diffuseBack.set(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
|
||||
_specularFrontAndBack = true;
|
||||
_specularFront.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_specularBack.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
_emissionFrontAndBack = true;
|
||||
_emissionFront.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_emissionBack.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
_shininessFrontAndBack = true;
|
||||
_shininessFront = 0.0f;
|
||||
_shininessBack = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
Material::~Material( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Material* Material::instance()
|
||||
{
|
||||
static ref_ptr<Material> s_Material(new Material);
|
||||
return s_Material.get();
|
||||
}
|
||||
|
||||
void Material::setAmbient( MaterialFace face, const Vec4& ambient )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_ambientFrontAndBack = false;
|
||||
_ambientFront = ambient;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_ambientFrontAndBack = false;
|
||||
_ambientBack = ambient;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_ambientFrontAndBack = true;
|
||||
_ambientFront = ambient;
|
||||
_ambientBack = ambient;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setAmbient()."<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getAmbient(MaterialFace face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _ambientFront;
|
||||
case(FACE_BACK):
|
||||
return _ambientBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_ambientFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getAmbient(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK ambient colors."<<endl;
|
||||
}
|
||||
return _ambientFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getAmbient()."<<endl;
|
||||
return _ambientFront;
|
||||
}
|
||||
|
||||
void Material::setDiffuse( MaterialFace face, const Vec4& diffuse )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_diffuseFrontAndBack = false;
|
||||
_diffuseFront = diffuse;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_diffuseFrontAndBack = false;
|
||||
_diffuseBack = diffuse;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_diffuseFrontAndBack = true;
|
||||
_diffuseFront = diffuse;
|
||||
_diffuseBack = diffuse;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setDiffuse()."<<endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getDiffuse(MaterialFace face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _diffuseFront;
|
||||
case(FACE_BACK):
|
||||
return _diffuseBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_diffuseFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getDiffuse(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK diffuse colors."<<endl;
|
||||
}
|
||||
return _diffuseFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getDiffuse()."<<endl;
|
||||
return _diffuseFront;
|
||||
}
|
||||
|
||||
void Material::setSpecular( MaterialFace face, const Vec4& specular )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_specularFrontAndBack = false;
|
||||
_specularFront = specular;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_specularFrontAndBack = false;
|
||||
_specularBack = specular;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_specularFrontAndBack = true;
|
||||
_specularFront = specular;
|
||||
_specularBack = specular;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setSpecular()."<<endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getSpecular(MaterialFace face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _specularFront;
|
||||
case(FACE_BACK):
|
||||
return _specularBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_specularFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getSpecular(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK specular colors."<<endl;
|
||||
}
|
||||
return _specularFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getSpecular()."<<endl;
|
||||
return _specularFront;
|
||||
}
|
||||
|
||||
void Material::setEmission( MaterialFace face, const Vec4& emission )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_emissionFrontAndBack = false;
|
||||
_emissionFront = emission;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_emissionFrontAndBack = false;
|
||||
_emissionBack = emission;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_emissionFrontAndBack = true;
|
||||
_emissionFront = emission;
|
||||
_emissionBack = emission;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setEmission()."<<endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const Vec4& Material::getEmission(MaterialFace face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _emissionFront;
|
||||
case(FACE_BACK):
|
||||
return _emissionBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_emissionFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getEmission(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK emission colors."<<endl;
|
||||
}
|
||||
return _emissionFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getEmission()."<<endl;
|
||||
return _emissionFront;
|
||||
}
|
||||
|
||||
void Material::setShininess( MaterialFace face, float shininess )
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
_shininessFrontAndBack = false;
|
||||
_shininessFront = shininess;
|
||||
break;
|
||||
case(FACE_BACK):
|
||||
_shininessFrontAndBack = false;
|
||||
_shininessBack = shininess;
|
||||
break;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
_shininessFrontAndBack = true;
|
||||
_shininessFront = shininess;
|
||||
_shininessBack = shininess;
|
||||
break;
|
||||
default:
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::setShininess()."<<endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float Material::getShininess(MaterialFace face) const
|
||||
{
|
||||
switch(face) {
|
||||
case(FACE_FRONT):
|
||||
return _shininessFront;
|
||||
case(FACE_BACK):
|
||||
return _shininessBack;
|
||||
case(FACE_FRONT_AND_BACK):
|
||||
if (!_shininessFrontAndBack)
|
||||
{
|
||||
notify(NOTICE)<<"Notice: Material::getShininess(FRONT_AND_BACK) called on material "<<endl;
|
||||
notify(NOTICE)<<" with seperate FRONT and BACK shininess colors."<<endl;
|
||||
}
|
||||
return _shininessFront;
|
||||
}
|
||||
notify(NOTICE)<<"Notice: invalid MaterialFace passed to Material::getShininess()."<<endl;
|
||||
return _shininessFront;
|
||||
}
|
||||
|
||||
|
||||
bool Material::matchFaceAndColor(Input& fr,const char* name,MaterialFace& mf,Vec4& color)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr[0].matchWord(name))
|
||||
{
|
||||
int fr_inc = 1;
|
||||
if (fr[1].matchWord("FRONT"))
|
||||
{
|
||||
mf = FACE_FRONT;
|
||||
++fr_inc;
|
||||
}
|
||||
else if (fr[1].matchWord("BACK"))
|
||||
{
|
||||
mf = FACE_BACK;
|
||||
++fr_inc;
|
||||
}
|
||||
|
||||
if (fr[fr_inc].getFloat(color[0]) && fr[fr_inc+1].getFloat(color[1]) && fr[fr_inc+2].getFloat(color[2]))
|
||||
{
|
||||
fr_inc += 3;
|
||||
|
||||
if (fr[fr_inc].getFloat(color[3])) ++fr_inc;
|
||||
else color[3] = 1.0f;
|
||||
|
||||
fr+=fr_inc;
|
||||
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Material::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
Vec4 data(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
MaterialFace mf = FACE_FRONT_AND_BACK;
|
||||
|
||||
if (fr[0].matchWord("ColorMode"))
|
||||
{
|
||||
if (fr[1].matchWord("AMBIENT"))
|
||||
{
|
||||
setColorMode(AMBIENT);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("DIFFUSE"))
|
||||
{
|
||||
setColorMode(DIFFUSE);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("SPECULAR"))
|
||||
{
|
||||
setColorMode(SPECULAR);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("EMISSION"))
|
||||
{
|
||||
setColorMode(EMISSION);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("AMBIENT_AND_DIFFUSE"))
|
||||
{
|
||||
setColorMode(AMBIENT_AND_DIFFUSE);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
else if (fr[1].matchWord("OFF"))
|
||||
{
|
||||
setColorMode(OFF);
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (matchFaceAndColor(fr,"ambientColor",mf,data))
|
||||
{
|
||||
setAmbient(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (matchFaceAndColor(fr,"diffuseColor",mf,data))
|
||||
{
|
||||
setDiffuse(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (matchFaceAndColor(fr,"specularColor",mf,data))
|
||||
{
|
||||
setSpecular(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (matchFaceAndColor(fr,"emissionColor",mf,data))
|
||||
{
|
||||
setEmission(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (matchFaceAndColor(fr,"ambientColor",mf,data))
|
||||
{
|
||||
setAmbient(mf,data);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
float shininess = 0.0f;
|
||||
if (fr[0].matchWord("shininess"))
|
||||
{
|
||||
|
||||
mf = FACE_FRONT_AND_BACK;
|
||||
int fr_inc = 1;
|
||||
|
||||
if (fr[1].matchWord("FRONT"))
|
||||
{
|
||||
mf = FACE_FRONT;
|
||||
++fr_inc;
|
||||
}
|
||||
else if (fr[1].matchWord("BACK"))
|
||||
{
|
||||
mf = FACE_BACK;
|
||||
++fr_inc;
|
||||
}
|
||||
|
||||
if (fr[fr_inc].getFloat(shininess))
|
||||
{
|
||||
fr+=(fr_inc+1);
|
||||
setShininess(mf,shininess);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float transparency = 0.0f;
|
||||
if (fr[0].matchWord("transparency") && fr[1].getFloat(transparency))
|
||||
{
|
||||
|
||||
_ambientFront[3] = 1.0f-transparency;
|
||||
_diffuseFront[3] = 1.0f-transparency;
|
||||
_specularFront[3] = 1.0f-transparency;
|
||||
_emissionFront[3] = 1.0f-transparency;
|
||||
|
||||
_ambientBack[3] = 1.0f-transparency;
|
||||
_diffuseBack[3] = 1.0f-transparency;
|
||||
_specularBack[3] = 1.0f-transparency;
|
||||
_emissionBack[3] = 1.0f-transparency;
|
||||
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Material::writeLocalData(Output& fw)
|
||||
{
|
||||
switch(_colorMode)
|
||||
{
|
||||
case(AMBIENT): fw.indent() << "ColorMode AMBIENT" << endl; break;
|
||||
case(DIFFUSE): fw.indent() << "ColorMode DIFFUSE" << endl; break;
|
||||
case(SPECULAR): fw.indent() << "ColorMode SPECULAR" << endl; break;
|
||||
case(EMISSION): fw.indent() << "ColorMode EMISSION" << endl; break;
|
||||
case(AMBIENT_AND_DIFFUSE): fw.indent() << "ColorMode AMBIENT_AND_DIFFUSE" << endl; break;
|
||||
case(OFF): fw.indent() << "ColorMode OFF" << endl; break;
|
||||
}
|
||||
|
||||
if (_ambientFrontAndBack)
|
||||
{
|
||||
fw.indent() << "ambientColor " << _ambientFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "ambientColor FRONT " << _ambientFront << endl;
|
||||
fw.indent() << "ambientColor BACK " << _ambientBack << endl;
|
||||
}
|
||||
|
||||
if (_diffuseFrontAndBack)
|
||||
{
|
||||
fw.indent() << "diffuseColor " << _diffuseFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "diffuseColor FRONT " << _diffuseFront << endl;
|
||||
fw.indent() << "diffuseColor BACK " << _diffuseBack << endl;
|
||||
}
|
||||
|
||||
if (_specularFrontAndBack)
|
||||
{
|
||||
fw.indent() << "specularColor " << _specularFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "specularColor FRONT " << _specularFront << endl;
|
||||
fw.indent() << "specularColor BACK " << _specularBack << endl;
|
||||
}
|
||||
|
||||
if (_emissionFrontAndBack)
|
||||
{
|
||||
fw.indent() << "emissionColor " << _emissionFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "emissionColor FRONT " << _emissionFront << endl;
|
||||
fw.indent() << "emissionColor BACK " << _emissionBack << endl;
|
||||
}
|
||||
|
||||
if (_shininessFrontAndBack)
|
||||
{
|
||||
fw.indent() << "shininess " << _shininessFront << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "shininess FRONT " << _shininessFront << endl;
|
||||
fw.indent() << "shininess BACK " << _shininessBack << endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void Material::apply( void )
|
||||
{
|
||||
if (_colorMode==OFF)
|
||||
{
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glColorMaterial(GL_FRONT_AND_BACK,(GLenum)_colorMode);
|
||||
switch(_colorMode) {
|
||||
case(AMBIENT): glColor4fv(_ambientFront.ptr()); break;
|
||||
case(DIFFUSE): glColor4fv(_diffuseFront.ptr()); break;
|
||||
case(SPECULAR): glColor4fv(_specularFront.ptr()); break;
|
||||
case(EMISSION): glColor4fv(_emissionFront.ptr()); break;
|
||||
case(AMBIENT_AND_DIFFUSE): glColor4fv(_diffuseFront.ptr()); break;
|
||||
case(OFF): break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_colorMode!=AMBIENT && _colorMode!=AMBIENT_AND_DIFFUSE)
|
||||
{
|
||||
if (_ambientFrontAndBack)
|
||||
{
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, _ambientFront.ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialfv( GL_FRONT, GL_AMBIENT, _ambientFront.ptr() );
|
||||
glMaterialfv( GL_BACK, GL_AMBIENT, _ambientBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
if (_colorMode!=DIFFUSE && _colorMode!=AMBIENT_AND_DIFFUSE)
|
||||
{
|
||||
if (_diffuseFrontAndBack)
|
||||
{
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, _diffuseFront.ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialfv( GL_FRONT, GL_DIFFUSE, _diffuseFront.ptr() );
|
||||
glMaterialfv( GL_BACK, GL_DIFFUSE, _diffuseBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
if (_colorMode!=SPECULAR)
|
||||
{
|
||||
if (_specularFrontAndBack)
|
||||
{
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, _specularFront.ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialfv( GL_FRONT, GL_SPECULAR, _specularFront.ptr() );
|
||||
glMaterialfv( GL_BACK, GL_SPECULAR, _specularBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
if (_colorMode!=EMISSION)
|
||||
{
|
||||
if (_emissionFrontAndBack)
|
||||
{
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, _emissionFront.ptr() );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialfv( GL_FRONT, GL_EMISSION, _emissionFront.ptr() );
|
||||
glMaterialfv( GL_BACK, GL_EMISSION, _emissionBack.ptr() );
|
||||
}
|
||||
}
|
||||
|
||||
if (_shininessFrontAndBack)
|
||||
{
|
||||
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, _shininessFront* 128.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
glMaterialf( GL_FRONT, GL_SHININESS, _shininessFront* 128.0f );
|
||||
glMaterialf( GL_BACK, GL_SHININESS, _shininessBack* 128.0f );
|
||||
}
|
||||
|
||||
}
|
||||
512
src/osg/Matrix.cpp
Normal file
512
src/osg/Matrix.cpp
Normal file
@@ -0,0 +1,512 @@
|
||||
#include <math.h>
|
||||
#include "osg/Matrix"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
|
||||
using namespace osg;
|
||||
|
||||
typedef struct quaternion_
|
||||
{
|
||||
double x ;
|
||||
double y ;
|
||||
double z ;
|
||||
double w ;
|
||||
} quaternion ;
|
||||
|
||||
/* C = a(row).b(row) */
|
||||
|
||||
#define matrix_inner_product( a, b, row, col, C ) \
|
||||
{ \
|
||||
(C)[row][col] = (a)[row][0] * (b)[0][col] + \
|
||||
(a)[row][1] * (b)[1][col] + \
|
||||
(a)[row][2] * (b)[2][col] + \
|
||||
(a)[row][3] * (b)[3][col]; \
|
||||
}
|
||||
|
||||
/* C = a.b */
|
||||
|
||||
#define matrix_mult( a, b, C ) \
|
||||
{ \
|
||||
matrix_inner_product( a, b, 0, 0, C ); \
|
||||
matrix_inner_product( a, b, 0, 1, C ); \
|
||||
matrix_inner_product( a, b, 0, 2, C ); \
|
||||
matrix_inner_product( a, b, 0, 3, C ); \
|
||||
matrix_inner_product( a, b, 1, 0, C ); \
|
||||
matrix_inner_product( a, b, 1, 1, C ); \
|
||||
matrix_inner_product( a, b, 1, 2, C ); \
|
||||
matrix_inner_product( a, b, 1, 3, C ); \
|
||||
matrix_inner_product( a, b, 2, 0, C ); \
|
||||
matrix_inner_product( a, b, 2, 1, C ); \
|
||||
matrix_inner_product( a, b, 2, 2, C ); \
|
||||
matrix_inner_product( a, b, 2, 3, C ); \
|
||||
matrix_inner_product( a, b, 3, 0, C ); \
|
||||
matrix_inner_product( a, b, 3, 1, C ); \
|
||||
matrix_inner_product( a, b, 3, 2, C ); \
|
||||
matrix_inner_product( a, b, 3, 3, C ); \
|
||||
}
|
||||
|
||||
static void quaternion_matrix( quaternion *q, double mat[4][4] )
|
||||
{
|
||||
/* copied from Shoemake/ACM SIGGRAPH 89 */
|
||||
double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz ;
|
||||
|
||||
xs = q->x + q->x;
|
||||
ys = q->y + q->y;
|
||||
zs = q->z + q->z;
|
||||
|
||||
wx = q->w * xs ; wy = q->w * ys ; wz = q->w * zs ;
|
||||
xx = q->x * xs ; xy = q->x * ys ; xz = q->x * zs ;
|
||||
yy = q->y * ys ; yz = q->y * zs ; zz = q->z * zs ;
|
||||
|
||||
mat[0][0] = 1.0 - ( yy + zz ) ;
|
||||
mat[0][1] = xy - wz ;
|
||||
mat[0][2] = xz + wy ;
|
||||
mat[1][0] = xy + wz ;
|
||||
mat[1][1] = 1.0 - ( xx + zz ) ;
|
||||
mat[1][2] = yz - wx ;
|
||||
mat[2][0] = xz - wy ;
|
||||
mat[2][1] = yz + wx ;
|
||||
mat[2][2] = 1.0 - ( xx + yy ) ;
|
||||
|
||||
mat[0][3] = 0.0;
|
||||
mat[1][3] = 0.0;
|
||||
mat[2][3] = 0.0;
|
||||
|
||||
mat[3][0] = 0.0;
|
||||
mat[3][1] = 0.0;
|
||||
mat[3][2] = 0.0;
|
||||
mat[3][3] = 1.0;
|
||||
}
|
||||
|
||||
|
||||
Matrix::Matrix()
|
||||
{
|
||||
makeIdent();
|
||||
}
|
||||
|
||||
|
||||
Matrix::Matrix(const Matrix& matrix) : Object()
|
||||
{
|
||||
memcpy(_mat,matrix._mat,sizeof(_mat));
|
||||
}
|
||||
|
||||
|
||||
Matrix& Matrix::operator = (const Matrix& matrix)
|
||||
{
|
||||
if (&matrix==this) return *this;
|
||||
memcpy(_mat,matrix._mat,sizeof(_mat));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Matrix::Matrix(
|
||||
float a00, float a01, float a02, float a03,
|
||||
float a10, float a11, float a12, float a13,
|
||||
float a20, float a21, float a22, float a23,
|
||||
float a30, float a31, float a32, float a33)
|
||||
{
|
||||
_mat[0][0] = a00;
|
||||
_mat[0][1] = a01;
|
||||
_mat[0][2] = a02;
|
||||
_mat[0][3] = a03;
|
||||
|
||||
_mat[1][0] = a10;
|
||||
_mat[1][1] = a11;
|
||||
_mat[1][2] = a12;
|
||||
_mat[1][3] = a13;
|
||||
|
||||
_mat[2][0] = a20;
|
||||
_mat[2][1] = a21;
|
||||
_mat[2][2] = a22;
|
||||
_mat[2][3] = a23;
|
||||
|
||||
_mat[3][0] = a30;
|
||||
_mat[3][1] = a31;
|
||||
_mat[3][2] = a32;
|
||||
_mat[3][3] = a33;
|
||||
}
|
||||
|
||||
|
||||
Matrix::~Matrix()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Matrix* Matrix::instance()
|
||||
{
|
||||
static ref_ptr<Matrix> s_matrix(new Matrix());
|
||||
return s_matrix.get();
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
bool matched = true;
|
||||
for(int k=0;k<16 && matched;++k)
|
||||
{
|
||||
matched = fr[k].isFloat();
|
||||
}
|
||||
if (matched)
|
||||
{
|
||||
int k=0;
|
||||
for(int i=0;i<4;++i)
|
||||
{
|
||||
for(int j=0;j<4;++j)
|
||||
{
|
||||
fr[k].getFloat(_mat[i][j]);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
fr += 16;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << _mat[0][0] << " " << _mat[0][1] << " " << _mat[0][2] << " " << _mat[0][3] << endl;
|
||||
fw.indent() << _mat[1][0] << " " << _mat[1][1] << " " << _mat[1][2] << " " << _mat[1][3] << endl;
|
||||
fw.indent() << _mat[2][0] << " " << _mat[2][1] << " " << _mat[2][2] << " " << _mat[2][3] << endl;
|
||||
fw.indent() << _mat[3][0] << " " << _mat[3][1] << " " << _mat[3][2] << " " << _mat[3][3] << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::makeIdent()
|
||||
{
|
||||
_mat[0][0] = 1.0f;
|
||||
_mat[0][1] = 0.0f;
|
||||
_mat[0][2] = 0.0f;
|
||||
_mat[0][3] = 0.0f;
|
||||
|
||||
_mat[1][0] = 0.0f;
|
||||
_mat[1][1] = 1.0f;
|
||||
_mat[1][2] = 0.0f;
|
||||
_mat[1][3] = 0.0f;
|
||||
|
||||
_mat[2][0] = 0.0f;
|
||||
_mat[2][1] = 0.0f;
|
||||
_mat[2][2] = 1.0f;
|
||||
_mat[2][3] = 0.0f;
|
||||
|
||||
_mat[3][0] = 0.0f;
|
||||
_mat[3][1] = 0.0f;
|
||||
_mat[3][2] = 0.0f;
|
||||
_mat[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
void Matrix::copy(const Matrix& matrix)
|
||||
{
|
||||
memcpy(_mat,matrix._mat,sizeof(_mat));
|
||||
}
|
||||
|
||||
void Matrix::makeScale(float sx, float sy, float sz)
|
||||
{
|
||||
makeIdent();
|
||||
_mat[0][0] = sx;
|
||||
_mat[1][1] = sy;
|
||||
_mat[2][2] = sz;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preScale( float sx, float sy, float sz, const Matrix& m )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeScale(sx, sy, sz);
|
||||
mult(transMat,m);
|
||||
}
|
||||
|
||||
void Matrix::postScale( const Matrix& m, float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeScale(sx, sy, sz);
|
||||
mult(m,transMat);
|
||||
}
|
||||
|
||||
void Matrix::preScale( float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeScale(sx, sy, sz);
|
||||
preMult(transMat);
|
||||
}
|
||||
|
||||
void Matrix::postScale( float sx, float sy, float sz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeScale(sx, sy, sz);
|
||||
postMult(transMat);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Matrix::makeTrans( float tx, float ty, float tz )
|
||||
{
|
||||
makeIdent();
|
||||
_mat[3][0] = tx;
|
||||
_mat[3][1] = ty;
|
||||
_mat[3][2] = tz;
|
||||
}
|
||||
|
||||
void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeTrans(tx, ty, tz);
|
||||
mult(transMat,m);
|
||||
}
|
||||
|
||||
void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeTrans(tx, ty, tz);
|
||||
mult(m,transMat);
|
||||
}
|
||||
|
||||
void Matrix::preTrans( float tx, float ty, float tz )
|
||||
{
|
||||
_mat[3][0] = (tx * _mat[0][0]) + (ty * _mat[1][0]) + (tz * _mat[2][0]) + _mat[3][0];
|
||||
_mat[3][1] = (tx * _mat[0][1]) + (ty * _mat[1][1]) + (tz * _mat[2][1]) + _mat[3][1];
|
||||
_mat[3][2] = (tx * _mat[0][2]) + (ty * _mat[1][2]) + (tz * _mat[2][2]) + _mat[3][2];
|
||||
_mat[3][3] = (tx * _mat[0][3]) + (ty * _mat[1][3]) + (tz * _mat[2][3]) + _mat[3][3];
|
||||
}
|
||||
|
||||
void Matrix::postTrans( float tx, float ty, float tz )
|
||||
{
|
||||
Matrix transMat;
|
||||
transMat.makeTrans(tx, ty, tz);
|
||||
postMult(transMat);
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float deg, float x, float y, float z )
|
||||
{
|
||||
double __mat[4][4];
|
||||
quaternion q;
|
||||
float d = sqrtf( square(x) + square(y) + square(z) );
|
||||
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
|
||||
float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
|
||||
|
||||
q.x = sin_HalfAngle * (x/d);
|
||||
q.y = sin_HalfAngle * (y/d);
|
||||
q.z = sin_HalfAngle * (z/d);
|
||||
q.w = cos_HalfAngle;
|
||||
|
||||
quaternion_matrix( &q, __mat );
|
||||
|
||||
for(int i=0;i<4;++i)
|
||||
{
|
||||
for(int j=0;j<4;++j)
|
||||
{
|
||||
_mat[i][j]=__mat[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m )
|
||||
{
|
||||
Matrix rotMat;
|
||||
rotMat.makeRot( deg, x, y, z );
|
||||
mult(rotMat,m);
|
||||
}
|
||||
|
||||
void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z )
|
||||
{
|
||||
Matrix rotMat;
|
||||
rotMat.makeRot( deg, x, y, z );
|
||||
mult(m,rotMat);
|
||||
}
|
||||
|
||||
void Matrix::preRot( float deg, float x, float y, float z )
|
||||
{
|
||||
quaternion q;
|
||||
double __mat[4][4];
|
||||
float res_mat[4][4];
|
||||
|
||||
float d = sqrtf( square(x) + square(y) + square(z) );
|
||||
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
|
||||
float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
|
||||
|
||||
q.x = sin_HalfAngle * (x/d);
|
||||
q.y = sin_HalfAngle * (y/d);
|
||||
q.z = sin_HalfAngle * (z/d);
|
||||
q.w = cos_HalfAngle;
|
||||
|
||||
quaternion_matrix( &q, __mat );
|
||||
matrix_mult( __mat, _mat, res_mat );
|
||||
memcpy( _mat, res_mat, sizeof( _mat ) );
|
||||
}
|
||||
|
||||
void Matrix::postRot( float deg, float x, float y, float z )
|
||||
{
|
||||
quaternion q;
|
||||
double __mat[4][4];
|
||||
float res_mat[4][4];
|
||||
|
||||
float d = sqrtf( square(x) + square(y) + square(z) );
|
||||
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
float sin_HalfAngle = sinf( DEG2RAD(deg/2) );
|
||||
float cos_HalfAngle = cosf( DEG2RAD(deg/2) );
|
||||
|
||||
q.x = sin_HalfAngle * (x/d);
|
||||
q.y = sin_HalfAngle * (y/d);
|
||||
q.z = sin_HalfAngle * (z/d);
|
||||
q.w = cos_HalfAngle;
|
||||
|
||||
quaternion_matrix( &q, __mat );
|
||||
matrix_mult( _mat, __mat , res_mat );
|
||||
memcpy( _mat, res_mat, sizeof( _mat ) );
|
||||
}
|
||||
|
||||
void Matrix::setTrans( float tx, float ty, float tz )
|
||||
{
|
||||
_mat[3][0] = tx;
|
||||
_mat[3][1] = ty;
|
||||
_mat[3][2] = tz;
|
||||
}
|
||||
void Matrix::setTrans( const Vec3& v )
|
||||
{
|
||||
_mat[3][0] = v[0];
|
||||
_mat[3][1] = v[1];
|
||||
_mat[3][2] = v[2];
|
||||
}
|
||||
|
||||
void Matrix::preMult(const Matrix& m)
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( m._mat, _mat, tm._mat );
|
||||
*this = tm;
|
||||
}
|
||||
|
||||
void Matrix::postMult(const Matrix& m)
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( _mat, m._mat, tm._mat );
|
||||
*this = tm;
|
||||
}
|
||||
|
||||
void Matrix::mult(const Matrix& lhs,const Matrix& rhs)
|
||||
{
|
||||
matrix_mult( lhs._mat, rhs._mat, _mat );
|
||||
}
|
||||
|
||||
Matrix Matrix::operator * (const Matrix& m) const
|
||||
{
|
||||
Matrix nm;
|
||||
matrix_mult( _mat,m._mat, nm._mat );
|
||||
return nm;
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::invert(const Matrix& _m)
|
||||
{
|
||||
// code lifted from VR Juggler.
|
||||
// not cleanly added, but seems to work. RO.
|
||||
|
||||
const float* a = reinterpret_cast<const float*>(_m._mat);
|
||||
float* b = reinterpret_cast<float*>(_mat);
|
||||
|
||||
int n = 4;
|
||||
int i, j, k;
|
||||
int r[ 4], c[ 4], row[ 4], col[ 4];
|
||||
float m[ 4][ 4*2], pivot, max_m, tmp_m, fac;
|
||||
|
||||
/* Initialization */
|
||||
for ( i = 0; i < n; i ++ )
|
||||
{
|
||||
r[ i] = c[ i] = 0;
|
||||
row[ i] = col[ i] = 0;
|
||||
}
|
||||
|
||||
/* Set working matrix */
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
for ( j = 0; j < n; j++ )
|
||||
{
|
||||
m[ i][ j] = a[ i * n + j];
|
||||
m[ i][ j + n] = ( i == j ) ? 1.0 : 0.0 ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Begin of loop */
|
||||
for ( k = 0; k < n; k++ )
|
||||
{
|
||||
/* Choosing the pivot */
|
||||
for ( i = 0, max_m = 0; i < n; i++ )
|
||||
{
|
||||
if ( row[ i] ) continue;
|
||||
for ( j = 0; j < n; j++ )
|
||||
{
|
||||
if ( col[ j] ) continue;
|
||||
tmp_m = fabs( m[ i][j]);
|
||||
if ( tmp_m > max_m)
|
||||
{
|
||||
max_m = tmp_m;
|
||||
r[ k] = i;
|
||||
c[ k] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
row[ r[k] ] = col[ c[k] ] = 1;
|
||||
pivot = m[ r[ k] ][ c[ k] ];
|
||||
|
||||
if ( fabs( pivot) <= 1e-20)
|
||||
{
|
||||
notify(WARN) << "*** pivot = %f in mat_inv. ***\n";
|
||||
//exit( 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Normalization */
|
||||
for ( j = 0; j < 2*n; j++ )
|
||||
{
|
||||
if ( j == c[ k] )
|
||||
m[ r[ k]][ j] = 1.0;
|
||||
else
|
||||
m[ r[ k]][ j] /=pivot;
|
||||
}
|
||||
|
||||
/* Reduction */
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
if ( i == r[ k] )
|
||||
continue;
|
||||
|
||||
for ( j=0, fac = m[ i][ c[k]];j < 2*n; j++ )
|
||||
{
|
||||
if ( j == c[ k] )
|
||||
m[ i][ j] =0.0;
|
||||
else
|
||||
m[ i][ j] -=fac * m[ r[k]][ j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign invers to a matrix */
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = 0; j < n; j++ )
|
||||
row[ i] = ( c[ j] == i ) ? r[j] : row[ i];
|
||||
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = 0; j < n; j++ )
|
||||
b[ i * n + j] = m[ row[ i]][j + n];
|
||||
|
||||
return true; // It worked
|
||||
}
|
||||
168
src/osg/Node.cpp
Normal file
168
src/osg/Node.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#include "osg/Node"
|
||||
#include "osg/Group"
|
||||
#include "osg/NodeVisitor"
|
||||
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include "osg/Registry"
|
||||
#include "osg/Notify"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Node> g_NodeProxy;
|
||||
|
||||
Node::Node()
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
_userData = NULL;
|
||||
_nodeMask = 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
if (_userData && _memoryAdapter.valid()) _memoryAdapter->decrementReference(_userData);
|
||||
}
|
||||
|
||||
|
||||
void Node::accept(NodeVisitor& nv)
|
||||
{
|
||||
nv.apply(*this);
|
||||
}
|
||||
|
||||
void Node::ascend(NodeVisitor& nv)
|
||||
{
|
||||
std::for_each(_parents.begin(),_parents.end(),NodeAcceptOp(nv));
|
||||
}
|
||||
|
||||
bool Node::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (Object::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
if (fr.matchSequence("name %s"))
|
||||
{
|
||||
_name = fr[1].takeStr();
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
// if (fr.matchSequence("user_data {"))
|
||||
// {
|
||||
// notify(DEBUG) << "Matched user_data {"<<endl;
|
||||
// int entry = fr[0].getNoNestedBrackets();
|
||||
// fr += 2;
|
||||
//
|
||||
// while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
// {
|
||||
// Object* object = fr.readObject();
|
||||
// if (object) setUserData(object);
|
||||
// notify(DEBUG) << "read "<<object<<endl;
|
||||
// ++fr;
|
||||
// }
|
||||
// iteratorAdvanced = true;
|
||||
// }
|
||||
|
||||
while (fr.matchSequence("description {"))
|
||||
{
|
||||
notify(DEBUG) << "Matched description {"<<endl;
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
fr += 2;
|
||||
|
||||
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
{
|
||||
_descriptions.push_back(fr[0].getStr());
|
||||
notify(DEBUG) << "read "<<_descriptions.back()<<endl;
|
||||
++fr;
|
||||
}
|
||||
iteratorAdvanced = true;
|
||||
|
||||
}
|
||||
|
||||
while (fr.matchSequence("description %s"))
|
||||
{
|
||||
notify(DEBUG) << "Matched description %s"<<endl;
|
||||
_descriptions.push_back(fr[1].getStr());
|
||||
notify(DEBUG) << "read "<<_descriptions.back()<<endl;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Node::writeLocalData(Output& fw)
|
||||
{
|
||||
Object::writeLocalData(fw);
|
||||
if (!_name.empty()) fw.indent() << "name "<<'"'<<_name<<'"'<<endl;
|
||||
|
||||
// if (_userData)
|
||||
// {
|
||||
// Object* object = dynamic_cast<Object*>(_userData);
|
||||
// if (object)
|
||||
// {
|
||||
// fw.indent() << "user_data {"<<endl;
|
||||
// fw.moveIn();
|
||||
// object->write(fw);
|
||||
// fw.moveOut();
|
||||
// fw.indent() << "}"<<endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!_descriptions.empty())
|
||||
{
|
||||
if (_descriptions.size()==1)
|
||||
{
|
||||
fw.indent() << "description "<<'"'<<_descriptions.front()<<'"'<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fw.indent() << "description {"<<endl;
|
||||
fw.moveIn();
|
||||
for(DescriptionList::iterator ditr=_descriptions.begin();
|
||||
ditr!=_descriptions.end();
|
||||
++ditr)
|
||||
{
|
||||
fw.indent() << '"'<<*ditr<<'"'<<endl;
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent() << "}"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Node::computeBound()
|
||||
{
|
||||
_bsphere.init();
|
||||
return false;
|
||||
}
|
||||
|
||||
const BoundingSphere& Node::getBound()
|
||||
{
|
||||
if(!_bsphere_computed) computeBound();
|
||||
return _bsphere;
|
||||
}
|
||||
|
||||
void Node::dirtyBound()
|
||||
{
|
||||
if (_bsphere_computed)
|
||||
{
|
||||
_bsphere_computed = false;
|
||||
|
||||
// dirty parent bounding sphere's to ensure that all are valid.
|
||||
for(ParentList::iterator itr=_parents.begin();
|
||||
itr!=_parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->dirtyBound();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
40
src/osg/NodeVisitor.cpp
Normal file
40
src/osg/NodeVisitor.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "osg/NodeVisitor"
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
NodeVisitor::NodeVisitor(TraversalMode tm)
|
||||
{
|
||||
_traverseVisitor = NULL;
|
||||
_traverseMode = tm;
|
||||
}
|
||||
|
||||
NodeVisitor::~NodeVisitor()
|
||||
{
|
||||
// if (_traverseVisitor) detach from _traverseVisitor;
|
||||
}
|
||||
|
||||
void NodeVisitor::setTraverseMode(TraversalMode mode)
|
||||
{
|
||||
if (_traverseMode==mode) return;
|
||||
if (mode==TRAVERSE_VISITOR)
|
||||
{
|
||||
if (_traverseVisitor==NULL) _traverseMode = TRAVERSE_NONE;
|
||||
else _traverseMode = TRAVERSE_VISITOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_traverseVisitor) _traverseVisitor=NULL;
|
||||
_traverseMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeVisitor::setTraverseVisitor(NodeVisitor* nv)
|
||||
{
|
||||
if (_traverseVisitor==nv) return;
|
||||
// if (_traverseVisitor) detach from _traverseVisitor;
|
||||
_traverseVisitor = nv;
|
||||
if (_traverseVisitor) _traverseMode = TRAVERSE_VISITOR;
|
||||
else _traverseMode = TRAVERSE_NONE;
|
||||
// attach to _traverseVisitor;
|
||||
}
|
||||
87
src/osg/Notify.cpp
Normal file
87
src/osg/Notify.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "osg/Notify"
|
||||
#include <string>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
int osg::NotifyInit::count_ = 0;
|
||||
NotifySeverity osg::g_NotifyLevel = osg::NOTICE;
|
||||
ofstream *osg::g_absorbStreamPtr = NULL;
|
||||
|
||||
void osg::setNotifyLevel(NotifySeverity severity)
|
||||
{
|
||||
g_NotifyLevel = severity;
|
||||
}
|
||||
|
||||
int osg::getNotifyLevel()
|
||||
{
|
||||
return g_NotifyLevel;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
ostream& osg::notify(NotifySeverity severity)
|
||||
{
|
||||
if (severity<=g_NotifyLevel || g_absorbStreamPtr==NULL)
|
||||
{
|
||||
if (severity<=osg::WARN) return cerr;
|
||||
else return cout;
|
||||
}
|
||||
return *g_absorbStreamPtr;
|
||||
}
|
||||
#endif
|
||||
|
||||
NotifyInit::NotifyInit()
|
||||
{
|
||||
if (count_++ == 0) {
|
||||
|
||||
// g_NotifyLevel
|
||||
// =============
|
||||
|
||||
g_NotifyLevel = osg::NOTICE; // Default value
|
||||
|
||||
char *OSGNOTIFYLEVEL=getenv("OSGNOTIFYLEVEL");
|
||||
if(OSGNOTIFYLEVEL){
|
||||
|
||||
std::string stringOSGNOTIFYLEVEL(OSGNOTIFYLEVEL);
|
||||
|
||||
// Convert to upper case
|
||||
for(std::string::iterator i=stringOSGNOTIFYLEVEL.begin();
|
||||
i!=stringOSGNOTIFYLEVEL.end();
|
||||
++i) *i=toupper(*i);
|
||||
|
||||
if(stringOSGNOTIFYLEVEL.find("ALWAYS")!=std::string::npos) g_NotifyLevel=osg::ALWAYS;
|
||||
else if(stringOSGNOTIFYLEVEL.find("FATAL")!=std::string::npos) g_NotifyLevel=osg::FATAL;
|
||||
else if(stringOSGNOTIFYLEVEL.find("WARN")!=std::string::npos) g_NotifyLevel=osg::WARN;
|
||||
else if(stringOSGNOTIFYLEVEL.find("NOTICE")!=std::string::npos) g_NotifyLevel=osg::NOTICE;
|
||||
else if(stringOSGNOTIFYLEVEL.find("INFO")!=std::string::npos) g_NotifyLevel=osg::INFO;
|
||||
else if(stringOSGNOTIFYLEVEL.find("DEBUG")!=std::string::npos) g_NotifyLevel=osg::DEBUG;
|
||||
else if(stringOSGNOTIFYLEVEL.find("FP_DEBUG")!=std::string::npos) g_NotifyLevel=osg::FP_DEBUG;
|
||||
|
||||
}
|
||||
|
||||
// g_absorbStreamPtr
|
||||
// =================
|
||||
|
||||
char *OSGNOTIFYABSORBFILE=getenv("OSGNOTIFYABSORBFILE");
|
||||
if (OSGNOTIFYABSORBFILE)
|
||||
{
|
||||
g_absorbStreamPtr=new ofstream(OSGNOTIFYABSORBFILE);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WIN32
|
||||
// What's the Windows equivalent of /dev/null?
|
||||
g_absorbStreamPtr=new ofstream("C:/Windows/Tmp/osg.log");
|
||||
#else
|
||||
g_absorbStreamPtr=new ofstream("/dev/null");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotifyInit::~NotifyInit()
|
||||
{
|
||||
if(--count_ == 0) {
|
||||
delete g_absorbStreamPtr;
|
||||
g_absorbStreamPtr=NULL;
|
||||
}
|
||||
}
|
||||
254
src/osg/OSG.cpp
Normal file
254
src/osg/OSG.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <Io.h>
|
||||
#include <Windows.h>
|
||||
#include <Winbase.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "osg/Notify"
|
||||
#include "osg/OSG"
|
||||
#include "osg/Node"
|
||||
#include "osg/Geode"
|
||||
#include "osg/Group"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#ifdef WIN32
|
||||
char *PathDelimitor = ";";
|
||||
static const char *s_default_file_path = ".;D:/OpenSceneGraph/Data;D:/OpenSceneGraph/Data/Images;D:/OpenSceneGraph/lib";
|
||||
//static char *s_filePath = (char *)s_default_file_path;
|
||||
static char *s_filePath = ".;";
|
||||
#else
|
||||
char *PathDelimitor = ":";
|
||||
static const char *s_default_file_path = ".:";
|
||||
#ifdef __sgi
|
||||
static const char *s_default_dso_path = "/usr/lib32/osgPlugins/";
|
||||
#else
|
||||
static const char *s_default_dso_path = "/usr/lib/osgPlugins/";
|
||||
#endif
|
||||
static char *s_filePath = ".:";
|
||||
//static char *s_filePath = s_default_file_path;
|
||||
#endif
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using std::vector;
|
||||
using std::find_if;
|
||||
|
||||
void osg::Init( void )
|
||||
{
|
||||
char *ptr;
|
||||
if( (ptr = getenv( "OSGFILEPATH" )) )
|
||||
{
|
||||
notify(DEBUG) << "osg::Init("<<ptr<<")"<<endl;
|
||||
SetFilePath( ptr );
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(DEBUG) << "osg::Init(NULL)"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void osg::SetFilePath( const char *_path )
|
||||
{
|
||||
char buff[1024];
|
||||
|
||||
notify(DEBUG) << "In osg::SetFilePath("<<_path<<")"<<endl;
|
||||
|
||||
buff[0] = 0;
|
||||
|
||||
/* notify(DEBUG) << "filePath " << s_filePath << endl;
|
||||
notify(DEBUG) << "defPath " << s_default_file_path << endl;
|
||||
notify(DEBUG) << "&filePath " << &s_filePath << endl;
|
||||
notify(DEBUG) << "&defPath " << &s_default_file_path << endl;
|
||||
*/
|
||||
if( s_filePath != s_default_file_path )
|
||||
{
|
||||
strcpy( buff, s_filePath );
|
||||
// delete s_filePath;
|
||||
}
|
||||
// if (strcmp(s_filePath, s_default_file_path) != 0)
|
||||
// {
|
||||
// strcpy( buff, s_filePath );
|
||||
// delete s_filePath;
|
||||
// }
|
||||
|
||||
strcat( buff, PathDelimitor );
|
||||
strcat( buff, _path );
|
||||
|
||||
s_filePath = strdup( buff );
|
||||
|
||||
notify(DEBUG) << "Out osg::SetFilePath("<<_path<<")"<<endl;
|
||||
}
|
||||
|
||||
|
||||
static char *FindFileInPath( const char *_file, const char * filePath )
|
||||
{
|
||||
char pathbuff[1024];
|
||||
char *tptr, *tmppath;
|
||||
char *path = 0L;
|
||||
|
||||
notify(DEBUG) << "FindFileInPath() : trying " << _file << " ...\n";
|
||||
#ifdef WIN32
|
||||
if( _access( _file, 4 ) == 0 ) return (char *)_file;
|
||||
#else
|
||||
if( access( _file, F_OK ) == 0 ) return (char *)_file;
|
||||
#endif
|
||||
|
||||
tptr = strdup( filePath );
|
||||
tmppath = strtok( tptr, PathDelimitor );
|
||||
|
||||
do
|
||||
{
|
||||
sprintf( pathbuff, "%s/%s", tmppath, _file );
|
||||
notify(DEBUG) << "FindFileInPath() : trying " << pathbuff << " ...\n";
|
||||
#ifdef WIN32
|
||||
if( _access( pathbuff, 4 ) == 0 ) break;
|
||||
#else
|
||||
if( access( pathbuff, F_OK ) == 0 ) break;
|
||||
#endif
|
||||
} while( (tmppath = strtok( 0, PathDelimitor )) );
|
||||
|
||||
if( tmppath != (char *)0L )
|
||||
path = strdup( pathbuff );
|
||||
|
||||
::free(tptr);
|
||||
|
||||
notify( DEBUG ) << "FindFileInPath() : returning " << path << "\n";
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
char *osg::FindFile( const char *file )
|
||||
{
|
||||
return FindFileInPath( file, s_filePath );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Order of precedence for
|
||||
|
||||
./
|
||||
OSG_LD_LIBRARY_PATH
|
||||
s_default_dso_path
|
||||
LD_LIBRARY*_PATH
|
||||
|
||||
* DO NOT USE PATH or OSGFILEPATH
|
||||
*/
|
||||
|
||||
char *osg::findDSO( const char *name )
|
||||
{
|
||||
char path[1024];
|
||||
char *ptr;
|
||||
|
||||
strcpy( path, "./" );
|
||||
|
||||
if((ptr = getenv( "OSG_LD_LIBRARY_PATH" )))
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, s_default_dso_path );
|
||||
|
||||
#ifdef __sgi
|
||||
|
||||
// bloody mess see rld(1) man page
|
||||
# if (_MIPS_SIM == _MIPS_SIM_ABI32)
|
||||
|
||||
if( (ptr = getenv( "LD_LIBRARY_PATH" )))
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
|
||||
# elif (_MIPS_SIM == _MIPS_SIM_NABI32)
|
||||
|
||||
if( !(ptr = getenv( "LD_LIBRARYN32_PATH" )))
|
||||
ptr = getenv( "LD_LIBRARY_PATH" );
|
||||
|
||||
if( ptr )
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
|
||||
# elif (_MIPS_SIM == _MIPS_SIM_ABI64)
|
||||
|
||||
if( !(ptr = getenv( "LD_LIBRARYN32_PATH" )))
|
||||
ptr = getenv( "LD_LIBRARY_PATH" );
|
||||
|
||||
if( ptr )
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
#if 0 // DO NOT USE PATH or OSGFILEPATH
|
||||
# ifdef WIN32
|
||||
if ((ptr = getenv( "PATH" )))
|
||||
{
|
||||
notify(DEBUG) << "PATH = "<<ptr<<endl;
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
# else
|
||||
if( (ptr = getenv( "LD_LIBRARY_PATH" )))
|
||||
{
|
||||
strcat( path, PathDelimitor );
|
||||
strcat( path, ptr );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
// #ifdef __sgi
|
||||
// strcat( path, PathDelimitor );
|
||||
// strcat( path, "/usr/lib32/osgPlugins" );
|
||||
// #else
|
||||
// strcat( path, PathDelimitor );
|
||||
// strcat( path, "/usr/lib/osgPlugins" );
|
||||
// #endif
|
||||
|
||||
#endif
|
||||
|
||||
strcat( path ,PathDelimitor );
|
||||
strcat( path, s_filePath );
|
||||
|
||||
char* fileFound = NULL;
|
||||
fileFound = FindFileInPath( name , path );
|
||||
if (fileFound) return fileFound;
|
||||
|
||||
// now try prepending the filename with "osgPlugins/"
|
||||
char* prependosgPlugins = new char[strlen(name)+12];
|
||||
strcpy(prependosgPlugins,"osgPlugins/");
|
||||
strcat(prependosgPlugins,name);
|
||||
|
||||
fileFound = FindFileInPath( prependosgPlugins , path );
|
||||
|
||||
delete prependosgPlugins;
|
||||
|
||||
return fileFound;
|
||||
#endif
|
||||
|
||||
return FindFileInPath( name, path );
|
||||
}
|
||||
|
||||
|
||||
78
src/osg/Object.cpp
Normal file
78
src/osg/Object.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "osg/Object"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Object* Object::readClone(Input& fr)
|
||||
{
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString())
|
||||
{
|
||||
Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
|
||||
if (obj && isSameKindAs(obj))
|
||||
{
|
||||
fr+=2;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
if (!fr[0].matchWord(className()) ||
|
||||
!fr[1].isOpenBracket()) return NULL;
|
||||
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
|
||||
Object* obj = clone();
|
||||
|
||||
fr+=2;
|
||||
|
||||
while(!fr.eof() && fr[0].getNoNestedBrackets()>entry)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (fr[0].matchWord("UniqueID") && fr[1].isString()) {
|
||||
fr.regisiterUniqueIDForObject(fr[1].getStr(),obj);
|
||||
fr += 2;
|
||||
}
|
||||
if (obj->readLocalData(fr)) iteratorAdvanced = true;
|
||||
if (!iteratorAdvanced) ++fr;
|
||||
}
|
||||
++fr; // step over trailing '}'
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
bool Object::write(Output& fw)
|
||||
{
|
||||
if (_refCount>1) {
|
||||
std::string uniqueID;
|
||||
if (fw.getUniqueIDForObject(this,uniqueID)) {
|
||||
fw.indent() << "Use " << uniqueID << endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fw.indent() << className() << " {"<<endl;
|
||||
|
||||
fw.moveIn();
|
||||
|
||||
if (_refCount>1) {
|
||||
std::string uniqueID;
|
||||
fw.createUniqueIDForObject(this,uniqueID);
|
||||
fw.registerUniqueIDForObject(this,uniqueID);
|
||||
fw.indent() << "UniqueID " << uniqueID << endl;
|
||||
}
|
||||
|
||||
writeLocalData(fw);
|
||||
|
||||
fw.moveOut();
|
||||
|
||||
fw.indent() << "}"<<endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
75
src/osg/Output.cpp
Normal file
75
src/osg/Output.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "osg/Output"
|
||||
#include "osg/Object"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Output::Output()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
Output::~Output()
|
||||
{
|
||||
_free();
|
||||
}
|
||||
|
||||
void Output::_init()
|
||||
{
|
||||
_indent = 0;
|
||||
_indentStep = 2;
|
||||
_numIndicesPerLine = 10;
|
||||
}
|
||||
|
||||
|
||||
void Output::_free()
|
||||
{
|
||||
// should I be calling ofstream's free as well???
|
||||
}
|
||||
|
||||
|
||||
Output& Output::indent()
|
||||
{
|
||||
for(int i=0;i<_indent;++i) *this<<' ';
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Output::moveIn()
|
||||
{
|
||||
_indent += _indentStep;
|
||||
}
|
||||
|
||||
|
||||
void Output::moveOut()
|
||||
{
|
||||
_indent -= _indentStep;
|
||||
if (_indent<0) _indent=0;
|
||||
}
|
||||
|
||||
bool Output::getUniqueIDForObject(Object* obj,std::string& uniqueID)
|
||||
{
|
||||
UniqueIDToLabelMapping::iterator fitr = _objectToUniqueIDMap.find(obj);
|
||||
if (fitr != _objectToUniqueIDMap.end())
|
||||
{
|
||||
uniqueID = (*fitr).second;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool Output::createUniqueIDForObject(Object* obj,std::string& uniqueID)
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str,"%s_%i",obj->className(),_objectToUniqueIDMap.size());
|
||||
uniqueID = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Output::registerUniqueIDForObject(Object* obj,std::string& uniqueID)
|
||||
{
|
||||
_objectToUniqueIDMap[obj] = uniqueID;
|
||||
return true;
|
||||
}
|
||||
|
||||
178
src/osg/Point.cpp
Normal file
178
src/osg/Point.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
// Ideas and code borrowed from GLUT pointburst demo
|
||||
// written by Mark J. Kilgard
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "osg/GL"
|
||||
#include "osg/Point"
|
||||
#include "osg/ExtensionSupported"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#if defined(GL_SGIS_point_parameters) && !defined(GL_EXT_point_parameters)
|
||||
/* Use the EXT point parameters interface for the SGIS implementation. */
|
||||
# define GL_POINT_SIZE_MIN_EXT GL_POINT_SIZE_MIN_SGIS
|
||||
# define GL_POINT_SIZE_MAX_EXT GL_POINT_SIZE_MAX_SGIS
|
||||
# define GL_POINT_FADE_THRESHOLD_SIZE_EXT GL_POINT_FADE_THRESHOLD_SIZE_SGIS
|
||||
# define GL_DISTANCE_ATTENUATION_EXT GL_DISTANCE_ATTENUATION_SGIS
|
||||
# define glPointParameterfEXT glPointParameterfSGIS
|
||||
# define glPointParameterfvEXT glPointParameterfvSGIS
|
||||
# define GL_EXT_point_parameters 1
|
||||
#endif
|
||||
|
||||
#if !defined(GL_EXT_point_parameters)
|
||||
# define GL_POINT_SIZE_MIN_EXT 0x8126
|
||||
# define GL_POINT_SIZE_MAX_EXT 0x8127
|
||||
# define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
|
||||
# define GL_DISTANCE_ATTENUATION_EXT 0x8129
|
||||
# ifdef _WIN32
|
||||
// Curse Microsoft for the insanity of wglGetProcAddress.
|
||||
typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
|
||||
typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
|
||||
# define GL_EXT_point_parameters 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
PFNGLPOINTPARAMETERFEXTPROC glPointParameterfEXT;
|
||||
PFNGLPOINTPARAMETERFVEXTPROC glPointParameterfvEXT;
|
||||
#endif
|
||||
|
||||
static int s_hasPointParameters;
|
||||
|
||||
|
||||
Point::Point( void )
|
||||
{
|
||||
_size = 1.0f; // TODO find proper default
|
||||
_fadeThresholdSize = 1.0f; // TODO find proper default
|
||||
_distanceAttenuation = Vec3(0.0f, 1.0f/5.f, 0.0f); // TODO find proper default
|
||||
}
|
||||
|
||||
|
||||
Point::~Point( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Point* Point::instance()
|
||||
{
|
||||
static ref_ptr<Point> s_point(new Point);
|
||||
return s_point.get();
|
||||
}
|
||||
|
||||
|
||||
void Point::init_GL_EXT()
|
||||
{
|
||||
s_hasPointParameters =
|
||||
ExtensionSupported("GL_SGIS_point_parameters") ||
|
||||
ExtensionSupported("GL_EXT_point_parameters");
|
||||
#ifdef _WIN32
|
||||
if (s_hasPointParameters)
|
||||
{
|
||||
glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)
|
||||
wglGetProcAddress("glPointParameterfEXT");
|
||||
glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)
|
||||
wglGetProcAddress("glPointParameterfvEXT");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Point::enableSmooth( void )
|
||||
{
|
||||
glEnable( GL_POINT_SMOOTH );
|
||||
}
|
||||
|
||||
|
||||
void Point::disableSmooth( void )
|
||||
{
|
||||
glDisable( GL_POINT_SMOOTH );
|
||||
}
|
||||
|
||||
|
||||
void Point::setSize( float size )
|
||||
{
|
||||
_size = size;
|
||||
}
|
||||
|
||||
void Point::setFadeThresholdSize(float fadeThresholdSize)
|
||||
{
|
||||
_fadeThresholdSize = fadeThresholdSize;
|
||||
}
|
||||
|
||||
void Point::setDistanceAttenuation(const Vec3& distanceAttenuation)
|
||||
{
|
||||
_distanceAttenuation = distanceAttenuation;
|
||||
}
|
||||
|
||||
void Point::apply( void )
|
||||
{
|
||||
glPointSize(_size);
|
||||
|
||||
#if GL_EXT_point_parameters
|
||||
static bool s_gl_ext_init=false;
|
||||
|
||||
if (!s_gl_ext_init)
|
||||
{
|
||||
s_gl_ext_init = true;
|
||||
init_GL_EXT();
|
||||
}
|
||||
|
||||
if (s_hasPointParameters)
|
||||
{
|
||||
glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, (const GLfloat*)&_distanceAttenuation);
|
||||
glPointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, _fadeThresholdSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool Point::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
float data;
|
||||
if (fr[0].matchWord("size") && fr[1].getFloat(data))
|
||||
{
|
||||
|
||||
_size = data;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("fade_threshold_size") && fr[1].getFloat(data))
|
||||
{
|
||||
|
||||
_fadeThresholdSize = data;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
Vec3 distAtten;
|
||||
if (fr[0].matchWord("distance_attenuation") &&
|
||||
fr[1].getFloat(distAtten[0]) && fr[2].getFloat(distAtten[1]) && fr[3].getFloat(distAtten[2]))
|
||||
{
|
||||
|
||||
_distanceAttenuation = distAtten;
|
||||
fr+=4;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Point::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "size " << _size << endl;
|
||||
fw.indent() << "fade_threshold_size " << _fadeThresholdSize << endl;
|
||||
fw.indent() << "distance_attenuation " << _distanceAttenuation << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
85
src/osg/PolygonOffset.cpp
Normal file
85
src/osg/PolygonOffset.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/PolygonOffset"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
PolygonOffset::PolygonOffset( void )
|
||||
{
|
||||
_factor = 0.0f; // are these sensible defaut values?
|
||||
_units = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
PolygonOffset::~PolygonOffset( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PolygonOffset* PolygonOffset::instance()
|
||||
{
|
||||
static ref_ptr<PolygonOffset> s_PolygonOffset(new PolygonOffset);
|
||||
return s_PolygonOffset.get();
|
||||
}
|
||||
|
||||
void PolygonOffset::setOffset(float factor,float units)
|
||||
{
|
||||
_factor = factor;
|
||||
_units = units;
|
||||
}
|
||||
|
||||
void PolygonOffset::enable( void )
|
||||
{
|
||||
glEnable( GL_POLYGON_OFFSET_FILL);
|
||||
glEnable( GL_POLYGON_OFFSET_LINE);
|
||||
glEnable( GL_POLYGON_OFFSET_POINT);
|
||||
}
|
||||
|
||||
|
||||
void PolygonOffset::disable( void )
|
||||
{
|
||||
glDisable( GL_POLYGON_OFFSET_FILL);
|
||||
glDisable( GL_POLYGON_OFFSET_LINE);
|
||||
glDisable( GL_POLYGON_OFFSET_POINT);
|
||||
}
|
||||
|
||||
void PolygonOffset::apply( void )
|
||||
{
|
||||
glPolygonOffset(_factor,_units);
|
||||
}
|
||||
|
||||
bool PolygonOffset::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
float data;
|
||||
if (fr[0].matchWord("factor") && fr[1].getFloat(data))
|
||||
{
|
||||
|
||||
_factor = data;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("units") && fr[1].getFloat(data))
|
||||
{
|
||||
|
||||
_units = data;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool PolygonOffset::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "factor " << _factor << endl;
|
||||
fw.indent() << "units " << _units << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
272
src/osg/Quat.cpp
Normal file
272
src/osg/Quat.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
#include "osg/Quat"
|
||||
#include "osg/Vec4"
|
||||
#include "osg/Vec3"
|
||||
#include "osg/Types"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/// Good introductions to Quaternions at:
|
||||
/// http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
/// http://mathworld.wolfram.com/Quaternion.html
|
||||
|
||||
using namespace osg;
|
||||
|
||||
/// Default constructor is empty
|
||||
Quat::Quat( void )
|
||||
{
|
||||
}
|
||||
|
||||
/// Constructor with four floats - just call the constructor for the Vec4
|
||||
Quat::Quat( const float x, const float y, const float z, const float w )
|
||||
{
|
||||
_fv = Vec4( x, y, z, w );
|
||||
}
|
||||
|
||||
/// Constructor with a Vec4
|
||||
Quat::Quat( const Vec4& vec )
|
||||
{
|
||||
_fv = vec;
|
||||
}
|
||||
|
||||
/// Set the elements of the Quat to represent a rotation of angle
|
||||
/// (radians) around the axis (x,y,z)
|
||||
void Quat::makeRot( const float angle,
|
||||
const float x,
|
||||
const float y,
|
||||
const float z )
|
||||
{
|
||||
float inversenorm = 1.0/sqrt( x*x + y*y + z*z );
|
||||
float coshalfangle = cos( 0.5*angle );
|
||||
float sinhalfangle = sin( 0.5*angle );
|
||||
|
||||
_fv[0] = x * sinhalfangle * inversenorm;
|
||||
_fv[1] = y * sinhalfangle * inversenorm;
|
||||
_fv[2] = z * sinhalfangle * inversenorm;
|
||||
_fv[3] = coshalfangle;
|
||||
}
|
||||
|
||||
void Quat::makeRot( const float angle, const Vec3& vec )
|
||||
{
|
||||
makeRot( angle, vec[0], vec[1], vec[2] );
|
||||
}
|
||||
|
||||
// Make a rotation Quat which will rotate vec1 to vec2
|
||||
// Generally take adot product to get the angle between these
|
||||
// and then use a cross product to get the rotation axis
|
||||
// Watch out for the two special cases of when the vectors
|
||||
// are co-incident or opposite in direction.
|
||||
void Quat::makeRot( const Vec3& vec1, const Vec3& vec2 )
|
||||
{
|
||||
const float epsilon = 0.00001f;
|
||||
|
||||
float length1 = vec1.length();
|
||||
float length2 = vec2.length();
|
||||
float cosangle = vec1*vec2/(2*length1*length2); // dot product vec1*vec2
|
||||
|
||||
if ( fabs(cosangle - 1) < epsilon )
|
||||
{
|
||||
// cosangle is close to 1, so the vectors are close to being coincident
|
||||
// Need to generate an angle of zero with any vector we like
|
||||
// We'll choose (1,0,0)
|
||||
makeRot( 0.0, 1.0, 0.0, 0.0 );
|
||||
}
|
||||
else
|
||||
if ( fabs(cosangle + 1) < epsilon )
|
||||
{
|
||||
// cosangle is close to -1, so the vectors are close to being opposite
|
||||
// The angle of rotation is going to be Pi, but around which axis?
|
||||
// Basically, any one perpendicular to vec1 = (x,y,z) is going to work.
|
||||
// Choose a vector to cross product vec1 with. Find the biggest
|
||||
// in magnitude of x, y and z and then put a zero in that position.
|
||||
float biggest = fabs(vec1[0]); int bigposn = 0;
|
||||
if ( fabs(vec1[1]) > biggest ) { biggest=fabs(vec1[1]); bigposn = 1; }
|
||||
if ( fabs(vec1[2]) > biggest ) { biggest=fabs(vec1[2]); bigposn = 2; }
|
||||
Vec3 temp = Vec3( 1.0, 1.0, 1.0 );
|
||||
temp[bigposn] = 0.0;
|
||||
Vec3 axis = vec1^temp; // this is a cross-product to generate the
|
||||
// axis around which to rotate
|
||||
makeRot( (float)M_PI, axis );
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the usual situation - take a cross-product of vec1 and vec2
|
||||
// and that is the axis around which to rotate.
|
||||
Vec3 axis = vec1^vec2;
|
||||
float angle = acos( cosangle );
|
||||
makeRot( angle, axis );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get the angle of rotation and axis of this Quat object.
|
||||
// Won't give very meaningful results if the Quat is not associated
|
||||
// with a rotation!
|
||||
void Quat::getRot( float& angle, Vec3& vec ) const
|
||||
{
|
||||
float sinhalfangle = sqrt( _fv[0]*_fv[0] + _fv[1]*_fv[1] + _fv[2]*_fv[2] );
|
||||
/// float coshalfangle = _fv[3];
|
||||
|
||||
/// These are not checked for performance reasons ? (cop out!)
|
||||
/// Point for discussion - how do one handle errors in the osg?
|
||||
/// if ( abs(sinhalfangle) > 1.0 ) { error };
|
||||
/// if ( abs(coshalfangle) > 1.0 ) { error };
|
||||
|
||||
// *angle = atan2( sinhalfangle, coshalfangle ); // see man atan2
|
||||
angle = 2 * atan2( sinhalfangle, _fv[3] ); // -pi < angle < pi
|
||||
vec = Vec3(_fv[0], _fv[1], _fv[2]) / sinhalfangle;
|
||||
}
|
||||
|
||||
void Quat::getRot( float& angle, float& x, float& y, float& z ) const
|
||||
{
|
||||
float sinhalfangle = sqrt( _fv[0]*_fv[0] + _fv[1]*_fv[1] + _fv[2]*_fv[2] );
|
||||
|
||||
angle = 2 * atan2( sinhalfangle, _fv[3] );
|
||||
x = _fv[0] / sinhalfangle;
|
||||
y = _fv[1] / sinhalfangle;
|
||||
z = _fv[2] / sinhalfangle;
|
||||
}
|
||||
|
||||
|
||||
/// Spherical Linear Interpolation
|
||||
/// As t goes from 0 to 1, the Quat object goes from "from" to "to"
|
||||
/// Reference: Shoemake at SIGGRAPH 89
|
||||
/// See also
|
||||
/// http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
void Quat::slerp( const float t, const Quat& from, const Quat& to )
|
||||
{
|
||||
const double epsilon = 0.00001;
|
||||
double omega, cosomega, sinomega, scale_from, scale_to ;
|
||||
|
||||
cosomega = from.asVec4() * to.asVec4() ; // this is a dot product
|
||||
|
||||
if( (1.0 - cosomega) > epsilon )
|
||||
{
|
||||
omega= acos(cosomega) ; // 0 <= omega <= Pi (see man acos)
|
||||
sinomega = sin(omega) ; // this sinomega should always be +ve so
|
||||
// could try sinomega=sqrt(1-cosomega*cosomega) to avoid a sin()?
|
||||
scale_from = sin((1.0-t)*omega)/sinomega ;
|
||||
scale_to = sin(t*omega)/sinomega ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* --------------------------------------------------
|
||||
The ends of the vectors are very close
|
||||
we can use simple linear interpolation - no need
|
||||
to worry about the "spherical" interpolation
|
||||
-------------------------------------------------- */
|
||||
scale_from = 1.0 - t ;
|
||||
scale_to = t ;
|
||||
}
|
||||
|
||||
_fv = (from._fv*scale_from) + (to._fv*scale_to); // use Vec4 arithmetic
|
||||
// so that we get a Vec4
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define QX _fv[0]
|
||||
#define QY _fv[1]
|
||||
#define QZ _fv[2]
|
||||
#define QW _fv[3]
|
||||
|
||||
void Quat::set( const Matrix& m )
|
||||
{
|
||||
// Source: Gamasutra, Rotating Objects Using Quaternions
|
||||
//
|
||||
//http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
|
||||
float tr, s;
|
||||
float tq[4];
|
||||
int i, j, k;
|
||||
|
||||
int nxt[3] = {1, 2, 0};
|
||||
|
||||
tr = m._mat[0][0] + m._mat[1][1] + m._mat[2][2];
|
||||
|
||||
// check the diagonal
|
||||
if (tr > 0.0)
|
||||
{
|
||||
s = (float)sqrt (tr + 1.0);
|
||||
QW = s / 2.0f;
|
||||
s = 0.5f / s;
|
||||
QX = (m._mat[1][2] - m._mat[2][1]) * s;
|
||||
QY = (m._mat[2][0] - m._mat[0][2]) * s;
|
||||
QZ = (m._mat[0][1] - m._mat[1][0]) * s;
|
||||
}
|
||||
else
|
||||
{
|
||||
// diagonal is negative
|
||||
i = 0;
|
||||
if (m._mat[1][1] > m._mat[0][0])
|
||||
i = 1;
|
||||
if (m._mat[2][2] > m._mat[i][i])
|
||||
i = 2;
|
||||
j = nxt[i];
|
||||
k = nxt[j];
|
||||
|
||||
s = (float)sqrt ((m._mat[i][i] - (m._mat[j][j] + m._mat[k][k])) + 1.0);
|
||||
|
||||
tq[i] = s * 0.5f;
|
||||
|
||||
if (s != 0.0f)
|
||||
s = 0.5f / s;
|
||||
|
||||
tq[3] = (m._mat[j][k] - m._mat[k][j]) * s;
|
||||
tq[j] = (m._mat[i][j] + m._mat[j][i]) * s;
|
||||
tq[k] = (m._mat[i][k] + m._mat[k][i]) * s;
|
||||
|
||||
QX = tq[0];
|
||||
QY = tq[1];
|
||||
QZ = tq[2];
|
||||
QW = tq[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Quat::get( Matrix& m ) const
|
||||
{
|
||||
// Source: Gamasutra, Rotating Objects Using Quaternions
|
||||
//
|
||||
//http://www.gamasutra.com/features/programming/19980703/quaternions_01.htm
|
||||
|
||||
float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
|
||||
|
||||
// calculate coefficients
|
||||
x2 = QX + QX;
|
||||
y2 = QY + QY;
|
||||
z2 = QZ + QZ;
|
||||
|
||||
xx = QX * x2;
|
||||
xy = QX * y2;
|
||||
xz = QX * z2;
|
||||
|
||||
yy = QY * y2;
|
||||
yz = QY * z2;
|
||||
zz = QZ * z2;
|
||||
|
||||
wx = QW * x2;
|
||||
wy = QW * y2;
|
||||
wz = QW * z2;
|
||||
|
||||
m._mat[0][0] = 1.0f - (yy + zz);
|
||||
m._mat[0][1] = xy - wz;
|
||||
m._mat[0][2] = xz + wy;
|
||||
m._mat[0][3] = 0.0f;
|
||||
|
||||
m._mat[1][0] = xy + wz;
|
||||
m._mat[1][1] = 1.0f - (xx + zz);
|
||||
m._mat[1][2] = yz - wx;
|
||||
m._mat[1][3] = 0.0f;
|
||||
|
||||
m._mat[2][0] = xz - wy;
|
||||
m._mat[2][1] = yz + wx;
|
||||
m._mat[2][2] = 1.0f - (xx + yy);
|
||||
m._mat[2][3] = 0.0f;
|
||||
|
||||
m._mat[3][0] = 0;
|
||||
m._mat[3][1] = 0;
|
||||
m._mat[3][2] = 0;
|
||||
m._mat[3][3] = 1;
|
||||
}
|
||||
101
src/osg/ReaderWriterOSG.cpp
Normal file
101
src/osg/ReaderWriterOSG.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "osg/Registry"
|
||||
|
||||
#include "osg/Object"
|
||||
#include "osg/Image"
|
||||
#include "osg/Node"
|
||||
#include "osg/Group"
|
||||
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#ifdef __sgi
|
||||
using std::string;
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
class DefaultReaderWriter : public ReaderWriter
|
||||
{
|
||||
public:
|
||||
virtual const char* className() { return "Default OSG Reader/Writer"; }
|
||||
virtual bool acceptsExtension(const string& extension) { return extension=="osg" || extension=="OSG"; }
|
||||
|
||||
virtual Object* readObject(const string& fileName) { return readNode(fileName); }
|
||||
virtual Node* readNode(const string& fileName)
|
||||
{
|
||||
ifstream fin(fileName.c_str());
|
||||
if (fin)
|
||||
{
|
||||
Input fr;
|
||||
fr.attach(&fin);
|
||||
|
||||
Group* group = new Group;
|
||||
group->setName("import group");
|
||||
|
||||
// load all nodes in file, placing them in a group.
|
||||
while(!fr.eof())
|
||||
{
|
||||
Node *node = fr.readNode();
|
||||
if (node) group->addChild(node);
|
||||
else fr.advanceOverCurrentFieldOrBlock();
|
||||
}
|
||||
|
||||
if (group->getNumChildren()>1)
|
||||
{
|
||||
return group;
|
||||
}
|
||||
else if (group->getNumChildren()==1)
|
||||
{
|
||||
// only one node loaded so just return that one node,
|
||||
// and delete the redundent group. Note, the
|
||||
// child must be referenced before defrencing
|
||||
// the group so to avoid delete its children.
|
||||
Node* node = group->getChild(0);
|
||||
node->ref();
|
||||
group->unref();
|
||||
return node;
|
||||
} // group->getNumChildren()==0
|
||||
else
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool writeObject(Object& obj,const string& fileName)
|
||||
{
|
||||
Output fout;
|
||||
fout.open(fileName.c_str());
|
||||
if (fout)
|
||||
{
|
||||
obj.write(fout);
|
||||
fout.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool writeNode(Node& node,const string& fileName)
|
||||
{
|
||||
Output fout;
|
||||
fout.open(fileName.c_str());
|
||||
if (fout)
|
||||
{
|
||||
|
||||
node.write(fout);
|
||||
fout.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
RegisterReaderWriterProxy<DefaultReaderWriter> g_defaultReaderWriterProxy;
|
||||
380
src/osg/ReaderWriterRGB.cpp
Normal file
380
src/osg/ReaderWriterRGB.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
#include "osg/Image"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Notify"
|
||||
#include "osg/FileNameUtils"
|
||||
|
||||
#include "osg/Registry"
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/GeoSet>
|
||||
#include <osg/GeoState>
|
||||
#include <osg/Texture>
|
||||
|
||||
#include "osg/GL"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
using namespace osg;
|
||||
|
||||
typedef struct _rawImageRec
|
||||
{
|
||||
unsigned short imagic;
|
||||
unsigned short type;
|
||||
unsigned short dim;
|
||||
unsigned short sizeX, sizeY, sizeZ;
|
||||
unsigned long min, max;
|
||||
unsigned long wasteBytes;
|
||||
char name[80];
|
||||
unsigned long colorMap;
|
||||
FILE *file;
|
||||
unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
|
||||
unsigned long rleEnd;
|
||||
GLuint *rowStart;
|
||||
GLint *rowSize;
|
||||
} rawImageRec;
|
||||
|
||||
static void ConvertShort(unsigned short *array, long length)
|
||||
{
|
||||
unsigned long b1, b2;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = (unsigned char *)array;
|
||||
while (length--)
|
||||
{
|
||||
b1 = *ptr++;
|
||||
b2 = *ptr++;
|
||||
*array++ = (unsigned short) ((b1 << 8) | (b2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ConvertLong(GLuint *array, long length)
|
||||
{
|
||||
unsigned long b1, b2, b3, b4;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = (unsigned char *)array;
|
||||
while (length--)
|
||||
{
|
||||
b1 = *ptr++;
|
||||
b2 = *ptr++;
|
||||
b3 = *ptr++;
|
||||
b4 = *ptr++;
|
||||
*array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static rawImageRec *RawImageOpen(const char *fileName)
|
||||
{
|
||||
union
|
||||
{
|
||||
int testWord;
|
||||
char testByte[4];
|
||||
} endianTest;
|
||||
rawImageRec *raw;
|
||||
GLenum swapFlag;
|
||||
int x;
|
||||
|
||||
endianTest.testWord = 1;
|
||||
if (endianTest.testByte[0] == 1)
|
||||
{
|
||||
swapFlag = GL_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
swapFlag = GL_FALSE;
|
||||
}
|
||||
|
||||
raw = (rawImageRec *)malloc(sizeof(rawImageRec));
|
||||
if (raw == NULL)
|
||||
{
|
||||
notify(WARN)<< "Out of memory!"<<endl;
|
||||
return NULL;
|
||||
}
|
||||
if ((raw->file = fopen(fileName, "rb")) == NULL)
|
||||
{
|
||||
perror(fileName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fread(raw, 1, 12, raw->file);
|
||||
|
||||
if (swapFlag)
|
||||
{
|
||||
ConvertShort(&raw->imagic, 6);
|
||||
}
|
||||
|
||||
raw->tmp = raw->tmpR = raw->tmpG = raw->tmpB = raw->tmpA = 0L;
|
||||
|
||||
raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
|
||||
if (raw->tmp == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( raw->sizeZ >= 1 )
|
||||
{
|
||||
if( (raw->tmpR = (unsigned char *)malloc(raw->sizeX)) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
free( raw->tmp );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( raw->sizeZ >= 2 )
|
||||
{
|
||||
if( (raw->tmpG = (unsigned char *)malloc(raw->sizeX)) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
free( raw->tmp );
|
||||
free( raw->tmpR );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( raw->sizeZ >= 3 )
|
||||
{
|
||||
if( (raw->tmpB = (unsigned char *)malloc(raw->sizeX)) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
free( raw->tmp );
|
||||
free( raw->tmpR );
|
||||
free( raw->tmpG );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (raw->sizeZ >= 4)
|
||||
{
|
||||
if( (raw->tmpA = (unsigned char *)malloc(raw->sizeX)) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
free( raw->tmp );
|
||||
free( raw->tmpR );
|
||||
free( raw->tmpG );
|
||||
free( raw->tmpB );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((raw->type & 0xFF00) == 0x0100)
|
||||
{
|
||||
x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
|
||||
raw->rowStart = (GLuint *)malloc(x);
|
||||
raw->rowSize = (GLint *)malloc(x);
|
||||
if (raw->rowStart == NULL || raw->rowSize == NULL)
|
||||
{
|
||||
notify(FATAL)<< "Out of memory!"<<endl;
|
||||
return NULL;
|
||||
}
|
||||
raw->rleEnd = 512 + (2 * x);
|
||||
fseek(raw->file, 512, SEEK_SET);
|
||||
fread(raw->rowStart, 1, x, raw->file);
|
||||
fread(raw->rowSize, 1, x, raw->file);
|
||||
if (swapFlag)
|
||||
{
|
||||
ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
|
||||
ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
|
||||
}
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
||||
|
||||
static void RawImageClose(rawImageRec *raw)
|
||||
{
|
||||
fclose(raw->file);
|
||||
free(raw->tmp);
|
||||
if( raw->tmpR )
|
||||
free(raw->tmpR);
|
||||
if( raw->tmpG )
|
||||
free(raw->tmpG);
|
||||
if( raw->tmpB )
|
||||
free(raw->tmpB);
|
||||
if( raw->tmpA )
|
||||
free(raw->tmpA);
|
||||
|
||||
free(raw);
|
||||
}
|
||||
|
||||
|
||||
static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
|
||||
{
|
||||
unsigned char *iPtr, *oPtr, pixel;
|
||||
int count, done = 0;
|
||||
|
||||
if ((raw->type & 0xFF00) == 0x0100)
|
||||
{
|
||||
fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
|
||||
fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
|
||||
raw->file);
|
||||
|
||||
iPtr = raw->tmp;
|
||||
oPtr = buf;
|
||||
while (!done)
|
||||
{
|
||||
pixel = *iPtr++;
|
||||
count = (int)(pixel & 0x7F);
|
||||
if (!count)
|
||||
{
|
||||
done = 1;
|
||||
return;
|
||||
}
|
||||
if (pixel & 0x80)
|
||||
{
|
||||
while (count--)
|
||||
{
|
||||
*oPtr++ = *iPtr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel = *iPtr++;
|
||||
while (count--)
|
||||
{
|
||||
*oPtr++ = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
|
||||
SEEK_SET);
|
||||
fread(buf, 1, raw->sizeX, raw->file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void RawImageGetData(rawImageRec *raw, unsigned char **data )
|
||||
{
|
||||
unsigned char *ptr;
|
||||
int i, j;
|
||||
|
||||
// // round the width to a factor 4
|
||||
// int width = (int)(floorf((float)raw->sizeX/4.0f)*4.0f);
|
||||
// if (width!=raw->sizeX) width += 4;
|
||||
|
||||
*data = (unsigned char *)malloc(2 * (raw->sizeX+1)*(raw->sizeY+1)*4);
|
||||
// *data = (unsigned char *)malloc(2 * (width+1)*(raw->sizeY+1)*4);
|
||||
|
||||
ptr = *data;
|
||||
for (i = 0; i < (int)(raw->sizeY); i++)
|
||||
{
|
||||
if( raw->sizeZ >= 1 )
|
||||
RawImageGetRow(raw, raw->tmpR, i, 0);
|
||||
if( raw->sizeZ >= 2 )
|
||||
RawImageGetRow(raw, raw->tmpG, i, 1);
|
||||
if( raw->sizeZ >= 3 )
|
||||
RawImageGetRow(raw, raw->tmpB, i, 2);
|
||||
if( raw->sizeZ >= 4 )
|
||||
RawImageGetRow(raw, raw->tmpA, i, 3);
|
||||
for (j = 0; j < (int)(raw->sizeX); j++)
|
||||
{
|
||||
if( raw->sizeZ >= 1 )
|
||||
*ptr++ = *(raw->tmpR + j);
|
||||
if( raw->sizeZ >= 2 )
|
||||
*ptr++ = *(raw->tmpG + j);
|
||||
if( raw->sizeZ >= 3 )
|
||||
*ptr++ = *(raw->tmpB + j);
|
||||
if( raw->sizeZ >= 4 )
|
||||
*ptr++ = *(raw->tmpA + j);
|
||||
}
|
||||
// // pad the image width with blanks to bring it up to the rounded width.
|
||||
// for(;j<width;++j) *ptr++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ReaderWriterRGB : public ReaderWriter
|
||||
{
|
||||
public:
|
||||
virtual const char* className() { return "Default RGB Image Reader/Writer"; }
|
||||
virtual bool acceptsExtension(const std::string& extension)
|
||||
{
|
||||
return extension=="rgb" || extension=="rgba" ||
|
||||
extension=="int" || extension=="inta" ||
|
||||
extension=="bw";
|
||||
}
|
||||
|
||||
|
||||
virtual Node* readNode(const std::string& fileName)
|
||||
{
|
||||
Image* image = readImage(fileName);
|
||||
if (image)
|
||||
{
|
||||
Geode* geode = createGeodeForImage(image);
|
||||
if (geode==NULL) image->unref();
|
||||
return geode;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual Image* readImage(const std::string& fileName)
|
||||
{
|
||||
std::string ext = getLowerCaseFileExtension(fileName);
|
||||
if (!acceptsExtension(ext)) return NULL;
|
||||
|
||||
rawImageRec *raw;
|
||||
|
||||
if( (raw = RawImageOpen(fileName.c_str())) == NULL )
|
||||
{
|
||||
notify(FATAL)<< "Unable to open \""<<fileName<<"\""<<endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int s = raw->sizeX;
|
||||
int t = raw->sizeY;
|
||||
int r = 1;
|
||||
|
||||
#if 0
|
||||
int internalFormat = raw->sizeZ == 3 ? GL_RGB5 :
|
||||
raw->sizeZ == 4 ? GL_RGB5_A1 : GL_RGB;
|
||||
#else
|
||||
int internalFormat = raw->sizeZ;
|
||||
#endif
|
||||
unsigned int pixelFormat =
|
||||
raw->sizeZ == 1 ? GL_LUMINANCE :
|
||||
raw->sizeZ == 2 ? GL_LUMINANCE_ALPHA :
|
||||
raw->sizeZ == 3 ? GL_RGB :
|
||||
raw->sizeZ == 4 ? GL_RGBA : (GLenum)-1;
|
||||
|
||||
unsigned int dataType = GL_UNSIGNED_BYTE;
|
||||
|
||||
unsigned char *data;
|
||||
RawImageGetData(raw, &data);
|
||||
RawImageClose(raw);
|
||||
|
||||
Image* image = new Image();
|
||||
image->setFileName(fileName.c_str());
|
||||
image->setImage(s,t,r,
|
||||
internalFormat,
|
||||
pixelFormat,
|
||||
dataType,
|
||||
data);
|
||||
|
||||
notify(INFO) << "image read ok "<<s<<" "<<t<<endl;
|
||||
return image;
|
||||
|
||||
}
|
||||
|
||||
virtual bool writeImage(Image& ,const std::string& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
RegisterReaderWriterProxy<ReaderWriterRGB> g_readerWriter_RGB_Proxy;
|
||||
543
src/osg/Registry.cpp
Normal file
543
src/osg/Registry.cpp
Normal file
@@ -0,0 +1,543 @@
|
||||
#include "osg/Registry"
|
||||
|
||||
#include "osg/Notify"
|
||||
#include "osg/Object"
|
||||
#include "osg/Image"
|
||||
#include "osg/Node"
|
||||
#include "osg/Group"
|
||||
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/FileNameUtils"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Object* osg::loadObjectFile(const char *name)
|
||||
{
|
||||
return Registry::instance()->readObject(name);
|
||||
}
|
||||
Image* osg::loadImageFile(const char *name)
|
||||
{
|
||||
return Registry::instance()->readImage(name);
|
||||
}
|
||||
|
||||
Node* osg::loadNodeFile(const char *name)
|
||||
{
|
||||
return Registry::instance()->readNode(name);
|
||||
}
|
||||
|
||||
bool osg::saveObjectFile(Object& object,const char *name)
|
||||
{
|
||||
return Registry::instance()->writeObject(object,name);
|
||||
}
|
||||
|
||||
bool osg::saveImageFile(Image& image,const char *name)
|
||||
{
|
||||
return Registry::instance()->writeImage(image,name);
|
||||
}
|
||||
|
||||
bool osg::saveNodeFile(Node& node,const char *name)
|
||||
{
|
||||
return Registry::instance()->writeNode(node,name);
|
||||
}
|
||||
|
||||
// definition of the Registry
|
||||
Registry::Registry()
|
||||
{
|
||||
notify(INFO) << "Constructing osg::Registry"<<endl;
|
||||
_openingLibrary = false;
|
||||
osg::Init();
|
||||
}
|
||||
|
||||
|
||||
Registry::~Registry()
|
||||
{
|
||||
// Don't write to notify() in here. Destruction order is indeterminate
|
||||
// (I think) and the notify stream may have been destroyed before this
|
||||
// is called.
|
||||
|
||||
// note, do not need to unregister attached prototype and reader/writers
|
||||
// as they will be automatically unreferenced by the std::vector
|
||||
// destructor & ref_ptr combination.
|
||||
|
||||
}
|
||||
|
||||
Registry* Registry::instance()
|
||||
{
|
||||
static Registry s_nodeFactory;
|
||||
return &s_nodeFactory;
|
||||
}
|
||||
|
||||
|
||||
void Registry::addPrototype(Object* obj)
|
||||
{
|
||||
if (obj==0L) return;
|
||||
|
||||
// works under win32, good old C :-)
|
||||
if (_openingLibrary) notify(INFO) << "Opening Library : ";
|
||||
notify(INFO) << "osg::Registry::addPrototype("<<obj->className()<<")"<<endl;
|
||||
|
||||
int newPos = _nodeProtoList.size();
|
||||
|
||||
_protoList.push_back(obj);
|
||||
|
||||
if (dynamic_cast<Node*>(obj))
|
||||
{
|
||||
_nodeProtoList.push_back(newPos);
|
||||
}
|
||||
if (dynamic_cast<Image*>(obj))
|
||||
{
|
||||
_imageProtoList.push_back(newPos);
|
||||
}
|
||||
}
|
||||
|
||||
void Registry::removePrototype(Object* obj)
|
||||
{
|
||||
if (obj==0L) return;
|
||||
|
||||
notify(INFO) << "osg::Registry::removePrototype()"<<endl;
|
||||
|
||||
PrototypeList::iterator pitr = std::find(_protoList.begin(),_protoList.end(),obj);
|
||||
if (pitr!=_protoList.end())
|
||||
{
|
||||
_protoList.erase(pitr);
|
||||
|
||||
// note need to handle the node and image lists,
|
||||
// to be implemented...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Registry::addReaderWriter(ReaderWriter* rw)
|
||||
{
|
||||
if (rw==0L) return;
|
||||
|
||||
if (_openingLibrary) notify(INFO) << "Opening Library : "<<endl;
|
||||
|
||||
notify(INFO) << "osg::Registry::addReaderWriter("<<rw->className()<<")"<<endl;
|
||||
|
||||
_rwList.push_back(rw);
|
||||
|
||||
}
|
||||
|
||||
void Registry::removeReaderWriter(ReaderWriter* rw)
|
||||
{
|
||||
if (rw==0L) return;
|
||||
|
||||
notify(INFO) << "osg::Registry::removeReaderWriter();"<<endl;
|
||||
|
||||
ReaderWriterList::iterator rwitr = std::find(_rwList.begin(),_rwList.end(),rw);
|
||||
if (rwitr!=_rwList.end())
|
||||
{
|
||||
_rwList.erase(rwitr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string Registry::createLibraryNameForFile(const std::string& fileName)
|
||||
{
|
||||
std::string ext = getLowerCaseFileExtension(fileName);
|
||||
return createLibraryNameForExt(ext);
|
||||
}
|
||||
|
||||
std::string Registry::createLibraryNameForExt(const std::string& ext)
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef _DEBUG
|
||||
return "osgdb_"+ext+"d.dll";
|
||||
# else
|
||||
return "osgdb_"+ext+".dll";
|
||||
# endif
|
||||
#else
|
||||
return "osgdb_"+ext+".so";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool Registry::loadLibrary(const std::string& fileName)
|
||||
{
|
||||
DynamicLibrary* dl = getLibrary(fileName);
|
||||
if (dl) return false;
|
||||
|
||||
_openingLibrary=true;
|
||||
|
||||
|
||||
dl = DynamicLibrary::loadLibrary(fileName);
|
||||
_openingLibrary=false;
|
||||
|
||||
if (dl)
|
||||
{
|
||||
dl->ref();
|
||||
_dlList.push_back(dl);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Registry::closeLibrary(const std::string& fileName)
|
||||
{
|
||||
DynamicLibraryList::iterator ditr = getLibraryItr(fileName);
|
||||
if (ditr!=_dlList.end())
|
||||
{
|
||||
(*ditr)->unref();
|
||||
_dlList.erase(ditr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Registry::DynamicLibraryList::iterator Registry::getLibraryItr(const std::string& fileName)
|
||||
{
|
||||
DynamicLibraryList::iterator ditr = _dlList.begin();
|
||||
for(;ditr!=_dlList.end();++ditr)
|
||||
{
|
||||
if ((*ditr)->getName()==fileName) return ditr;
|
||||
}
|
||||
return _dlList.end();
|
||||
}
|
||||
|
||||
DynamicLibrary* Registry::getLibrary(const std::string& fileName)
|
||||
{
|
||||
DynamicLibraryList::iterator ditr = getLibraryItr(fileName);
|
||||
if (ditr!=_dlList.end()) return ditr->get();
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
||||
Object* Registry::readObject(Input& fr)
|
||||
{
|
||||
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString()) {
|
||||
Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
|
||||
if (obj) fr+=2;
|
||||
return obj;
|
||||
}
|
||||
else return NULL;
|
||||
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<_protoList.size();++i)
|
||||
{
|
||||
Object* obj = _protoList[i]->readClone(fr);
|
||||
if (obj) return obj;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
Object* Registry::readObject(const std::string& fileName)
|
||||
{
|
||||
char *file = FindFile( fileName.c_str() );
|
||||
if (file==NULL) return NULL;
|
||||
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
Object* obj = (*itr)->readObject(file);
|
||||
if (obj) return obj;
|
||||
}
|
||||
|
||||
// now look for a plug-in to load the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (Registry::instance()->loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
Object* obj = (*itr)->readObject(file);
|
||||
if (obj) return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to read file "<<fileName<<endl;
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool Registry::writeObject(Object& obj,const std::string& fileName)
|
||||
{
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
if ((*itr)->writeObject(obj,fileName)) return true;
|
||||
}
|
||||
|
||||
// now look for a plug-in to save the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
if ((*itr)->writeObject(obj,fileName)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to write file "<<fileName<<endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Image* Registry::readImage(Input& fr)
|
||||
{
|
||||
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString()) {
|
||||
Image* image = dynamic_cast<Image*>(fr.getObjectForUniqueID(fr[1].getStr()));
|
||||
if (image) fr+=2;
|
||||
return image;
|
||||
}
|
||||
else return NULL;
|
||||
|
||||
}
|
||||
|
||||
for(std::vector<int>::iterator itr=_imageProtoList.begin();
|
||||
itr!=_imageProtoList.end();
|
||||
++itr)
|
||||
{
|
||||
int i=*itr;
|
||||
Object* obj = _protoList[i]->readClone(fr);
|
||||
if (obj)
|
||||
{
|
||||
Image* image = static_cast<Image*>(obj);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
Image* Registry::readImage(const std::string& fileName)
|
||||
{
|
||||
char *file = FindFile( fileName.c_str() );
|
||||
if (file==NULL) return NULL;
|
||||
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
Image* image = (*itr)->readImage(file);
|
||||
if (image) return image;
|
||||
}
|
||||
|
||||
// now look for a plug-in to load the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
Image* image = (*itr)->readImage(file);
|
||||
if (image) return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to read file "<<fileName<<endl;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool Registry::writeImage(Image& image,const std::string& fileName)
|
||||
{
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
if ((*itr)->writeImage(image,fileName)) return true;
|
||||
}
|
||||
|
||||
// now look for a plug-in to save the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
if ((*itr)->writeImage(image,fileName)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to write file "<<fileName<<endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Node* Registry::readNode(Input& fr)
|
||||
{
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString()) {
|
||||
Node* node = dynamic_cast<Node*>(fr.getObjectForUniqueID(fr[1].getStr()));
|
||||
if (node) fr+=2;
|
||||
return node;
|
||||
}
|
||||
else return NULL;
|
||||
|
||||
}
|
||||
|
||||
std::vector<int>::iterator itr=_nodeProtoList.begin();
|
||||
for(;itr!=_nodeProtoList.end();++itr)
|
||||
{
|
||||
int i=*itr;
|
||||
Object* obj = _protoList[i]->readClone(fr);
|
||||
if (obj)
|
||||
{
|
||||
Node* node = static_cast<Node*>(obj);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
Node* Registry::readNode(const std::string& fileName)
|
||||
{
|
||||
|
||||
char *file = FindFile( fileName.c_str() );
|
||||
if (file==NULL) return NULL;
|
||||
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
Node* node = (*itr)->readNode(file);
|
||||
if (node) return node;
|
||||
}
|
||||
|
||||
// now look for a plug-in to load the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
notify(INFO) << "Now checking for plug-in "<<libraryName<<endl;
|
||||
if (loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
Node* node = (*itr)->readNode(file);
|
||||
if (node) return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to read file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to read file "<<fileName<<endl;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool Registry::writeNode(Node& node,const std::string& fileName)
|
||||
{
|
||||
// record the existing reader writer.
|
||||
std::set<ReaderWriter*> rwOriginal;
|
||||
|
||||
// first attempt to load the file from existing ReaderWriter's
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
rwOriginal.insert(itr->get());
|
||||
if ((*itr)->writeNode(node,fileName)) return true;
|
||||
}
|
||||
|
||||
// now look for a plug-in to save the file.
|
||||
std::string libraryName = createLibraryNameForFile(fileName);
|
||||
if (Registry::instance()->loadLibrary(libraryName))
|
||||
{
|
||||
for(ReaderWriterList::iterator itr=_rwList.begin();
|
||||
itr!=_rwList.end();
|
||||
++itr)
|
||||
{
|
||||
if (rwOriginal.find(itr->get())==rwOriginal.end())
|
||||
{
|
||||
if ((*itr)->writeNode(node,fileName)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(NOTICE)<<"Warning: Could not find plugin to write file with extension ."
|
||||
<<getLowerCaseFileExtension(fileName)<<endl;
|
||||
}
|
||||
notify(NOTICE)<<"Warning: Unable to write file "<<fileName<<endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
69
src/osg/Scene.cpp
Normal file
69
src/osg/Scene.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "osg/Scene"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Scene> g_SceneProxy;
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
_gstate = NULL;
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
if (_gstate) _gstate->unref();
|
||||
}
|
||||
|
||||
void Scene::setGState(osg::GeoState* gstate)
|
||||
{
|
||||
if (gstate==_gstate) return;
|
||||
|
||||
if (_gstate) _gstate->unref();
|
||||
|
||||
_gstate = gstate;
|
||||
if (_gstate) _gstate->ref();
|
||||
}
|
||||
|
||||
bool Scene::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr[0].matchWord("Use"))
|
||||
{
|
||||
if (fr[1].isString()) {
|
||||
GeoState* geostate = dynamic_cast<GeoState*>(fr.getObjectForUniqueID(fr[1].getStr()));
|
||||
if (geostate) {
|
||||
fr+=2;
|
||||
_gstate = geostate;
|
||||
_gstate->ref();
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GeoState* readState = static_cast<GeoState*>(GeoState::instance()->readClone(fr)))
|
||||
{
|
||||
_gstate = readState;
|
||||
_gstate->ref();
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (Group::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
bool Scene::writeLocalData(Output& fw)
|
||||
{
|
||||
if (_gstate)
|
||||
{
|
||||
_gstate->write(fw);
|
||||
}
|
||||
|
||||
Group::writeLocalData(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
270
src/osg/Seg.cpp
Normal file
270
src/osg/Seg.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
#include "osg/Seg"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
bool Seg::intersectAndClip(Vec3& s,Vec3& e,const BoundingBox& bb)
|
||||
{
|
||||
// compate s and e against the xMin to xMax range of bb.
|
||||
if (s.x()<=e.x())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.x()<bb.xMin()) return false;
|
||||
if (s.x()>bb.xMax()) return false;
|
||||
|
||||
if (s.x()<bb.xMin())
|
||||
{
|
||||
// clip s to xMin.
|
||||
s = s+(e-s)*(bb.xMin()-s.x())/(e.x()-s.x());
|
||||
}
|
||||
|
||||
if (e.x()>bb.xMax())
|
||||
{
|
||||
// clip e to xMax.
|
||||
e = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.x()<bb.xMin()) return false;
|
||||
if (e.x()>bb.xMax()) return false;
|
||||
|
||||
if (e.x()<bb.xMin())
|
||||
{
|
||||
// clip s to xMin.
|
||||
e = s+(e-s)*(bb.xMin()-s.x())/(e.x()-s.x());
|
||||
}
|
||||
|
||||
if (s.x()>bb.xMax())
|
||||
{
|
||||
// clip e to xMax.
|
||||
s = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x());
|
||||
}
|
||||
}
|
||||
|
||||
// compate s and e against the yMin to yMax range of bb.
|
||||
if (s.y()<=e.y())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.y()<bb.yMin()) return false;
|
||||
if (s.y()>bb.yMax()) return false;
|
||||
|
||||
if (s.y()<bb.yMin())
|
||||
{
|
||||
// clip s to yMin.
|
||||
s = s+(e-s)*(bb.yMin()-s.y())/(e.y()-s.y());
|
||||
}
|
||||
|
||||
if (e.y()>bb.yMax())
|
||||
{
|
||||
// clip e to yMax.
|
||||
e = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.y()<bb.yMin()) return false;
|
||||
if (e.y()>bb.yMax()) return false;
|
||||
|
||||
if (e.y()<bb.yMin())
|
||||
{
|
||||
// clip s to yMin.
|
||||
e = s+(e-s)*(bb.yMin()-s.y())/(e.y()-s.y());
|
||||
}
|
||||
|
||||
if (s.y()>bb.yMax())
|
||||
{
|
||||
// clip e to yMax.
|
||||
s = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y());
|
||||
}
|
||||
}
|
||||
|
||||
// compate s and e against the zMin to zMax range of bb.
|
||||
if (s.z()<=e.z())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.z()<bb.zMin()) return false;
|
||||
if (s.z()>bb.zMax()) return false;
|
||||
|
||||
if (s.z()<bb.zMin())
|
||||
{
|
||||
// clip s to zMin.
|
||||
s = s+(e-s)*(bb.zMin()-s.z())/(e.z()-s.z());
|
||||
}
|
||||
|
||||
if (e.z()>bb.zMax())
|
||||
{
|
||||
// clip e to zMax.
|
||||
e = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.z()<bb.zMin()) return false;
|
||||
if (e.z()>bb.zMax()) return false;
|
||||
|
||||
if (e.z()<bb.zMin())
|
||||
{
|
||||
// clip s to zMin.
|
||||
e = s+(e-s)*(bb.zMin()-s.z())/(e.z()-s.z());
|
||||
}
|
||||
|
||||
if (s.z()>bb.zMax())
|
||||
{
|
||||
// clip e to zMax.
|
||||
s = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seg::intersect(const BoundingBox& bb) const
|
||||
{
|
||||
if (!bb.isValid()) return false;
|
||||
|
||||
Vec3 s=_s,e=_e;
|
||||
return intersectAndClip(s,e,bb);
|
||||
}
|
||||
|
||||
bool Seg::intersect(const BoundingBox& bb,float& r1,float& r2) const
|
||||
{
|
||||
if (!bb.isValid()) return false;
|
||||
|
||||
Vec3 s=_s,e=_e;
|
||||
return intersectAndClip(s,e,bb);
|
||||
}
|
||||
|
||||
bool Seg::intersect(const BoundingSphere& bs,float& r1,float& r2) const
|
||||
{
|
||||
Vec3 sm = _s-bs._center;
|
||||
float c = sm.length2()-bs._radius*bs._radius;
|
||||
|
||||
Vec3 se = _e-_s;
|
||||
float a = se.length2();
|
||||
|
||||
float b = sm*se*2.0f;
|
||||
|
||||
float d = b*b-4.0f*a*c;
|
||||
|
||||
if (d<0.0f) return false;
|
||||
|
||||
d = sqrtf(d);
|
||||
|
||||
float div = 1.0f/(2.0f*a);
|
||||
|
||||
r1 = (-b-d)*div;
|
||||
r2 = (-b+d)*div;
|
||||
|
||||
if (r1<=0.0f && r2<=0.0f) return false;
|
||||
|
||||
if (r1>=1.0f && r2>=1.0f) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seg::intersect(const BoundingSphere& bs) const
|
||||
{
|
||||
Vec3 sm = _s-bs._center;
|
||||
float c = sm.length2()-bs._radius*bs._radius;
|
||||
if (c<0.0f) return true;
|
||||
|
||||
Vec3 se = _e-_s;
|
||||
float a = se.length2();
|
||||
|
||||
float b = (sm*se)*2.0f;
|
||||
|
||||
float d = b*b-4.0f*a*c;
|
||||
|
||||
if (d<0.0f) return false;
|
||||
|
||||
d = sqrtf(d);
|
||||
|
||||
float div = 1.0f/(2.0f*a);
|
||||
|
||||
float r1 = (-b-d)*div;
|
||||
float r2 = (-b+d)*div;
|
||||
|
||||
if (r1<=0.0f && r2<=0.0f) return false;
|
||||
|
||||
if (r1>=1.0f && r2>=1.0f) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seg::intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r)
|
||||
{
|
||||
if (v1==v2 || v2==v3 || v1==v3) return false;
|
||||
|
||||
Vec3 vse = _e-_s;
|
||||
|
||||
Vec3 v12 = v2-v1;
|
||||
Vec3 n12 = v12^vse;
|
||||
float ds12 = (_s-v1)*n12;
|
||||
float d312 = (v3-v1)*n12;
|
||||
if (d312>=0.0f)
|
||||
{
|
||||
if (ds12<0.0f) return false;
|
||||
if (ds12>d312) return false;
|
||||
}
|
||||
else // d312 < 0
|
||||
{
|
||||
if (ds12>0.0f) return false;
|
||||
if (ds12<d312) return false;
|
||||
}
|
||||
|
||||
|
||||
Vec3 v23 = v3-v2;
|
||||
Vec3 n23 = v23^vse;
|
||||
float ds23 = (_s-v2)*n23;
|
||||
float d123 = (v1-v2)*n23;
|
||||
if (d123>=0.0f)
|
||||
{
|
||||
if (ds23<0.0f) return false;
|
||||
if (ds23>d123) return false;
|
||||
}
|
||||
else // d123 < 0
|
||||
{
|
||||
if (ds23>0.0f) return false;
|
||||
if (ds23<d123) return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vec3 v31 = v1-v3;
|
||||
Vec3 n31 = v31^vse;
|
||||
float ds31 = (_s-v3)*n31;
|
||||
float d231 = (v2-v3)*n31;
|
||||
if (d231>=0.0f)
|
||||
{
|
||||
if (ds31<0.0f) return false;
|
||||
if (ds31>d231) return false;
|
||||
}
|
||||
else // d231 < 0
|
||||
{
|
||||
if (ds31>0.0f) return false;
|
||||
if (ds31<d231) return false;
|
||||
}
|
||||
|
||||
float r3 = ds12/d312;
|
||||
float r1 = ds23/d123;
|
||||
float r2 = ds31/d231;
|
||||
|
||||
// float rt = r1+r2+r3;
|
||||
|
||||
Vec3 in = v1*r1+v2*r2+v3*r3;
|
||||
|
||||
float length = vse.length();
|
||||
vse /= length;
|
||||
float d = (in-_s)*vse;
|
||||
|
||||
|
||||
if (d<0.0f) return false;
|
||||
if (d>length) return false;
|
||||
|
||||
r = d/length;
|
||||
|
||||
return true;
|
||||
}
|
||||
8
src/osg/Sequence.cpp
Normal file
8
src/osg/Sequence.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "osg/Sequence"
|
||||
#include "osg/Registry"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Sequence> g_SequenceProxy;
|
||||
|
||||
// to be written :-)
|
||||
87
src/osg/Switch.cpp
Normal file
87
src/osg/Switch.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "osg/Switch"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
RegisterObjectProxy<Switch> g_SwitchProxy;
|
||||
|
||||
Switch::Switch()
|
||||
{
|
||||
_value = ALL_CHILDREN_OFF;
|
||||
}
|
||||
|
||||
void Switch::traverse(NodeVisitor& nv)
|
||||
{
|
||||
switch(nv.getTraverseMode())
|
||||
{
|
||||
case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
|
||||
switch(_value)
|
||||
{
|
||||
case(ALL_CHILDREN_ON):
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
case(ALL_CHILDREN_OFF):
|
||||
return;
|
||||
default:
|
||||
if (_value>=0 && (unsigned int)_value<_children.size()) _children[_value]->accept(nv);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Switch::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
|
||||
if (fr.matchSequence("value"))
|
||||
{
|
||||
if (fr[1].matchWord("ALL_CHILDREN_ON"))
|
||||
{
|
||||
_value = ALL_CHILDREN_ON;
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
else if (fr[1].matchWord("ALL_CHILDREN_ON"))
|
||||
{
|
||||
_value = ALL_CHILDREN_OFF;
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
else if (fr[1].isInt())
|
||||
{
|
||||
fr[1].getInt(_value);
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
}
|
||||
|
||||
if (Group::readLocalData(fr)) iteratorAdvanced = true;
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
bool Switch::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "value ";
|
||||
switch(_value)
|
||||
{
|
||||
case(ALL_CHILDREN_ON): fw<<"ALL_CHILDREN_ON"<<endl;break;
|
||||
case(ALL_CHILDREN_OFF): fw<<"ALL_CHILDREN_OFF"<<endl;break;
|
||||
default: fw<<_value<<endl;break;
|
||||
}
|
||||
|
||||
Group::writeLocalData(fw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
78
src/osg/TexEnv.cpp
Normal file
78
src/osg/TexEnv.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "osg/TexEnv"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexEnv::TexEnv( void )
|
||||
{
|
||||
_mode = MODULATE;
|
||||
}
|
||||
|
||||
TexEnv::~TexEnv( void )
|
||||
{
|
||||
}
|
||||
|
||||
TexEnv* TexEnv::instance()
|
||||
{
|
||||
static ref_ptr<TexEnv> s_TexEnv(new TexEnv);
|
||||
return s_TexEnv.get();
|
||||
}
|
||||
|
||||
|
||||
void TexEnv::setMode( TexEnvMode mode )
|
||||
{
|
||||
_mode = (mode == DECAL ||
|
||||
mode == MODULATE ||
|
||||
mode == BLEND ) ?
|
||||
mode : MODULATE;
|
||||
}
|
||||
|
||||
void TexEnv::apply( void )
|
||||
{
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, _mode);
|
||||
}
|
||||
|
||||
bool TexEnv::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
TexEnvMode mode;
|
||||
if (fr[0].matchWord("mode") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_mode = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool TexEnv::matchModeStr(const char* str,TexEnvMode& mode)
|
||||
{
|
||||
if (strcmp(str,"DECAL")==0) mode = DECAL;
|
||||
else if (strcmp(str,"MODULATE")==0) mode = MODULATE;
|
||||
else if (strcmp(str,"BLEND")==0) mode = BLEND;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* TexEnv::getModeStr(TexEnvMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(DECAL): return "DECAL";
|
||||
case(MODULATE): return "MODULATE";
|
||||
case(BLEND): return "BLEND";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool TexEnv::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "mode " << getModeStr(_mode) << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
89
src/osg/TexGen.cpp
Normal file
89
src/osg/TexGen.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
#include "osg/TexGen"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexGen::TexGen( void )
|
||||
{
|
||||
_mode = OBJECT_LINEAR;
|
||||
}
|
||||
|
||||
|
||||
TexGen::~TexGen( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TexGen* TexGen::instance()
|
||||
{
|
||||
static ref_ptr<TexGen> s_texgen(new TexGen);
|
||||
return s_texgen.get();
|
||||
}
|
||||
|
||||
|
||||
bool TexGen::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
TexGenMode mode;
|
||||
if (fr[0].matchWord("mode") && matchModeStr(fr[1].getStr(),mode))
|
||||
{
|
||||
_mode = mode;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool TexGen::matchModeStr(const char* str,TexGenMode& mode)
|
||||
{
|
||||
if (strcmp(str,"EYE_LINEAR")==0) mode = EYE_LINEAR;
|
||||
else if (strcmp(str,"OBJECT_LINEAR")==0) mode = OBJECT_LINEAR;
|
||||
else if (strcmp(str,"SPHERE_MAP")==0) mode = SPHERE_MAP;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* TexGen::getModeStr(TexGenMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case(EYE_LINEAR): return "EYE_LINEAR";
|
||||
case(OBJECT_LINEAR): return "OBJECT_LINEAR";
|
||||
case(SPHERE_MAP): return "SPHERE_MAP";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool TexGen::writeLocalData(Output& fw)
|
||||
{
|
||||
fw.indent() << "mode " << getModeStr(_mode) << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TexGen::enable( void )
|
||||
{
|
||||
glEnable( GL_TEXTURE_GEN_S );
|
||||
glEnable( GL_TEXTURE_GEN_T );
|
||||
}
|
||||
|
||||
|
||||
void TexGen::disable( void )
|
||||
{
|
||||
glDisable( GL_TEXTURE_GEN_S );
|
||||
glDisable( GL_TEXTURE_GEN_T );
|
||||
}
|
||||
|
||||
|
||||
void TexGen::apply( void )
|
||||
{
|
||||
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
|
||||
}
|
||||
25
src/osg/TexMat.cpp
Normal file
25
src/osg/TexMat.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "osg/GL"
|
||||
#include "osg/TexMat"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
TexMat::TexMat( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TexMat::~TexMat( void )
|
||||
{
|
||||
}
|
||||
|
||||
TexMat* TexMat::instance()
|
||||
{
|
||||
static ref_ptr<TexMat> s_texmat(new TexMat);
|
||||
return s_texmat.get();
|
||||
}
|
||||
|
||||
void TexMat::apply( void )
|
||||
{
|
||||
glMatrixMode( GL_TEXTURE );
|
||||
glLoadMatrixf( (GLfloat *)_mat );
|
||||
}
|
||||
257
src/osg/Texture.cpp
Normal file
257
src/osg/Texture.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
#include "osg/Texture"
|
||||
#include "osg/Input"
|
||||
#include "osg/Output"
|
||||
#include "osg/Registry"
|
||||
#include "osg/Image"
|
||||
#include "osg/Referenced"
|
||||
#include "osg/Notify"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Texture::Texture()
|
||||
{
|
||||
_handle = 0;
|
||||
|
||||
_wrap_s = CLAMP;
|
||||
_wrap_t = CLAMP;
|
||||
_wrap_r = CLAMP;
|
||||
_min_filter = NEAREST_MIPMAP_LINEAR;
|
||||
_mag_filter = LINEAR;
|
||||
}
|
||||
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
if (_handle!=0) glDeleteTextures( 1, &_handle );
|
||||
}
|
||||
|
||||
|
||||
Texture* Texture::instance()
|
||||
{
|
||||
static ref_ptr<Texture> s_texture(new Texture);
|
||||
return s_texture.get();
|
||||
}
|
||||
|
||||
|
||||
bool Texture::readLocalData(Input& fr)
|
||||
{
|
||||
bool iteratorAdvanced = false;
|
||||
if (fr[0].matchWord("file") && fr[1].isString())
|
||||
{
|
||||
_image = fr.readImage(fr[1].getStr());
|
||||
fr += 2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
WrapMode wrap;
|
||||
if (fr[0].matchWord("wrap_s") && matchWrapStr(fr[1].getStr(),wrap))
|
||||
{
|
||||
_wrap_s = wrap;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("wrap_t") && matchWrapStr(fr[1].getStr(),wrap))
|
||||
{
|
||||
_wrap_t = wrap;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("wrap_r") && matchWrapStr(fr[1].getStr(),wrap))
|
||||
{
|
||||
_wrap_r = wrap;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
FilterMode filter;
|
||||
if (fr[0].matchWord("min_filter") && matchFilterStr(fr[1].getStr(),filter))
|
||||
{
|
||||
_min_filter = filter;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("mag_filter") && matchFilterStr(fr[1].getStr(),filter))
|
||||
{
|
||||
_mag_filter = filter;
|
||||
fr+=2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
return iteratorAdvanced;
|
||||
}
|
||||
|
||||
|
||||
bool Texture::writeLocalData(Output& fw)
|
||||
{
|
||||
if (_image.valid())
|
||||
{
|
||||
fw.indent() << "file \""<<_image->getFileName()<<"\""<<endl;
|
||||
}
|
||||
|
||||
fw.indent() << "wrap_s " << getWrapStr(_wrap_s) << endl;
|
||||
fw.indent() << "wrap_t " << getWrapStr(_wrap_t) << endl;
|
||||
fw.indent() << "wrap_r " << getWrapStr(_wrap_r) << endl;
|
||||
|
||||
fw.indent() << "min_filter " << getFilterStr(_min_filter) << endl;
|
||||
fw.indent() << "mag_filter " << getFilterStr(_mag_filter) << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Texture::matchWrapStr(const char* str,WrapMode& wrap)
|
||||
{
|
||||
if (strcmp(str,"CLAMP")==0) wrap = CLAMP;
|
||||
else if (strcmp(str,"REPEAT")==0) wrap = REPEAT;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* Texture::getWrapStr(WrapMode wrap)
|
||||
{
|
||||
switch(wrap)
|
||||
{
|
||||
case(CLAMP): return "CLAMP";
|
||||
case(REPEAT): return "REPEAT";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool Texture::matchFilterStr(const char* str,FilterMode& filter)
|
||||
{
|
||||
if (strcmp(str,"NEAREST")==0) filter = NEAREST;
|
||||
else if (strcmp(str,"LINEAR")==0) filter = LINEAR;
|
||||
else if (strcmp(str,"NEAREST_MIPMAP_NEAREST")==0) filter = NEAREST_MIPMAP_NEAREST;
|
||||
else if (strcmp(str,"LINEAR_MIPMAP_NEAREST")==0) filter = LINEAR_MIPMAP_NEAREST;
|
||||
else if (strcmp(str,"NEAREST_MIPMAP_LINEAR")==0) filter = NEAREST_MIPMAP_LINEAR;
|
||||
else if (strcmp(str,"LINEAR_MIPMAP_LINEAR")==0) filter = LINEAR_MIPMAP_LINEAR;
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* Texture::getFilterStr(FilterMode filter)
|
||||
{
|
||||
switch(filter)
|
||||
{
|
||||
case(NEAREST): return "NEAREST";
|
||||
case(LINEAR): return "LINEAR";
|
||||
case(NEAREST_MIPMAP_NEAREST): return "NEAREST_MIPMAP_NEAREST";
|
||||
case(LINEAR_MIPMAP_NEAREST): return "LINEAR_MIPMAP_NEAREST";
|
||||
case(NEAREST_MIPMAP_LINEAR): return "NEAREST_MIPMAP_LINEAR";
|
||||
case(LINEAR_MIPMAP_LINEAR): return "LINEAR_MIPMAP_LINEAR";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void Texture::setImage(Image* image)
|
||||
{
|
||||
if (_handle!=0) glDeleteTextures( 1, &_handle );
|
||||
_handle = 0;
|
||||
_image = image;
|
||||
}
|
||||
|
||||
void Texture::setWrap(WrapParameter which, WrapMode wrap)
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case WRAP_S : _wrap_s = wrap; break;
|
||||
case WRAP_T : _wrap_t = wrap; break;
|
||||
case WRAP_R : _wrap_r = wrap; break;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed Texture::setWrap("<<(unsigned int)which<<","<<(unsigned int)wrap<<")"<<endl; break;
|
||||
}
|
||||
}
|
||||
|
||||
Texture::WrapMode Texture::getWrap(WrapParameter which) const
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case WRAP_S : return _wrap_s;
|
||||
case WRAP_T : return _wrap_t;
|
||||
case WRAP_R : return _wrap_r;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed Texture::getWrap(which)"<<endl; return _wrap_s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Texture::setFilter(FilterParameter which, FilterMode filter)
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case MIN_FILTER : _min_filter = filter; break;
|
||||
case MAG_FILTER : _mag_filter = filter; break;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed Texture::setFilter("<<(unsigned int)which<<","<<(unsigned int)filter<<")"<<endl; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Texture::FilterMode Texture::getFilter(FilterParameter which) const
|
||||
{
|
||||
switch( which )
|
||||
{
|
||||
case MIN_FILTER : return _min_filter;
|
||||
case MAG_FILTER : return _mag_filter;
|
||||
default : notify(WARN)<<"Error: invalid 'which' passed Texture::getFilter(which)"<<endl; return _min_filter;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::enable( void )
|
||||
{
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
|
||||
void Texture::disable( void )
|
||||
{
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
|
||||
void Texture::apply( void )
|
||||
{
|
||||
if(_handle!=0)
|
||||
{
|
||||
glBindTexture( GL_TEXTURE_2D, _handle );
|
||||
}
|
||||
else if (_image.valid())
|
||||
{
|
||||
|
||||
_image->ensureDimensionsArePowerOfTwo();
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,_image->packing());
|
||||
|
||||
|
||||
glGenTextures( 1, &_handle );
|
||||
glBindTexture( GL_TEXTURE_2D, _handle );
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrap_s );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter);
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter);
|
||||
if( _min_filter == LINEAR || _min_filter == NEAREST )
|
||||
{
|
||||
|
||||
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, _image->internalFormat(),
|
||||
_image->s(), _image->t(), 0,
|
||||
(GLenum)_image->pixelFormat(),
|
||||
(GLenum)_image->dataType(),
|
||||
_image->data() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
gluBuild2DMipmaps( GL_TEXTURE_2D, _image->internalFormat(),
|
||||
_image->s(),_image->t(),
|
||||
(GLenum)_image->pixelFormat(), (GLenum)_image->dataType(),
|
||||
_image->data() );
|
||||
}
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, _handle );
|
||||
|
||||
}
|
||||
}
|
||||
205
src/osg/Timer.cpp
Normal file
205
src/osg/Timer.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#ifdef WIN32 // [
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
|
||||
int Timer::inited = 0;
|
||||
double Timer::cpu_mhz = 0.0;
|
||||
|
||||
void Timer::init( void )
|
||||
{
|
||||
Timer_t start_time = tick();
|
||||
Sleep (1000);
|
||||
Timer_t end_time = tick();
|
||||
cpu_mhz = (double)(end_time-start_time)*1e-6;
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
if( !inited ) init();
|
||||
}
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (((double)delta/cpu_mhz)*1e-6);
|
||||
}
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (((double)delta/cpu_mhz)*1e-3);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0)/cpu_mhz);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0) * 1e3/cpu_mhz);
|
||||
}
|
||||
|
||||
#endif // ]
|
||||
|
||||
#ifdef __linux // [
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int Timer::inited = 0;
|
||||
double Timer::cpu_mhz = 0.0;
|
||||
|
||||
void Timer::init( void )
|
||||
{
|
||||
char buff[128];
|
||||
FILE *fp = fopen( "/proc/cpuinfo", "r" );
|
||||
|
||||
while( fgets( buff, sizeof( buff ), fp ) > 0 )
|
||||
{
|
||||
if( !strncmp( buff, "cpu MHz", strlen( "cpu MHz" )))
|
||||
{
|
||||
char *ptr = buff;
|
||||
|
||||
while( ptr && *ptr != ':' ) ptr++;
|
||||
if( ptr )
|
||||
{
|
||||
ptr++;
|
||||
sscanf( ptr, "%lf", &cpu_mhz );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
if( !inited ) init();
|
||||
}
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta/cpu_mhz*1e-6);
|
||||
}
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta/cpu_mhz*1e-3);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0)/cpu_mhz);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0) * 1e3/cpu_mhz);
|
||||
}
|
||||
|
||||
#endif // ]
|
||||
#ifdef __sgi // [
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/syssgi.h>
|
||||
#include <sys/immu.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
unsigned long Timer::dummy = 0;
|
||||
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
__psunsigned_t phys_addr, raddr;
|
||||
unsigned int cycleval;
|
||||
volatile unsigned long counter_value, *iotimer_addr;
|
||||
int fd, poffmask;
|
||||
|
||||
poffmask = getpagesize() - 1;
|
||||
phys_addr = syssgi( SGI_QUERY_CYCLECNTR, &cycleval );
|
||||
microseconds_per_click = (double)cycleval/1e6;
|
||||
nanoseconds_per_click = (double)cycleval/1e3;
|
||||
raddr = phys_addr & ~poffmask;
|
||||
|
||||
clk = &dummy;
|
||||
|
||||
if( (fd = open( "/dev/mmem", O_RDONLY )) < 0 )
|
||||
{
|
||||
perror( "/dev/mmem" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
iotimer_addr = (volatile unsigned long *)mmap(
|
||||
(void *)0L,
|
||||
(size_t)poffmask,
|
||||
(int)PROT_READ,
|
||||
(int)MAP_PRIVATE, fd, (off_t)raddr);
|
||||
|
||||
iotimer_addr = (unsigned long *)(
|
||||
(__psunsigned_t)iotimer_addr + (phys_addr & poffmask)
|
||||
);
|
||||
|
||||
|
||||
cycleCntrSize = syssgi( SGI_CYCLECNTR_SIZE );
|
||||
|
||||
if( cycleCntrSize > 32 )
|
||||
++iotimer_addr;
|
||||
|
||||
clk = (unsigned long *)iotimer_addr;
|
||||
}
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-6);
|
||||
}
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-3);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (Timer_t)((double)delta * microseconds_per_click);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
unsigned long delta = t2 - t1;
|
||||
return (Timer_t )((double)delta * nanoseconds_per_click);
|
||||
}
|
||||
|
||||
#endif // ]
|
||||
46
src/osg/Transparency.cpp
Normal file
46
src/osg/Transparency.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "osg/OSG"
|
||||
#include "osg/Transparency"
|
||||
|
||||
using namespace osg;
|
||||
|
||||
Transparency::Transparency( void )
|
||||
{
|
||||
_source_factor = SRC_ALPHA;
|
||||
_destination_factor = ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
|
||||
|
||||
Transparency::~Transparency( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Transparency* Transparency::instance()
|
||||
{
|
||||
static ref_ptr<Transparency> s_transparency(new Transparency);
|
||||
return s_transparency.get();
|
||||
}
|
||||
|
||||
void Transparency::enable( void )
|
||||
{
|
||||
glEnable( GL_BLEND );
|
||||
}
|
||||
|
||||
|
||||
void Transparency::disable( void )
|
||||
{
|
||||
glDisable( GL_BLEND );
|
||||
}
|
||||
|
||||
|
||||
void Transparency::apply( void )
|
||||
{
|
||||
glBlendFunc( (GLenum)_source_factor, (GLenum)_destination_factor );
|
||||
}
|
||||
|
||||
|
||||
void Transparency::setFunction( int source, int destination )
|
||||
{
|
||||
_source_factor = source;
|
||||
_destination_factor = destination;
|
||||
}
|
||||
11
src/osg/Version.cpp
Normal file
11
src/osg/Version.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "osg/Version"
|
||||
|
||||
const char* osgGetVersion()
|
||||
{
|
||||
return "0.8.34";
|
||||
}
|
||||
|
||||
const char* osgGetLibraryName()
|
||||
{
|
||||
return "Open Scene Graph Library";
|
||||
}
|
||||
Reference in New Issue
Block a user