#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());
}
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());
osg::Vec4 oColor = GetHexColor(m_strColor);
osg::Geode* pColorNode = new osg::Geode;
pModelTransform->addChild(pColorNode);
pModelTransform->addChild(pModelNode.get());
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* , tVoid* )
{
pManipulator->setVisible(!pManipulator->isVisible());
RETURN_NOERROR;
}
tVoid cLoadModelMixin::ValuesChangedInManipulator(cSensorManipulator* pManip)
{
tFloat64 fX, fY, fZ;
tFloat64 fRoll, fPitch, fYaw;
if (pModelTransform)
{
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& )
{
oMenu.AddSeparator();
auto pMenuItem = oMenu.AddMenuItem("Model Properties");
pMenuItem->SetCheckable(tTrue);
pMenuItem->SetChecked(pManipulator->isVisible());
pMenuItem->SetEventHandler(this);
RETURN_NOERROR;
}