ADTF_DISPLAY_TOOLBOX  3.8.0 (ADTF 3.14.3)
Source Code for Demo 3D Load Model Mixin
Location
./src/examples/src/loadmodelmixin
This example shows:
  • how to read a 3d model
  • how to extend the context menu to add object specific actions
  • how to offer a possibility to transform the color of a 3D object
  • how to offer a possibility to select (pick) an object
Header
#pragma once
#include <osgFX/Scribe>
#include <memory>
using namespace adtf::util;
using namespace adtf::ucom;
using namespace adtf::disptb::mixinlib;
class cLoadModelMixin: public cMixin, public cSensorManipulator::Delegate
{
public:
ADTF_CLASS_ID_NAME(cLoadModelMixin, "demo_load_model.3d_mixin.disptb.cid", "Demo 3D Load Model Mixin");
public:
cLoadModelMixin();
tResult InitScene() override;
tVoid ValuesChangedInManipulator(cSensorManipulator* pManip) override;
tResult AddMenuItemForPick(IMenu& oMenu, const tNodePath& sNodePath) override;
tResult HandleMenuEvent(const tChar* strMenuText, tVoid* pvEventData) override;
protected:
adtf::base::property_variable<cFilename> m_strModelFile;
adtf::base::property_variable<tFloat32> m_fScale = 1.0;
adtf::base::property_variable<cString> m_strColor = {"#ffffff"};
std::unique_ptr<cSensorManipulator> pManipulator;
osg::ref_ptr<osg::PositionAttitudeTransform> pModelTransform;
};
Copyright © Audi Electronics Venture GmbH.
Namespace for functionality provided by the Mixin Library.
Definition: baseobject.h:23
Copyright © Audi Electronics Venture GmbH.
Implementation
#include "loadmodelmixin.h"
#ifndef WIN32
#pragma GCC visibility push(default)
#endif
#include <osg/PositionAttitudeTransform>
#include <osgDB/ReadFile>
#ifndef WIN32
#pragma GCC visibility pop
#endif
ADTF_PLUGIN_VERSION("Demo 3D Load Model Mixin Plugin",
disptb,
DISPTB_VERSION_MAJOR,
DISPTB_VERSION_MINOR,
DISPTB_VERSION_PATCH,
cLoadModelMixin)
static osg::Vec4 GetHexColor(const cString& strColor)
{
if (strColor.GetLength() != 7 ||
!strColor.StartsWith("#"))
{
return osg::Vec4(0.0, 0.0, 0.0, 1.0);
}
return osg::Vec4(("0x" + strColor.Mid(1, 2)).AsInt32() / 255.0,
("0x" + strColor.Mid(3, 2)).AsInt32() / 255.0,
("0x" + strColor.Mid(5, 2)).AsInt32() / 255.0,
1.0);
}
cLoadModelMixin::cLoadModelMixin()
{
m_strModelFile.SetDescription("Model to be loaded.");
RegisterPropertyVariable("model_file", m_strModelFile);
m_fScale.SetDescription("Scaling of the model.");
RegisterPropertyVariable("model_scale", m_fScale);
m_strColor.SetDescription("Color key for the model.");
RegisterPropertyVariable("model_color", m_strColor);
SetDescription("Use this Mixin to load and show a 3D model in the scene.");
adtf::streaming::set_help_link(*this, "$(ADTF_DISPLAY_TOOLBOX_DIR)/doc/displaytoolbox_html/page_3d_load_model_mixin_example_readme.html");
}
tResult cLoadModelMixin::InitScene()
{
LOG_INFO("Loading file: " + static_cast<cFilename>(m_strModelFile));
osg::ref_ptr<osg::Node> pModelNode = osgDB::readNodeFile(m_strModelFile->GetPtr());
if (!pModelNode)
{
RETURN_ERROR_DESC(ERR_NOT_FOUND, "unable to load model %s", m_strModelFile->GetPtr());
}
// enable rescaling of normals (otherwise lightnig would suffer because of scaleing the model)
pModelNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
pManipulator.reset(new cSensorManipulator());
pManipulator->setDelegate(this);
pManipulator->setWindowTitle(m_strModelFile->GetNameWithoutExtension().GetPtr());
pModelTransform = new osg::PositionAttitudeTransform;
GetRoot()->addChild(pModelTransform.get());
// always set the glColor (for model files that do not set them explicitly)
osg::Vec4 oColor = GetHexColor(m_strColor);
osg::Geode* pColorNode = new osg::Geode;
pModelTransform->addChild(pColorNode);
//model node
pModelTransform->addChild(pModelNode.get());
// Set default Material
osg::StateSet* pStateSet = pModelNode.get()->getStateSet();
osg::Material* pMaterial = new osg::Material();
pMaterial->setDiffuse(osg::Material::FRONT_AND_BACK,
osg::Vec4(oColor.r(), oColor.g(), oColor.b(), 1.0));
pStateSet->setAttribute(pMaterial);
pModelNode.get()->setStateSet(pStateSet);
RETURN_NOERROR;
}
tResult cLoadModelMixin::HandleMenuEvent(const tChar* /*strMenuText*/, tVoid* /*pvEventData*/)
{
pManipulator->setVisible(!pManipulator->isVisible());
RETURN_NOERROR;
}
tVoid cLoadModelMixin::ValuesChangedInManipulator(cSensorManipulator* pManip)
{
tFloat64 fX, fY, fZ;
tFloat64 fRoll, fPitch, fYaw;
if (pModelTransform)
{
// get values
pManip->getXYZ(fX, fY, fZ);
pManip->getRollPitchYawRad(fRoll, fPitch, fYaw);
pModelTransform->setPosition(osg::Vec3d(fX, fY, fZ));
pModelTransform->setAttitude(osg::Quat(fRoll, osg::Vec3d(1,0,0), fPitch, osg::Vec3d(0,1,0), fYaw, osg::Vec3d(0,0,1)));
}
}
tResult cLoadModelMixin::AddMenuItemForPick(IMenu& oMenu, const tNodePath& /*sNodePath*/)
{
oMenu.AddSeparator();
auto pMenuItem = oMenu.AddMenuItem("Model Properties");
pMenuItem->SetCheckable(tTrue);
pMenuItem->SetChecked(pManipulator->isVisible());
pMenuItem->SetEventHandler(this);
RETURN_NOERROR;
}