Merge branch 'MultiViewAutoTransform'

This commit is contained in:
Robert Osfield
2017-05-11 14:35:50 +01:00
10 changed files with 342 additions and 288 deletions

View File

@@ -18,7 +18,9 @@
#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/CompositeViewer>
#include <osg/Material>
#include <osg/Geode>
@@ -193,13 +195,125 @@ osg::Node* createScene()
return root;
}
int main(int, char**)
osgViewer::View* createView(osg::ref_ptr<osg::Node> scenegraph, osg::ref_ptr<osg::GraphicsContext> gc, unsigned int x, unsigned int y, unsigned int width, unsigned int height)
{
// construct the viewer.
osgViewer::Viewer viewer;
OSG_NOTICE<<"createView(....,x="<<x<<", y="<<y<<", width="<<width<<", height="<<height<<")"<<std::endl;
// set the scene to render
viewer.setSceneData(createScene());
if (!gc)
{
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = x;
traits->y = y;
traits->width = width;
traits->height = height;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (!gc)
{
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl;
return 0;
}
x = 0;
y = 0;
}
osgViewer::View* view = new osgViewer::View;
view->getCamera()->setGraphicsContext(gc);
view->getCamera()->setViewport(new osg::Viewport(x, y, width, height));
//view->getCamera()->setProjectionMatrixAsPerspective(30.0, double(width) / double(height), 1.0, 1000.0);
view->setCameraManipulator(new osgGA::TrackballManipulator);
view->setSceneData(scenegraph);
return view;
}
int main(int argc, char** argv)
{
osg::ArgumentParser arguments(&argc, argv);
// construct the viewer.
osgViewer::CompositeViewer viewer(arguments);
// create the scene graph that contains osg::AutoTransform nodes, see about for implementation details
osg::ref_ptr<osg::Node> scenegraph = createScene();
unsigned int numViews = 1;
while (arguments.read("-n",numViews)) {}
bool windows = false;
while (arguments.read("-w")) { windows = true; }
if (numViews<=1)
{
osgViewer::View* view = new osgViewer::View;
view->setUpViewAcrossAllScreens();
view->setSceneData(scenegraph.get());
view->setCameraManipulator(new osgGA::TrackballManipulator);
view->addEventHandler( new osgViewer::StatsHandler );
viewer.addView(view);
}
else
{
osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi)
{
osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
return 1;
}
unsigned int width, height;
wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
unsigned int x=0, y=0;
while(arguments.read("--window", x, y, width, height)) {}
osg::ref_ptr<osg::GraphicsContext> gc;
if (!windows)
{
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = x;
traits->y = y;
traits->width = width;
traits->height = height;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (!gc)
{
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl;
return 1;
}
}
if (numViews==2)
{
viewer.addView(createView(scenegraph, gc, 0, 0, width/2, height));
viewer.addView(createView(scenegraph, gc, width/2, 0, width/2, height));
}
else if (numViews==3)
{
viewer.addView(createView(scenegraph, gc, 0, 0, width/2, height/2));
viewer.addView(createView(scenegraph, gc, width/2, 0, width/2, height/2));
viewer.addView(createView(scenegraph, gc, 0, height/2, width, height/2));
}
else
{
viewer.addView(createView(scenegraph, gc, 0, 0, width/2, height/2));
viewer.addView(createView(scenegraph, gc, width/2, 0, width/2, height/2));
viewer.addView(createView(scenegraph, gc, 0, height/2, width/2, height/2));
viewer.addView(createView(scenegraph, gc, width/2, height/2, width/2, height/2));
}
viewer.getView(0)->addEventHandler( new osgViewer::StatsHandler );
}
// run the viewers frame loop
return viewer.run();

View File

