ADTF_DISPLAY_TOOLBOX  3.8.0 (ADTF 3.14.3)
Source Code for Demo 3D Road Mixin
Location
./src/examples/src/roadmixin
This example shows:
  • how to create a road-like 3D object
  • how to extend the context menu to add object specific actions
  • how to offer a possibility to transform a 3D object
  • how to offer a possibility to select (pick) an object
Header
#pragma once
#include <osgFX/Scribe>
#include <memory>
using namespace adtf::ucom;
using namespace adtf::disptb::mixinlib;
class cRoadMixin: public cMixin, public cSensorManipulator::Delegate
{
public:
ADTF_CLASS_ID_NAME(cRoadMixin, "demo_road.3d_mixin.disptb.cid", "Demo 3D Road Mixin");
cRoadMixin();
tResult InitScene() override;
tResult OnPick(tInt32 nPosX,
tInt32 nPosY,
tUInt32 nFlags,
const tNodePath& sNodePath) override;
tResult AddMenuItemForPick(IMenu& oMenu, const tNodePath& sNodePath) override;
tResult HandleMenuEvent(const tChar* strMenuText, tVoid* /*pvEventData*/) override;
tVoid ValuesChangedInManipulator(cSensorManipulator* pManip) override;
private:
std::unique_ptr<cSensorManipulator> m_pSensorManipulator = nullptr;
osg::ref_ptr<osg::PositionAttitudeTransform> m_pRoadtransform = nullptr;
osg::ref_ptr<osgFX::Scribe> m_pScribe = nullptr;
osg::ref_ptr<osg::Switch> m_pPickSwitch = nullptr;
};
Copyright © Audi Electronics Venture GmbH.
Namespace for functionality provided by the Mixin Library.
Definition: baseobject.h:23
Copyright © Audi Electronics Venture GmbH.
Implementation
#include "roadmixin.h"
#include <osg/PositionAttitudeTransform>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Switch>
#include <osgFX/Scribe>
ADTF_PLUGIN_VERSION("Demo 3D Road Mixin Plugin",
disptb,
DISPTB_VERSION_MAJOR,
DISPTB_VERSION_MINOR,
DISPTB_VERSION_PATCH,
cRoadMixin)
cRoadMixin::cRoadMixin()
{
SetDescription("Use this Mixin to model a 3D road for the scene.");
adtf::streaming::set_help_link(*this, "$(ADTF_DISPLAY_TOOLBOX_DIR)/doc/displaytoolbox_html/page_3d_road_mixin_example_readme.html");
}
tResult cRoadMixin::InitScene()
{
m_pSensorManipulator = std::make_unique<cSensorManipulator>(nullptr, Qt::Window | Qt::WindowTitleHint | Qt::WindowStaysOnTopHint);
m_pSensorManipulator->setDelegate(this);
m_pSensorManipulator->setWindowTitle("Road Mixin Manipulator");
m_pRoadtransform = new osg::PositionAttitudeTransform;
// osg nodes are managed with the internal osg reference counting
auto pRoad = new osg::Geode;
m_pRoadtransform->addChild(pRoad);
auto pRoadGeometry = new osg::Geometry;
pRoad->addDrawable(pRoadGeometry);
auto pCoords = new osg::Vec3Array;
auto pColors = new osg::Vec4Array;
auto pNormals = new osg::Vec3Array;
float z_level = 0.02f;
osg::Vec3 road_corner_1(-50, 1.5f, z_level);
pCoords->push_back(road_corner_1);
osg::Vec3 road_corner_2(100, 1.5f, z_level);
pCoords->push_back(road_corner_2);
osg::Vec3 road_corner_3(100, -1.5f, z_level);
pCoords->push_back(road_corner_3);
osg::Vec3 road_corner_4(-50, -1.5f, z_level);
pCoords->push_back(road_corner_4);
pNormals->push_back(osg::Vec3(0, 0, 1));
pColors->push_back(osg::Vec4(.2f, .2f, .3f, 1.0f));
pRoadGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
pRoadGeometry->setVertexArray(pCoords);
pRoadGeometry->setColorArray(pColors, osg::Array::BIND_PER_PRIMITIVE_SET);
pRoadGeometry->setNormalArray(pNormals, osg::Array::BIND_PER_PRIMITIVE_SET);
m_pScribe = new osgFX::Scribe();
m_pScribe->addChild(m_pRoadtransform);
m_pPickSwitch = new osg::Switch;
m_pPickSwitch->addChild(m_pRoadtransform);
m_pPickSwitch->addChild(m_pScribe);
m_pPickSwitch->setSingleChildOn(0);
GetRoot()->addChild(m_pPickSwitch);
RETURN_NOERROR;
}
tResult cRoadMixin::OnPick(tInt32 /*nPosX*/,
tInt32 /*nPosY*/,
tUInt32 nFlags,
const adtf::disptb::mixinlib::tNodePath& /*sNodePath*/)
{
if (nFlags & INodeHandler::CM_LEFT_MB)
{
if (m_pPickSwitch->getChildValue(m_pRoadtransform))
{
m_pPickSwitch->setSingleChildOn(1);
}
else
{
m_pPickSwitch->setSingleChildOn(0);
}
}
RETURN_NOERROR;
}
tResult cRoadMixin::AddMenuItemForPick(IMenu& oMenu, const tNodePath& /*sNodePath*/)
{
std::string strName;
GetName(adtf_string_intf(strName));
IMenuItem* pItem = oMenu.AddMenuItem((strName + " Properties").c_str());
pItem->SetEventHandler(this);
RETURN_NOERROR;
}
tResult cRoadMixin::HandleMenuEvent(const tChar* /*strMenuText*/, tVoid* /*pvEventData*/)
{
// we only have one menu entry, so we do not have to check the text
if (m_pSensorManipulator->isVisible())
{
m_pSensorManipulator->hide();
}
else
{
m_pSensorManipulator->show();
}
RETURN_NOERROR;
}
void cRoadMixin::ValuesChangedInManipulator(cSensorManipulator* pManip)
{
tFloat64 fX, fY, fZ;
tFloat64 fRoll, fPitch, fYaw;
if (m_pRoadtransform)
{
// get values
pManip->getXYZ(fX, fY, fZ);
pManip->getRollPitchYawRad(fRoll, fPitch, fYaw);
m_pRoadtransform->setPosition(osg::Vec3d(fX, fY, fZ));
m_pRoadtransform->setAttitude(osg::Quat(fRoll, osg::Vec3d(1,0,0), fPitch, osg::Vec3d(0,1,0), fYaw, osg::Vec3d(0,0,1)));
}
}