Synch with 20010921
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!smake
|
||||
SHELL=/bin/sh
|
||||
|
||||
DIRS = sgv osgconv osgcube osgreflect osgtexture osgimpostor osgviews hangglide
|
||||
DIRS = sgv osgconv osgcube osgreflect osgtexture osgimpostor osgviews hangglide osgcluster
|
||||
|
||||
all :
|
||||
for f in $(DIRS) ; do cd $$f; $(MAKE) || exit 1; cd ..; done
|
||||
|
||||
@@ -26,13 +26,15 @@ class CameraPacket {
|
||||
|
||||
CameraPacket():_masterKilled(false) {}
|
||||
|
||||
void setPacket(const osg::Camera& camera,int tnum, double rtime)
|
||||
void setPacket(const osg::Camera& camera,const osg::FrameStamp* frameStamp)
|
||||
{
|
||||
_eye = camera.getEyePoint();
|
||||
_center = camera.getCenterPoint();
|
||||
_up = camera.getUpVector();
|
||||
_traversalNumber = tnum;
|
||||
_referenceTime = rtime;
|
||||
if (frameStamp)
|
||||
{
|
||||
_frameStamp = *frameStamp;
|
||||
}
|
||||
}
|
||||
|
||||
void getCamera(osg::Camera& camera,float angle_offset=0.0f)
|
||||
@@ -50,8 +52,9 @@ class CameraPacket {
|
||||
|
||||
void getSceneViewUpdate(osgUtil::SceneView& sv)
|
||||
{
|
||||
sv.setTraversalNumber(_traversalNumber);
|
||||
sv.setReferenceTime(_referenceTime);
|
||||
// note pass a seperate reference counted FrameStamp
|
||||
// rather than this frame stamp as it can get overwritten.
|
||||
sv.setFrameStamp(new osg::FrameStamp(_frameStamp));
|
||||
}
|
||||
|
||||
void setMasterKilled(const bool flag) { _masterKilled = flag; }
|
||||
@@ -63,9 +66,12 @@ class CameraPacket {
|
||||
osg::Vec3 _up;
|
||||
bool _attachMatrix;
|
||||
osg::Matrix _matrix;
|
||||
|
||||
int _traversalNumber;
|
||||
double _referenceTime;
|
||||
|
||||
// note don't use a ref_ptr as used elsewhere for FrameStamp
|
||||
// since we don't want to copy the pointer - but the memory.
|
||||
// FrameStamp doesn't have a private destructor to allow
|
||||
// us to do this, even though its a reference counted object.
|
||||
osg::FrameStamp _frameStamp;
|
||||
|
||||
};
|
||||
|
||||
@@ -99,7 +105,7 @@ class MySceneView : public osgUtil::SceneView {
|
||||
{
|
||||
// need to broadcast my death.
|
||||
CameraPacket cp;
|
||||
cp.setPacket(*getCamera(),getTraversalNumber(),getReferenceTime());
|
||||
cp.setPacket(*getCamera(),getFrameStamp());
|
||||
cp.setMasterKilled(true);
|
||||
|
||||
_bc.setBuffer(&cp, sizeof( CameraPacket ));
|
||||
@@ -119,7 +125,7 @@ class MySceneView : public osgUtil::SceneView {
|
||||
case(MASTER):
|
||||
{
|
||||
CameraPacket cp;
|
||||
cp.setPacket(*getCamera(),getTraversalNumber(),getReferenceTime());
|
||||
cp.setPacket(*getCamera(),getFrameStamp());
|
||||
|
||||
_bc.setBuffer(&cp, sizeof( CameraPacket ));
|
||||
_bc.sync();
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
// simple animation demo written by Graeme Harkness.
|
||||
// note from Robert to Robert. The animiation techinque
|
||||
// present here using glut timer callbacks is one
|
||||
// approach, other approaches will soon be supported
|
||||
// within the osg itself via an app cullback which
|
||||
// can be attached to nodes themselves. This later
|
||||
// method will be the prefered approach (have a look
|
||||
// at osgreflect's app visitor for a clue.)
|
||||
|
||||
|
||||
#include <osg/Geode>
|
||||
@@ -25,48 +18,60 @@
|
||||
// ----------------------------------------------------------------------
|
||||
// Global variables - this is basically the stuff which will be animated
|
||||
// ----------------------------------------------------------------------
|
||||
osg::Transform* myTransform;
|
||||
osg::GeoSet* cube;
|
||||
|
||||
int mytime=0; // in milliseconds
|
||||
unsigned int dt=50; // in milliseconds
|
||||
double omega=0.002; // in inverse milliseconds
|
||||
class TransformCallback : public osg::NodeCallback{
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// This is the callback function registered with GLUT to be called
|
||||
// at a future time in the GLUT loop
|
||||
// ----------------------------------------------------------------
|
||||
void timedCB( int delta_t )
|
||||
{
|
||||
public:
|
||||
|
||||
static float lastdx = 0;
|
||||
static float lastdy = 0;
|
||||
static float lastdz = 0;
|
||||
TransformCallback(osg::Transform* node,float angularVelocity)
|
||||
{
|
||||
_nodeToOperateOn = node;
|
||||
_angular_velocity = angularVelocity;
|
||||
_previousTraversalNumber = -1;
|
||||
_orig_t = _timer.tick();
|
||||
}
|
||||
|
||||
mytime+=dt;
|
||||
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (nv)
|
||||
{
|
||||
if (_nodeToOperateOn && node==_nodeToOperateOn)
|
||||
{
|
||||
// ensure that we do not operate on this node more than
|
||||
// once during this traversal. This is an issue since node
|
||||
// can be shared between multiple parents.
|
||||
if (nv->getTraversalNumber()!=_previousTraversalNumber)
|
||||
{
|
||||
osg::Timer_t new_t = _timer.tick();
|
||||
float delta_angle = _angular_velocity*_timer.delta_s(_orig_t,new_t);
|
||||
|
||||
osg::Matrix matrix;
|
||||
matrix.makeRot(delta_angle,1.0f,1.0f,1.0f);
|
||||
matrix.postTrans(1.0f,0.0f,0.0f);
|
||||
matrix.postRot(delta_angle,0.0f,0.0f,1.0f);
|
||||
|
||||
_nodeToOperateOn->setMatrix(matrix);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Update the Transform so that the cube will appear to oscillate
|
||||
// ---------------------------------------------------------
|
||||
double dx = 0.5 * cos( (double) omega * (double) mytime );
|
||||
double dy = 0.5 * sin( (double) omega * (double) mytime );
|
||||
double dz = 0.0;
|
||||
myTransform->preTranslate( -lastdx, -lastdy, -lastdz );
|
||||
myTransform->preTranslate( (float) dx, (float) dy, dz );
|
||||
lastdx=dx; lastdy=dy; lastdz=dz;
|
||||
_previousTraversalNumber = nv->getTraversalNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// must continue subgraph traversal.
|
||||
nv->traverse(*node);
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
osg::Transform* _nodeToOperateOn;
|
||||
float _angular_velocity;
|
||||
|
||||
// Graeme, commeted out this call as the cube itself remains static.
|
||||
// cube->dirtyDisplayList();
|
||||
|
||||
// -------------------------------------------
|
||||
// If required, reschedule the timed callback
|
||||
// -------------------------------------------
|
||||
if ( delta_t != 0 )
|
||||
{
|
||||
glutTimerFunc( (unsigned int) delta_t, timedCB, delta_t );
|
||||
}
|
||||
}
|
||||
int _previousTraversalNumber;
|
||||
osg::Timer _timer;
|
||||
osg::Timer_t _orig_t;
|
||||
|
||||
};
|
||||
|
||||
osg::Geode* createCube()
|
||||
{
|
||||
@@ -75,7 +80,7 @@ osg::Geode* createCube()
|
||||
// -------------------------------------------
|
||||
// Set up a new GeoSet which will be our cube
|
||||
// -------------------------------------------
|
||||
cube = new osg::GeoSet();
|
||||
osg::GeoSet* cube = new osg::GeoSet();
|
||||
|
||||
// set up the primitives
|
||||
cube->setPrimType( osg::GeoSet::POLYGON );
|
||||
@@ -145,10 +150,7 @@ osg::Geode* createCube()
|
||||
osg::StateSet* cubeState = new osg::StateSet();
|
||||
osg::Material* redMaterial = new osg::Material();
|
||||
osg::Vec4 red( 1.0f, 0.0f, 0.0f, 1.0f );
|
||||
redMaterial->setEmission( osg::Material::FRONT_AND_BACK, red );
|
||||
redMaterial->setAmbient( osg::Material::FRONT_AND_BACK, red );
|
||||
redMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, red );
|
||||
redMaterial->setSpecular( osg::Material::FRONT_AND_BACK, red );
|
||||
cubeState->setAttribute( redMaterial );
|
||||
|
||||
cube->setStateSet( cubeState );
|
||||
@@ -164,23 +166,19 @@ int main( int argc, char **argv )
|
||||
glutInit( &argc, argv );
|
||||
|
||||
|
||||
myTransform = new osg::Transform();
|
||||
osg::Transform* myTransform = new osg::Transform();
|
||||
myTransform->addChild( createCube() );
|
||||
|
||||
// move node in a circle at 90 degrees a sec.
|
||||
myTransform->setAppCallback(new TransformCallback(myTransform,90.0f));
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Register a timer callback with GLUT, in the first instance as a test
|
||||
// This will call the function "timedCB(value)" after dt ms
|
||||
// I have decided to use value as the time for the next scheduling
|
||||
// If the last parameter=0 then don't reschedule the timer.
|
||||
// ---------------------------------------------------------------------
|
||||
glutTimerFunc( dt, timedCB, dt );
|
||||
|
||||
// create the viewer and the model to it.
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.addViewport( myTransform );
|
||||
|
||||
// register trackball, flight and drive.
|
||||
// register trackball maniupulators.
|
||||
viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
|
||||
|
||||
|
||||
viewer.open();
|
||||
|
||||
viewer.run();
|
||||
|
||||
@@ -41,55 +41,64 @@
|
||||
// we apply them.
|
||||
|
||||
|
||||
// create an app visitor, to be used on each frame update,
|
||||
// the below app visitor rotates the loaded model.
|
||||
class AppVisitor : public osg::NodeVisitor {
|
||||
class TransformCallback : public osg::NodeCallback{
|
||||
|
||||
public:
|
||||
|
||||
bool _haveDoneTransformTransform;
|
||||
float _delta_angle;
|
||||
float _angular_velocity;
|
||||
osg::Vec3 _pivotPoint;
|
||||
osg::Transform* _modifyTransform;
|
||||
osg::Timer _timer;
|
||||
osg::Timer_t _previous_t;
|
||||
|
||||
AppVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||
TransformCallback(osg::Transform* node,float angularVelocity)
|
||||
{
|
||||
_haveDoneTransformTransform = true;
|
||||
_modifyTransform = NULL;
|
||||
_delta_angle = 0;
|
||||
_angular_velocity = 45; //degrees a sec.
|
||||
_nodeToOperateOn = node;
|
||||
if (node)
|
||||
{
|
||||
_pivotPoint = node->getBound().center();
|
||||
}
|
||||
|
||||
_angular_velocity = angularVelocity;
|
||||
_previousTraversalNumber = -1;
|
||||
_previous_t = _timer.tick();
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
// set to no transform done so far in this new traversal.
|
||||
_haveDoneTransformTransform = false;
|
||||
|
||||
// update angle of rotation.
|
||||
osg::Timer_t new_t = _timer.tick();
|
||||
_delta_angle = _angular_velocity*_timer.delta_s(_previous_t,new_t);
|
||||
_previous_t = new_t;
|
||||
|
||||
}
|
||||
|
||||
virtual void apply(osg::Transform& visitor_dcs)
|
||||
{
|
||||
|
||||
if (&visitor_dcs == _modifyTransform && !_haveDoneTransformTransform)
|
||||
if (nv)
|
||||
{
|
||||
// update the specified dcs.
|
||||
visitor_dcs.preTranslate(_pivotPoint[0],_pivotPoint[1],_pivotPoint[2]);
|
||||
visitor_dcs.preRotate(_delta_angle,0.0f,0.0f,1.0f);
|
||||
visitor_dcs.preTranslate(-_pivotPoint[0],-_pivotPoint[1],-_pivotPoint[2]);
|
||||
if (_nodeToOperateOn && node==_nodeToOperateOn)
|
||||
{
|
||||
// ensure that we do not operate on this node more than
|
||||
// once during this traversal. This is an issue since node
|
||||
// can be shared between multiple parents.
|
||||
if (nv->getTraversalNumber()!=_previousTraversalNumber)
|
||||
{
|
||||
osg::Timer_t new_t = _timer.tick();
|
||||
float delta_angle = _angular_velocity*_timer.delta_s(_previous_t,new_t);
|
||||
_previous_t = new_t;
|
||||
|
||||
// set to true to prevent applying rotation more than once
|
||||
// since the subgraph appears twice in the overall scene.
|
||||
_haveDoneTransformTransform = true;
|
||||
// update the specified dcs.
|
||||
_nodeToOperateOn->preTranslate(_pivotPoint[0],_pivotPoint[1],_pivotPoint[2]);
|
||||
_nodeToOperateOn->preRotate(delta_angle,0.0f,0.0f,1.0f);
|
||||
_nodeToOperateOn->preTranslate(-_pivotPoint[0],-_pivotPoint[1],-_pivotPoint[2]);
|
||||
|
||||
_previousTraversalNumber = nv->getTraversalNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// must continue subgraph traversal.
|
||||
nv->traverse(*node);
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
osg::Transform* _nodeToOperateOn;
|
||||
float _angular_velocity;
|
||||
osg::Vec3 _pivotPoint;
|
||||
|
||||
int _previousTraversalNumber;
|
||||
osg::Timer _timer;
|
||||
osg::Timer_t _previous_t;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -463,13 +472,7 @@ int main( int argc, char **argv )
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.addViewport( rootNode );
|
||||
|
||||
|
||||
// create and register the app visitor.
|
||||
AppVisitor* appVisitor = new AppVisitor();
|
||||
appVisitor->_modifyTransform = loadedModelTransform;
|
||||
appVisitor->_pivotPoint = bs.center();
|
||||
|
||||
viewer.getViewportSceneView(0)->setAppVisitor(appVisitor);
|
||||
loadedModelTransform->setAppCallback(new TransformCallback(loadedModelTransform,45.0f));
|
||||
|
||||
// register trackball, flight and drive.
|
||||
viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
#include <GL/glut.h>
|
||||
#include <osgGLUT/Viewer>
|
||||
|
||||
#include <osg/Quat>
|
||||
#include <osgUtil/OptimizeStateVisitor>
|
||||
|
||||
|
||||
/*
|
||||
* Function to read several files (typically one) as specified on the command
|
||||
@@ -130,6 +131,18 @@ int main( int argc, char **argv )
|
||||
osg::Timer_t after_load = timer.tick();
|
||||
cout << "Time for load = "<<timer.delta_s(before_load,after_load)<<" seconds"<<endl;
|
||||
|
||||
// note, the Microsoft visual C++ compilers can't handle the STL
|
||||
// in the OptimizeStateVisitor and crash if we run it. For the
|
||||
// time being we'll just not use the optimize visitor under windows.
|
||||
#ifndef WIN32
|
||||
// optimize the state in scene graph, removing duplicate state.
|
||||
osgUtil::OptimizeStateVisitor osv;
|
||||
rootnode->accept(osv);
|
||||
osv.optimize();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// initialize the viewer.
|
||||
osgGLUT::Viewer viewer;
|
||||
viewer.addViewport( rootnode );
|
||||
|
||||
@@ -82,6 +82,7 @@ void Billboard::calcRotation(const Vec3& eye_local, const Vec3& pos_local,Matrix
|
||||
float ev_length = ev.length();
|
||||
if (ev_length>0.0f)
|
||||
{
|
||||
mat.makeIdent();
|
||||
//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;
|
||||
|
||||
@@ -11,6 +11,8 @@ using namespace osg;
|
||||
Camera::Camera()
|
||||
{
|
||||
|
||||
_adjustAspectRatioMode = ADJUST_HORIZONTAL;
|
||||
|
||||
// projection details.
|
||||
setPerspective(60,1.0,1.0,1000.0);
|
||||
|
||||
@@ -117,6 +119,34 @@ void Camera::setPerspective(const double fovy,const double aspectRatio,
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/** Set a sysmetical perspective projection using field of view.*/
|
||||
void Camera::setFOV(const double fovx,const double fovy,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
_projectionType = PERSPECTIVE;
|
||||
|
||||
// note, in Frustum/Perspective mode these values are scaled
|
||||
// by the zNear from when they were initialised to ensure that
|
||||
// subsequent changes in zNear do not affect them.
|
||||
|
||||
// calculate the appropriate left, right etc.
|
||||
double tan_fovx = tan(DEG2RAD(fovx*0.5));
|
||||
double tan_fovy = tan(DEG2RAD(fovy*0.5));
|
||||
_right = tan_fovx;
|
||||
_left = -_right;
|
||||
_top = tan_fovy;
|
||||
_bottom = -_top;
|
||||
|
||||
_zNear = zNear;
|
||||
_zFar = zFar;
|
||||
|
||||
notify(INFO)<<"osg::Camera::setFOV(fovx="<<fovx<<",fovy="<<fovy<<","<<endl;
|
||||
notify(INFO)<<" zNear="<<zNear<<", zFar="<<zFar<<")"<<endl;
|
||||
notify(INFO)<<" osg::Camera::calc_fovx()="<<calc_fovx()<<endl;
|
||||
notify(INFO)<<" osg::Camera::calc_fovy()="<<calc_fovy()<<endl;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/** Set the near and far clipping planes.*/
|
||||
void Camera::setNearFar(const double zNear, const double zFar)
|
||||
@@ -134,7 +164,7 @@ void Camera::setNearFar(const double zNear, const double zFar)
|
||||
|
||||
/** Adjust the clipping planes to account for a new window aspcect ratio.
|
||||
* Typicall used after resizeing a window.*/
|
||||
void Camera::adjustAspectRatio(const double newAspectRatio, const AdjustAxis aa)
|
||||
void Camera::adjustAspectRatio(const double newAspectRatio, const AdjustAspectRatioMode aa)
|
||||
{
|
||||
double previousAspectRatio = (_right-_left)/(_top-_bottom);
|
||||
double deltaRatio = newAspectRatio/previousAspectRatio;
|
||||
@@ -668,15 +698,15 @@ void Camera::ensureOrthogonalUpVector()
|
||||
_up.normalize();
|
||||
}
|
||||
|
||||
const bool Camera::project(const Vec3& obj,const int* view,Vec3& win) const
|
||||
const bool Camera::project(const Vec3& obj,const Viewport& viewport,Vec3& win) const
|
||||
{
|
||||
if (_MP.valid())
|
||||
{
|
||||
Vec3 v = obj * (*_MP);
|
||||
|
||||
win.set(
|
||||
view[0] + view[2]*(v[0]+1.0f)*0.5f,
|
||||
view[1] + view[3]*(v[1]+1.0f)*0.5f,
|
||||
(float)viewport.x() + (float)viewport.width()*(v[0]+1.0f)*0.5f,
|
||||
(float)viewport.y() + (float)viewport.height()*(v[1]+1.0f)*0.5f,
|
||||
(v[2]+1.0f)*0.5f
|
||||
);
|
||||
|
||||
@@ -686,13 +716,13 @@ const bool Camera::project(const Vec3& obj,const int* view,Vec3& win) const
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool Camera::unproject(const Vec3& win,const int* view,Vec3& obj) const
|
||||
const bool Camera::unproject(const Vec3& win,const Viewport& viewport,Vec3& obj) const
|
||||
{
|
||||
if (_inverseMP.valid())
|
||||
{
|
||||
Vec3 v(
|
||||
2.0f*(win[0]-view[0])/view[2] - 1.0f,
|
||||
2.0f*(win[1]-view[1])/view[3] - 1.0f,
|
||||
2.0f*(win[0]-(float)viewport.x())/viewport.width() - 1.0f,
|
||||
2.0f*(win[1]-(float)viewport.y())/viewport.height() - 1.0f,
|
||||
2.0f*(win[2]) - 1.0f
|
||||
);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ using namespace osg;
|
||||
|
||||
ClipPlane::ClipPlane()
|
||||
{
|
||||
_clipPlane = new double[4];
|
||||
_clipPlane[0] = 0.0;
|
||||
_clipPlane[1] = 0.0;
|
||||
_clipPlane[2] = 0.0;
|
||||
@@ -16,7 +15,6 @@ ClipPlane::ClipPlane()
|
||||
|
||||
ClipPlane::~ClipPlane()
|
||||
{
|
||||
delete _clipPlane;
|
||||
}
|
||||
|
||||
void ClipPlane::setClipPlane(const Vec4& plane)
|
||||
@@ -68,17 +66,10 @@ void ClipPlane::getClipPlane(Plane& plane) const
|
||||
|
||||
void ClipPlane::getClipPlane(double* plane) const
|
||||
{
|
||||
if (plane)
|
||||
{
|
||||
plane[0] = _clipPlane[0];
|
||||
plane[1] = _clipPlane[1];
|
||||
plane[2] = _clipPlane[2];
|
||||
plane[3] = _clipPlane[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(WARN)<<"Warning: ClipPlane::getClipPlane() passed NULL plane array, ignoring operation."<<endl;
|
||||
}
|
||||
plane[0] = _clipPlane[0];
|
||||
plane[1] = _clipPlane[1];
|
||||
plane[2] = _clipPlane[2];
|
||||
plane[3] = _clipPlane[3];
|
||||
}
|
||||
|
||||
void ClipPlane::setClipPlaneNum(const unsigned int num)
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
#include <math.h>
|
||||
#include "osg/Geode"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef __sgi
|
||||
using std::find;
|
||||
using std::for_each;
|
||||
#endif
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
using namespace osg;
|
||||
|
||||
@@ -5,12 +5,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// #ifdef __sgi
|
||||
// using std::find;
|
||||
// using std::for_each;
|
||||
// using std::string;
|
||||
// #endif
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
using namespace osg;
|
||||
@@ -58,6 +52,16 @@ bool Group::addChild( Node *child )
|
||||
|
||||
dirtyBound();
|
||||
|
||||
// could now require app traversal thanks to the new subgraph,
|
||||
// so need to check and update if required.
|
||||
if (child->getNumChildrenRequiringAppTraversal()>0 ||
|
||||
child->getAppCallback())
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(
|
||||
getNumChildrenRequiringAppTraversal()+1
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
@@ -73,10 +77,23 @@ bool Group::removeChild( Node *child )
|
||||
ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),this);
|
||||
if (pitr!=child->_parents.end()) child->_parents.erase(pitr);
|
||||
|
||||
// could now require app traversal thanks to the new subgraph,
|
||||
// so need to check and update if required.
|
||||
// note, need to do this checking before the erase of the child
|
||||
// otherwise child will be invalid.
|
||||
if (child->getNumChildrenRequiringAppTraversal()>0 ||
|
||||
child->getAppCallback())
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(
|
||||
getNumChildrenRequiringAppTraversal()-1
|
||||
);
|
||||
}
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing child's reference count.
|
||||
_children.erase(itr);
|
||||
dirtyBound();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
@@ -41,7 +41,7 @@ ImpostorSprite::~ImpostorSprite()
|
||||
}
|
||||
}
|
||||
|
||||
const float ImpostorSprite::calcPixelError(const Camera& camera,const int* viewport,const osg::Matrix* matrix) const
|
||||
const float ImpostorSprite::calcPixelError(const Camera& camera,const Viewport& viewport,const osg::Matrix* matrix) const
|
||||
{
|
||||
// find the maximum screen space pixel error between the control coords and the quad coners.
|
||||
float max_error_sqrd = 0.0f;
|
||||
@@ -139,6 +139,12 @@ void ImpostorSprite::setTexture(Texture* tex,int s,int t)
|
||||
|
||||
ImpostorSpriteManager::ImpostorSpriteManager()
|
||||
{
|
||||
_texenv = new TexEnv;
|
||||
_texenv->setMode(TexEnv::REPLACE);
|
||||
|
||||
_alphafunc = new osg::AlphaFunc;
|
||||
_alphafunc->setFunction( AlphaFunc::GREATER, 0.000f );
|
||||
|
||||
_first = NULL;
|
||||
_last = NULL;
|
||||
}
|
||||
@@ -250,8 +256,12 @@ ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,i
|
||||
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
|
||||
|
||||
Texture* texture = new Texture;
|
||||
stateset->setAttributeAndModes(texture,StateAttribute::ON);
|
||||
|
||||
stateset->setAttributeAndModes(texture,StateAttribute::ON);
|
||||
stateset->setAttributeAndModes( _alphafunc.get(), StateAttribute::ON );
|
||||
stateset->setAttribute(_texenv.get());
|
||||
|
||||
/*
|
||||
TexEnv* texenv = new TexEnv;
|
||||
texenv->setMode(TexEnv::REPLACE);
|
||||
stateset->setAttribute(texenv);
|
||||
@@ -259,6 +269,8 @@ ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,i
|
||||
AlphaFunc* alphafunc = new osg::AlphaFunc;
|
||||
alphafunc->setFunction( AlphaFunc::GREATER, 0.000f );
|
||||
stateset->setAttributeAndModes( alphafunc, StateAttribute::ON );
|
||||
*/
|
||||
|
||||
|
||||
// stateset->setMode( GL_ALPHA_TEST, StateAttribute::OFF );
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ C++FILES = \
|
||||
Depth.cpp \
|
||||
Drawable.cpp\
|
||||
Fog.cpp\
|
||||
FrameStamp.cpp\
|
||||
FrontFace.cpp\
|
||||
Geode.cpp\
|
||||
GeoSet.cpp\
|
||||
@@ -48,6 +49,7 @@ C++FILES = \
|
||||
Transform.cpp\
|
||||
Transparency.cpp\
|
||||
Version.cpp\
|
||||
Viewport.cpp\
|
||||
|
||||
|
||||
TARGET_BASENAME = osg
|
||||
@@ -69,6 +71,7 @@ TARGET_INCLUDE_FILES = \
|
||||
osg/Drawable\
|
||||
osg/Export\
|
||||
osg/Fog\
|
||||
osg/FrameStamp\
|
||||
osg/FrontFace\
|
||||
osg/GL\
|
||||
osg/GLExtensions\
|
||||
@@ -86,6 +89,7 @@ TARGET_INCLUDE_FILES = \
|
||||
osg/Matrix\
|
||||
osg/MemoryAdapter\
|
||||
osg/Node\
|
||||
osg/NodeCallback\
|
||||
osg/NodeVisitor\
|
||||
osg/Notify\
|
||||
osg/Object\
|
||||
@@ -112,6 +116,7 @@ TARGET_INCLUDE_FILES = \
|
||||
osg/Vec3\
|
||||
osg/Vec4\
|
||||
osg/Version\
|
||||
osg/Viewport\
|
||||
osg/mem_ptr\
|
||||
osg/ref_ptr\
|
||||
|
||||
|
||||
@@ -1,418 +1,90 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <osg/Types>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Quat>
|
||||
#include <osg/Notify>
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Types>
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
#define RAD2DEG(x) ((x)*180.0/M_PI)
|
||||
#include <cstdlib> //memcpy
|
||||
#include <cmath> //acos
|
||||
|
||||
using namespace osg;
|
||||
|
||||
typedef struct quaternion_
|
||||
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
#define RAD2DEG(x) ((x)*180.0/M_PI)
|
||||
|
||||
|
||||
//#define WARN_DEPRECATED
|
||||
#define ANGLES_IN_DEGREES
|
||||
|
||||
#define SET_ROW(row, v1, v2, v3, v4 ) \
|
||||
_mat[(row)][0] = (v1); \
|
||||
_mat[(row)][1] = (v2); \
|
||||
_mat[(row)][2] = (v3); \
|
||||
_mat[(row)][3] = (v4);
|
||||
|
||||
#define INNER_PRODUCT(a,b,r,c) \
|
||||
((a)._mat[r][0] * (b)._mat[0][c]) \
|
||||
+((a)._mat[r][1] * (b)._mat[1][c]) \
|
||||
+((a)._mat[r][2] * (b)._mat[2][c]) \
|
||||
+((a)._mat[r][3] * (b)._mat[3][c])
|
||||
|
||||
|
||||
Matrix::Matrix() : Object(), fully_realized(false) {}
|
||||
|
||||
Matrix::Matrix( const Matrix& other ) : Object()
|
||||
{
|
||||
double x ;
|
||||
double y ;
|
||||
double z ;
|
||||
double w ;
|
||||
} quaternion ;
|
||||
set( (float const * const) other._mat );
|
||||
}
|
||||
|
||||
/* C = a(row).b(row) */
|
||||
Matrix::Matrix( float const * const def )
|
||||
{
|
||||
set( def );
|
||||
}
|
||||
|
||||
#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] )
|
||||
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)
|
||||
{
|
||||
/* copied from Shoemake/ACM SIGGRAPH 89 */
|
||||
double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz ;
|
||||
SET_ROW(0, a00, a01, a02, a03 )
|
||||
SET_ROW(1, a10, a11, a12, a13 )
|
||||
SET_ROW(2, a20, a21, a22, a23 )
|
||||
SET_ROW(3, a30, a31, a32, a33 )
|
||||
|
||||
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;
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
Matrix& Matrix::operator = (const Matrix& other ) {
|
||||
if( &other == this ) return *this;
|
||||
set((const float*)other._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;
|
||||
void Matrix::set( float const * const def ) {
|
||||
memcpy( _mat, def, sizeof(_mat) );
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
|
||||
Matrix::~Matrix()
|
||||
void Matrix::set( float a00, float a01, float a02, float a03,
|
||||
float a10, float a11, float a12, float a13,
|
||||
float a20, float a21, float a22, float a23,
|
||||
float a30, float a31, float a32, float a33)
|
||||
{
|
||||
SET_ROW(0, a00, a01, a02, a03 )
|
||||
SET_ROW(1, a10, a11, a12, a13 )
|
||||
SET_ROW(2, a20, a21, a22, a23 )
|
||||
SET_ROW(3, a30, a31, a32, a33 )
|
||||
|
||||
fully_realized = 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::set(const float* m)
|
||||
{
|
||||
_mat[0][0] = m[0];
|
||||
_mat[0][1] = m[1];
|
||||
_mat[0][2] = m[2];
|
||||
_mat[0][3] = m[3];
|
||||
|
||||
_mat[1][0] = m[4];
|
||||
_mat[1][1] = m[5];
|
||||
_mat[1][2] = m[6];
|
||||
_mat[1][3] = m[7];
|
||||
|
||||
_mat[2][0] = m[8];
|
||||
_mat[2][1] = m[9];
|
||||
_mat[2][2] = m[10];
|
||||
_mat[2][3] = m[11];
|
||||
|
||||
_mat[3][0] = m[12];
|
||||
_mat[3][1] = m[13];
|
||||
_mat[3][2] = m[14];
|
||||
_mat[3][3] = m[15];
|
||||
}
|
||||
|
||||
|
||||
void Matrix::set(
|
||||
float a00, float a01, float a02, float a03,
|
||||
float a10, float a11, float a12, float a13,
|
||||
float a20, float a21, float a22, float a23,
|
||||
float a30, float a31, float a32, float a33)
|
||||
{
|
||||
_mat[0][0] = a00;
|
||||
_mat[0][1] = a01;
|
||||
_mat[0][2] = a02;
|
||||
_mat[0][3] = a03;
|
||||
|
||||
_mat[1][0] = a10;
|
||||
_mat[1][1] = a11;
|
||||
_mat[1][2] = a12;
|
||||
_mat[1][3] = a13;
|
||||
|
||||
_mat[2][0] = a20;
|
||||
_mat[2][1] = a21;
|
||||
_mat[2][2] = a22;
|
||||
_mat[2][3] = a23;
|
||||
|
||||
_mat[3][0] = a30;
|
||||
_mat[3][1] = a31;
|
||||
_mat[3][2] = a32;
|
||||
_mat[3][3] = a33;
|
||||
}
|
||||
|
||||
void Matrix::copy(const Matrix& matrix)
|
||||
{
|
||||
memcpy(_mat,matrix._mat,sizeof(_mat));
|
||||
}
|
||||
|
||||
|
||||
void Matrix::makeScale(float sx, float sy, float sz)
|
||||
{
|
||||
makeIdent();
|
||||
_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( const Vec3& old_vec, const Vec3& new_vec )
|
||||
{
|
||||
/* dot product == cos(angle old_vec<>new_vec). */
|
||||
double d = new_vec * old_vec;
|
||||
if ( d < 0.9999 )
|
||||
{
|
||||
double angle = acos( d );
|
||||
Vec3 rot_axis = new_vec ^ old_vec;
|
||||
makeRot( RAD2DEG(angle),
|
||||
rot_axis.x(), rot_axis.y(), rot_axis.z() );
|
||||
}
|
||||
else
|
||||
makeIdent();
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float deg, float x, float y, float z )
|
||||
{
|
||||
double __mat[4][4];
|
||||
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 )
|
||||
{
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::setTrans is deprecated.";
|
||||
#endif
|
||||
_mat[3][0] = tx;
|
||||
_mat[3][1] = ty;
|
||||
_mat[3][2] = tz;
|
||||
@@ -421,62 +93,238 @@ void Matrix::setTrans( float tx, float ty, float tz )
|
||||
|
||||
void Matrix::setTrans( const Vec3& v )
|
||||
{
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::setTrans is deprecated.";
|
||||
#endif
|
||||
_mat[3][0] = v[0];
|
||||
_mat[3][1] = v[1];
|
||||
_mat[3][2] = v[2];
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preMult(const Matrix& m)
|
||||
void Matrix::makeIdent()
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( m._mat, _mat, tm._mat );
|
||||
*this = tm;
|
||||
SET_ROW(0, 1, 0, 0, 0 )
|
||||
SET_ROW(1, 0, 1, 0, 0 )
|
||||
SET_ROW(2, 0, 0, 1, 0 )
|
||||
SET_ROW(3, 0, 0, 0, 1 )
|
||||
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
|
||||
void Matrix::postMult(const Matrix& m)
|
||||
void Matrix::makeScale( const Vec3& v )
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( _mat, m._mat, tm._mat );
|
||||
*this = tm;
|
||||
makeScale(v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
|
||||
void Matrix::mult(const Matrix& lhs,const Matrix& rhs)
|
||||
void Matrix::makeScale( float x, float y, float z )
|
||||
{
|
||||
if (&lhs==this || &rhs==this)
|
||||
{
|
||||
osg::Matrix tm;
|
||||
matrix_mult( lhs._mat, rhs._mat, tm._mat );
|
||||
*this = tm;
|
||||
SET_ROW(0, x, 0, 0, 0 )
|
||||
SET_ROW(1, 0, y, 0, 0 )
|
||||
SET_ROW(2, 0, 0, z, 0 )
|
||||
SET_ROW(3, 0, 0, 0, 1 )
|
||||
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
void Matrix::makeTrans( const Vec3& v )
|
||||
{
|
||||
makeTrans( v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
void Matrix::makeTrans( float x, float y, float z )
|
||||
{
|
||||
SET_ROW(0, 1, 0, 0, 0 )
|
||||
SET_ROW(1, 0, 1, 0, 0 )
|
||||
SET_ROW(2, 0, 0, 1, 0 )
|
||||
SET_ROW(3, x, y, z, 1 )
|
||||
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
void Matrix::makeRot( const Vec3& from, const Vec3& to )
|
||||
{
|
||||
double d = from * to; // dot product == cos( angle between from & to )
|
||||
if( d < 0.9999 ) {
|
||||
double angle = acos(d);
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
angle = RAD2DEG(angle);
|
||||
#endif
|
||||
Vec3 axis = to ^ from; //we know ((to) x (from)) is perpendicular to both
|
||||
makeRot( angle, axis );
|
||||
}
|
||||
else
|
||||
makeIdent();
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float angle, const Vec3& axis )
|
||||
{
|
||||
makeRot( angle, axis.x(), axis.y(), axis.z() );
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float angle, float x, float y, float z ) {
|
||||
float d = sqrt( x*x + y*y + z*z );
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
angle = DEG2RAD(angle);
|
||||
#endif
|
||||
|
||||
float sin_half = sin( angle/2 );
|
||||
float cos_half = cos( angle/2 );
|
||||
|
||||
Quat q( sin_half * (x/d),
|
||||
sin_half * (y/d),
|
||||
sin_half * (z/d),
|
||||
cos_half );//NOTE: original used a private quaternion made of doubles
|
||||
makeRot( q ); // but Quat stores the values in a Vec4 made of floats.
|
||||
}
|
||||
|
||||
void Matrix::makeRot( const Quat& q ) {
|
||||
// taken from Shoemake/ACM SIGGRAPH 89
|
||||
Vec4 v = q.asVec4();
|
||||
|
||||
double xs = 2 * v.x(); //assume q is already normalized? assert?
|
||||
double ys = 2 * v.y(); // if not, xs = 2 * v.x() / d, ys = 2 * v.y() / d
|
||||
double zs = 2 * v.z(); // and zs = 2 * v.z() /d where d = v.length2()
|
||||
|
||||
double xx = xs * v.x();
|
||||
double xy = ys * v.x();
|
||||
double xz = zs * v.x();
|
||||
double yy = ys * v.y();
|
||||
double yz = zs * v.y();
|
||||
double zz = zs * v.z();
|
||||
double wx = xs * v.w();
|
||||
double wy = ys * v.w();
|
||||
double wz = zs * v.w();
|
||||
|
||||
SET_ROW(0, 1.0-(yy+zz), xy - wz, xz + wy, 0.0 )
|
||||
SET_ROW(1, xy + wz, 1.0-(xx+zz),yz - wx, 0.0 )
|
||||
SET_ROW(2, xz - wy, yz + wx, 1.0-(xx+yy),0.0 )
|
||||
SET_ROW(3, 0.0, 0.0, 0.0, 1.0 )
|
||||
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float yaw, float pitch, float roll)
|
||||
{
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
yaw = DEG2RAD(yaw);
|
||||
pitch = DEG2RAD(pitch);
|
||||
roll = DEG2RAD(roll);
|
||||
#endif
|
||||
|
||||
// lifted straight from SOLID library v1.01 Quaternion.h
|
||||
// available from http://www.win.tue.nl/~gino/solid/
|
||||
// and also distributed under the LGPL
|
||||
float cosYaw = cos(yaw / 2);
|
||||
float sinYaw = sin(yaw / 2);
|
||||
float cosPitch = cos(pitch / 2);
|
||||
float sinPitch = sin(pitch / 2);
|
||||
float cosRoll = cos(roll / 2);
|
||||
float sinRoll = sin(roll / 2);
|
||||
Quat q(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
|
||||
cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
|
||||
cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
|
||||
cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
|
||||
makeRot( q );
|
||||
}
|
||||
|
||||
void Matrix::mult( const Matrix& lhs, const Matrix& rhs )
|
||||
{
|
||||
// PRECONDITION: We assume neither &lhs nor &rhs == this
|
||||
// if it did, use preMult or postMult instead
|
||||
_mat[0][0] = INNER_PRODUCT(lhs, rhs, 0, 0);
|
||||
_mat[0][1] = INNER_PRODUCT(lhs, rhs, 0, 1);
|
||||
_mat[0][2] = INNER_PRODUCT(lhs, rhs, 0, 2);
|
||||
_mat[0][3] = INNER_PRODUCT(lhs, rhs, 0, 3);
|
||||
_mat[1][0] = INNER_PRODUCT(lhs, rhs, 1, 0);
|
||||
_mat[1][1] = INNER_PRODUCT(lhs, rhs, 1, 1);
|
||||
_mat[1][2] = INNER_PRODUCT(lhs, rhs, 1, 2);
|
||||
_mat[1][3] = INNER_PRODUCT(lhs, rhs, 1, 3);
|
||||
_mat[2][0] = INNER_PRODUCT(lhs, rhs, 2, 0);
|
||||
_mat[2][1] = INNER_PRODUCT(lhs, rhs, 2, 1);
|
||||
_mat[2][2] = INNER_PRODUCT(lhs, rhs, 2, 2);
|
||||
_mat[2][3] = INNER_PRODUCT(lhs, rhs, 2, 3);
|
||||
_mat[3][0] = INNER_PRODUCT(lhs, rhs, 3, 0);
|
||||
_mat[3][1] = INNER_PRODUCT(lhs, rhs, 3, 1);
|
||||
_mat[3][2] = INNER_PRODUCT(lhs, rhs, 3, 2);
|
||||
_mat[3][3] = INNER_PRODUCT(lhs, rhs, 3, 3);
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
void Matrix::preMult( const Matrix& other )
|
||||
{
|
||||
if( !fully_realized ) {
|
||||
//act as if this were an identity Matrix
|
||||
set((const float*)other._mat);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
// brute force method requiring a copy
|
||||
//Matrix tmp(other* *this);
|
||||
// *this = tmp;
|
||||
|
||||
// more efficient method just use a float[4] for temporary storage.
|
||||
float t[4];
|
||||
for(int col=0; col<4; ++col) {
|
||||
t[0] = INNER_PRODUCT( other, *this, 0, col );
|
||||
t[1] = INNER_PRODUCT( other, *this, 1, col );
|
||||
t[2] = INNER_PRODUCT( other, *this, 2, col );
|
||||
t[3] = INNER_PRODUCT( other, *this, 3, col );
|
||||
_mat[0][col] = t[0];
|
||||
_mat[1][col] = t[1];
|
||||
_mat[2][col] = t[2];
|
||||
_mat[3][col] = t[3];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Matrix::postMult( const Matrix& other )
|
||||
{
|
||||
if( !fully_realized ) {
|
||||
//act as if this were an identity Matrix
|
||||
set((const float*)other._mat);
|
||||
return;
|
||||
}
|
||||
// brute force method requiring a copy
|
||||
//Matrix tmp(*this * other);
|
||||
// *this = tmp;
|
||||
|
||||
// more efficient method just use a float[4] for temporary storage.
|
||||
float t[4];
|
||||
for(int row=0; row<4; ++row)
|
||||
{
|
||||
matrix_mult( lhs._mat, rhs._mat, _mat );
|
||||
t[0] = INNER_PRODUCT( *this, other, row, 0 );
|
||||
t[1] = INNER_PRODUCT( *this, other, row, 1 );
|
||||
t[2] = INNER_PRODUCT( *this, other, row, 2 );
|
||||
t[3] = INNER_PRODUCT( *this, other, row, 3 );
|
||||
SET_ROW(row, t[0], t[1], t[2], t[3] )
|
||||
}
|
||||
}
|
||||
|
||||
#undef SET_ROW
|
||||
#undef INNER_PRODUCT
|
||||
|
||||
Matrix Matrix::operator * (const Matrix& m) const
|
||||
bool Matrix::invert( const Matrix& _m )
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( _mat,m._mat, tm._mat );
|
||||
return tm;
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::invert(const Matrix& invm)
|
||||
{
|
||||
if (&invm==this) {
|
||||
Matrix tm(invm);
|
||||
if (&_m==this)
|
||||
{
|
||||
Matrix tm(_m);
|
||||
return invert(tm);
|
||||
}
|
||||
/*if ( _m._mat[0][3] == 0.0
|
||||
&& _m._mat[1][3] == 0.0
|
||||
&& _m._mat[2][3] == 0.0
|
||||
&& _m._mat[3][3] == 1.0 )
|
||||
{
|
||||
return invertAffine( _m );
|
||||
}*/
|
||||
|
||||
// code lifted from VR Juggler.
|
||||
// not cleanly added, but seems to work. RO.
|
||||
|
||||
const float* a = reinterpret_cast<const float*>(invm._mat);
|
||||
const float* a = reinterpret_cast<const float*>(_m._mat);
|
||||
float* b = reinterpret_cast<float*>(_mat);
|
||||
|
||||
int n = 4;
|
||||
@@ -491,7 +339,7 @@ bool Matrix::invert(const Matrix& invm)
|
||||
row[ i] = col[ i] = 0;
|
||||
}
|
||||
|
||||
/* Set working matrix */
|
||||
/* Set working Matrix */
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
for ( j = 0; j < n; j++ )
|
||||
@@ -555,7 +403,7 @@ bool Matrix::invert(const Matrix& invm)
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign invers to a matrix */
|
||||
/* Assign invers to a Matrix */
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = 0; j < n; j++ )
|
||||
row[ i] = ( c[ j] == i ) ? r[j] : row[ i];
|
||||
@@ -566,3 +414,154 @@ bool Matrix::invert(const Matrix& invm)
|
||||
|
||||
return true; // It worked
|
||||
}
|
||||
|
||||
const double PRECISION_LIMIT = 1.0e-15;
|
||||
|
||||
bool Matrix::invertAffine( const Matrix& _m )
|
||||
{
|
||||
// adapted from Graphics Gems II.
|
||||
//
|
||||
// This method treats the Matrix as a block Matrix and calculates
|
||||
// the inverse of one subMatrix, improving performance over something
|
||||
// that inverts any non-singular Matrix:
|
||||
// -1
|
||||
// -1 [ A 0 ] -1 [ A 0 ]
|
||||
// M = [ ] = [ -1 ]
|
||||
// [ C 1 ] [-CA 1 ]
|
||||
//
|
||||
// returns true if _m is nonsingular, and (*this) contains its inverse
|
||||
// otherwise returns false. (*this unchanged)
|
||||
|
||||
// assert( this->isAffine())?
|
||||
double det_1, pos, neg, temp;
|
||||
|
||||
pos = neg = 0.0;
|
||||
|
||||
#define ACCUMULATE \
|
||||
{ \
|
||||
if(temp >= 0.0) pos += temp; \
|
||||
else neg += temp; \
|
||||
}
|
||||
|
||||
temp = _m._mat[0][0] * _m._mat[1][1] * _m._mat[2][2]; ACCUMULATE;
|
||||
temp = _m._mat[0][1] * _m._mat[1][2] * _m._mat[2][0]; ACCUMULATE;
|
||||
temp = _m._mat[0][2] * _m._mat[1][0] * _m._mat[2][1]; ACCUMULATE;
|
||||
|
||||
temp = - _m._mat[0][2] * _m._mat[1][1] * _m._mat[2][0]; ACCUMULATE;
|
||||
temp = - _m._mat[0][1] * _m._mat[1][0] * _m._mat[2][2]; ACCUMULATE;
|
||||
temp = - _m._mat[0][0] * _m._mat[1][2] * _m._mat[2][1]; ACCUMULATE;
|
||||
|
||||
det_1 = pos + neg;
|
||||
|
||||
if( (det_1 == 0.0) || (abs(det_1/(pos-neg)) < PRECISION_LIMIT )) {
|
||||
// _m has no inverse
|
||||
notify(WARN) << "Matrix::invert(): Matrix has no inverse." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// inverse is adj(A)/det(A)
|
||||
det_1 = 1.0 / det_1;
|
||||
|
||||
_mat[0][0] = (_m._mat[1][1] * _m._mat[2][2] - _m._mat[1][2] * _m._mat[2][1]) * det_1;
|
||||
_mat[1][0] = (_m._mat[1][0] * _m._mat[2][2] - _m._mat[1][2] * _m._mat[2][0]) * det_1;
|
||||
_mat[2][0] = (_m._mat[1][0] * _m._mat[2][1] - _m._mat[1][1] * _m._mat[2][0]) * det_1;
|
||||
_mat[0][1] = (_m._mat[0][1] * _m._mat[2][2] - _m._mat[0][2] * _m._mat[2][1]) * det_1;
|
||||
_mat[1][1] = (_m._mat[0][0] * _m._mat[2][2] - _m._mat[0][2] * _m._mat[2][0]) * det_1;
|
||||
_mat[2][1] = (_m._mat[0][0] * _m._mat[2][1] - _m._mat[0][1] * _m._mat[2][0]) * det_1;
|
||||
_mat[0][2] = (_m._mat[0][1] * _m._mat[1][2] - _m._mat[0][2] * _m._mat[1][1]) * det_1;
|
||||
_mat[1][2] = (_m._mat[0][0] * _m._mat[1][2] - _m._mat[0][2] * _m._mat[1][0]) * det_1;
|
||||
_mat[2][2] = (_m._mat[0][0] * _m._mat[1][1] - _m._mat[0][1] * _m._mat[1][0]) * det_1;
|
||||
|
||||
// calculate -C * inv(A)
|
||||
_mat[3][0] = -(_m._mat[3][0] * _mat[0][0] + _m._mat[3][1] * _mat[1][0] + _m._mat[3][2] * _mat[2][0] );
|
||||
_mat[3][1] = -(_m._mat[3][0] * _mat[0][1] + _m._mat[3][1] * _mat[1][1] + _m._mat[3][2] * _mat[2][1] );
|
||||
_mat[3][2] = -(_m._mat[3][0] * _mat[0][2] + _m._mat[3][1] * _mat[1][2] + _m._mat[3][2] * _mat[2][2] );
|
||||
|
||||
_mat[0][3] = 0.0;
|
||||
_mat[1][3] = 0.0;
|
||||
_mat[2][3] = 0.0;
|
||||
_mat[3][3] = 1.0;
|
||||
|
||||
fully_realized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//Deprecated methods
|
||||
void Matrix::copy( const Matrix& other) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::copy is deprecated. Use = instead.";
|
||||
#endif
|
||||
(*this) = other;
|
||||
}
|
||||
void Matrix::preScale( float sx, float sy, float sz, const Matrix& m ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preScale is deprecated. Use result = (Matrix::scale * m) instead.";
|
||||
#endif
|
||||
(*this) = ( scale(sx,sy,sz) * m );
|
||||
}
|
||||
void Matrix::postScale( const Matrix& m, float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postScale is deprecated. Use result = (m * Matrix::scale()) instead.";
|
||||
#endif
|
||||
(*this) = ( m * scale(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::preScale( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preScale is deprecated. Use M.preMult( Matrix::scale ) instead.";
|
||||
#endif
|
||||
preMult( scale(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::postScale( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postScale is deprecated. Use M.postMult( Matrix::scale ) instead.";
|
||||
#endif
|
||||
postMult( scale(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.";
|
||||
#endif
|
||||
(*this) = trans(tx,ty,tz) * m;
|
||||
}
|
||||
void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.";
|
||||
#endif
|
||||
(*this) = m * trans(tx,ty,tz);
|
||||
}
|
||||
void Matrix::preTrans( float tx, float ty, float tz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.";
|
||||
#endif
|
||||
preMult( trans(tx,ty,tz) );
|
||||
}
|
||||
void Matrix::postTrans( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.";
|
||||
#endif
|
||||
postMult( trans(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preRot is deprecated. Use result = Matrix::rot * m instead.";
|
||||
#endif
|
||||
(*this) = rotate(deg,x,y,z) * m;
|
||||
}
|
||||
void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postRot is deprecated. Use result = m * Matrix::rotate instead.";
|
||||
#endif
|
||||
(*this) = m * rotate(deg,x,y,z);
|
||||
}
|
||||
void Matrix::preRot( float deg, float x, float y, float z ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preRot is deprecated. Use m.preMult( Matrix::rotate ) instead.";
|
||||
#endif
|
||||
preMult( rotate(deg,x,y,z) );
|
||||
}
|
||||
void Matrix::postRot( float deg, float x, float y, float z ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postRot is deprecated. Use m.postMult( Matrix::rotate ) instead.";
|
||||
#endif
|
||||
postMult( rotate(deg,x,y,z) );
|
||||
}
|
||||
|
||||
@@ -8,7 +8,12 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
#define RAD2DEG(x) ((x)*180.0/M_PI)
|
||||
|
||||
|
||||
#define WARN_DEPRECATED
|
||||
#define ANGLES_IN_DEGREES
|
||||
|
||||
Matrix::Matrix() : Object(), fully_realized(false) {}
|
||||
|
||||
@@ -86,11 +91,10 @@ void Matrix::set(
|
||||
}
|
||||
|
||||
#define SET_ROW(row, v1, v2, v3, v4 ) \
|
||||
_mat[0][(row)] = (v1); \
|
||||
_mat[1][(row)] = (v2); \
|
||||
_mat[2][(row)] = (v3); \
|
||||
_mat[3][(row)] = (v4);
|
||||
|
||||
_mat[(row)][0] = (v1); \
|
||||
_mat[(row)][1] = (v2); \
|
||||
_mat[(row)][2] = (v3); \
|
||||
_mat[(row)][3] = (v4);
|
||||
|
||||
void Matrix::makeIdent() {
|
||||
SET_ROW(0, 1, 0, 0, 0 )
|
||||
@@ -119,10 +123,10 @@ void Matrix::makeTrans( const Vec3& v ) {
|
||||
}
|
||||
|
||||
void Matrix::makeTrans( float x, float y, float z ) {
|
||||
SET_ROW(0, 1, 0, 0, x )
|
||||
SET_ROW(1, 0, 1, 0, y )
|
||||
SET_ROW(2, 0, 0, 1, z )
|
||||
SET_ROW(3, 0, 0, 0, 1 )
|
||||
SET_ROW(0, 1, 0, 0, 0 )
|
||||
SET_ROW(1, 0, 1, 0, 0 )
|
||||
SET_ROW(2, 0, 0, 1, 0 )
|
||||
SET_ROW(3, x, y, z, 1 )
|
||||
|
||||
fully_realized = true;
|
||||
}
|
||||
@@ -131,6 +135,9 @@ void Matrix::makeRot( const Vec3& from, const Vec3& to ) {
|
||||
double d = from * to; // dot product == cos( angle between from & to )
|
||||
if( d < 0.9999 ) {
|
||||
double angle = acos(d);
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
angle = RAD2DEG(angle);
|
||||
#endif
|
||||
Vec3 axis = to ^ from; //we know ((to) x (from)) is perpendicular to both
|
||||
makeRot( angle, axis );
|
||||
}
|
||||
@@ -138,7 +145,8 @@ void Matrix::makeRot( const Vec3& from, const Vec3& to ) {
|
||||
makeIdent();
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float angle, const Vec3& axis ) {
|
||||
void Matrix::makeRot( float angle, const Vec3& axis )
|
||||
{
|
||||
makeRot( angle, axis.x(), axis.y(), axis.z() );
|
||||
}
|
||||
|
||||
@@ -147,6 +155,10 @@ void Matrix::makeRot( float angle, float x, float y, float z ) {
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
angle = DEG2RAD(angle);
|
||||
#endif
|
||||
|
||||
float sin_half = sin( angle/2 );
|
||||
float cos_half = cos( angle/2 );
|
||||
|
||||
@@ -175,15 +187,22 @@ void Matrix::makeRot( const Quat& q ) {
|
||||
double wy = ys * v.w();
|
||||
double wz = zs * v.w();
|
||||
|
||||
SET_ROW(0, 1.0-(yy+zz), xy - wz, xz + wz, 0.0 )
|
||||
SET_ROW(1, xy + wz, 1.0-(xx+zz),yz - wx, 0.0 )
|
||||
SET_ROW(2, xz - wy, yz + wx, 1.0-(xx+yy),0.0 )
|
||||
SET_ROW(0, 1.0-(yy+zz), xy + wz, xz - wy, 0.0 )
|
||||
SET_ROW(1, xy - wz, 1.0-(xx+zz),yz + wx, 0.0 )
|
||||
SET_ROW(2, xz + wz, yz - wx, 1.0-(xx+yy),0.0 )
|
||||
SET_ROW(3, 0.0, 0.0, 0.0, 1.0 )
|
||||
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float yaw, float pitch, float roll) {
|
||||
void Matrix::makeRot( float yaw, float pitch, float roll)
|
||||
{
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
yaw = DEG2RAD(yaw);
|
||||
pitch = DEG2RAD(pitch);
|
||||
roll = DEG2RAD(roll);
|
||||
#endif
|
||||
|
||||
// lifted straight from SOLID library v1.01 Quaternion.h
|
||||
// available from http://www.win.tue.nl/~gino/solid/
|
||||
// and also distributed under the LGPL
|
||||
@@ -200,11 +219,11 @@ void Matrix::makeRot( float yaw, float pitch, float roll) {
|
||||
makeRot( q );
|
||||
}
|
||||
|
||||
#define INNER_PRODUCT(a,b,c,r) \
|
||||
((a)._mat[0][r] * (b)._mat[c][0]) \
|
||||
+((a)._mat[1][r] * (b)._mat[c][1]) \
|
||||
+((a)._mat[2][r] * (b)._mat[c][2]) \
|
||||
+((a)._mat[3][r] * (b)._mat[c][3])
|
||||
#define INNER_PRODUCT(a,b,r,c) \
|
||||
((a)._mat[r][0] * (b)._mat[0][c]) \
|
||||
+((a)._mat[r][1] * (b)._mat[1][c]) \
|
||||
+((a)._mat[r][2] * (b)._mat[2][c]) \
|
||||
+((a)._mat[r][3] * (b)._mat[3][c])
|
||||
|
||||
void Matrix::mult( const Matrix& lhs, const Matrix& rhs ) {
|
||||
// PRECONDITION: We assume neither &lhs nor &rhs == this
|
||||
@@ -390,7 +409,7 @@ bool Matrix::invertAffine( const Matrix& _m ) {
|
||||
// returns true if _m is nonsingular, and (*this) contains its inverse
|
||||
// otherwise returns false. (*this unchanged)
|
||||
|
||||
// assert (this.isAffine()) ?
|
||||
// assert( this->isAffine())?
|
||||
double det_1, pos, neg, temp;
|
||||
|
||||
pos = neg = 0.0;
|
||||
@@ -487,72 +506,72 @@ void Matrix::copy( const Matrix& other) {
|
||||
void Matrix::preScale( float sx, float sy, float sz, const Matrix& m ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preScale is deprecated. Use result = (Matrix::scale * m) instead.";
|
||||
(*this) = ( scale(sx,sy,sz) * m );
|
||||
#endif
|
||||
(*this) = ( scale(sx,sy,sz) * m );
|
||||
}
|
||||
void Matrix::postScale( const Matrix& m, float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postScale is deprecated. Use result = (m * Matrix::scale()) instead.";
|
||||
(*this) = ( m * scale(sx,sy,sz) );
|
||||
#endif
|
||||
(*this) = ( m * scale(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::preScale( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preScale is deprecated. Use M.preMult( Matrix::scale ) instead.";
|
||||
preMult( scale(sx,sy,sz) );
|
||||
#endif
|
||||
preMult( scale(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::postScale( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postScale is deprecated. Use M.postMult( Matrix::scale ) instead.";
|
||||
postMult( scale(sx,sy,sz) );
|
||||
#endif
|
||||
postMult( scale(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.";
|
||||
(*this) = trans(tx,ty,tz) * m;
|
||||
#endif
|
||||
(*this) = trans(tx,ty,tz) * m;
|
||||
}
|
||||
void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.";
|
||||
(*this) = m * trans(tx,ty,tz);
|
||||
#endif
|
||||
(*this) = m * trans(tx,ty,tz);
|
||||
}
|
||||
void Matrix::preTrans( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.";
|
||||
preMult( trans(sx,sy,sz) );
|
||||
#endif
|
||||
preMult( trans(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::postTrans( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.";
|
||||
postMult( trans(sx,sy,sz) );
|
||||
#endif
|
||||
postMult( trans(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preRot is deprecated. Use result = Matrix::rot * m instead.";
|
||||
(*this) = rotate(deg,x,y,z) * m;
|
||||
#endif
|
||||
(*this) = rotate(deg,x,y,z) * m;
|
||||
}
|
||||
void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postRot is deprecated. Use result = m * Matrix::rotate instead.";
|
||||
(*this) = m * rotate(deg,x,y,z);
|
||||
#endif
|
||||
(*this) = m * rotate(deg,x,y,z);
|
||||
}
|
||||
void Matrix::preRot( float deg, float x, float y, float z ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preRot is deprecated. Use m.preMult( Matrix::rotate ) instead.";
|
||||
preMult( rotate(deg,x,y,z) );
|
||||
#endif
|
||||
preMult( rotate(deg,x,y,z) );
|
||||
}
|
||||
void Matrix::postRot( float deg, float x, float y, float z ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postRot is deprecated. Use m.postMult( Matrix::rotate ) instead.";
|
||||
postMult( rotate(deg,x,y,z) );
|
||||
#endif
|
||||
postMult( rotate(deg,x,y,z) );
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ Node::Node()
|
||||
_bsphere_computed = false;
|
||||
_userData = NULL;
|
||||
_nodeMask = 0xffffffff;
|
||||
|
||||
_numChildrenRequiringAppTraversal = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +26,7 @@ Node::~Node()
|
||||
|
||||
void Node::accept(NodeVisitor& nv)
|
||||
{
|
||||
nv.apply(*this);
|
||||
if (nv.validNodeMask(*this)) nv.apply(*this);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +35,83 @@ void Node::ascend(NodeVisitor& nv)
|
||||
std::for_each(_parents.begin(),_parents.end(),NodeAcceptOp(nv));
|
||||
}
|
||||
|
||||
void Node::setAppCallback(NodeCallback* nc)
|
||||
{
|
||||
// if no changes just return.
|
||||
if (_appCallback==nc) return;
|
||||
|
||||
// app callback has been changed, will need to update
|
||||
// both _appCallback and possibly the numChildrenRequiringAppTraversal
|
||||
// if the number of callbacks changes.
|
||||
|
||||
|
||||
// update the parents numChildrenRequiringAppTraversal
|
||||
// note, if _numChildrenRequiringAppTraversal!=0 then the
|
||||
// parents won't be affected by any app callback change,
|
||||
// so no need to inform them.
|
||||
if (_numChildrenRequiringAppTraversal==0 && !_parents.empty())
|
||||
{
|
||||
int delta = 0;
|
||||
if (_appCallback.valid()) --delta;
|
||||
if (nc) ++delta;
|
||||
if (delta!=0)
|
||||
{
|
||||
// the number of callbacks has changed, need to pass this
|
||||
// on to parents so they know whether app traversal is
|
||||
// reqired on this subgraph.
|
||||
for(ParentList::iterator itr =_parents.begin();
|
||||
itr != _parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->setNumChildrenRequiringAppTraversal(
|
||||
(*itr)->getNumChildrenRequiringAppTraversal()+delta );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// set the app callback itself.
|
||||
_appCallback = nc;
|
||||
|
||||
}
|
||||
|
||||
void Node::setNumChildrenRequiringAppTraversal(const int num)
|
||||
{
|
||||
// if no changes just return.
|
||||
if (_numChildrenRequiringAppTraversal==num) return;
|
||||
|
||||
// note, if _appCallback is set then the
|
||||
// parents won't be affected by any changes to
|
||||
// _numChildrenRequiringAppTraversal so no need to inform them.
|
||||
if (!_appCallback && !_parents.empty())
|
||||
{
|
||||
|
||||
// need to pass on changes to parents.
|
||||
int delta = 0;
|
||||
if (_numChildrenRequiringAppTraversal>0) --delta;
|
||||
if (num>0) ++delta;
|
||||
if (delta!=0)
|
||||
{
|
||||
// the number of callbacks has changed, need to pass this
|
||||
// on to parents so they know whether app traversal is
|
||||
// reqired on this subgraph.
|
||||
for(ParentList::iterator itr =_parents.begin();
|
||||
itr != _parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->setNumChildrenRequiringAppTraversal(
|
||||
(*itr)->getNumChildrenRequiringAppTraversal()+delta
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// finally update this objects value.
|
||||
_numChildrenRequiringAppTraversal=num;
|
||||
|
||||
}
|
||||
|
||||
const bool Node::computeBound() const
|
||||
{
|
||||
_bsphere.init();
|
||||
|
||||
@@ -5,8 +5,12 @@ using namespace osg;
|
||||
|
||||
NodeVisitor::NodeVisitor(TraversalMode tm)
|
||||
{
|
||||
_traversalNumber = -1;
|
||||
|
||||
_traversalVisitor = NULL;
|
||||
_traversalMode = tm;
|
||||
_traversalMask = 0xffffffff;
|
||||
_nodeMaskOverride = 0x0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
// Ideas and code borrowed from GLUT pointburst demo
|
||||
// written by Mark J. Kilgard
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "osg/GL"
|
||||
#include "osg/GLExtensions"
|
||||
#include "osg/Point"
|
||||
|
||||
@@ -8,7 +8,6 @@ using namespace osg;
|
||||
State::State()
|
||||
{
|
||||
_contextID = 0;
|
||||
_frameNumber = 0;
|
||||
_fineGrainedErrorDetection = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,31 +155,6 @@ void StateSet::compile(State& state) const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const StateSet::ModeVector StateSet::getModeVector() const
|
||||
{
|
||||
ModeVector vec;
|
||||
for (ModeList::const_iterator itr = _modeList.begin();
|
||||
itr!=_modeList.end();
|
||||
++itr)
|
||||
{
|
||||
vec.push_back(*itr);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
const StateSet::AttributeVector StateSet::getAttributeVector() const
|
||||
{
|
||||
AttributeVector vec;
|
||||
for (AttributeList::const_iterator itr = _attributeList.begin();
|
||||
itr!=_attributeList.end();
|
||||
++itr)
|
||||
{
|
||||
vec.push_back(itr->second.first.get());
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
void StateSet::setRenderingHint(const int hint)
|
||||
{
|
||||
_renderingHint = hint;
|
||||
|
||||
@@ -46,6 +46,50 @@ Texture::~Texture()
|
||||
dirtyTextureObject();
|
||||
}
|
||||
|
||||
int Texture::compare(const StateAttribute& sa) const
|
||||
{
|
||||
// check the types are equal and then create the rhs variable
|
||||
// used by the COMPARE_StateAttribute_Paramter macro's below.
|
||||
COMPARE_StateAttribute_Types(Texture,sa)
|
||||
|
||||
if (_image!=rhs._image) // smart pointer comparison.
|
||||
{
|
||||
if (_image.valid())
|
||||
{
|
||||
if (rhs._image.valid())
|
||||
{
|
||||
if (_image->getFileName()<rhs._image->getFileName()) return -1;
|
||||
else if (_image->getFileName()>rhs._image->getFileName()) return 1;;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; // valid lhs._image is greater than null.
|
||||
}
|
||||
}
|
||||
else if (rhs._image.valid())
|
||||
{
|
||||
return -1; // valid rhs._image is greater than null.
|
||||
}
|
||||
}
|
||||
|
||||
// compare each paramter in turn against the rhs.
|
||||
COMPARE_StateAttribute_Parameter(_textureUnit)
|
||||
COMPARE_StateAttribute_Parameter(_wrap_s)
|
||||
COMPARE_StateAttribute_Parameter(_wrap_t)
|
||||
COMPARE_StateAttribute_Parameter(_wrap_r)
|
||||
COMPARE_StateAttribute_Parameter(_min_filter)
|
||||
COMPARE_StateAttribute_Parameter(_mag_filter)
|
||||
COMPARE_StateAttribute_Parameter(_internalFormatMode)
|
||||
COMPARE_StateAttribute_Parameter(_internalFormatValue)
|
||||
COMPARE_StateAttribute_Parameter(_textureWidth)
|
||||
COMPARE_StateAttribute_Parameter(_textureHeight)
|
||||
COMPARE_StateAttribute_Parameter(_subloadMode)
|
||||
COMPARE_StateAttribute_Parameter(_subloadOffsX)
|
||||
COMPARE_StateAttribute_Parameter(_subloadOffsY)
|
||||
|
||||
return 0; // passed all the above comparison macro's, must be equal.
|
||||
}
|
||||
|
||||
void Texture::setImage(Image* image)
|
||||
{
|
||||
// delete old texture objects.
|
||||
@@ -410,7 +454,7 @@ void Texture::applyImmediateMode(State& state) const
|
||||
* OpenGL texture objects to cached until they can be deleted
|
||||
* by the OpenGL context in which they were created, specified
|
||||
* by contextID.*/
|
||||
void Texture::deleteTextureObject(uint contextID,uint handle)
|
||||
void Texture::deleteTextureObject(uint contextID,GLuint handle)
|
||||
{
|
||||
if (handle!=0)
|
||||
{
|
||||
@@ -443,7 +487,7 @@ void Texture::copyTexImage2D(State& state, int x, int y, int width, int height )
|
||||
const uint contextID = state.getContextID();
|
||||
|
||||
// get the globj for the current contextID.
|
||||
uint& handle = getHandle(contextID);
|
||||
GLuint& handle = getHandle(contextID);
|
||||
|
||||
if (handle)
|
||||
{
|
||||
@@ -484,7 +528,6 @@ void Texture::copyTexImage2D(State& state, int x, int y, int width, int height )
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter );
|
||||
// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, width, height, 0 );
|
||||
|
||||
|
||||
@@ -515,7 +558,6 @@ void Texture::copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, i
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter );
|
||||
// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, xoffset,yoffset, x, y, width, height);
|
||||
|
||||
/* Redundant, delete later */
|
||||
|
||||
@@ -1,273 +1,203 @@
|
||||
#include <stdlib.h>
|
||||
//#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef macintosh
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#ifdef WIN32 // [
|
||||
// follows are the constructors of the Timer class, once version
|
||||
// for each OS combination. The order is WIN32, FreeBSD, Linux, IRIX,
|
||||
// and the rest of the world.
|
||||
//
|
||||
// all the rest of the timer methods are implemented within the header.
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#ifdef WIN32
|
||||
|
||||
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 // ]
|
||||
|
||||
#if defined(__linux) || defined(__FreeBSD__) // [
|
||||
|
||||
# include <unistd.h>
|
||||
# if defined(__linux)
|
||||
# include <sys/mman.h>
|
||||
# elif defined(__FreeBSD__)
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
# endif
|
||||
|
||||
int Timer::inited = 0;
|
||||
double Timer::cpu_mhz = 0.0;
|
||||
|
||||
void Timer::init( void )
|
||||
{
|
||||
# if defined(__FreeBSD__)
|
||||
int cpuspeed;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(cpuspeed);
|
||||
if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &len, NULL, NULL) == -1) {
|
||||
perror("sysctlbyname(machdep.tsc_freq)");
|
||||
return;
|
||||
}
|
||||
cpu_mhz = cpuspeed / 1e6;
|
||||
|
||||
# elif defined(__linux)
|
||||
char buff[128];
|
||||
FILE *fp = fopen( "/proc/cpuinfo", "r" );
|
||||
|
||||
while( fgets( buff, sizeof( buff ), fp ) > 0 )
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
Timer::Timer()
|
||||
{
|
||||
if( !strncmp( buff, "cpu MHz", strlen( "cpu MHz" )))
|
||||
{
|
||||
char *ptr = buff;
|
||||
_useStandardClock = false;
|
||||
|
||||
if (_useStandardClock)
|
||||
{
|
||||
_secsPerClick = (1.0 / (double) CLOCKS_PER_SEC);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
while( ptr && *ptr != ':' ) ptr++;
|
||||
if( ptr )
|
||||
{
|
||||
ptr++;
|
||||
sscanf( ptr, "%lf", &cpu_mhz );
|
||||
}
|
||||
break;
|
||||
}
|
||||
Timer_t start_time = tick();
|
||||
Sleep (1000);
|
||||
Timer_t end_time = tick();
|
||||
|
||||
_secsPerClick = 1.0/(double)(end_time-start_time);
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
# endif
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
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 )
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
Timer::Timer()
|
||||
{
|
||||
perror( "/dev/mmem" );
|
||||
return;
|
||||
_useStandardClock = false;
|
||||
|
||||
if (_useStandardClock)
|
||||
{
|
||||
_secsPerClick = 1e-6; // gettimeofday()'s precision.
|
||||
}
|
||||
else
|
||||
{
|
||||
int cpuspeed;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(cpuspeed);
|
||||
if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &len, NULL, NULL) == -1)
|
||||
{
|
||||
_useStandardClock = true;
|
||||
perror("sysctlbyname(machdep.tsc_freq)");
|
||||
return;
|
||||
}
|
||||
|
||||
_secsPerClick = 1.0/cpuspeed;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__linux)
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
Timer::Timer()
|
||||
{
|
||||
_useStandardClock = false;
|
||||
|
||||
if (_useStandardClock)
|
||||
{
|
||||
_secsPerClick = 1e-6; // gettimeofday()'s precision.
|
||||
}
|
||||
else
|
||||
{
|
||||
char buff[128];
|
||||
FILE *fp = fopen( "/proc/cpuinfo", "r" );
|
||||
|
||||
double cpu_mhz=0.0f;
|
||||
|
||||
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 );
|
||||
|
||||
if (cpu_mhz==0.0f)
|
||||
{
|
||||
// error - no cpu_mhz found.
|
||||
Timer_t start_time = tick();
|
||||
sleep (1);
|
||||
Timer_t end_time = tick();
|
||||
_secsPerClick = 1.0/(double)(end_time-start_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
_secsPerClick = 1e-6/cpu_mhz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iotimer_addr = (volatile unsigned long *)mmap(
|
||||
(void *)0L,
|
||||
(size_t)poffmask,
|
||||
(int)PROT_READ,
|
||||
(int)MAP_PRIVATE, fd, (off_t)raddr);
|
||||
#elif defined(__sgi)
|
||||
|
||||
iotimer_addr = (unsigned long *)(
|
||||
(__psunsigned_t)iotimer_addr + (phys_addr & poffmask)
|
||||
);
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syssgi.h>
|
||||
#include <sys/immu.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
cycleCntrSize = syssgi( SGI_CYCLECNTR_SIZE );
|
||||
unsigned long Timer::_dummy = 0;
|
||||
|
||||
if( cycleCntrSize > 32 )
|
||||
++iotimer_addr;
|
||||
Timer::Timer( void )
|
||||
{
|
||||
_useStandardClock = false;
|
||||
|
||||
clk = (unsigned long *)iotimer_addr;
|
||||
}
|
||||
if (_useStandardClock)
|
||||
{
|
||||
_secsPerClick = 1e-6; // gettimeofday()'s precision.
|
||||
}
|
||||
else
|
||||
{
|
||||
__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 );
|
||||
raddr = phys_addr & ~poffmask;
|
||||
|
||||
_clockAddress = &_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;
|
||||
|
||||
_clockAddress = (unsigned long *)iotimer_addr;
|
||||
_secsPerClick = (double)(cycleval)* 1e-12;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
#elif defined(unix)
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
_useStandardClock = true;
|
||||
_secsPerClick = 1e-6; // gettimeofday()'s precision.
|
||||
}
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-6);
|
||||
}
|
||||
#else
|
||||
|
||||
// handle the rest of the OS world by just using the std::clock,
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-3);
|
||||
}
|
||||
Timer::Timer( void )
|
||||
{
|
||||
_useStandardClock = true;
|
||||
_secsPerClick = (1.0 / (double) CLOCKS_PER_SEC);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (Timer_t)((double)delta * microseconds_per_click);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
unsigned long delta = t2 - t1;
|
||||
return (Timer_t )((double)delta * nanoseconds_per_click);
|
||||
}
|
||||
|
||||
#endif // ]
|
||||
|
||||
#ifdef macintosh // [
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
microseconds_per_click = (1.0 / (double) CLOCKS_PER_SEC) * 1e6;
|
||||
nanoseconds_per_click = (1.0 / (double) CLOCKS_PER_SEC) * 1e9;
|
||||
}
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
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 // ]
|
||||
#endif
|
||||
|
||||
@@ -75,8 +75,8 @@ Viewer::Viewer()
|
||||
fullscreen = false;
|
||||
_is_open = 0;
|
||||
_saved_wx = wx = _saved_wy = wy = 0;
|
||||
_saved_ww = ww = 1024,
|
||||
_saved_wh = wh = 768;
|
||||
_saved_ww = ww = 800,
|
||||
_saved_wh = wh = 600;
|
||||
|
||||
_title = "OSG Viewer";
|
||||
|
||||
@@ -119,6 +119,10 @@ Viewer::Viewer()
|
||||
frRate=0; // added by gwm to display fram Rate smoothed
|
||||
|
||||
_focusedViewport = 0; // The viewport with mouse/keyboard focus
|
||||
|
||||
|
||||
_frameStamp = new osg::FrameStamp;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +207,9 @@ bool Viewer::open()
|
||||
Node* node = itr->sceneView->getSceneData();
|
||||
if (node) node->accept(vrv);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
vrv.setMinimumNumStencilBits(8); //gwm 12.8.01 to force stencils available for DC test
|
||||
#endif
|
||||
// set up each render stage to clear the appropriate buffers.
|
||||
GLbitfield clear_mask=0;
|
||||
if (vrv.requiresRGB()) clear_mask |= GL_COLOR_BUFFER_BIT;
|
||||
@@ -322,11 +328,13 @@ float Viewer::app(unsigned int viewport)
|
||||
osg::Timer_t beforeApp = _timer.tick();
|
||||
|
||||
// do app traversal.
|
||||
|
||||
getViewportSceneView(viewport)->setFrameStamp(_frameStamp.get());
|
||||
getViewportSceneView(viewport)->app();
|
||||
|
||||
// update the camera manipulator.
|
||||
osg::ref_ptr<GLUTEventAdapter> ea = new GLUTEventAdapter;
|
||||
ea->adaptFrame(clockSeconds());
|
||||
ea->adaptFrame(_frameStamp->getReferenceTime());
|
||||
|
||||
if (_viewportList[viewport]._cameraManipulator->handle(*ea,*this))
|
||||
{
|
||||
@@ -757,7 +765,8 @@ void Viewer::showStats()
|
||||
int wid=ww, ht=wh; // temporary local screen size - must change during this section
|
||||
if (wid>0 && ht>0) {
|
||||
const int blsize=16;
|
||||
char *clin=new char[wid/blsize+2]; // buffer to print
|
||||
char *clin=new char[wid/blsize+2]; // buffer to print dc
|
||||
char *ctext=new char[128]; // buffer to print details
|
||||
float mdc=0;
|
||||
GLubyte *buffer=new GLubyte[wid*ht];
|
||||
if (buffer) {
|
||||
@@ -786,13 +795,14 @@ void Viewer::showStats()
|
||||
*clpt='\0';
|
||||
displaytext(0,(int)(0.84f*vh-(j*12)/blsize),clin); // display average DC over the blsize box
|
||||
}
|
||||
sprintf(clin, "Pixels hit %.1f Mean DC %.2f: %4d by %4d pixels.", mdc, mdc/(wid*ht), wid, ht);
|
||||
sprintf(ctext, "Pixels hit %.1f Mean DC %.2f: %4d by %4d pixels.", mdc, mdc/(wid*ht), wid, ht);
|
||||
displaytext(0,(int)(0.86f*vh),clin);
|
||||
|
||||
glEnable(GL_STENCIL_TEST); // re-enable stencil buffer counting
|
||||
delete [] buffer;
|
||||
}
|
||||
delete [] clin;
|
||||
delete [] ctext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,9 +813,12 @@ void Viewer::showStats()
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void Viewer::display()
|
||||
{
|
||||
|
||||
_frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1);
|
||||
_frameStamp->setReferenceTime(clockSeconds());
|
||||
|
||||
// application traverasal.
|
||||
times[2].timeApp=0.0f;
|
||||
|
||||
@@ -828,7 +841,7 @@ void Viewer::display()
|
||||
}
|
||||
|
||||
|
||||
glFinish();
|
||||
if (_printStats>1) glFinish();
|
||||
|
||||
times[2].frameend=updateFrameTick(); // absolute time
|
||||
|
||||
@@ -841,9 +854,12 @@ void Viewer::display()
|
||||
times[1]=times[2];
|
||||
}
|
||||
|
||||
|
||||
glutSwapBuffers(); // moved after draw of stats & glFinish() to get accurate timing (excluding stat draw!)
|
||||
// cout << "Time elapsed "<<_timer.delta_s(_initialTick,_timer.tick())<<endl;
|
||||
|
||||
if (_printStats>1) glFinish();
|
||||
|
||||
#ifdef SGV_USE_RTFS
|
||||
fs->frame();
|
||||
#endif
|
||||
@@ -1028,14 +1044,19 @@ void Viewer::keyboard(unsigned char key, int x, int y)
|
||||
break;
|
||||
|
||||
case 'p' :
|
||||
if (_printStats==4) glDisable(GL_STENCIL_TEST); // switch off stencil counting
|
||||
_printStats++; //gwm jul 2001 range of possible outputs, 0-4 = !_printStats;
|
||||
if (_printStats>4) _printStats=0;
|
||||
if (_printStats==4) { // count depth complexity by incrementing the stencil buffer every
|
||||
// time a pixel is hit
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilOp(GL_INCR ,GL_INCR ,GL_INCR);
|
||||
} else {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
int nsten=0; // Number of stencil planes available
|
||||
glGetIntegerv(GL_STENCIL_BITS , &nsten);
|
||||
if (nsten>0) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilOp(GL_INCR ,GL_INCR ,GL_INCR);
|
||||
} else {// skip this option
|
||||
_printStats++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1409,11 +1430,11 @@ void Viewer::addViewport(osgUtil::SceneView* sv,
|
||||
void Viewer::addViewport(osg::Node* rootnode,
|
||||
float x, float y, float width, float height)
|
||||
{
|
||||
osgUtil::SceneView *sceneView = new osgUtil::SceneView;
|
||||
sceneView->setDefaults();
|
||||
sceneView->setSceneData(rootnode);
|
||||
osgUtil::SceneView *sceneView = new osgUtil::SceneView;
|
||||
sceneView->setDefaults();
|
||||
sceneView->setSceneData(rootnode);
|
||||
|
||||
addViewport( sceneView, x, y, width, height );
|
||||
addViewport( sceneView, x, y, width, height );
|
||||
}
|
||||
|
||||
void Viewer::init(osg::Node* rootnode)
|
||||
|
||||
@@ -874,6 +874,7 @@ bool GeoSet_writeLocalData(const Object& obj, Output& fw)
|
||||
fw << (int)*itrRowData<<" ";
|
||||
itrRowData += 1;
|
||||
}
|
||||
itrRowComp++;
|
||||
}
|
||||
fw << endl;
|
||||
|
||||
|
||||
@@ -377,42 +377,6 @@ bool StateSet_writeLocalData(const Object& obj, Output& fw)
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define USE_VECTOR_VERSIONS
|
||||
#endif
|
||||
|
||||
#ifdef USE_VECTOR_VERSIONS
|
||||
|
||||
StateSet::ModeVector modes = stateset.getModeVector();
|
||||
|
||||
for(StateSet::ModeVector::iterator mitr=modes.begin();
|
||||
mitr!=modes.end();
|
||||
++mitr)
|
||||
{
|
||||
GLModeToGLNameMap::iterator nitr = s_GLModeToGLNameMap.find(mitr->first);
|
||||
if (nitr!=s_GLModeToGLNameMap.end())
|
||||
{
|
||||
fw.indent() << nitr->second << " " << StateSet_getModeStr(mitr->second) << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no name defined for GLMode so just pass its value to fw.
|
||||
fw.indent() << "0x" << hex << (osg::uint)mitr->first << dec <<" " << StateSet_getModeStr(mitr->second) << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
StateSet::AttributeVector attributes = stateset.getAttributeVector();
|
||||
|
||||
for(StateSet::AttributeVector::iterator sitr=attributes.begin();
|
||||
sitr!=attributes.end();
|
||||
++sitr)
|
||||
{
|
||||
fw.writeObject(*(*sitr));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const StateSet::ModeList& ml = stateset.getModeList();
|
||||
const StateSet::AttributeList& sl = stateset.getAttributeList();
|
||||
|
||||
@@ -439,8 +403,6 @@ bool StateSet_writeLocalData(const Object& obj, Output& fw)
|
||||
fw.writeObject(*(sitr->second.first));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,8 +80,6 @@ class PrintVisitor : public NodeVisitor
|
||||
|
||||
CullVisitor::CullVisitor()
|
||||
{
|
||||
_frameNumber = 0;
|
||||
|
||||
// overide the default node visitor mode.
|
||||
setTraversalMode(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
|
||||
|
||||
@@ -109,10 +107,7 @@ CullVisitor::CullVisitor()
|
||||
_calculated_znear = FLT_MAX;
|
||||
_calculated_zfar = -FLT_MAX;
|
||||
|
||||
_view[0] = 0;
|
||||
_view[1] = 0;
|
||||
_view[2] = 1024;
|
||||
_view[3] = 768;
|
||||
_viewport = NULL;
|
||||
|
||||
_impostorActive = true;
|
||||
_depthSortImpostorSprites = false;
|
||||
@@ -682,8 +677,14 @@ void CullVisitor::apply(Impostor& node)
|
||||
// traverse the appropriate child of the LOD.
|
||||
node.getChild(eval)->accept(*this);
|
||||
}
|
||||
else
|
||||
else if (!_viewport.valid())
|
||||
{
|
||||
// need to use impostor but no valid viewport is defined to simply
|
||||
// default to using the LOD child as above.
|
||||
node.getChild(eval)->accept(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// within the impostor distance threshold therefore attempt
|
||||
// to use impostor instead.
|
||||
|
||||
@@ -695,7 +696,7 @@ void CullVisitor::apply(Impostor& node)
|
||||
if (impostorSprite)
|
||||
{
|
||||
// impostor found, now check to see if it is good enough to use
|
||||
float error = impostorSprite->calcPixelError(*_camera,_view,matrix);
|
||||
float error = impostorSprite->calcPixelError(*_camera,*_viewport,matrix);
|
||||
|
||||
if (error>_impostorPixelErrorThreshold)
|
||||
{
|
||||
@@ -765,7 +766,7 @@ void CullVisitor::apply(Impostor& node)
|
||||
if (stateset) popStateSet();
|
||||
|
||||
// update frame number to show that impostor is in action.
|
||||
impostorSprite->setLastFrameUsed(_frameNumber);
|
||||
impostorSprite->setLastFrameUsed(getTraversalNumber());
|
||||
|
||||
}
|
||||
else
|
||||
@@ -1085,8 +1086,8 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
// equivilant window coordinates by using the camera's project method.
|
||||
Vec3 c00_win;
|
||||
Vec3 c11_win;
|
||||
_camera->project(c00_world,_view,c00_win);
|
||||
_camera->project(c11_world,_view,c11_win);
|
||||
_camera->project(c00_world,*_viewport,c00_win);
|
||||
_camera->project(c11_world,*_viewport,c11_win);
|
||||
|
||||
|
||||
// adjust texture size to be nearest power of 2.
|
||||
@@ -1114,17 +1115,26 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
int new_t = (int)(powf(2.0f,rounded_tp2));
|
||||
|
||||
// if dimension is bigger than window divide it down.
|
||||
while (new_s>_view[2]) new_s /= 2;
|
||||
while (new_s>_viewport->width()) new_s /= 2;
|
||||
|
||||
// if dimension is bigger than window divide it down.
|
||||
while (new_t>_view[3]) new_t /= 2;
|
||||
while (new_t>_viewport->height()) new_t /= 2;
|
||||
|
||||
rtts->setViewport(_view[0],_view[1],new_s,new_t);
|
||||
|
||||
// offset the impostor viewport from the center of the main window
|
||||
// viewport as often the edges of the viewport might be obscured by
|
||||
// other windows, which can cause image/reading writing problems.
|
||||
int center_x = _viewport->x()+_viewport->width()/2;
|
||||
int center_y = _viewport->y()+_viewport->height()/2;
|
||||
|
||||
Viewport* viewport = new Viewport;
|
||||
viewport->setViewport(center_x-new_s/2,center_y-new_t/2,new_s,new_t);
|
||||
rtts->setViewport(viewport);
|
||||
|
||||
// create the impostor sprite.
|
||||
|
||||
ImpostorSprite* impostorSprite =
|
||||
_impostorSpriteManager->createOrReuseImpostorSprite(new_s,new_t,_frameNumber-_numFramesToKeepImpostorSprites);
|
||||
_impostorSpriteManager->createOrReuseImpostorSprite(new_s,new_t,getTraversalNumber()-_numFramesToKeepImpostorSprites);
|
||||
|
||||
if (impostorSprite==NULL) return NULL;
|
||||
|
||||
@@ -1143,7 +1153,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
Texture* texture = impostorSprite->getTexture();
|
||||
|
||||
// update frame number to show that impostor is in action.
|
||||
impostorSprite->setLastFrameUsed(_frameNumber);
|
||||
impostorSprite->setLastFrameUsed(getTraversalNumber());
|
||||
|
||||
Vec3* coords = impostorSprite->getCoords();
|
||||
Vec2* texcoords = impostorSprite->getTexCoords();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
include ../../Make/makedefs
|
||||
|
||||
C++FILES = \
|
||||
AppVisitor.cpp\
|
||||
CameraManipulator.cpp\
|
||||
CullVisitor.cpp\
|
||||
CullViewState.cpp\
|
||||
@@ -12,6 +13,7 @@ C++FILES = \
|
||||
IntersectVisitor.cpp\
|
||||
InsertImpostorsVisitor.cpp\
|
||||
NvTriStripObjects.cpp\
|
||||
OptimizeStateVisitor.cpp\
|
||||
RenderBin.cpp\
|
||||
RenderGraph.cpp\
|
||||
RenderLeaf.cpp\
|
||||
@@ -39,6 +41,7 @@ LIB = ../../lib/lib$(TARGET_BASENAME).so
|
||||
|
||||
TARGET_LIB_FILES = lib$(TARGET_BASENAME).so
|
||||
TARGET_INCLUDE_FILES = \
|
||||
osgUtil/AppVisitor\
|
||||
osgUtil/CameraManipulator\
|
||||
osgUtil/CullVisitor\
|
||||
osgUtil/CullViewState\
|
||||
@@ -52,6 +55,7 @@ TARGET_INCLUDE_FILES = \
|
||||
osgUtil/GUIEventHandler\
|
||||
osgUtil/IntersectVisitor\
|
||||
osgUtil/InsertImpostorsVisitor\
|
||||
osgUtil/OptimizeStateVisitor\
|
||||
osgUtil/RenderBin\
|
||||
osgUtil/RenderGraph\
|
||||
osgUtil/RenderLeaf\
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgUtil/RenderStage>
|
||||
|
||||
using namespace osg;
|
||||
@@ -44,6 +46,12 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
{
|
||||
if (_stageDrawnThisFrame) return;
|
||||
|
||||
if (!_viewport)
|
||||
{
|
||||
notify(FATAL) << "Error: cannot drawm stage due to undefined viewport."<<endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_stageDrawnThisFrame = true;
|
||||
|
||||
for(DependencyList::iterator itr=_dependencyList.begin();
|
||||
@@ -57,11 +65,11 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
|
||||
#define USE_SISSOR_TEST
|
||||
#ifdef USE_SISSOR_TEST
|
||||
glScissor( _view[0], _view[1], _view[2], _view[3] );
|
||||
glScissor( _viewport->x(), _viewport->y(), _viewport->width(), _viewport->height() );
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
#endif
|
||||
|
||||
glViewport( _view[0], _view[1], _view[2], _view[3] );
|
||||
_viewport->apply(state);
|
||||
|
||||
// glEnable( GL_DEPTH_TEST );
|
||||
|
||||
@@ -86,6 +94,10 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
#endif
|
||||
|
||||
// pass the camera we're about to set up to state, so that
|
||||
// subsequent operatiosn know about it, such as for CLOD etc.
|
||||
state.setCamera(_camera.get());
|
||||
|
||||
// set up projection
|
||||
const Matrix& projectionMat = _camera->getProjectionMatrix();
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
@@ -104,6 +116,7 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
// set up camera modelview.
|
||||
const Matrix& modelView = _camera->getModelViewMatrix();
|
||||
glMultMatrixf((GLfloat*)modelView._mat);
|
||||
|
||||
|
||||
if (getLightingMode()==RenderStageLighting::SKY_LIGHT && light)
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
RenderStage::draw(state,previous);
|
||||
|
||||
// now copy the rendered image to attached texture.
|
||||
if (_texture.valid()) _texture->copyTexImage2D(state,_view[0],_view[1],_view[2],_view[3]);
|
||||
if (_texture.valid())
|
||||
_texture->copyTexImage2D(state,_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height());
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <osgUtil/SceneView>
|
||||
#include <osgUtil/AppVisitor>
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/Texture>
|
||||
@@ -25,12 +26,7 @@ SceneView::SceneView()
|
||||
|
||||
_prioritizeTextures = false;
|
||||
|
||||
_view[0] = 0;
|
||||
_view[1] = 0;
|
||||
_view[2] = 1024;
|
||||
_view[3] = 768;
|
||||
|
||||
_frameNumber = 0;
|
||||
_viewport = new Viewport;
|
||||
|
||||
}
|
||||
|
||||
@@ -58,6 +54,10 @@ void SceneView::setDefaults()
|
||||
|
||||
_rendergraph = new osgUtil::RenderGraph;
|
||||
_renderStage = new osgUtil::RenderStage;
|
||||
|
||||
_appVisitor = new osgUtil::AppVisitor;
|
||||
|
||||
|
||||
_cullVisitor = new osgUtil::CullVisitor;
|
||||
|
||||
_cullVisitor->setRenderGraph(_rendergraph.get());
|
||||
@@ -88,26 +88,43 @@ void SceneView::setDefaults()
|
||||
|
||||
void SceneView::app()
|
||||
{
|
||||
++_frameNumber;
|
||||
|
||||
if (_sceneData.valid() && _appVisitor.valid())
|
||||
{
|
||||
_appVisitor->reset();
|
||||
|
||||
_appVisitor->setFrameStamp(_frameStamp.get());
|
||||
|
||||
// use the frame number for the traversal number.
|
||||
if (_frameStamp.valid())
|
||||
{
|
||||
_appVisitor->setTraversalNumber(_frameStamp->getFrameNumber());
|
||||
}
|
||||
|
||||
_sceneData->accept(*_appVisitor.get());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SceneView::cull()
|
||||
{
|
||||
if (!_sceneData) return;
|
||||
|
||||
_camera->adjustAspectRatio((GLfloat)_view[2]/(GLfloat) _view[3]);
|
||||
_camera->adjustAspectRatio(_viewport->aspectRatio());
|
||||
|
||||
|
||||
_rendergraph->clean();
|
||||
|
||||
_cullVisitor->reset();
|
||||
|
||||
_cullVisitor->setFrameStamp(_frameStamp.get());
|
||||
|
||||
// use the frame number for the traversal number.
|
||||
if (_frameStamp.valid())
|
||||
{
|
||||
_cullVisitor->setTraversalNumber(_frameStamp->getFrameNumber());
|
||||
}
|
||||
|
||||
// comment out reset of rendergraph since clean is more efficient.
|
||||
// _rendergraph->reset();
|
||||
|
||||
@@ -115,14 +132,13 @@ void SceneView::cull()
|
||||
// reuse the structure on the rendergraph in the next frame. This
|
||||
// achieves a certain amount of frame cohereancy of memory allocation.
|
||||
|
||||
_cullVisitor->setFrameNumber(_frameNumber);
|
||||
_cullVisitor->setLODBias(_lodBias);
|
||||
_cullVisitor->setCamera(*_camera);
|
||||
_cullVisitor->setViewport(_view[0],_view[1],_view[2],_view[3]);
|
||||
_cullVisitor->setViewport(_viewport.get());
|
||||
|
||||
_renderStage->reset();
|
||||
|
||||
_renderStage->setViewport(_view[0],_view[1],_view[2],_view[3]);
|
||||
_renderStage->setViewport(_viewport.get());
|
||||
_renderStage->setCamera(_camera.get());
|
||||
_renderStage->setClearColor(_backgroundColor);
|
||||
_renderStage->setLight(_light.get());
|
||||
@@ -207,6 +223,8 @@ void SceneView::draw()
|
||||
}
|
||||
// we in theory should be able to
|
||||
_state->reset();
|
||||
|
||||
_state->setFrameStamp(_frameStamp.get());
|
||||
|
||||
// note, to support multi-pipe systems the deletion of OpenGL display list
|
||||
// and texture objects is deferred until the OpenGL context is the correct
|
||||
@@ -233,7 +251,7 @@ void SceneView::draw()
|
||||
windows coordinates are calculated relative to the bottom left of the window.*/
|
||||
bool SceneView::projectWindowIntoObject(const osg::Vec3& window,osg::Vec3& object) const
|
||||
{
|
||||
return _camera->unproject(window,_view,object);
|
||||
return _camera->unproject(window,*_viewport,object);
|
||||
}
|
||||
|
||||
|
||||
@@ -244,8 +262,8 @@ bool SceneView::projectWindowIntoObject(const osg::Vec3& window,osg::Vec3& objec
|
||||
windows coordinates are calculated relative to the bottom left of the window.*/
|
||||
bool SceneView::projectWindowXYIntoObject(int x,int y,osg::Vec3& near_point,osg::Vec3& far_point) const
|
||||
{
|
||||
bool result_near = _camera->unproject(Vec3(x,y,0.0f),_view,near_point);
|
||||
bool result_far = _camera->unproject(Vec3(x,y,1.0f),_view,far_point);
|
||||
bool result_near = _camera->unproject(Vec3(x,y,0.0f),*_viewport,near_point);
|
||||
bool result_far = _camera->unproject(Vec3(x,y,1.0f),*_viewport,far_point);
|
||||
return result_near & result_far;
|
||||
}
|
||||
|
||||
@@ -256,5 +274,5 @@ bool SceneView::projectWindowXYIntoObject(int x,int y,osg::Vec3& near_point,osg:
|
||||
windows coordinates are calculated relative to the bottom left of the window.*/
|
||||
bool SceneView::projectObjectIntoWindow(const osg::Vec3& object,osg::Vec3& window) const
|
||||
{
|
||||
return _camera->project(object,_view,window);
|
||||
return _camera->project(object,*_viewport,window);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user