I don't know if this is the right place for this, but while searching for a solution to a problem I've seen some older posts struggling with techniques to highlight entities and it looks like something that bother people (or at least used to in the past.. don't know about now).
anyway I wrote a quite simple solution for that and I thought it might be nice to share it with other users and maybe get some better ideas or other approaches.
my idea is this - a class that gets a list of entities and creates a clone of them on the same position and properties, but a little bit bigger and with additive blending effect. the class also handles their disposal so its quite simple to use.
the code looks like this:
Code: Select all
class Highlighter
{
private:
Ogre::SceneManager* m_scene;
std::vector<Ogre::Entity*> m_entities;
public:
// destroy the highlighter
~Highlighter()
{
while (!m_entities.empty())
{
Ogre::Entity* entity = m_entities.back();
Ogre::SceneNode* node = entity->getParentSceneNode();
node->detachObject(entity);
m_scene->destroyEntity(entity);
node->getParentSceneNode()->removeChild(node);
m_scene->destroySceneNode(node);
m_entities.pop_back();
}
}
// create the Highlighter based on a single entity
Highlighter(Ogre::SceneManager* scene, Ogre::Entity* entity) : m_scene(scene)
{
std::vector<Ogre::Entity*> temp;
temp.push_back(entity);
create(temp);
}
// create the Highlighter based on a list of entities
Highlighter(Ogre::SceneManager* scene, std::vector<Ogre::Entity*>& entities) : m_scene(scene)
{
// now set hightlight
create(entities);
}
private:
// generate the list of entities
void create(std::vector<Ogre::Entity*>& entities)
{
for (auto entity = entities.begin(); entity != entities.end(); ++entity)
{
// create a clone entity and set its mateiral to the highlight material
GraphicEntity* NewEnt = (*entity)->clone((*entity)->getName() + "_H");
NewEnt->setMaterialName("highlighter_mat", RESOURCE_GROUP_FRAMEWORK);
// create a node for the highlight entity
GraphicNode* pNewNode = (*entity)->getParentSceneNode()->createChildSceneNode();
pNewNode->translate(0, 2, 0); // to make it a bit heigher than original entity. this helps handle stuff like flat terrain tiles
pNewNode->setScale(pNewNode->getScale() * 1.025f); // to make it a bit bigger than the original
// attach entity to the node and add to the list of entities
pNewNode->attachObject(NewEnt);
m_entities.push_back(NewEnt);
}
}
};
Code: Select all
material highlighter_mat
{
technique
{
pass
{
lighting off
scene_blend add
depth_write off
texture_unit
{
colour_op_ex source1 src_manual src_current 0.25 0.25 0.25
}
}
}
}
I think it looks decent enough for level editors.
anyway feel free to use and give feedback or ideas if you have any. also, if there's an easier solution that I somehow missed I'd love to hear about it
thanks!
PS. I know it would make more sense if the class constructor would get a single scene node and iterate on its children (instead of entities vector), but my editor keeps vectors of entities anyway so it was quicker for me.