@@ -37,16 +37,14 @@ class OSG_EXPORT AutoTransform : public Transform
virtual const char* className() const { return "AutoTransform"; }
virtual const char* libraryName() const { return "osg"; }
virtual void accept(NodeVisitor& nv);
virtual AutoTransform* asAutoTransform() { return this; }
virtual const AutoTransform* asAutoTransform() const { return this; }
inline void setPosition(const Vec3d& pos) { _position = pos; _matrixDirty=true; dirtyBound(); }
inline void setPosition(const Vec3d& pos) { _position = pos; dirtyBound(); }
inline const Vec3d& getPosition() const { return _position; }
inline void setRotation(const Quat& quat) { _rotation = quat; _matrixDirty=true; dirtyBound(); }
inline void setRotation(const Quat& quat) { _rotation = quat; dirtyBound(); }
inline const Quat& getRotation() const { return _rotation; }
inline void setScale(double scale) { setScale(osg::Vec3(scale,scale,scale)); }
@@ -60,7 +58,7 @@ class OSG_EXPORT AutoTransform : public Transform
void setMaximumScale(double maximumScale) { _maximumScale = maximumScale; }
double getMaximumScale() const { return _maximumScale; }
inline void setPivotPoint(const Vec3d& pivot) { _pivotPoint = pivot; _matrixDirty=true; dirtyBound(); }
inline void setPivotPoint(const Vec3d& pivot) { _pivotPoint = pivot; dirtyBound(); }
inline const Vec3d& getPivotPoint() const { return _pivotPoint; }
@@ -91,7 +89,7 @@ class OSG_EXPORT AutoTransform : public Transform
/** Get the front face direction normal. */
inline const Vec3& getNormal() const { return _normal; }
void setAutoScaleToScreen(bool autoScaleToScreen) { _autoScaleToScreen = autoScaleToScreen; _matrixDirty=true; }
void setAutoScaleToScreen(bool autoScaleToScreen) { _autoScaleToScreen = autoScaleToScreen; }
bool getAutoScaleToScreen() const { return _autoScaleToScreen; }
@@ -120,21 +118,14 @@ class OSG_EXPORT AutoTransform : public Transform
mutable Quat _rotation;
mutable Vec3d _scale;
mutable bool _firstTimeToInitEyePoint;
mutable osg::Vec3 _previousEyePoint;
mutable osg::Vec3 _previousLocalUp;
mutable Viewport::value_type _previousWidth;
mutable Viewport::value_type _previousHeight;
mutable osg::Matrixd _previousProjection;
mutable osg::Vec3d _previousPosition;
double _minimumScale;
double _maximumScale;
double _autoScaleTransitionWidthRatio;
void computeMatrix() const;
osg::Matrixd computeMatrix(const osg::NodeVisitor* nv) const;
mutable bool _matrixDirty;
mutable bool _matrixInitalized;
mutable osg::Matrixd _cachedMatrix;
enum AxisAligned

View File

@@ -143,8 +143,14 @@ class OSG_EXPORT CullStack : public osg::CullSettings
inline const CullingSet& getCurrentCullingSet() const { return *_back_modelviewCullingStack; }
inline osg::Viewport* getViewport();
inline const osg::Viewport* getViewport() const;
inline osg::RefMatrix* getModelViewMatrix();
inline const osg::RefMatrix* getModelViewMatrix() const;
inline osg::RefMatrix* getProjectionMatrix();
inline const osg::RefMatrix* getProjectionMatrix() const;
inline osg::Matrix getWindowMatrix() const;
inline const osg::RefMatrix* getMVPW();
@@ -224,38 +230,32 @@ class OSG_EXPORT CullStack : public osg::CullSettings
inline osg::Viewport* CullStack::getViewport()
{
if (!_viewportStack.empty())
{
return _viewportStack.back().get();
}
else
{
return 0L;
}
return _viewportStack.empty() ? 0 : _viewportStack.back().get();
}
inline const osg::Viewport* CullStack::getViewport() const
{
return _viewportStack.empty() ? 0 : _viewportStack.back().get();
}
inline osg::RefMatrix* CullStack::getModelViewMatrix()
{
if (!_modelviewStack.empty())
{
return _modelviewStack.back().get();
}
else
{
return _identity.get();
}
return _modelviewStack.empty() ? _identity.get() : _modelviewStack.back().get();
}
inline const osg::RefMatrix* CullStack::getModelViewMatrix() const
{
return _modelviewStack.empty() ? _identity.get() : _modelviewStack.back().get();
}
inline osg::RefMatrix* CullStack::getProjectionMatrix()
{
if (!_projectionStack.empty())
{
return _projectionStack.back().get();
}
else
{
return _identity.get();
}
return _projectionStack.empty() ? _identity.get() : _projectionStack.back().get();
}
inline const osg::RefMatrix* CullStack::getProjectionMatrix() const
{
return _projectionStack.empty() ? _identity.get() : _projectionStack.back().get();
}
inline osg::Matrix CullStack::getWindowMatrix() const

