ObjectTitle
From Ogre Wiki
Contents |
Yet Another?
I was having some wonky perspective issues with ObjectTextDisplay and I needed something that could automatically center the title-- so I decided to write my own solution. (See ObjectTitle::update for a walk-through of my approach).
The Code
ObjectTitle.h
#ifndef __ObjectTitle_H__
#define __ObjectTitle_H__
#include "Ogre.h"
class ObjectTitle
{
const Ogre::MovableObject* object;
const Ogre::Camera* camera;
Ogre::Overlay* overlay;
Ogre::OverlayElement* textArea;
Ogre::OverlayContainer* container;
Ogre::Vector2 textDim;
Ogre::Font* font;
Ogre::Vector2 getTextDimensions(Ogre::String text);
public:
ObjectTitle(const Ogre::String& name, Ogre::MovableObject* object, Ogre::Camera* camera, const Ogre::String& title,
const Ogre::String& fontName, const Ogre::ColourValue& color = Ogre::ColourValue::White);
~ObjectTitle();
void setTitle(const Ogre::String& title);
void update();
};
#endif
ObjectTitle.cpp
#include "ObjectTitle.h"
#include <OgreFontManager.h>
using namespace Ogre;
ObjectTitle::ObjectTitle(const String& name, MovableObject* object, Camera* camera, const String& title,
const String& fontName, const Ogre::ColourValue& color) : object(object), camera(camera)
{
overlay = OverlayManager::getSingleton().create(name+"_TitleOverlay");
container = (OverlayContainer*)OverlayManager::getSingleton().createOverlayElement("Panel", name+"_TitleContainer");
overlay->add2D(container);
textArea = OverlayManager::getSingleton().createOverlayElement("TextArea", name+"_TitleTextArea");
textArea->setDimensions(0.8, 0.8);
textArea->setMetricsMode(GMM_PIXELS);
textArea->setPosition(0.1, 0.1);
FontManager::getSingleton().load(fontName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
font = (Font*)FontManager::getSingleton().getByName(fontName).getPointer();
textArea->setParameter("font_name", fontName);
textArea->setParameter("char_height", font->getParameter("size"));
textArea->setParameter("horz_align", "left");
textArea->setColour(color);
textArea->setCaption(title);
container->addChild(textArea);
overlay->show();
textDim = getTextDimensions(title);
container->setDimensions(textDim.x, textDim.y);
}
ObjectTitle::~ObjectTitle()
{
OverlayManager *overlayManager = OverlayManager::getSingletonPtr();
container->removeChild(textArea->getName());
overlay->remove2D(container);
overlayManager->destroyOverlayElement(textArea);
overlayManager->destroyOverlayElement(container);
overlayManager->destroy(overlay);
}
void ObjectTitle::setTitle(const String& title)
{
textArea->setCaption(title);
textDim = getTextDimensions(title);
container->setDimensions(textDim.x, textDim.y);
}
void ObjectTitle::update()
{
if(!object->isInScene())
{
overlay->hide();
return;
}
// Derive the average point between the top-most corners of the object's bounding box
const Ogre::AxisAlignedBox &AABB = object->getWorldBoundingBox(true);
Ogre::Vector3 point = (AABB.getCorner(AxisAlignedBox::FAR_LEFT_TOP)
+ AABB.getCorner(AxisAlignedBox::FAR_RIGHT_TOP)
+ AABB.getCorner(AxisAlignedBox::NEAR_LEFT_TOP)
+ AABB.getCorner(AxisAlignedBox::NEAR_RIGHT_TOP)) / 4;
// Is the camera facing that point? If not, hide the overlay and return.
Ogre::Plane cameraPlane = Plane(Vector3(camera->getDerivedOrientation().zAxis()), camera->getDerivedPosition());
if(cameraPlane.getSide(point) != Plane::NEGATIVE_SIDE)
{
overlay->hide();
return;
}
// Derive the 2D screen-space coordinates for that point
point = camera->getProjectionMatrix() * (camera->getViewMatrix() * point);
// Transform from coordinate space [-1, 1] to [0, 1]
Real x = (point.x / 2) + 0.5f;
Real y = 1 - ((point.y / 2) + 0.5f);
// Update the position (centering the text)
container->setPosition(x - (textDim.x / 2), y);
overlay->show();
}
Vector2 ObjectTitle::getTextDimensions(String text)
{
Real charHeight = StringConverter::parseReal(font->getParameter("size"));
Vector2 result(0, 0);
for(String::iterator i = text.begin(); i < text.end(); i++)
{
if (*i == 0x0020)
result.x += font->getGlyphAspectRatio(0x0030);
else
result.x += font->getGlyphAspectRatio(*i);
}
result.x = (result.x * charHeight) / (float)camera->getViewport()->getActualWidth();
result.y = charHeight / (float)camera->getViewport()->getActualHeight();
return result;
}
--Ajs15822 08:08, 7 February 2008 (GMT)

