Hi Robert,

I hope you're not sick of hearing from me yet.  I have uncovered a difference 
of behavior between 3.4 and 3.6 in osgText::Text's bounding box calculation.  
The attached program attempts to demonstrate the difference.

In one place in our application, we are trying to determine the width of a text 
string in model coordinates.  This works well using getBoundingBox().  The 
problem we are seeing is if we change the text string, then call 
getBoundingBox() before drawImplementation() has a chance to run, the bounding 
box is vastly different than expected.  I believe this is because 
computePositions() passes in 0 for the osg::State to computeMatrix().

Because of this, it's unclear when we call getBoundingBox if we're getting 
model coordinates or screen coordinates. (sorry, I'm not sure if that's the 
correct terminology)


In OSG 3.4, if you run the attached program, you'll get the same value printout 
before and after change.  In OSG 3.6, you get a value that is vastly larger 
after.  You can see the relevant code in TextWidthPrinter::handle(), and on the 
console by pressing 't' at runtime.


This is not a blocker for us because we have access to the osg::State in our 
code and can multiply against the correct matrix to value we need.  We can #if 
OSG_VERSION_GREATER_THAN our code.  But this change looks unintentional, so I 
wanted to pass along this test program that demonstrates the issue.

I hope this is helpful.

 - Dan

/* OpenSceneGraph example, osgtext.
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/

#include <iostream>
#include <osgDB/ReadFile>

#include <osgGA/StateSetManipulator>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/config/SingleWindow>

#include <osg/Camera>
#include <osg/MatrixTransform>

#include <osgText/Font>
#include <osgText/Text>

osgText::Text* createText(const std::string& textString, float xPosition)
{
    osgText::Text* returnValue = new osgText::Text;
    returnValue->setDataVariance(osg::Object::DYNAMIC);
    returnValue->setFont("fonts/times.ttf");
    returnValue->setCharacterSize(32.f);
    returnValue->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);
    returnValue->setPosition(osg::Vec3(xPosition, -0.05, 0.0));
    returnValue->setAlignment(osgText::TextBase::CENTER_CENTER);
    returnValue->setAutoRotateToScreen(true);
    returnValue->setText(textString);

    // Note that adding a drop shadow makes text's alignment pretty far off.  
This does
    // not seem to have a huge negative impact in my app, but was noticed 
during the copy
    // over to this demo.  Probably just an artifact of only having text in the 
scene?
    //returnValue->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
    return returnValue;
}

class TextWidthPrinter : public osgGA::GUIEventHandler
{
public:
    TextWidthPrinter(osgText::Text* text)
      : text_(text)
    {
    }

    virtual bool handle(const osgGA::GUIEventAdapter& ea, 
osgGA::GUIActionAdapter& aa)
    {
      if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == 't')
      {
        // Matrix has -1 as left side as window, +1 as right side of window.  
So one
        // would expect that this would be approximately 0.44 (~1/4 of screen)
        std::cout << "Text width before setText(): " << getTextWidth() << "\n";

        // Change the text string, then change it back to old text
        const osgText::String oldText = text_->getText();
        text_->setText("Anything else");
        text_->setText(oldText);

        // Demonstrate that the bounding box units are drastically different.  
This appears
        // to be the actual on-screen text width, not in the model coordinates.
        std::cout << "Text width after setText(): " << getTextWidth() << "\n";
        return true;
      }
      return false;
    }

    /** Returns the bounding box's size in X coordinates */
    float getTextWidth() const
    {
      const osg::BoundingBox bb = text_->getBoundingBox();
      return bb.xMax() - bb.xMin();
    }

private:
    osgText::Text* text_;
};

int main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc, argv);

    // construct the viewer.
    osgViewer::Viewer viewer(arguments);

    // make sure the root node is group so we can add extra nodes to it.
    osg::Group* group = new osg::Group;
    osgText::Text* testText = createText("Press 't' to test", 0.0);
    group->addChild(testText);

    // set the scene to render
    viewer.setSceneData(group);

    viewer.addEventHandler(new 
osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
    viewer.addEventHandler(new osgViewer::StatsHandler());
    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
    viewer.addEventHandler(new TextWidthPrinter(testText));

    int width = 800;
    int height = 600;
    viewer.setUpViewInWindow(100, 100, width, height);

    // Configure an ortho-2D projection, using -1 and +1 as bounds
    osg::Camera* camera = viewer.getCamera();
    camera->getOrCreateStateSet()->setGlobalDefaults();
    camera->setProjectionMatrixAsOrtho2D(-1.f, 1.f, -1.f, 1.f);
    camera->setProjectionResizePolicy(osg::Camera::FIXED);
    camera->setViewMatrixAsLookAt(
      osg::Vec3d(0, 0, 100),
      osg::Vec3d(0, 0, 0),
      osg::Y_AXIS);

    viewer.run();

    return 0;
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to