View File

@@ -40,6 +40,8 @@ class OccluderNode;
class OcclusionQueryNode;
class PagedLOD;
class PositionAttitudeTransform;
class AutoTransform;
class MultiViewAutoTransform;
class Projection;
class ProxyNode;
class Sequence;
@@ -50,6 +52,7 @@ class Camera;
class CameraView;
class Drawable;
class Geometry;
class CullStack;
@@ -147,6 +150,13 @@ class OSG_EXPORT NodeVisitor : public virtual Object
* Equivalent to dynamic_cast<const osgUtil::IntersectionVisitor*>(this).*/
virtual const osgUtil::IntersectionVisitor* asIntersectionVisitor() const { return 0; }
/** Convert 'this' into a osg::CullStack pointer if Object is a osg::CullStack, otherwise return 0.
* Equivalent to dynamic_cast<osg::CullStack*>(this).*/
virtual osg::CullStack* asCullStack() { return 0; }
/** convert 'const this' into a const osg::CullStack pointer if Object is a osg::CullStack, otherwise return 0.
* Equivalent to dynamic_cast<const osg::CullStack*>(this).*/
virtual const osg::CullStack* asCullStack() const { return 0; }
@@ -338,6 +348,7 @@ class OSG_EXPORT NodeVisitor : public virtual Object
virtual void apply(CameraView& node);
virtual void apply(MatrixTransform& node);
virtual void apply(PositionAttitudeTransform& node);
virtual void apply(AutoTransform& node);
virtual void apply(Switch& node);
virtual void apply(Sequence& node);

View File

