176 lines
6.0 KiB
C++
176 lines
6.0 KiB
C++
/*
|
|
* Copyright (C) 2012 Open Source Robotics Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*/
|
|
|
|
#include "gazebo/common/Console.hh"
|
|
#include "gazebo/rendering/ogre_gazebo.h"
|
|
#include "gazebo/rendering/selection_buffer/MaterialSwitcher.hh"
|
|
#include "gazebo/rendering/RenderTypes.hh"
|
|
|
|
using namespace gazebo;
|
|
using namespace rendering;
|
|
|
|
/////////////////////////////////////////////////
|
|
MaterialSwitcher::MaterialSwitcher()
|
|
: lastTechnique(nullptr)
|
|
{
|
|
this->currentColor = common::Color(0.0, 0.0, 0.1);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
MaterialSwitcher::~MaterialSwitcher()
|
|
{
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
Ogre::Technique *MaterialSwitcher::handleSchemeNotFound(
|
|
uint16_t /*_schemeIndex*/, const Ogre::String & /*_schemeName*/,
|
|
Ogre::Material *_originalMaterial, uint16_t /*_lodIndex*/,
|
|
const Ogre::Renderable *_rend)
|
|
{
|
|
if (_rend)
|
|
{
|
|
if (typeid(*_rend) == typeid(Ogre::SubEntity))
|
|
{
|
|
const Ogre::SubEntity *subEntity =
|
|
static_cast<const Ogre::SubEntity *>(_rend);
|
|
|
|
if (!(subEntity->getParent()->getVisibilityFlags() &
|
|
GZ_VISIBILITY_SELECTABLE))
|
|
{
|
|
const_cast<Ogre::SubEntity *>(subEntity)->setCustomParameter(1,
|
|
Ogre::Vector4(0, 0, 0, 0));
|
|
return nullptr;
|
|
}
|
|
|
|
if (this->lastEntity == subEntity->getParent()->getName())
|
|
{
|
|
const_cast<Ogre::SubEntity *>(subEntity)->setCustomParameter(1,
|
|
Ogre::Vector4(this->currentColor.r, this->currentColor.g,
|
|
this->currentColor.b, 1.0));
|
|
}
|
|
else
|
|
{
|
|
// load the selection buffer material
|
|
if (this->plainTechnique == nullptr)
|
|
{
|
|
// plain opaque material
|
|
Ogre::ResourcePtr res =
|
|
Ogre::MaterialManager::getSingleton().load("gazebo/plain_color",
|
|
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
|
|
|
// OGRE 1.9 changes the shared pointer definition
|
|
// But the 1.9 RC, which we're using on Windows, doesn't have the
|
|
// staticCast change. It will be in the final release.
|
|
#if (OGRE_VERSION < ((1 << 16) | (9 << 8) | 0)) || defined(_WIN32)
|
|
Ogre::MaterialPtr plainMaterial = static_cast<Ogre::MaterialPtr>(res);
|
|
#else
|
|
Ogre::MaterialPtr plainMaterial = res.staticCast<Ogre::Material>();
|
|
#endif
|
|
|
|
this->plainTechnique = plainMaterial->getTechnique(0);
|
|
Ogre::Pass *plainPass = this->plainTechnique->getPass(0);
|
|
plainPass->setDepthCheckEnabled(true);
|
|
plainPass->setDepthWriteEnabled(true);
|
|
|
|
// overlay material
|
|
Ogre::MaterialPtr overlayMaterial =
|
|
plainMaterial->clone("plain_color_overlay");
|
|
this->overlayTechnique =
|
|
overlayMaterial->getTechnique(0);
|
|
if (!this->overlayTechnique || !this->overlayTechnique->getPass(0))
|
|
{
|
|
gzerr << "Problem creating the selection buffer overlay material"
|
|
<< std::endl;
|
|
return nullptr;
|
|
}
|
|
Ogre::Pass *overlayPass = this->overlayTechnique->getPass(0);
|
|
overlayPass->setDepthCheckEnabled(false);
|
|
overlayPass->setDepthWriteEnabled(false);
|
|
}
|
|
|
|
// Make sure we keep the same depth properties so that
|
|
// certain overlay objects can be picked by the mouse.
|
|
Ogre::Technique *newTechnique = this->plainTechnique;
|
|
|
|
Ogre::Technique *originalTechnique = _originalMaterial->getTechnique(0);
|
|
if (originalTechnique)
|
|
{
|
|
Ogre::Pass *originalPass = originalTechnique->getPass(0);
|
|
if (originalPass)
|
|
{
|
|
// check if it's an overlay material by assuming the
|
|
// depth check and depth write properties are off.
|
|
bool depthCheck = originalPass->getDepthCheckEnabled();
|
|
bool depthWrite = originalPass->getDepthWriteEnabled();
|
|
if (!depthCheck && !depthWrite)
|
|
newTechnique = this->overlayTechnique;
|
|
}
|
|
}
|
|
|
|
this->lastTechnique = newTechnique;
|
|
|
|
this->GetNextColor();
|
|
|
|
const_cast<Ogre::SubEntity *>(subEntity)->setCustomParameter(1,
|
|
Ogre::Vector4(this->currentColor.r, this->currentColor.g,
|
|
this->currentColor.b, 1.0));
|
|
|
|
this->lastEntity = subEntity->getParent()->getName();
|
|
this->colorDict[this->currentColor.GetAsRGBA()] = this->lastEntity;
|
|
}
|
|
|
|
return this->lastTechnique;
|
|
}
|
|
// else
|
|
// gzerr << "Object is not a SubEntity["
|
|
// << _rend->getMaterial()->getName() << "] Type[" <<
|
|
// typeid(*_rend).name() << "]\n";
|
|
}
|
|
// else
|
|
// gzerr << "Rendering scheme without a Renderable: " << _schemeName
|
|
// << ", " + _originalMaterial->getName() << std::endl;
|
|
return nullptr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
const std::string &MaterialSwitcher::GetEntityName(
|
|
const common::Color &_color) const
|
|
{
|
|
ColorMapConstIter iter = this->colorDict.find(_color.GetAsRGBA());
|
|
|
|
if (iter != this->colorDict.end())
|
|
return (*iter).second;
|
|
else
|
|
return this->emptyString;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void MaterialSwitcher::GetNextColor()
|
|
{
|
|
common::Color::ARGB color = this->currentColor.GetAsARGB();
|
|
color++;
|
|
this->currentColor.SetFromARGB(color);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void MaterialSwitcher::Reset()
|
|
{
|
|
this->currentColor = common::Color(0.0, 0.0, 0.1);
|
|
this->lastEntity.clear();
|
|
this->colorDict.clear();
|
|
}
|