Hi Eric

On 4/5/07, E. Wing <[EMAIL PROTECTED]> wrote:
This is kind of a follow up to a problem I had many months back which
I can't remember the topic name. My basic problem is that I'm trying
to render something on screen that has text labels. I need to make
sure to adjust the view so that all the text fits on the screen and
doesn't run off the edges. (But I don't want too much empty padding so
I want my values to be deterministic.)

I moved away from SCREEN_COORDS mode to OBJECT_COORDS mode because it
seemed that SCREEN_COORDS mode couldn't deterministically tell me what
the bounding box of the text would be until after it was rendered.
Since I need to compute my view range before I render, this didn't
work out.

So now I am back to OBJECT_COORDS mode and I also have to recalculate
my character height and aspect ratio manually. I have implemented this
and this part of the code seems to work well.

My problem though is that I'm still not consistent or correct values
for the size of my text via computeBound(). The values seem to be more
correct than SCREEN_COORDS mode, but I noticed my values are still off
slightly when I have a large scale projection change.

I'm trying to understand what's causing this. I haven't yet
determined/proved if the problem is in my stuff or how osgText works,
but I'm hoping to get a better explanation of how computeBound() works
for regular osgText modes. Basically, I just want to specify a string
via setText(), and a character size and aspect ratio via
setCharacterSize(), and call computeBound() on the text to get the
width and height of my text. Under OBJECT_COORDS, shouldn't this do
the correct thing? If the answer is yes, then I know the problem is in
my code. If the answer is no, I need to understand how it actually
works a little better and how to work around it.

I am under an orthographic projection (2D) if it makes a difference.


I am currently using a stupid but efficient technique to get
osgText::Text fit into a 2D label. I don't know what yours is, maybe
it's the same, but mine has not shown offsets or artifacts yet.
Basically, as I can't compute (in a deterministic way, that is) the
final bounding box of a text, I just assign it a predefined size. Then
I make it bigger or smaller until it fits in the label or until
min/max threshold has been reached. This is very time consuming, but
is done only once for a label as long as its text do not change.

I use the following function to get 'node' fit into 'fit', which is
the BB of the label; 'maxCharSize' is the max size, the min size is 1.

void View::fitText(osgText::Text* node, const osg::BoundingBox& fit,
int maxCharSize)
{
        int currentCharSize = (int)floor(node->getCharacterHeight());
        int bestCharSize = currentCharSize;

        node->setCharacterSize(bestCharSize);
        while (currentCharSize > 1)
        {
                osg::BoundingBox bb(node->getBound());
                bb._max -= bb._min;
                bb._min = osg::Vec3(0.0, 0.0, 0.0);

                if (bb._max.x() > fit._max.x() || bb._max.y() > fit._max.y())
                {
                        currentCharSize -= 1;
                        node->setCharacterSize((double)currentCharSize);
                }else{
                        bestCharSize = currentCharSize;
                        break;
                }
        }

        node->setCharacterSize(bestCharSize);
        while (currentCharSize < maxCharSize)
        {
                osg::BoundingBox bb(node->getBound());
                bb._max -= bb._min;
                bb._min = osg::Vec3(0.0, 0.0, 0.0);

                if (bb._max.x() < fit._max.x() && bb._max.y() < fit._max.y())
                {
                        currentCharSize += 1;
                        node->setCharacterSize((double)currentCharSize);
                }else{
                        bestCharSize = currentCharSize;
                        break;
                }
        }
        osg::notify(osg::INFO) << "adjusted text " <<
node->getText().createUTF8EncodedString() << " to " << bestCharSize <<
" points" << std::endl;
        node->setCharacterSize(bestCharSize);
}

note: all sizes are in default coordinates mode - I did not change
that parameter.

I don't know whether you can use this trick in your app (and if it
differs from your current technique, actually) but if you are not too
much concerned by the speed at which the size of a label is computed,
you can give it a try.

Cheers

Thibault
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to