@@ -91,6 +91,9 @@ class OSG_EXPORT Transform : public Group
virtual PositionAttitudeTransform* asPositionAttitudeTransform() { return 0; }
virtual const PositionAttitudeTransform* asPositionAttitudeTransform() const { return 0; }
virtual AutoTransform* asAutoTransform() { return 0; }
virtual const AutoTransform* asAutoTransform() const { return 0; }
enum ReferenceFrame
{
RELATIVE_RF,

View File

@@ -67,6 +67,15 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
* Equivalent to dynamic_cast<const osgUtil::CullVisitor*>(this).*/
virtual const osgUtil::CullVisitor* asCullVisitor() const { return this; }
/** Convert 'this' into a osg::CullStack pointer if Object is a osg::CullStack, otherwise return 0.
* Equivalent to dynamic_cast<osg::CullStack*>(this).*/
virtual osg::CullStack* asCullStack() { return static_cast<osg::CullStack*>(this); }
/** convert 'const this' into a const osg::CullStack pointer if Object is a osg::CullStack, otherwise return 0.
* Equivalent to dynamic_cast<const osg::CullStack*>(this).*/
virtual const osg::CullStack* asCullStack() const { return static_cast<const osg::CullStack*>(this); }
using osg::NodeVisitor::clone;
/** Create a shallow copy of the CullVisitor, used by CullVisitor::create() to clone the prototype. */

View File

@@ -22,13 +22,10 @@ AutoTransform::AutoTransform():
_autoRotateMode(NO_ROTATION),
_autoScaleToScreen(false),
_scale(1.0,1.0,1.0),
_firstTimeToInitEyePoint(true),
_previousWidth(0),
_previousHeight(0),
_minimumScale(0.0),
_maximumScale(DBL_MAX),
_autoScaleTransitionWidthRatio(0.25),
_matrixDirty(true),
_matrixInitalized(false),
_axis(0.0f,0.0f,1.0f),
_normal(0.0f,-1.0f,0.0f),
_cachedMode(NO_ROTATION),
@@ -46,13 +43,10 @@ AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop):
_autoScaleToScreen(pat._autoScaleToScreen),
_rotation(pat._rotation),
_scale(pat._scale),
_firstTimeToInitEyePoint(true),
_previousWidth(0),
_previousHeight(0),
_minimumScale(pat._minimumScale),
_maximumScale(pat._maximumScale),
_autoScaleTransitionWidthRatio(pat._autoScaleTransitionWidthRatio),
_matrixDirty(true),
_matrixInitalized(false),
_axis(pat._axis),
_normal(pat._normal),
_cachedMode(pat._cachedMode),
@@ -64,7 +58,6 @@ AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop):
void AutoTransform::setAutoRotateMode(AutoRotateMode mode)
{
_autoRotateMode = mode;
_firstTimeToInitEyePoint = true;
_cachedMode = CACHE_DIRTY;
updateCache();
}
@@ -109,284 +102,211 @@ void AutoTransform::setScale(const Vec3d& scale)
if (_scale.y()>_maximumScale) _scale.y() = _maximumScale;
if (_scale.z()>_maximumScale) _scale.z() = _maximumScale;
_matrixDirty=true;
dirtyBound();
}
bool AutoTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const
bool AutoTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const
{
if (_matrixDirty) computeMatrix();
if (_referenceFrame==RELATIVE_RF)
{
matrix.preMult(_cachedMatrix);
matrix.preMult(computeMatrix(nv));
}
else // absolute
{
matrix = _cachedMatrix;
matrix = computeMatrix(nv);
}
return true;
}
bool AutoTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const
bool AutoTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const
{
if (_scale.x() == 0.0 || _scale.y() == 0.0 || _scale.z() == 0.0)
return false;
if (_referenceFrame==RELATIVE_RF)
{
matrix.postMultTranslate(-_position);
matrix.postMultRotate(_rotation.inverse());
matrix.postMultScale(Vec3d(1.0/_scale.x(), 1.0/_scale.y(), 1.0/_scale.z()));
matrix.postMultTranslate(_pivotPoint);
matrix.postMult(osg::Matrix::inverse(computeMatrix(nv)));
}
else // absolute
{
matrix.makeRotate(_rotation.inverse());
matrix.preMultTranslate(-_position);
matrix.postMultScale(Vec3d(1.0/_scale.x(), 1.0/_scale.y(), 1.0/_scale.z()));
matrix.postMultTranslate(_pivotPoint);
matrix = osg::Matrix::inverse(computeMatrix(nv));
}
return true;
}
void AutoTransform::computeMatrix() const
osg::Matrixd AutoTransform::computeMatrix(const osg::NodeVisitor* nv) const
{
if (!_matrixDirty) return;
_matrixInitalized = true;
_cachedMatrix.makeRotate(_rotation);
_cachedMatrix.postMultTranslate(_position);
_cachedMatrix.preMultScale(_scale);
_cachedMatrix.preMultTranslate(-_pivotPoint);
Quat rotation = _rotation;
osg::Vec3d scale = _scale;
_matrixDirty = false;
}
void AutoTransform::accept(NodeVisitor& nv)
{
if (nv.validNodeMask(*this))
const CullStack* cs = nv ? nv->asCullStack() : 0;
if (cs)
{
// if app traversal update the frame count.
if (nv.getVisitorType()==NodeVisitor::UPDATE_VISITOR)
{
}
else
if (nv.getVisitorType()==NodeVisitor::CULL_VISITOR)
{
osg::Vec3d eyePoint = cs->getEyeLocal();
osg::Vec3d localUp = cs->getUpLocal();
CullStack* cs = dynamic_cast<CullStack*>(&nv);
if (cs)
if (getAutoScaleToScreen())
{
double size = 1.0/cs->pixelSize(getPosition(),0.48f);
//if (_autoScaleTransitionWidthRatio>0.0)
{
Viewport::value_type width = _previousWidth;
Viewport::value_type height = _previousHeight;
osg::Viewport* viewport = cs->getViewport();
if (viewport)
if (_minimumScale>0.0)
{
width = viewport->width();
height = viewport->height();
double j = _minimumScale;
double i = (_maximumScale<DBL_MAX) ?
_minimumScale+(_maximumScale-_minimumScale)*_autoScaleTransitionWidthRatio :
_minimumScale*(1.0+_autoScaleTransitionWidthRatio);
double c = 1.0/(4.0*(i-j));
double b = 1.0 - 2.0*c*i;
double a = j + b*b / (4.0*c);
double k = -b / (2.0*c);
if (size<k) size = _minimumScale;
else if (size<i) size = a + b*size + c*(size*size);
}
osg::Vec3d eyePoint = cs->getEyeLocal();
osg::Vec3d localUp = cs->getUpLocal();
osg::Vec3d position = getPosition();
const osg::Matrix& projection = *(cs->getProjectionMatrix());
bool doUpdate = _firstTimeToInitEyePoint;
if (!_firstTimeToInitEyePoint)
if (_maximumScale<DBL_MAX)
{
osg::Vec3d dv = _previousEyePoint-eyePoint;
if (dv.length2()>getAutoUpdateEyeMovementTolerance()*(eyePoint-getPosition()).length2())
{
doUpdate = true;
}
osg::Vec3d dupv = _previousLocalUp-localUp;
// rotating the camera only affects ROTATE_TO_*
if (_autoRotateMode &&
dupv.length2()>getAutoUpdateEyeMovementTolerance())
{
doUpdate = true;
}
else if (width!=_previousWidth || height!=_previousHeight)
{
doUpdate = true;
}
else if (projection != _previousProjection)
{
doUpdate = true;
}
else if (position != _previousPosition)
{
doUpdate = true;
}
double n = _maximumScale;
double m = (_minimumScale>0.0) ?
_maximumScale+(_minimumScale-_maximumScale)*_autoScaleTransitionWidthRatio :
_maximumScale*(1.0-_autoScaleTransitionWidthRatio);
double c = 1.0 / (4.0*(m-n));
double b = 1.0 - 2.0*c*m;
double a = n + b*b/(4.0*c);
double p = -b / (2.0*c);
if (size>p) size = _maximumScale;
else if (size>m) size = a + b*size + c*(size*size);
}
_firstTimeToInitEyePoint = false;
if (doUpdate)
{
if (getAutoScaleToScreen())
{
double size = 1.0/cs->pixelSize(getPosition(),0.48f);
if (_autoScaleTransitionWidthRatio>0.0)
{
if (_minimumScale>0.0)
{
double j = _minimumScale;
double i = (_maximumScale<DBL_MAX) ?
_minimumScale+(_maximumScale-_minimumScale)*_autoScaleTransitionWidthRatio :
_minimumScale*(1.0+_autoScaleTransitionWidthRatio);
double c = 1.0/(4.0*(i-j));
double b = 1.0 - 2.0*c*i;
double a = j + b*b / (4.0*c);
double k = -b / (2.0*c);
if (size<k) size = _minimumScale;
else if (size<i) size = a + b*size + c*(size*size);
}
if (_maximumScale<DBL_MAX)
{
double n = _maximumScale;
double m = (_minimumScale>0.0) ?
_maximumScale+(_minimumScale-_maximumScale)*_autoScaleTransitionWidthRatio :
_maximumScale*(1.0-_autoScaleTransitionWidthRatio);
double c = 1.0 / (4.0*(m-n));
double b = 1.0 - 2.0*c*m;
double a = n + b*b/(4.0*c);
double p = -b / (2.0*c);
if (size>p) size = _maximumScale;
else if (size>m) size = a + b*size + c*(size*size);
}
}
setScale(size);
}
if (_autoRotateMode==ROTATE_TO_SCREEN)
{
osg::Vec3d translation;
osg::Quat rotation;
osg::Vec3d scale;
osg::Quat so;
cs->getModelViewMatrix()->decompose( translation, rotation, scale, so );
setRotation(rotation.inverse());
}
else if (_autoRotateMode==ROTATE_TO_CAMERA)
{
osg::Vec3d PosToEye = _position - eyePoint;
osg::Matrix lookto = osg::Matrix::lookAt(
osg::Vec3d(0,0,0), PosToEye, localUp);
Quat q;
q.set(osg::Matrix::inverse(lookto));
setRotation(q);
}
else if (_autoRotateMode==ROTATE_TO_AXIS)
{
Matrix matrix;
Vec3 ev(eyePoint - _position);
switch(_cachedMode)
{
case(AXIAL_ROT_Z_AXIS):
{
ev.z() = 0.0f;
float ev_length = ev.length();
if (ev_length>0.0f)
{
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
//mat.makeRotate(inRadians(rotation_z),0.0f,0.0f,1.0f);
float inv = 1.0f/ev_length;
float s = ev.x()*inv;
float c = -ev.y()*inv;
matrix(0,0) = c;
matrix(1,0) = -s;
matrix(0,1) = s;
matrix(1,1) = c;
}
break;
}
case(AXIAL_ROT_Y_AXIS):
{
ev.y() = 0.0f;
float ev_length = ev.length();
if (ev_length>0.0f)
{
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
//mat.makeRotate(inRadians(rotation_z),0.0f,0.0f,1.0f);
float inv = 1.0f/ev_length;
float s = -ev.z()*inv;
float c = ev.x()*inv;
matrix(0,0) = c;
matrix(2,0) = s;
matrix(0,2) = -s;
matrix(2,2) = c;
}
break;
}
case(AXIAL_ROT_X_AXIS):
{
ev.x() = 0.0f;
float ev_length = ev.length();
if (ev_length>0.0f)
{
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
//mat.makeRotate(inRadians(rotation_z),0.0f,0.0f,1.0f);
float inv = 1.0f/ev_length;
float s = -ev.z()*inv;
float c = -ev.y()*inv;
matrix(1,1) = c;
matrix(2,1) = -s;
matrix(1,2) = s;
matrix(2,2) = c;
}
break;
}
case(ROTATE_TO_AXIS): // need to implement
{
float ev_side = ev*_side;
float ev_normal = ev*_normal;
float rotation = atan2f(ev_side,ev_normal);
matrix.makeRotate(rotation,_axis);
break;
}
}
Quat q;
q.set(matrix);
setRotation(q);
}
_previousEyePoint = eyePoint;
_previousLocalUp = localUp;
_previousWidth = width;
_previousHeight = height;
_previousProjection = projection;
_previousPosition = position;
_matrixDirty = true;
}
}
// TODO setScale(size);
scale.set(size, size, size);
}
// now do the proper accept
Transform::accept(nv);
if (_autoRotateMode==ROTATE_TO_SCREEN)
{
osg::Vec3d mv_translation;
osg::Vec3d mv_scale;
osg::Quat mv_rotation;
osg::Quat mv_so;
cs->getModelViewMatrix()->decompose( mv_translation, mv_rotation, mv_scale, mv_so );
// TODO setRotation(rotation.inverse());
rotation = mv_rotation.inverse();
}
else if (_autoRotateMode==ROTATE_TO_CAMERA)
{
osg::Vec3d PosToEye = _position - eyePoint;
osg::Matrix lookto = osg::Matrix::lookAt(
osg::Vec3d(0,0,0), PosToEye, localUp);
Quat q;
q.set(osg::Matrix::inverse(lookto));
// TODO setRotation(q);
rotation = q;
}
else if (_autoRotateMode==ROTATE_TO_AXIS)
{
Matrix matrix;
Vec3 ev(eyePoint - _position);
switch(_cachedMode)
{
case(AXIAL_ROT_Z_AXIS):
{
ev.z() = 0.0f;
float ev_length = ev.length();
if (ev_length>0.0f)
{
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
//mat.makeRotate(inRadians(rotation_z),0.0f,0.0f,1.0f);
float inv = 1.0f/ev_length;
float s = ev.x()*inv;
float c = -ev.y()*inv;
matrix(0,0) = c;
matrix(1,0) = -s;
matrix(0,1) = s;
matrix(1,1) = c;
}
break;
}
case(AXIAL_ROT_Y_AXIS):
{
ev.y() = 0.0f;
float ev_length = ev.length();
if (ev_length>0.0f)
{
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
//mat.makeRotate(inRadians(rotation_z),0.0f,0.0f,1.0f);
float inv = 1.0f/ev_length;
float s = -ev.z()*inv;
float c = ev.x()*inv;
matrix(0,0) = c;
matrix(2,0) = s;
matrix(0,2) = -s;
matrix(2,2) = c;
}
break;
}
case(AXIAL_ROT_X_AXIS):
{
ev.x() = 0.0f;
float ev_length = ev.length();
if (ev_length>0.0f)
{
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
//mat.makeRotate(inRadians(rotation_z),0.0f,0.0f,1.0f);
float inv = 1.0f/ev_length;
float s = -ev.z()*inv;
float c = -ev.y()*inv;
matrix(1,1) = c;
matrix(2,1) = -s;
matrix(1,2) = s;
matrix(2,2) = c;
}
break;
}
case(ROTATE_TO_AXIS): // need to implement
{
float ev_side = ev*_side;
float ev_normal = ev*_normal;
float angle = atan2f(ev_side,ev_normal);
matrix.makeRotate(angle,_axis);
break;
}
}
Quat q;
q.set(matrix);
// TODO setRotation(q);
rotation = q;
}
}
_rotation = rotation;
_scale = scale;
// setRotation(rotation);
// setScale(scale);
osg::Matrixd matrix;
matrix.makeRotate(rotation);
matrix.postMultTranslate(_position);
matrix.preMultScale(scale);
matrix.preMultTranslate(-_pivotPoint);
_cachedMatrix = matrix;
return matrix;
}
BoundingSphere AutoTransform::computeBound() const
{
BoundingSphere bsphere;
if ( getAutoScaleToScreen() && _firstTimeToInitEyePoint )
if ( getAutoScaleToScreen() && !_matrixInitalized )
return bsphere;
bsphere = Transform::computeBound();

View File

@@ -51,7 +51,7 @@ void LOD::traverse(NodeVisitor& nv)
}
else
{
osg::CullStack* cullStack = dynamic_cast<osg::CullStack*>(&nv);
osg::CullStack* cullStack = nv.asCullStack();
if (cullStack && cullStack->getLODScale())
{
required_range = cullStack->clampedPixelSize(getBound()) / cullStack->getLODScale();

View File

@@ -25,6 +25,7 @@
#include <osg/OcclusionQueryNode>
#include <osg/PagedLOD>
#include <osg/PositionAttitudeTransform>
#include <osg/AutoTransform>
#include <osg/Projection>
#include <osg/ProxyNode>
#include <osg/Sequence>
@@ -161,6 +162,11 @@ void NodeVisitor::apply(PositionAttitudeTransform& node)
apply(static_cast<Transform&>(node));
}
void NodeVisitor::apply(AutoTransform& node)
{
apply(static_cast<Transform&>(node));
}
void NodeVisitor::apply(Switch& node)
{
apply(static_cast<Group&>(node));

View File

@@ -150,7 +150,7 @@ void PagedLOD::traverse(NodeVisitor& nv)
}
else
{
osg::CullStack* cullStack = dynamic_cast<osg::CullStack*>(&nv);
osg::CullStack* cullStack = nv.asCullStack();
if (cullStack && cullStack->getLODScale()>0.0f)
{
required_range = cullStack->clampedPixelSize(getBound()) / cullStack->getLODScale();