*** empty log message ***

This commit is contained in:
Don BURNS
2003-06-24 15:40:09 +00:00
parent 5a939f5420
commit 15f88f35b2
91 changed files with 2871 additions and 1937 deletions

View File

@@ -22,121 +22,22 @@
using namespace osgText;
struct TextCullCallback : public osg::Drawable::CullCallback
{
struct PositionData
{
PositionData():
_traversalNumber(-1),
_previousWidth(0),
_previousHeight(0) {}
int _traversalNumber;
int _previousWidth;
int _previousHeight;
osg::Vec3 _eyePosition;
};
TextCullCallback(osgText::Text* text):
_text(text) {}
/** do customized cull code.*/
virtual bool cull(osg::NodeVisitor *nv, osg::Drawable*, osg::State*) const
{
osgUtil::CullVisitor* cs = static_cast<osgUtil::CullVisitor*>(nv);
if (!cs) return false;
unsigned int contextID = cs->getState() ? cs->getState()->getContextID() : 0;
PositionData& positionData = _positions[contextID];
int width = positionData._previousWidth;
int height = positionData._previousHeight;
osg::Viewport* viewport = cs->getViewport();
if (viewport)
{
width = viewport->width();
height = viewport->height();
}
osg::Vec3 eyePoint = cs->getEyeLocal();
bool doUpdate = positionData._traversalNumber==-1;
if (positionData._traversalNumber>=0)
{
osg::Vec3 dv = positionData._eyePosition-eyePoint;
if (dv.length2()>_text->getAutoUpdateEyeMovementTolerance()*(eyePoint-_text->getPosition()).length2())
{
doUpdate = true;
}
else if (width!=positionData._previousWidth || height!=positionData._previousHeight)
{
doUpdate = true;
}
}
positionData._traversalNumber = nv->getTraversalNumber();
positionData._previousWidth = width;
positionData._previousHeight = height;
if (doUpdate)
{
float scale=_text->getScale(contextID);
if (_text->getAutoScaleToLimitScreenSizeToFontResolution())
{
float numPixels = cs->pixelSize(_text->getPosition(),_text->getCharacterHeight());
if (numPixels>_text->getFontHeight())
{
scale = _text->getFontHeight()/numPixels;
}
//float size = 1.0f/cs->pixelSize(_text->getPosition(),1.0f);
//_text->setScale(size);
}
osg::Quat rotation = _text->getRotation(contextID);
if (_text->getAutoRotateToScreen())
{
rotation.set(cs->getModelViewMatrix());
rotation = rotation.inverse();
}
_text->setScaleAndRotation(contextID,scale,rotation);
}
return false;
}
typedef osg::buffered_object<PositionData> PositionList;
mutable PositionList _positions;
mutable osgText::Text* _text;
};
Text::Text():
_fontWidth(32),
_fontHeight(32),
_characterHeight(32),
_characterAspectRatio(1.0f),
_characterSizeMode(OBJECT_COORDS),
_maximumWidth(0.0f),
_maximumHeight(0.0f),
_alignment(BASE_LINE),
_autoUpdateEyeMovementTolerance(0.0f),
_autoRotateToScreen(false),
_autoScaleToLimitScreenSizeToFontResolution(false),
_layout(LEFT_TO_RIGHT),
_color(1.0f,1.0f,1.0f,1.0f),
_drawMode(TEXT)
{
setUseDisplayList(false);
setScale(1.0f);
}
Text::Text(const Text& text,const osg::CopyOp& copyop):
@@ -146,21 +47,18 @@ Text::Text(const Text& text,const osg::CopyOp& copyop):
_fontHeight(text._fontHeight),
_characterHeight(text._characterHeight),
_characterAspectRatio(text._characterAspectRatio),
_characterSizeMode(text._characterSizeMode),
_maximumWidth(text._maximumWidth),
_maximumHeight(text._maximumHeight),
_text(text._text),
_position(text._position),
_alignment(text._alignment),
_rotation(text._rotation),
_scale(text._scale),
_autoUpdateEyeMovementTolerance(text._autoUpdateEyeMovementTolerance),
_autoRotateToScreen(text._autoRotateToScreen),
_autoScaleToLimitScreenSizeToFontResolution(text._autoScaleToLimitScreenSizeToFontResolution),
_layout(text._layout),
_color(text._color),
_drawMode(text._drawMode)
{
setUpAutoCallback();
computeGlyphRepresentation();
}
@@ -189,7 +87,6 @@ void Text::setFontResolution(unsigned int width, unsigned int height)
computeGlyphRepresentation();
}
void Text::setCharacterSize(float height,float aspectRatio)
{
_characterHeight = height;
@@ -278,75 +175,19 @@ void Text::setAxisAlignment(AxisAlignment axis)
void Text::setRotation(const osg::Quat& quat)
{
for(unsigned int i=0;i<_rotation.size();++i)
{
setRotation(i,quat);
}
_rotation = quat;
computePositions();
}
void Text::setRotation(unsigned int contextID, const osg::Quat& quat)
{
if (_rotation[contextID]==quat) return;
_rotation[contextID] = quat;
computePositions(contextID);
}
void Text::setScale(float scale)
{
for(unsigned int i=0;i<_scale.size();++i)
{
setScale(i,scale);
}
}
void Text::setScale(unsigned int contextID, float scale)
{
if (_scale[contextID]==scale) return;
_scale[contextID] = scale;
computePositions(contextID);
}
void Text::setScaleAndRotation(unsigned int contextID, float scale,const osg::Quat& quat)
{
if (_scale[contextID]==scale && _rotation[contextID]==quat) return;
_scale[contextID] = scale;
_rotation[contextID] = quat;
computePositions(contextID);
}
void Text::setAutoScaleToLimitScreenSizeToFontResolution(bool autoScaleToScreen)
{
if (_autoScaleToLimitScreenSizeToFontResolution==autoScaleToScreen) return;
_autoScaleToLimitScreenSizeToFontResolution = autoScaleToScreen;
setUpAutoCallback();
}
void Text::setAutoRotateToScreen(bool autoRotateToScreen)
{
if (_autoRotateToScreen==autoRotateToScreen) return;
_autoRotateToScreen = autoRotateToScreen;
setUpAutoCallback();
}
void Text::setUpAutoCallback()
{
if (_autoRotateToScreen || _autoScaleToLimitScreenSizeToFontResolution)
{
if (!getCullCallback())
{
setCullCallback(new TextCullCallback(this));
}
}
else setCullCallback(0);
}
void Text::setLayout(Layout layout)
{
if (_layout==layout) return;
@@ -369,7 +210,7 @@ void Text::setDrawMode(unsigned int mode)
_drawMode=mode;
if (_drawMode&TEXT_PIXMAP)
{
setAutoScaleToLimitScreenSizeToFontResolution(true);
setCharacterSizeMode(SCREEN_COORDS);
setAutoRotateToScreen(true);
}
computeGlyphRepresentation();
@@ -388,9 +229,9 @@ bool Text::computeBound() const
if (_textBB.valid())
{
for(unsigned int i=0;i<_matrix.size();++i)
for(unsigned int i=0;i<_autoTransformCache.size();++i)
{
osg::Matrix& matrix = _matrix[i];
osg::Matrix& matrix = _autoTransformCache[i]._matrix;
_bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix);
_bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*matrix);
_bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*matrix);
@@ -605,13 +446,13 @@ void Text::computeGlyphRepresentation()
void Text::computePositions()
{
for(unsigned int i=0;i<_matrix.size();++i)
for(unsigned int i=0;i<_autoTransformCache.size();++i)
{
computePositions(i);
}
}
void Text::computePositions(unsigned int contextID)
void Text::computePositions(unsigned int contextID) const
{
switch(_alignment)
@@ -632,18 +473,92 @@ void Text::computePositions(unsigned int contextID)
case RIGHT_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin()),0.0f,0.0f); break;
}
osg::Matrix& matrix = _matrix[contextID];
AutoTransformCache& atc = _autoTransformCache[contextID];
osg::Matrix& matrix = atc._matrix;
if (_scale[contextID]!=1.0f || !_rotation[contextID].zeroRotation())
if (_characterSizeMode!=OBJECT_COORDS || _autoRotateToScreen)
{
matrix.makeTranslate(-_offset);
if (_scale[contextID]!=1.0f)
matrix.postMult(osg::Matrix::scale(_scale[contextID],_scale[contextID],_scale[contextID]));
if (!_rotation[contextID].zeroRotation())
matrix.postMult(osg::Matrix::rotate(_rotation[contextID]));
osg::Matrix rotate_matrix;
if (_autoRotateToScreen)
{
osg::Vec3 trans(atc._modelview.getTrans());
atc._modelview.setTrans(0.0f,0.0f,0.0f);
rotate_matrix.invert(atc._modelview);
atc._modelview.setTrans(trans);
}
if (_characterSizeMode!=OBJECT_COORDS)
{
osg::Matrix M(rotate_matrix*osg::Matrix::translate(_position)*atc._modelview);
osg::Matrix& P = atc._projection;
// compute the pixel size vector.
// pre adjust P00,P20,P23,P33 by multiplying them by the viewport window matrix.
// here we do it in short hand with the knowledge of how the window matrix is formed
// note P23,P33 are multiplied by an implicit 1 which would come from the window matrix.
// Robert Osfield, June 2002.
// scaling for horizontal pixels
float P00 = P(0,0)*atc._width*0.5f;
float P20_00 = P(2,0)*atc._width*0.5f + P(2,3)*atc._width*0.5f;
osg::Vec3 scale_00(M(0,0)*P00 + M(0,2)*P20_00,
M(1,0)*P00 + M(1,2)*P20_00,
M(2,0)*P00 + M(2,2)*P20_00);
// scaling for vertical pixels
float P10 = P(1,1)*atc._height*0.5f;
float P20_10 = P(2,1)*atc._height*0.5f + P(2,3)*atc._height*0.5f;
osg::Vec3 scale_10(M(0,1)*P10 + M(0,2)*P20_10,
M(1,1)*P10 + M(1,2)*P20_10,
M(2,1)*P10 + M(2,2)*P20_10);
float P23 = P(2,3);
float P33 = P(3,3);
float pixelSizeVector_w = M(3,2)*P23 + M(3,3)*P33;
float pixelSize = (_characterHeight*sqrtf(scale_00.length2()+scale_10.length2()))/(pixelSizeVector_w*0.701f);
if (_characterSizeMode==SCREEN_COORDS)
{
float scale_font = _characterHeight/pixelSize;
matrix.postMult(osg::Matrix::scale(scale_font, scale_font,1.0f));
}
else if (pixelSize>_fontHeight)
{
float scale_font = _fontHeight/pixelSize;
matrix.postMult(osg::Matrix::scale(scale_font, scale_font,1.0f));
}
}
if (_autoRotateToScreen)
{
matrix.postMult(rotate_matrix);
}
if (!_rotation.zeroRotation() )
{
matrix.postMult(osg::Matrix::rotate(_rotation));
}
matrix.postMult(osg::Matrix::translate(_position));
}
else if (!_rotation.zeroRotation())
{
matrix.makeTranslate(-_offset);
matrix.postMult(osg::Matrix::rotate(_rotation));
matrix.postMult(osg::Matrix::translate(_position));
}
else
@@ -651,6 +566,7 @@ void Text::computePositions(unsigned int contextID)
matrix.makeTranslate(_position-_offset);
}
// now apply matrix to the glyphs.
for(TextureGlyphQuadMap::iterator titr=_textureGlyphQuadMap.begin();
@@ -676,13 +592,60 @@ void Text::computePositions(unsigned int contextID)
_normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix);
_normal.normalize();
dirtyBound();
const_cast<Text*>(this)->dirtyBound();
}
void Text::drawImplementation(osg::State& state) const
{
unsigned int contextID = state.getContextID();
if (_characterSizeMode!=OBJECT_COORDS || _autoRotateToScreen)
{
int frameNumber = state.getFrameStamp()?state.getFrameStamp()->getFrameNumber():0;
AutoTransformCache& atc = _autoTransformCache[contextID];
const osg::Matrix& modelview = state.getModelViewMatrix();
osg::Vec3 newTransformedPosition = _position*modelview;
int width = atc._width;
int height = atc._height;
const osg::Viewport* viewport = state.getCurrentViewport();
if (viewport)
{
width = viewport->width();
height = viewport->height();
}
bool doUpdate = atc._traversalNumber==-1;
if (atc._traversalNumber>=0)
{
if (atc._modelview!=modelview)
{
doUpdate = true;
}
else if (width!=atc._width || height!=atc._height)
{
doUpdate = true;
}
}
atc._traversalNumber = frameNumber;
atc._width = width;
atc._height = height;
if (doUpdate)
{
atc._transformedPosition = newTransformedPosition;
atc._projection = state.getProjectionMatrix();
atc._modelview = modelview;
computePositions(contextID);
}
}
glNormal3fv(_normal.ptr());
glColor4fv(_color.ptr());
@@ -745,7 +708,7 @@ void Text::drawImplementation(osg::State& state) const
{
state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);
osg::Matrix& matrix = _matrix[contextID];
const osg::Matrix& matrix = _autoTransformCache[contextID]._matrix;
osg::Vec3 c00(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix);
osg::Vec3 c10(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*matrix);
@@ -767,9 +730,9 @@ void Text::drawImplementation(osg::State& state) const
{
glColor4f(1.0f,0.0f,1.0f,1.0f);
float cursorsize = _characterHeight*0.5f*_scale[contextID];
float cursorsize = _characterHeight*0.5f;
osg::Matrix& matrix = _matrix[contextID];
const osg::Matrix& matrix = _autoTransformCache[contextID]._matrix;
osg::Vec3 hl(osg::Vec3(_offset.x()-cursorsize,_offset.y(),_offset.z())*matrix);
osg::Vec3 hr(osg::Vec3(_offset.x()+cursorsize,_offset.y(),_offset.z())*matrix);
@@ -814,14 +777,6 @@ void Text::accept(osg::Drawable::PrimitiveFunctor& pf) const
pf.setVertexArray(glyphquad._transformedCoords[0].size(),&(glyphquad._transformedCoords[0].front()));
pf.drawArrays(GL_QUADS,0,glyphquad._transformedCoords[0].size());
// pf.begin(GL_QUADS);
// for(GlyphQuads::Coords3::const_iterator itr = glyphquad._transformedCoords.begin();
// itr!=glyphquad._transformedCoords.end();
// ++itr)
// {
// pf.vertex(*itr);
// }
// pf.end();
}
}