FlightGear next
marker.cxx
Go to the documentation of this file.
1// marker.cxx - 3D Marker pins in FlightGear
2// Copyright (C) 2022 Tobias Dammers
3// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
4
5#ifdef HAVE_CONFIG_H
6# include <config.h>
7#endif
8
9#include "Scenery/marker.hxx"
10#include <simgear/scene/util/SGNodeMasks.hxx>
11#include <simgear/scene/util/SGReaderWriterOptions.hxx>
12#include <simgear/scene/material/Effect.hxx>
13#include <simgear/scene/material/EffectGeode.hxx>
14#include <osg/Geometry>
15#include <osg/Material>
16#include <osg/Node>
17#include <osg/Billboard>
18#include <osgText/Text>
19#include <osgText/String>
20#include <osgDB/ReadFile>
21#include <osgDB/WriteFile>
22#include <osgDB/Registry>
23
24osg::Node* fgCreateMarkerNode(const osgText::String& label, float font_size, float pin_height, float tip_height, const osg::Vec4f& color)
25{
26 auto mainNode = new osg::Group;
27
28 auto textNode = new osg::Billboard;
29 mainNode->addChild(textNode);
30
31 textNode->setMode(osg::Billboard::AXIAL_ROT);
32
33 auto text = new osgText::Text;
34 text->setText(label);
35 text->setAlignment(osgText::Text::CENTER_BOTTOM);
36 text->setAxisAlignment(osgText::Text::XZ_PLANE);
37 text->setFont("Fonts/LiberationFonts/LiberationSans-Regular.ttf");
38 // text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
39 text->setCharacterSize(font_size, 1.0f);
40 text->setFontResolution(std::max(32.0f, font_size), std::max(32.0f, font_size));
41 text->setColor(color);
42 text->setPosition(osg::Vec3(0, 0, pin_height));
43 text->setBackdropType(osgText::Text::OUTLINE);
44 text->setBackdropColor(osg::Vec4(0, 0, 0, 0.75));
45 textNode->addDrawable(text);
46
47 float top_spacing = font_size * 0.25;
48
49 if (pin_height - top_spacing > tip_height) {
50 osg::Vec4f solid = color;
51 osg::Vec4f transparent = color;
52 osg::Vec3f nvec(0, 1, 0);
53
54 solid[3] = 1.0f;
55 transparent[3] = 0.0f;
56
57 auto geoNode = new simgear::EffectGeode;
58 mainNode->addChild(geoNode);
59 auto pinGeo = new osg::Geometry;
60 osg::Vec3Array* vtx = new osg::Vec3Array;
61 osg::Vec3Array* nor = new osg::Vec3Array;
62 osg::Vec4Array* rgb = new osg::Vec4Array;
63
64 nor->push_back(nvec);
65
66 vtx->push_back(osg::Vec3f(0, 0, tip_height));
67 rgb->push_back(solid);
68
69 vtx->push_back(osg::Vec3f(-font_size * 0.125, 0, pin_height - top_spacing));
70 rgb->push_back(transparent);
71
72 vtx->push_back(osg::Vec3f(0, font_size * 0.125, pin_height - top_spacing));
73 rgb->push_back(transparent);
74
75 vtx->push_back(osg::Vec3f(font_size * 0.125, 0, pin_height - top_spacing));
76 rgb->push_back(transparent);
77
78 vtx->push_back(osg::Vec3f(0, -font_size * 0.125, pin_height - top_spacing));
79 rgb->push_back(transparent);
80
81 vtx->push_back(osg::Vec3f(-font_size * 0.125, 0, pin_height - top_spacing));
82 rgb->push_back(transparent);
83
84 pinGeo->setVertexArray(vtx);
85 pinGeo->setColorArray(rgb, osg::Array::BIND_PER_VERTEX);
86 pinGeo->setNormalArray(nor, osg::Array::BIND_OVERALL);
87 pinGeo->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, 0, vtx->size()));
88 geoNode->addDrawable(pinGeo);
89
90 osg::ref_ptr<simgear::SGReaderWriterOptions> opt;
91 opt = simgear::SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
92 simgear::Effect* effect = simgear::makeEffect("Effects/marker-pin", true, opt);
93 if (effect)
94 geoNode->setEffect(effect);
95 }
96
97 mainNode->setNodeMask(~simgear::CASTSHADOW_BIT);
98 return mainNode;
99}
osg::Node * fgCreateMarkerNode(const osgText::String &label, float font_size, float pin_height, float tip_height, const osg::Vec4f &color)
Definition marker.cxx:24