To osg::AutoTransform added support for MinimumScale, MaximumScale and AutoScaleTransitionWidth parameters

and a new scheme for computing the scaling when using autoscale that introduces smooth
transitions to the scaling of the subgraph so that it looks more natural.
This commit is contained in:
Robert Osfield
2008-03-18 15:37:38 +00:00
parent b08f438946
commit 1d1dcf2cf3
6 changed files with 80 additions and 7 deletions

View File

@@ -28,6 +28,8 @@
#include <osg/AutoTransform>
#include <osg/Geometry>
#include <osgDB/WriteFile>
#include <osgText/Text>
#include <iostream>
@@ -112,6 +114,7 @@ osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps, osg::
osg::Geometry* geom = new osg::Geometry;
geom->setVertexArray(vertices);
geom->setColorArray(colors);
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size()));
osg::Geode* geode = new osg::Geode;
@@ -138,6 +141,7 @@ osg::Node* createAxis(const osg::Vec3& s, const osg::Vec3& e, int numReps, osg::
osg::Geometry* geom = new osg::Geometry;
geom->setVertexArray(vertices);
geom->setColorArray(colors);
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP,0,vertices->size()));
osg::Geode* geode = new osg::Geode;

View File

@@ -83,6 +83,9 @@ class OSG_EXPORT AutoTransform : public Transform
bool getAutoScaleToScreen() const { return _autoScaleToScreen; }
void setAutoScaleTransistionWidthRatio(float ratio) { _autoScaleTransitionWidthRatio = ratio; }
float getAutoScaleTransistionWidthRatio() const { return _autoScaleTransitionWidthRatio; }
virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const;
@@ -115,7 +118,7 @@ class OSG_EXPORT AutoTransform : public Transform
float _minimumScale;
float _maximumScale;
float _autoScaleTransitionWidthRatio;
void computeMatrix() const;

View File

@@ -25,6 +25,7 @@ AutoTransform::AutoTransform():
_firstTimeToInitEyePoint(true),
_minimumScale(0.0f),
_maximumScale(FLT_MAX),
_autoScaleTransitionWidthRatio(0.25f),
_matrixDirty(true)
{
// setNumChildrenRequiringUpdateTraversal(1);
@@ -42,6 +43,7 @@ AutoTransform::AutoTransform(const AutoTransform& pat,const CopyOp& copyop):
_firstTimeToInitEyePoint(true),
_minimumScale(pat._minimumScale),
_maximumScale(pat._maximumScale),
_autoScaleTransitionWidthRatio(pat._autoScaleTransitionWidthRatio),
_matrixDirty(true)
{
// setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
@@ -178,9 +180,39 @@ void AutoTransform::accept(NodeVisitor& nv)
if (getAutoScaleToScreen())
{
float size = 1.0f/cs->pixelSize(getPosition(),0.48f);
if (size<_minimumScale) size = _minimumScale;
if (size>_maximumScale) size = _maximumScale;
if (_autoScaleTransitionWidthRatio>0.0f)
{
if (_minimumScale>0.0f)
{
float j = _minimumScale;
float i = (_maximumScale<FLT_MAX) ?
_minimumScale+(_maximumScale-_minimumScale)*_autoScaleTransitionWidthRatio :
_minimumScale*(1.0f+_autoScaleTransitionWidthRatio);
float c = 1.0f/(4.0f*(i-j));
float b = 1.0f - 2.0f*c*i;
float a = j + b*b / (4.0f*c);
float k = -b / (2.0f*c);
if (size<k) size = _minimumScale;
else if (size<i) size = a + b*size + c*(size*size);
}
if (_maximumScale<FLT_MAX)
{
float n = _maximumScale;
float m = (_minimumScale>0.0) ?
_maximumScale+(_minimumScale-_maximumScale)*_autoScaleTransitionWidthRatio :
_maximumScale*(1.0f-_autoScaleTransitionWidthRatio);
float c = 1.0f / (4.0f*(m-n));
float b = 1.0f - 2.0f*c*m;
float a = n + b*b/(4.0f*c);
float p = -b / (2.0f*c);
if (size>p) size = _maximumScale;
else if (size>m) size = a + b*size + c*(size*size);
}
}
setScale(size);
}

View File

@@ -37,8 +37,16 @@ void AutoTransform::write(DataOutputStream* out){
out->writeBool(getAutoScaleToScreen());
if ( out->getVersion() >= VERSION_0025 )
{
out->writeFloat(getMinimumScale());
out->writeFloat(getMaximumScale());
out->writeFloat(getAutoScaleTransistionWidthRatio());
}
out->writeQuat(getRotation());
out->writeVec3(getScale());
}
void AutoTransform::read(DataInputStream* in){
@@ -64,8 +72,17 @@ void AutoTransform::read(DataInputStream* in){
setAutoScaleToScreen(in->readBool());
if ( in->getVersion() >= VERSION_0025 )
{
setMinimumScale(in->readFloat());
setMaximumScale(in->readFloat());
setAutoScaleTransistionWidthRatio(in->readFloat());
}
setRotation(in->readQuat());
setScale(in->readVec3());
}
else{
throw Exception("AutoTransform::read(): Expected AutoTransform identification.");

View File

@@ -33,8 +33,9 @@
#define VERSION_0022 22
#define VERSION_0023 23
#define VERSION_0024 24
#define VERSION_0025 25
#define VERSION VERSION_0024
#define VERSION VERSION_0025
/* The BYTE_SEX tag is used to check the endian
of the IVE file being read in. The IVE format

View File

@@ -140,6 +140,18 @@ bool AutoTransform_readLocalData(Object& obj, Input& fr)
iteratorAdvanced = true;
}
if (fr.matchSequence("autoScaleTransistionWidthRatio %f"))
{
float ratio;
fr[1].getFloat(ratio);
transform.setAutoScaleTransistionWidthRatio(ratio);
fr += 2;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
@@ -167,8 +179,12 @@ bool AutoTransform_writeLocalData(const Object& obj, Output& fw)
default: fw<<"NO_ROTATION"<<std::endl; break;
}
fw.indent()<<"autoScaleToScreen "<<(transform.getAutoScaleToScreen()?"TRUE":"FALSE")<<std::endl;
if (transform.getAutoScaleTransistionWidthRatio()!=0.25)
{
fw.indent()<<"autoScaleTransistionWidthRatio "<<transform.getAutoScaleTransistionWidthRatio()<<std::endl;
}
return true;
}