ADTF_DISPLAY_TOOLBOX  3.8.0 (ADTF 3.14.3)
Source Code for Demo 3D Cartesian Grid Mixin
Location
./src/examples/src/cartesiangridmixin
This example shows:
  • how to create a cartesian grid as base
Header
#pragma once
using namespace adtf::ucom;
using namespace adtf::disptb::mixinlib;
class cCartesianGridMixin: public cMixin
{
public:
ADTF_CLASS_ID_NAME(cCartesianGridMixin, "demo_grid.3d_mixin.disptb.cid", "Demo 3D Cartesian Grid Mixin");
public:
cCartesianGridMixin();
tResult InitScene() override;
private:
adtf::base::property_variable<tFloat32> m_fStepX = 5.0;
adtf::base::property_variable<tFloat32> m_fStepY = 5.0;
adtf::base::property_variable<tFloat32> m_fMinY = -50.0;
adtf::base::property_variable<tFloat32> m_fMaxY = 50.0;
adtf::base::property_variable<tFloat32> m_fMinX = -100.0;
adtf::base::property_variable<tFloat32> m_fMaxX = 100.0;
adtf::base::property_variable<tFloat32> m_fZ = 0.0;
adtf::base::property_variable<tFloat32> m_fFontSize = 0.75;
adtf::base::property_variable<tBool> m_bCoordsX = tTrue;
adtf::base::property_variable<tBool> m_bCoordsY = tTrue;
};
Copyright © Audi Electronics Venture GmbH.
Namespace for functionality provided by the Mixin Library.
Definition: baseobject.h:23
Implementation
#include "cartesiangridmixin.h"
#include <osg/Group>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Drawable>
#include <osg/LineWidth>
#include <osgText/Text>
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <cmath>
#ifndef M_PI
namespace
{
const double M_PI = std::acos(-1.0);
const double M_PI_2 = M_PI/2.0;
}
#endif
ADTF_PLUGIN_VERSION("Demo 3D Cartesian Grid Mixin Plugin",
disptb,
DISPTB_VERSION_MAJOR,
DISPTB_VERSION_MINOR,
DISPTB_VERSION_PATCH,
cCartesianGridMixin)
cCartesianGridMixin::cCartesianGridMixin()
{
m_fStepX.SetDescription("Step for the grid x-axis.");
RegisterPropertyVariable("gridstep_x", m_fStepX);
m_fStepY.SetDescription("Step for the grid y-axis.");
RegisterPropertyVariable("gridstep_y", m_fStepY);
m_fMinX.SetDescription("Minimum value for the grid x-axis.");
RegisterPropertyVariable("gridmin_x", m_fMinX);
m_fMaxX.SetDescription("Maximum value for the grid x-axis.");
RegisterPropertyVariable("gridmax_x", m_fMaxX);
m_fMinY.SetDescription("Minimum value for the grid y-axis.");
RegisterPropertyVariable("gridmin_y", m_fMinY);
m_fMaxY.SetDescription("Maximum value for the grid y-axis.");
RegisterPropertyVariable("gridmax_y", m_fMaxY);
m_fZ.SetDescription("Value for the grid z-axis.");
RegisterPropertyVariable("grid_z", m_fZ);
m_fFontSize.SetDescription("Value for the grid font size.");
RegisterPropertyVariable("grid_font_size", m_fFontSize);
m_bCoordsX.SetDescription("If enabled, labels for x-axis will be created.");
RegisterPropertyVariable("gridcoords_x", m_bCoordsX);
m_bCoordsY.SetDescription("If enabled, labels for y-axis will be created.");
RegisterPropertyVariable("gridcoords_y", m_bCoordsY);
SetDescription("Use this Mixin to provide a cartesian grid for the scene.");
adtf::streaming::set_help_link(*this, "$(ADTF_DISPLAY_TOOLBOX_DIR)/doc/displaytoolbox_html/page_3d_cartesian_grid_mixin_example_readme.html");
}
tResult cCartesianGridMixin::InitScene()
{
// grid: from -50 to +50 in x, y in 5m steps
if (m_fStepX <= 0.0)
{
RETURN_ERROR_DESC(ERR_INVALID_ARG, "Invalid value for 'gridstep_x' property");
}
if (m_fStepY<= 0.0)
{
RETURN_ERROR_DESC(ERR_INVALID_ARG, "Invalid value for 'gridstep_y' property");
}
/*
* Create grid
*/
{
auto pGrid = new osg::Geode;
GetRoot()->addChild(pGrid);
// Create one geometry for each solid color
osg::Geometry* pGreyGridGeometry = new osg::Geometry;
osg::Geometry* pWhiteGridGeometry = new osg::Geometry;
pGrid->addDrawable(pGreyGridGeometry);
pGrid->addDrawable(pWhiteGridGeometry);
pGreyGridGeometry->setUseVertexBufferObjects(true);
pWhiteGridGeometry->setUseVertexBufferObjects(true);
pGreyGridGeometry->setUseDisplayList(false);
pWhiteGridGeometry->setUseDisplayList(false);
osg::Vec4Array* pColorWhite = new osg::Vec4Array;
osg::Vec4Array* pColorGray = new osg::Vec4Array;
pColorWhite->push_back(osg::Vec4(.8f, .8f, .8f, 1.0f));
pColorGray->push_back(osg::Vec4(.5f, .5f, .5f, 1.0f));
osg::Vec3Array* pCoordsWhite = new osg::Vec3Array;
osg::Vec3Array* pCoordsGray = new osg::Vec3Array;
osg::Vec3Array* pNormals = new osg::Vec3Array;
pNormals->push_back(osg::Vec3(0, 0, 1));
tInt nIndex = 0;
tBool bGray = tFalse;
for (tFloat fX = m_fMinX; fX < m_fMaxX; fX += m_fStepX)
{
bGray = !bGray;
for (tFloat fY = m_fMinY; fY < m_fMaxY; fY += m_fStepY, nIndex++)
{
// Append to either grey or white geometry
osg::Vec3Array* pCoords = bGray ? pCoordsGray : pCoordsWhite;
pCoords->push_back(osg::Vec3(fX + m_fStepX, fY, m_fZ));
pCoords->push_back(osg::Vec3(fX + m_fStepX, fY + m_fStepY, m_fZ));
pCoords->push_back(osg::Vec3(fX, fY + m_fStepY, m_fZ));
pCoords->push_back(osg::Vec3(fX, fY + m_fStepY, m_fZ));
pCoords->push_back(osg::Vec3(fX, fY, m_fZ));
pCoords->push_back(osg::Vec3(fX + m_fStepX, fY, m_fZ));
bGray = !bGray;
}
}
pGreyGridGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, pCoordsGray->size()));
pGreyGridGeometry->setColorArray(pColorGray, osg::Array::BIND_OVERALL);
pGreyGridGeometry->setVertexArray(pCoordsGray);
pGreyGridGeometry->setNormalArray(pNormals, osg::Array::BIND_OVERALL);
pWhiteGridGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, pCoordsWhite->size()));
pWhiteGridGeometry->setColorArray(pColorWhite, osg::Array::BIND_OVERALL);
pWhiteGridGeometry->setVertexArray(pCoordsWhite);
pWhiteGridGeometry->setNormalArray(pNormals, osg::Array::BIND_OVERALL);
}
/*
* Create distance coordinate bar
*/
if(m_bCoordsX)
{
auto pCoordXBar = new osg::Geode;
GetRoot()->addChild(pCoordXBar);
osg::Geometry* pCoordXBarGeometry = new osg::Geometry;
pCoordXBar->addDrawable(pCoordXBarGeometry);
pCoordXBarGeometry->setUseVertexBufferObjects(true);
pCoordXBarGeometry->setUseDisplayList(false);
osg::Vec4Array* pColors = new osg::Vec4Array;
osg::Vec3Array* pCoords = new osg::Vec3Array;
osg::LineWidth* coordXLineWidth = new osg::LineWidth;
coordXLineWidth->setWidth(2.0f);
pCoordXBar->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
pCoordXBar->getOrCreateStateSet()->setAttributeAndModes(coordXLineWidth, osg::StateAttribute::ON);
tInt nIndex = 0;
for(tFloat fX = m_fMinX; fX < m_fMaxX; fX += 2 * m_fStepX, nIndex++)
{
if(fabs(fX) < m_fStepX/2.0f) continue;
osg::Vec4 color(1.1f-fabs(fX)/100.0f, fabs(fX)/100.0f-.1f, fabs(fX)/200.0f, 1.0f);
// We need to add the color two times, because
// we want to bind the color per vertex and we draw lines
pColors->push_back(color);
pColors->push_back(color);
pCoords->push_back(osg::Vec3(fX, 1.5f, m_fZ + .1f));
pCoords->push_back(osg::Vec3(fX, -1.5f, m_fZ + .1f));
osgText::Text* coordText = new osgText::Text;
pCoordXBar->addDrawable(coordText);
coordText->setFont(GetFont());
coordText->setCharacterSize(m_fFontSize);
coordText->setPosition(osg::Vec3(fX, -1.7f, .5f));
coordText->setRotation(osg::Quat(-M_PI_2, osg::Vec3(0, 0, 1)));
coordText->setAxisAlignment(osgText::Text::SCREEN);
coordText->setColor(color);
coordText->setText(adtf::util::cString::Format("%dm", (int)fX).GetPtr());
}
pCoordXBarGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, pCoords->size()));
pCoordXBarGeometry->setColorArray(pColors, osg::Array::BIND_PER_VERTEX);
pCoordXBarGeometry->setVertexArray(pCoords);
}
if(m_bCoordsY)
{
auto pCoordYBar = new osg::Geode;
GetRoot()->addChild(pCoordYBar);
osg::Geometry* pCoordYBarGeometry = new osg::Geometry;
pCoordYBar->addDrawable(pCoordYBarGeometry);
pCoordYBarGeometry->setUseVertexBufferObjects(true);
pCoordYBarGeometry->setUseDisplayList(false);
osg::Vec4Array* pColors = new osg::Vec4Array;
osg::Vec3Array* pCoords = new osg::Vec3Array;
osg::LineWidth* coordYLineWidth = new osg::LineWidth;
coordYLineWidth->setWidth(2.0f);
pCoordYBar->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
pCoordYBar->getOrCreateStateSet()->setAttributeAndModes(coordYLineWidth, osg::StateAttribute::ON);
tInt nIndex = 0;
for(tFloat fY = m_fMinY; fY < m_fMaxY; fY += 2 * m_fStepY, nIndex++)
{
if(fabs(fY) < m_fStepY/2.0f) continue;
osg::Vec4 color(1.1f-fabs(fY)/100.0f, fabs(fY)/100.0f-.1f, fabs(fY)/200.0f, 1.0f);
// We need to add the color two times, because
// we want to bind the color per vertex and we draw lines
pColors->push_back(color);
pColors->push_back(color);
pCoords->push_back(osg::Vec3(1.5f, fY, m_fZ + .1f));
pCoords->push_back(osg::Vec3(-1.5f, fY, m_fZ + .1f));
osgText::Text* coordText = new osgText::Text;
pCoordYBar->addDrawable(coordText);
coordText->setFont(GetFont());
coordText->setCharacterSize(m_fFontSize);
coordText->setPosition(osg::Vec3(-1.7f, fY, .5f));
coordText->setRotation(osg::Quat(-M_PI_2, osg::Vec3(0, 0, 1)));
coordText->setAxisAlignment(osgText::Text::SCREEN);
coordText->setColor(color);
coordText->setText(adtf::util::cString::Format("%dm", (int)fY).GetPtr());
}
pCoordYBarGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, pCoords->size()));
pCoordYBarGeometry->setColorArray(pColors, osg::Array::BIND_PER_VERTEX);
pCoordYBarGeometry->setVertexArray(pCoords);
}
RETURN_NOERROR;
}