|
osgEarth 2.1.1
|
Public Member Functions | |
| PixelAutoTransform () | |
| void | setMinPixelWidthAtScaleOne (double pixels) |
| void | setSizingNode (osg::Node *node) |
| void | dirty () |
| void | accept (osg::NodeVisitor &nv) |
Protected Attributes | |
| double | _minPixels |
| bool | _dirty |
| osg::observer_ptr< osg::Node > | _sizingNode |
| PixelAutoTransform::PixelAutoTransform | ( | ) |
| void PixelAutoTransform::accept | ( | osg::NodeVisitor & | nv | ) |
Definition at line 106 of file Utils.cpp.
{
if ( nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR )
{
// re-activate culling now that the first cull traversal has taken place.
this->setCullingActive( true );
osg::CullStack* cs = dynamic_cast<osg::CullStack*>(&nv);
if ( cs )
{
osg::Viewport::value_type width = _previousWidth;
osg::Viewport::value_type height = _previousHeight;
osg::Viewport* viewport = cs->getViewport();
if (viewport)
{
width = viewport->width();
height = viewport->height();
}
osg::Vec3d eyePoint = cs->getEyeLocal();
osg::Vec3d localUp = cs->getUpLocal();
osg::Vec3d position = getPosition();
const osg::Matrix& projection = *(cs->getProjectionMatrix());
bool doUpdate = _firstTimeToInitEyePoint || _dirty;
if ( !_firstTimeToInitEyePoint )
{
osg::Vec3d dv = _previousEyePoint - eyePoint;
if (dv.length2() > getAutoUpdateEyeMovementTolerance() * (eyePoint-getPosition()).length2())
{
doUpdate = true;
}
else
{
osg::Vec3d dupv = _previousLocalUp - localUp;
// rotating the camera only affects ROTATE_TO_*
if ((_autoRotateMode && dupv.length2() > getAutoUpdateEyeMovementTolerance()) ||
(width != _previousWidth || height != _previousHeight) ||
(projection != _previousProjection) ||
(position != _previousPosition) )
{
doUpdate = true;
}
}
}
_firstTimeToInitEyePoint = false;
if ( doUpdate )
{
if ( getAutoScaleToScreen() )
{
double radius =
_sizingNode.valid() ? _sizingNode->getBound().radius() :
getNumChildren() > 0 ? getChild(0)->getBound().radius() :
0.48;
double pixels = cs->pixelSize( getPosition(), radius );
double scaledMinPixels = _minPixels * _minimumScale;
double scale = pixels < scaledMinPixels ? scaledMinPixels / pixels : 1.0;
OE_DEBUG << LC
<< "Pixels = " << pixels << ", minPix = " << _minPixels << ", scale = " << scale
<< std::endl;
setScale( scale );
}
_previousEyePoint = eyePoint;
_previousLocalUp = localUp;
_previousWidth = width;
_previousHeight = height;
_previousProjection = projection;
_previousPosition = position;
_matrixDirty = true;
}
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);
osg::Quat q;
q.set(osg::Matrix::inverse(lookto));
setRotation(q);
}
#if OSG_MIN_VERSION_REQUIRED(3,0,0)
else if (_autoRotateMode==ROTATE_TO_AXIS)
{
osg::Matrix matrix;
osg::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;
}
}
osg::Quat q;
q.set(matrix);
setRotation(q);
}
#endif
_dirty = false;
}
}
// finally, skip AT's accept and do Transform.
Transform::accept(nv);
}
| void PixelAutoTransform::dirty | ( | ) |
| void osgEarth::PixelAutoTransform::setMinPixelWidthAtScaleOne | ( | double | pixels | ) | [inline] |
Sets the minimim width of the object, in pixels, when the scale factor is 1.0.
Definition at line 225 of file Utils.
{ _minPixels = pixels; }
| void osgEarth::PixelAutoTransform::setSizingNode | ( | osg::Node * | node | ) | [inline] |
Sets the node to use to calculate the screen size. If this is NULL, it will use the size of the first child node.
Definition at line 231 of file Utils.
{ _sizingNode = node; dirty(); }
bool osgEarth::PixelAutoTransform::_dirty [protected] |
double osgEarth::PixelAutoTransform::_minPixels [protected] |
osg::observer_ptr<osg::Node> osgEarth::PixelAutoTransform::_sizingNode [protected] |
1.7.3