GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
// |
||
2 |
// node.cpp |
||
3 |
// gepetto-viewer |
||
4 |
// |
||
5 |
// Created by Justin Carpentier, Mathieu Geisert in November 2014. |
||
6 |
// Copyright (c) 2014 LAAS-CNRS. All rights reserved. |
||
7 |
// |
||
8 |
|||
9 |
#include <gepetto/viewer/node-visitor.h> |
||
10 |
#include <gepetto/viewer/node.h> |
||
11 |
#include <gepetto/viewer/window-manager.h> |
||
12 |
|||
13 |
#include <climits> |
||
14 |
#include <osg/LineWidth> |
||
15 |
#include <osg/Material> |
||
16 |
#include <osgFX/Outline> |
||
17 |
#include <osgFX/Scribe> |
||
18 |
|||
19 |
#include "log.hh" |
||
20 |
|||
21 |
namespace gepetto { |
||
22 |
namespace viewer { |
||
23 |
namespace { |
||
24 |
const osg::StateSetRefPtr& getVisibleStateSet(const LightingMode& mode) { |
||
25 |
static osg::StateSetRefPtr ssOn, ssOff; |
||
26 |
switch (mode) { |
||
27 |
case LIGHT_INFLUENCE_ON: |
||
28 |
if (false && !ssOn) { // Disable because this is the default. |
||
29 |
ssOn = osg::StateSetRefPtr(new osg::StateSet()); |
||
30 |
ssOn->setRenderBinToInherit(); |
||
31 |
ssOn->setMode(GL_DEPTH_TEST, ::osg::StateAttribute::ON | |
||
32 |
::osg::StateAttribute::PROTECTED); |
||
33 |
ssOn->setMode(GL_CULL_FACE, ::osg::StateAttribute::OFF | |
||
34 |
::osg::StateAttribute::PROTECTED); |
||
35 |
ssOn->setMode(GL_LIGHTING, ::osg::StateAttribute::ON | |
||
36 |
::osg::StateAttribute::PROTECTED); |
||
37 |
} |
||
38 |
return ssOn; |
||
39 |
case LIGHT_INFLUENCE_OFF: |
||
40 |
if (!ssOff) { |
||
41 |
ssOff = osg::StateSetRefPtr(new osg::StateSet()); |
||
42 |
ssOff->setRenderBinToInherit(); |
||
43 |
ssOff->setMode(GL_DEPTH_TEST, ::osg::StateAttribute::ON | |
||
44 |
::osg::StateAttribute::PROTECTED); |
||
45 |
ssOff->setMode(GL_CULL_FACE, ::osg::StateAttribute::OFF | |
||
46 |
::osg::StateAttribute::PROTECTED); |
||
47 |
ssOff->setMode(GL_LIGHTING, ::osg::StateAttribute::OFF | |
||
48 |
::osg::StateAttribute::PROTECTED); |
||
49 |
} |
||
50 |
return ssOff; |
||
51 |
default: |
||
52 |
ASSERT(false, "LightingMode is not well defined"); |
||
53 |
break; |
||
54 |
}; |
||
55 |
} |
||
56 |
|||
57 |
const osg::StateSetRefPtr& getAlwaysOnTopStateSet(const LightingMode& mode) { |
||
58 |
static osg::StateSetRefPtr ssOn, ssOff; |
||
59 |
switch (mode) { |
||
60 |
case LIGHT_INFLUENCE_ON: |
||
61 |
if (!ssOn) { // Disable because this is the default. |
||
62 |
ssOn = osg::StateSetRefPtr(new osg::StateSet()); |
||
63 |
ssOn->setRenderBinDetails(INT_MAX, "DepthSortedBin"); |
||
64 |
ssOn->setMode(GL_DEPTH_TEST, ::osg::StateAttribute::OFF | |
||
65 |
::osg::StateAttribute::PROTECTED); |
||
66 |
ssOn->setMode(GL_CULL_FACE, ::osg::StateAttribute::ON | |
||
67 |
::osg::StateAttribute::PROTECTED); |
||
68 |
ssOn->setMode(GL_LIGHTING, ::osg::StateAttribute::ON | |
||
69 |
::osg::StateAttribute::PROTECTED); |
||
70 |
} |
||
71 |
return ssOn; |
||
72 |
case LIGHT_INFLUENCE_OFF: |
||
73 |
if (!ssOff) { |
||
74 |
ssOff = osg::StateSetRefPtr(new osg::StateSet()); |
||
75 |
ssOff->setRenderBinDetails(INT_MAX, "DepthSortedBin"); |
||
76 |
ssOff->setMode(GL_DEPTH_TEST, ::osg::StateAttribute::OFF | |
||
77 |
::osg::StateAttribute::PROTECTED); |
||
78 |
ssOff->setMode(GL_CULL_FACE, ::osg::StateAttribute::ON | |
||
79 |
::osg::StateAttribute::PROTECTED); |
||
80 |
ssOff->setMode(GL_LIGHTING, ::osg::StateAttribute::OFF | |
||
81 |
::osg::StateAttribute::PROTECTED); |
||
82 |
} |
||
83 |
return ssOff; |
||
84 |
default: |
||
85 |
ASSERT(false, "LightingMode is not well defined"); |
||
86 |
break; |
||
87 |
}; |
||
88 |
} |
||
89 |
|||
90 |
1 |
const osg::StateSetRefPtr& getWireframeStateSet() { |
|
91 |
✓✗✓✗ |
1 |
static osg::StateSetRefPtr ss; |
92 |
✓✗ | 1 |
if (!ss) { |
93 |
✓✗✓✗ ✓✗ |
1 |
ss = osg::StateSetRefPtr(new osg::StateSet()); |
94 |
|||
95 |
/* Allowing wireframe mode */ |
||
96 |
✓✗✓✗ |
2 |
osg::PolygonModeRefPtr polygon_mode_ptr = new ::osg::PolygonMode; |
97 |
✓✗ | 1 |
polygon_mode_ptr->setMode(::osg::PolygonMode::FRONT_AND_BACK, |
98 |
::osg::PolygonMode::LINE); |
||
99 |
1 |
polygon_mode_ptr->setDataVariance(osg::Object::STATIC); |
|
100 |
|||
101 |
✓✗✓✗ |
2 |
::osg::MaterialRefPtr material_wireframe_ptr = new osg::Material; |
102 |
1 |
material_wireframe_ptr->setColorMode(osg::Material::DIFFUSE); |
|
103 |
✓✗ | 2 |
material_wireframe_ptr->setDiffuse(osg::Material::FRONT_AND_BACK, |
104 |
1 |
osgVector4(1., 1., 1., 1.)); |
|
105 |
1 |
material_wireframe_ptr->setDataVariance(osg::Object::STATIC); |
|
106 |
|||
107 |
✓✗ | 1 |
ss->setMode( |
108 |
GL_BLEND, |
||
109 |
::osg::StateAttribute::OFF | |
||
110 |
::osg::StateAttribute::PROTECTED); // PROTECTED attribut allows |
||
111 |
// wireframe node to not be |
||
112 |
// influenced by alpha |
||
113 |
✓✗ | 1 |
ss->setAttributeAndModes( |
114 |
polygon_mode_ptr, |
||
115 |
::osg::StateAttribute::PROTECTED | ::osg::StateAttribute::ON); |
||
116 |
✓✗ | 1 |
ss->setAttributeAndModes( |
117 |
material_wireframe_ptr, |
||
118 |
::osg::StateAttribute::ON | ::osg::StateAttribute::PROTECTED); |
||
119 |
} |
||
120 |
1 |
return ss; |
|
121 |
} |
||
122 |
|||
123 |
template <unsigned int state> |
||
124 |
12 |
const osg::StateSetRefPtr& getHighlightStateSet() { |
|
125 |
✓✗✓✗ |
12 |
static osg::StateSetRefPtr ss; |
126 |
if (state == 0) return ss; |
||
127 |
✓✗ | 12 |
if (!ss) { |
128 |
✓✗✓✗ ✓✗ |
12 |
ss = osg::StateSetRefPtr(new osg::StateSet()); |
129 |
✓✗✓✗ |
24 |
::osg::MaterialRefPtr material_switch_ptr = new osg::Material; |
130 |
12 |
int glModeValue = ::osg::StateAttribute::INHERIT; |
|
131 |
/// Some color codes are taken from |
||
132 |
/// http://devernay.free.fr/cours/opengl/materials.html |
||
133 |
switch (state) { |
||
134 |
case 1: /// collision |
||
135 |
2 |
glModeValue = |
|
136 |
::osg::StateAttribute::ON | ::osg::StateAttribute::OVERRIDE; |
||
137 |
2 |
material_switch_ptr->setColorMode(osg::Material::AMBIENT); |
|
138 |
✓✗ | 2 |
material_switch_ptr->setDiffuse(osg::Material::FRONT_AND_BACK, |
139 |
osgVector4(1.0f, 0.f, 0.f, 1.f)); |
||
140 |
✓✗ | 2 |
material_switch_ptr->setTransparency(osg::Material::FRONT_AND_BACK, |
141 |
0.5f); |
||
142 |
2 |
break; |
|
143 |
case 2: /// selection |
||
144 |
2 |
glModeValue = ::osg::StateAttribute::ON | |
|
145 |
::osg::StateAttribute::OVERRIDE | |
||
146 |
::osg::StateAttribute::PROTECTED; |
||
147 |
/// Blue |
||
148 |
✓✗ | 2 |
material_switch_ptr->setAmbient(osg::Material::FRONT_AND_BACK, |
149 |
osgVector4(0.f, 0.f, 0.f, 1.f)); |
||
150 |
✓✗ | 2 |
material_switch_ptr->setDiffuse(osg::Material::FRONT_AND_BACK, |
151 |
osgVector4(0.f, 0.f, 1.f, 1.f)); |
||
152 |
✓✗ | 2 |
material_switch_ptr->setSpecular(osg::Material::FRONT_AND_BACK, |
153 |
osgVector4(0.6f, 0.6f, 0.7f, 1.f)); |
||
154 |
✓✗ | 2 |
material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 128.f); |
155 |
2 |
break; |
|
156 |
case 3: /// selection |
||
157 |
2 |
glModeValue = ::osg::StateAttribute::ON | |
|
158 |
::osg::StateAttribute::OVERRIDE | |
||
159 |
::osg::StateAttribute::PROTECTED; |
||
160 |
/// Red |
||
161 |
✓✗ | 2 |
material_switch_ptr->setAmbient(osg::Material::FRONT_AND_BACK, |
162 |
osgVector4(0.f, 0.f, 0.f, 1.f)); |
||
163 |
✓✗ | 2 |
material_switch_ptr->setDiffuse(osg::Material::FRONT_AND_BACK, |
164 |
osgVector4(1.0f, 0.f, 0.f, 1.f)); |
||
165 |
✓✗ | 2 |
material_switch_ptr->setSpecular(osg::Material::FRONT_AND_BACK, |
166 |
osgVector4(0.7f, 0.6f, 0.6f, 1.f)); |
||
167 |
✓✗ | 2 |
material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 96.f); |
168 |
2 |
break; |
|
169 |
case 4: /// selection |
||
170 |
2 |
glModeValue = ::osg::StateAttribute::ON | |
|
171 |
::osg::StateAttribute::OVERRIDE | |
||
172 |
::osg::StateAttribute::PROTECTED; |
||
173 |
/// Red plastic |
||
174 |
✓✗ | 2 |
material_switch_ptr->setAmbient(osg::Material::FRONT_AND_BACK, |
175 |
osgVector4(0.f, 0.f, 0.f, 1.f)); |
||
176 |
✓✗ | 2 |
material_switch_ptr->setDiffuse(osg::Material::FRONT_AND_BACK, |
177 |
osgVector4(0.5f, 0.f, 0.f, 1.f)); |
||
178 |
✓✗ | 2 |
material_switch_ptr->setSpecular(osg::Material::FRONT_AND_BACK, |
179 |
osgVector4(0.7f, 0.6f, 0.6f, 1.f)); |
||
180 |
✓✗ | 2 |
material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 32.f); |
181 |
2 |
break; |
|
182 |
case 5: /// selection |
||
183 |
2 |
glModeValue = ::osg::StateAttribute::ON | |
|
184 |
::osg::StateAttribute::OVERRIDE | |
||
185 |
::osg::StateAttribute::PROTECTED; |
||
186 |
/// Bronze |
||
187 |
✓✗ | 2 |
material_switch_ptr->setAmbient( |
188 |
osg::Material::FRONT_AND_BACK, |
||
189 |
osgVector4(0.2125f, 0.1275f, 0.054f, 1.f)); |
||
190 |
✓✗ | 2 |
material_switch_ptr->setDiffuse( |
191 |
osg::Material::FRONT_AND_BACK, |
||
192 |
osgVector4(0.714f, 0.4284f, 0.18144f, 1.f)); |
||
193 |
✓✗ | 2 |
material_switch_ptr->setSpecular( |
194 |
osg::Material::FRONT_AND_BACK, |
||
195 |
osgVector4(0.393548f, 0.271906f, 0.166721f, 1.f)); |
||
196 |
✓✗ | 2 |
material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 26.f); |
197 |
2 |
break; |
|
198 |
case 6: /// selection |
||
199 |
2 |
glModeValue = ::osg::StateAttribute::ON | |
|
200 |
::osg::StateAttribute::OVERRIDE | |
||
201 |
::osg::StateAttribute::PROTECTED; |
||
202 |
/// Red rubber |
||
203 |
✓✗ | 2 |
material_switch_ptr->setAmbient(osg::Material::FRONT_AND_BACK, |
204 |
osgVector4(0.05f, 0.f, 0.f, 1.f)); |
||
205 |
✓✗ | 2 |
material_switch_ptr->setDiffuse(osg::Material::FRONT_AND_BACK, |
206 |
osgVector4(0.5f, 0.5f, 0.4f, 1.f)); |
||
207 |
✓✗ | 2 |
material_switch_ptr->setSpecular(osg::Material::FRONT_AND_BACK, |
208 |
osgVector4(0.7f, 0.04f, 0.04f, 1.f)); |
||
209 |
✓✗ | 2 |
material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 10.f); |
210 |
2 |
break; |
|
211 |
default: |
||
212 |
ASSERT(false, "HighlightState is not well defined"); |
||
213 |
break; |
||
214 |
} |
||
215 |
12 |
material_switch_ptr->setDataVariance(osg::Object::STATIC); |
|
216 |
✓✗ | 12 |
ss->setAttributeAndModes(material_switch_ptr, glModeValue); |
217 |
} |
||
218 |
12 |
return ss; |
|
219 |
} |
||
220 |
|||
221 |
int getNodeVisibilityMode(Node* node) { return node->getVisibilityMode(); } |
||
222 |
void setNodeVisibilityMode(Node* node, const int& v) { |
||
223 |
node->setVisibilityMode((VisibilityMode)v); |
||
224 |
} |
||
225 |
|||
226 |
int getNodeWireFrameMode(Node* node) { return node->getWireFrameMode(); } |
||
227 |
void setNodeWireFrameMode(Node* node, const int& v) { |
||
228 |
node->setWireFrameMode((WireFrameMode)v); |
||
229 |
} |
||
230 |
|||
231 |
int getNodeLightingMode(Node* node) { return node->getLightingMode(); } |
||
232 |
void setNodeLightingMode(Node* node, const int& v) { |
||
233 |
node->setLightingMode((LightingMode)v); |
||
234 |
} |
||
235 |
|||
236 |
void setNodeLandmark(Node* node, bool enable) { |
||
237 |
if (enable) |
||
238 |
node->addLandmark(0.05f); |
||
239 |
else |
||
240 |
node->deleteLandmark(); |
||
241 |
} |
||
242 |
|||
243 |
int getNodeHighlightState(Node* node) { return (int)node->getHighlightState(); } |
||
244 |
void setNodeHighlightState(Node* node, const int& v) { |
||
245 |
node->setHighlightState(v); |
||
246 |
} |
||
247 |
|||
248 |
void setFlag(::osg::Node* node, osg::Node::NodeMask bit, bool on) { |
||
249 |
if (on) |
||
250 |
node->setNodeMask(node->getNodeMask() | bit); |
||
251 |
else |
||
252 |
node->setNodeMask(node->getNodeMask() & ~bit); |
||
253 |
} |
||
254 |
|||
255 |
1 |
MetaEnum* highlightStateEnum() { |
|
256 |
✓✗✓✗ |
1 |
static MetaEnum hs; |
257 |
✓✗ | 1 |
if (hs.type.size() == 0) { |
258 |
1 |
hs.type = "HighlightState"; |
|
259 |
✓✗✓✗ |
1 |
hs.names.push_back("None"); |
260 |
✓✗ | 1 |
hs.values.push_back(0); |
261 |
✓✗✓✗ |
1 |
hs.names.push_back("1"); |
262 |
✓✗ | 1 |
hs.values.push_back(1); |
263 |
✓✗✓✗ |
1 |
hs.names.push_back("2"); |
264 |
✓✗ | 1 |
hs.values.push_back(2); |
265 |
✓✗✓✗ |
1 |
hs.names.push_back("3"); |
266 |
✓✗ | 1 |
hs.values.push_back(3); |
267 |
✓✗✓✗ |
1 |
hs.names.push_back("4"); |
268 |
✓✗ | 1 |
hs.values.push_back(4); |
269 |
✓✗✓✗ |
1 |
hs.names.push_back("5"); |
270 |
✓✗ | 1 |
hs.values.push_back(5); |
271 |
✓✗✓✗ |
1 |
hs.names.push_back("6"); |
272 |
✓✗ | 1 |
hs.values.push_back(6); |
273 |
✓✗✓✗ |
1 |
hs.names.push_back("7"); |
274 |
✓✗ | 1 |
hs.values.push_back(7); |
275 |
✓✗✓✗ |
1 |
hs.names.push_back("8"); |
276 |
✓✗ | 1 |
hs.values.push_back(8); |
277 |
} |
||
278 |
1 |
return &hs; |
|
279 |
} |
||
280 |
} // namespace |
||
281 |
using ::osg::Matrix; |
||
282 |
|||
283 |
const float Node::TransparencyRenderingBinThreshold = 0.99f; |
||
284 |
|||
285 |
/* Declaration of private function members */ |
||
286 |
1 |
void Node::init() { |
|
287 |
/* Build local conformation |
||
288 |
<- wireframe_node_ptr_ |
||
289 |
connected to the parent <- switch_node_ptr_ <- |
||
290 |
auto_transform_ptr_ <- connection of children here |
||
291 |
<- normal_node_ptr_ |
||
292 |
*/ |
||
293 |
1 |
scale_.value = osgVector3(1, 1, 1); |
|
294 |
1 |
scale_.min = 0.f; |
|
295 |
1 |
scale_.step = 0.1f; |
|
296 |
1 |
scale_.adaptiveDecimal = true; |
|
297 |
✓✗✓✗ ✓✗ |
1 |
scale_.callback(boost::bind(&Node::updateTransform, this)); |
298 |
|||
299 |
✓✗ | 1 |
M_.callback(scale_.callback()); |
300 |
|||
301 |
✓✗✓✗ ✓✗ |
1 |
switch_node_ptr_ = new ::osg::Group; |
302 |
✓✗✓✗ ✓✗ |
1 |
hl_switch_node_ptr_ = new ::osg::Group; |
303 |
✓✗✓✗ ✓✗ |
1 |
transform_ptr_ = new ::osg::MatrixTransform; |
304 |
✓✗ | 1 |
transform_ptr_->setName("positionInParentNode"); |
305 |
|||
306 |
1 |
switch_node_ptr_->setNodeMask(VisibilityBit | NodeBit | IntersectionBit); |
|
307 |
✓✗ | 1 |
switch_node_ptr_->setName(id_name_); |
308 |
✓✗ | 1 |
wireframe_modes_.resize(2); |
309 |
✓✗✓✗ ✓✗ |
1 |
wireframe_modes_[FILL] = new ::osg::Group; |
310 |
✓✗ | 1 |
wireframe_modes_[FILL]->setName("wireframe: FILL"); |
311 |
✓✗✓✗ ✓✗ |
1 |
wireframe_modes_[WIREFRAME] = new ::osg::Group; |
312 |
✓✗ | 1 |
wireframe_modes_[WIREFRAME]->setName("wireframe: WIREFRAME"); |
313 |
|||
314 |
/* Building hierarchie */ |
||
315 |
1 |
selected_wireframe_ = FILL; |
|
316 |
✓✗ | 1 |
switch_node_ptr_->addChild(wireframe_modes_[FILL]); |
317 |
✓✗ | 1 |
wireframe_modes_[FILL]->addChild(hl_switch_node_ptr_); |
318 |
1 |
wireframe_modes_[FILL]->setDataVariance(osg::Object::STATIC); |
|
319 |
|||
320 |
// Setup highlight states |
||
321 |
✓✗ | 1 |
highlight_nodes_.resize(9); |
322 |
1 |
selected_highlight_ = 0; |
|
323 |
1 |
highlight_enabled_ = true; |
|
324 |
✓✗ | 1 |
highlight_nodes_[0] = transform_ptr_; |
325 |
✓✓ | 9 |
for (unsigned int i = 1; i < 9; ++i) { |
326 |
✓✗✓✗ |
8 |
highlight_nodes_[i] = setupHighlightState(i); |
327 |
✓✗ | 8 |
highlight_nodes_[i]->addChild(transform_ptr_); |
328 |
} |
||
329 |
// setHighlightState(0); |
||
330 |
✓✗ | 1 |
hl_switch_node_ptr_->addChild(highlight_nodes_[selected_highlight_]); |
331 |
✓✗ | 1 |
hl_switch_node_ptr_->setName("highlight switch"); |
332 |
|||
333 |
✓✗✓✗ |
1 |
wireframe_modes_[WIREFRAME]->setStateSet(getWireframeStateSet()); |
334 |
1 |
wireframe_modes_[WIREFRAME]->setDataVariance(osg::Object::STATIC); |
|
335 |
✓✗ | 1 |
geode_ptr_ = NULL; |
336 |
1 |
alpha_ = 1.; |
|
337 |
|||
338 |
1 |
visibilityMode_ = VISIBILITY_ON; |
|
339 |
1 |
lightingMode_ = LIGHT_INFLUENCE_ON; |
|
340 |
|||
341 |
✓✗✓✗ ✓✗ |
1 |
addProperty(EnumProperty::create( |
342 |
✓✗ | 1 |
"Highlight/State", highlightStateEnum(), |
343 |
✓✗✓✗ |
2 |
EnumProperty::Getter_t(boost::bind(getNodeHighlightState, this)), |
344 |
✓✗✓✗ |
2 |
EnumProperty::Setter_t(boost::bind(setNodeHighlightState, this, _1)))); |
345 |
✓✗✓✗ ✓✗ |
1 |
addProperty(BoolProperty::create("Highlight/Enable", this, |
346 |
&Node::getHighlightEnabled, |
||
347 |
&Node::setHighlightEnabled)); |
||
348 |
✓✗✓✗ ✓✗ |
1 |
addProperty(EnumProperty::create( |
349 |
✓✗ | 1 |
"Visibility", visibilityModeEnum(), |
350 |
✓✗✓✗ |
2 |
EnumProperty::Getter_t(boost::bind(getNodeVisibilityMode, this)), |
351 |
✓✗✓✗ |
2 |
EnumProperty::Setter_t(boost::bind(setNodeVisibilityMode, this, _1)))); |
352 |
✓✗✓✗ ✓✗ |
1 |
addProperty(EnumProperty::create( |
353 |
✓✗ | 1 |
"WireframeMode", wireFrameModeEnum(), |
354 |
✓✗✓✗ |
2 |
EnumProperty::Getter_t(boost::bind(getNodeWireFrameMode, this)), |
355 |
✓✗✓✗ |
2 |
EnumProperty::Setter_t(boost::bind(setNodeWireFrameMode, this, _1)))); |
356 |
✓✗✓✗ ✓✗ |
1 |
addProperty(EnumProperty::create( |
357 |
✓✗ | 1 |
"LightingMode", lightingModeEnum(), |
358 |
✓✗✓✗ |
2 |
EnumProperty::Getter_t(boost::bind(getNodeLightingMode, this)), |
359 |
✓✗✓✗ |
2 |
EnumProperty::Setter_t(boost::bind(setNodeLightingMode, this, _1)))); |
360 |
✓✗✓✗ ✓✗ |
1 |
addProperty(BoolProperty::create( |
361 |
"Landmark", |
||
362 |
✓✗ | 2 |
BoolProperty::getterFromMemberFunction(this, &Node::hasLandmark), |
363 |
✓✗✓✗ |
2 |
BoolProperty::Setter_t(boost::bind(setNodeLandmark, this, _1)))); |
364 |
✓✗✓✗ ✓✗ |
1 |
addProperty(BoolProperty::create("Selectable", this, &Node::isSelectable, |
365 |
&Node::setSelectable)); |
||
366 |
✓✗✓✗ ✓✗ |
1 |
addProperty(StringProperty::createRO("Name", this, &Node::getID)); |
367 |
✓✗✓✗ ✓✗ |
1 |
addProperty(Vector4Property::createWO("Color", this, &Node::setColor)); |
368 |
|||
369 |
RangedFloatProperty::Ptr_t alphaProp = RangedFloatProperty::create( |
||
370 |
✓✗✓✗ |
3 |
"Alpha", this, &Node::getAlpha, &Node::setAlpha); |
371 |
1 |
alphaProp->setRange(0.f, 1.f, 0.1f); |
|
372 |
✓✗ | 1 |
addProperty(alphaProp); |
373 |
|||
374 |
✓✗ | 1 |
addProperty(&scale_); |
375 |
✓✗ | 1 |
addProperty(&M_); |
376 |
1 |
} |
|
377 |
|||
378 |
1 |
Node::Node(const std::string& name) |
|
379 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
1 |
: id_name_(name), dirty_(true), scale_("Scale"), M_("Transform") { |
380 |
✓✗ | 1 |
init(); |
381 |
1 |
} |
|
382 |
|||
383 |
Node::Node(const Node& other) |
||
384 |
: id_name_(other.getID()), dirty_(true), scale_("Scale"), M_("Transform") { |
||
385 |
init(); |
||
386 |
} |
||
387 |
|||
388 |
void Node::setSelectable(bool selectable) { |
||
389 |
setFlag(transform_ptr_.get(), IntersectionBit, selectable); |
||
390 |
} |
||
391 |
|||
392 |
5 |
void Node::updateTransform() { |
|
393 |
✓✗ | 5 |
osg::Matrixf M; |
394 |
✓✗ | 5 |
M.setRotate(M_.value.quat); |
395 |
✓✗ | 5 |
M.setTrans(M_.value.position); |
396 |
|||
397 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
5 |
transform_ptr_->setMatrix(::osg::Matrix::scale(scale_.value) * Ms_ * M); |
398 |
5 |
dirty_ = true; |
|
399 |
5 |
} |
|
400 |
|||
401 |
2 |
void Node::setStaticTransform(const osgVector3& position, const osgQuat& quat) { |
|
402 |
2 |
Ms_.setRotate(quat); |
|
403 |
2 |
Ms_.setTrans(position); |
|
404 |
|||
405 |
2 |
updateTransform(); |
|
406 |
2 |
} |
|
407 |
|||
408 |
2 |
osgQuat Node::getStaticRotation() const { |
|
409 |
2 |
osgQuat q, so; |
|
410 |
2 |
osgVector3 t, s; |
|
411 |
✓✗ | 2 |
Ms_.decompose(t, q, s, so); |
412 |
4 |
return q; |
|
413 |
} |
||
414 |
|||
415 |
2 |
osgVector3 Node::getStaticPosition() const { |
|
416 |
2 |
osgQuat q, so; |
|
417 |
2 |
osgVector3 t, s; |
|
418 |
✓✗ | 2 |
Ms_.decompose(t, q, s, so); |
419 |
2 |
return t; |
|
420 |
} |
||
421 |
|||
422 |
void Node::setVisibilityMode(const VisibilityMode& mode) { |
||
423 |
if (visibilityMode_ == mode) return; |
||
424 |
visibilityMode_ = mode; |
||
425 |
switch (mode) { |
||
426 |
case VISIBILITY_ON: |
||
427 |
setFlag(transform_ptr_.get(), VisibilityBit, true); |
||
428 |
transform_ptr_->setStateSet(getVisibleStateSet(lightingMode_)); |
||
429 |
break; |
||
430 |
case VISIBILITY_OFF: |
||
431 |
setFlag(transform_ptr_.get(), VisibilityBit, false); |
||
432 |
transform_ptr_->setStateSet(getVisibleStateSet(lightingMode_)); |
||
433 |
break; |
||
434 |
case ALWAYS_ON_TOP: |
||
435 |
setFlag(transform_ptr_.get(), VisibilityBit, true); |
||
436 |
transform_ptr_->setStateSet(getAlwaysOnTopStateSet(lightingMode_)); |
||
437 |
break; |
||
438 |
|||
439 |
default: |
||
440 |
ASSERT(false, "mode is not well defined"); |
||
441 |
break; |
||
442 |
} |
||
443 |
dirty_ = true; |
||
444 |
} |
||
445 |
|||
446 |
void Node::setLightingMode(const LightingMode& mode) { |
||
447 |
if (mode == lightingMode_) return; |
||
448 |
lightingMode_ = mode; |
||
449 |
switch (visibilityMode_) { |
||
450 |
case VISIBILITY_ON: |
||
451 |
case VISIBILITY_OFF: |
||
452 |
transform_ptr_->setStateSet(getVisibleStateSet(lightingMode_)); |
||
453 |
break; |
||
454 |
case ALWAYS_ON_TOP: |
||
455 |
transform_ptr_->setStateSet(getAlwaysOnTopStateSet(lightingMode_)); |
||
456 |
break; |
||
457 |
default: |
||
458 |
ASSERT(false, "mode is not well defined"); |
||
459 |
break; |
||
460 |
} |
||
461 |
dirty_ = true; |
||
462 |
} |
||
463 |
|||
464 |
LightingMode Node::getLightingMode() const { return lightingMode_; } |
||
465 |
|||
466 |
void Node::setWireFrameMode(const WireFrameMode& mode) { |
||
467 |
if (mode == selected_wireframe_) return; |
||
468 |
bool fillSelected = (selected_wireframe_ == FILL) || |
||
469 |
(selected_wireframe_ == FILL_AND_WIREFRAME); |
||
470 |
bool wireSelected = (selected_wireframe_ == WIREFRAME) || |
||
471 |
(selected_wireframe_ == FILL_AND_WIREFRAME); |
||
472 |
// 0: keep as it is |
||
473 |
// 1: select |
||
474 |
// 2: deselect |
||
475 |
int selectFill = 0, selectWire = 0; |
||
476 |
switch (mode) { |
||
477 |
case FILL: |
||
478 |
if (wireSelected) selectWire = 2; |
||
479 |
if (!fillSelected) selectFill = 1; |
||
480 |
break; |
||
481 |
case WIREFRAME: |
||
482 |
if (!wireSelected) selectWire = 1; |
||
483 |
if (fillSelected) selectFill = 2; |
||
484 |
break; |
||
485 |
case FILL_AND_WIREFRAME: |
||
486 |
if (!wireSelected) selectWire = 1; |
||
487 |
if (!fillSelected) selectFill = 1; |
||
488 |
break; |
||
489 |
default: |
||
490 |
ASSERT(false, "WireFrameMode set with bad option"); |
||
491 |
break; |
||
492 |
} |
||
493 |
switch (selectFill) { |
||
494 |
case 0: |
||
495 |
break; |
||
496 |
case 1: |
||
497 |
wireframe_modes_[FILL]->addChild(hl_switch_node_ptr_); |
||
498 |
switch_node_ptr_->addChild(wireframe_modes_[FILL]); |
||
499 |
break; |
||
500 |
case 2: |
||
501 |
wireframe_modes_[FILL]->removeChild(hl_switch_node_ptr_); |
||
502 |
switch_node_ptr_->removeChild(wireframe_modes_[FILL]); |
||
503 |
break; |
||
504 |
default: |
||
505 |
assert(false && "Wrong action"); |
||
506 |
}; |
||
507 |
switch (selectWire) { |
||
508 |
case 0: |
||
509 |
break; |
||
510 |
case 1: |
||
511 |
wireframe_modes_[WIREFRAME]->addChild(hl_switch_node_ptr_); |
||
512 |
switch_node_ptr_->addChild(wireframe_modes_[WIREFRAME]); |
||
513 |
break; |
||
514 |
case 2: |
||
515 |
wireframe_modes_[WIREFRAME]->removeChild(hl_switch_node_ptr_); |
||
516 |
switch_node_ptr_->removeChild(wireframe_modes_[WIREFRAME]); |
||
517 |
break; |
||
518 |
default: |
||
519 |
assert(false && "Wrong action"); |
||
520 |
}; |
||
521 |
selected_wireframe_ = mode; |
||
522 |
dirty_ = true; |
||
523 |
} |
||
524 |
|||
525 |
void Node::addLandmark(const float& size) { |
||
526 |
::osg::GeometryRefPtr geom_ptr = new ::osg::Geometry(); |
||
527 |
|||
528 |
/* Define points of the beam */ |
||
529 |
::osg::Vec3ArrayRefPtr points_ptr = new ::osg::Vec3Array(6); |
||
530 |
points_ptr->at(0) = osgVector3(0., 0., 0.); |
||
531 |
points_ptr->at(1) = osgVector3(size, 0., 0.); |
||
532 |
points_ptr->at(2) = osgVector3(0., 0., 0.); |
||
533 |
points_ptr->at(3) = osgVector3(0., size, 0.); |
||
534 |
points_ptr->at(4) = osgVector3(0., 0., 0.); |
||
535 |
points_ptr->at(5) = osgVector3(0., 0., size); |
||
536 |
|||
537 |
/* Define the color */ |
||
538 |
::osg::Vec4ArrayRefPtr color_ptr = new ::osg::Vec4Array(3); |
||
539 |
color_ptr->at(0) = osgVector4(1., 0., 0., 1.); |
||
540 |
color_ptr->at(1) = osgVector4(0., 1., 0., 1.); |
||
541 |
color_ptr->at(2) = osgVector4(0., 0., 1., 1.); |
||
542 |
|||
543 |
geom_ptr->setVertexArray(points_ptr.get()); |
||
544 |
geom_ptr->setColorArray(color_ptr.get()); |
||
545 |
geom_ptr->setColorBinding(::osg::Geometry::BIND_PER_PRIMITIVE_SET); |
||
546 |
geom_ptr->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, 2)); |
||
547 |
geom_ptr->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 2, 2)); |
||
548 |
geom_ptr->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 4, 2)); |
||
549 |
|||
550 |
transform_ptr_->removeChild(landmark_geode_ptr_); |
||
551 |
landmark_geode_ptr_ = new osg::Geode(); |
||
552 |
landmark_geode_ptr_->addDrawable(geom_ptr); |
||
553 |
|||
554 |
// set Landmark as ALWAYS ON TOP |
||
555 |
setFlag(landmark_geode_ptr_.get(), VisibilityBit, true); |
||
556 |
landmark_geode_ptr_->setStateSet(getAlwaysOnTopStateSet(LIGHT_INFLUENCE_OFF)); |
||
557 |
|||
558 |
transform_ptr_->addChild(landmark_geode_ptr_); |
||
559 |
dirty_ = true; |
||
560 |
} |
||
561 |
|||
562 |
bool Node::hasLandmark() const { return landmark_geode_ptr_; } |
||
563 |
|||
564 |
void Node::deleteLandmark() { |
||
565 |
if (landmark_geode_ptr_) { |
||
566 |
transform_ptr_->removeChild(landmark_geode_ptr_); |
||
567 |
landmark_geode_ptr_.release(); |
||
568 |
dirty_ = true; |
||
569 |
} |
||
570 |
} |
||
571 |
|||
572 |
8 |
::osg::Group* Node::setupHighlightState(unsigned int state) { |
|
573 |
16 |
osg::StateSetRefPtr ss; |
|
574 |
✓✓✓✓ ✓✓✓✓ ✗ |
8 |
switch (state) { |
575 |
1 |
case 1: /// collision |
|
576 |
✓✗✓✗ |
1 |
ss = getHighlightStateSet<1>(); |
577 |
1 |
break; |
|
578 |
1 |
case 2: /// selection |
|
579 |
✓✗✓✗ |
1 |
ss = getHighlightStateSet<2>(); |
580 |
1 |
break; |
|
581 |
1 |
case 3: /// selection |
|
582 |
✓✗✓✗ |
1 |
ss = getHighlightStateSet<3>(); |
583 |
1 |
break; |
|
584 |
1 |
case 4: /// selection |
|
585 |
✓✗✓✗ |
1 |
ss = getHighlightStateSet<4>(); |
586 |
1 |
break; |
|
587 |
1 |
case 5: /// selection |
|
588 |
✓✗✓✗ |
1 |
ss = getHighlightStateSet<5>(); |
589 |
1 |
break; |
|
590 |
1 |
case 6: /// selection |
|
591 |
✓✗✓✗ |
1 |
ss = getHighlightStateSet<6>(); |
592 |
1 |
break; |
|
593 |
1 |
case 7: /// Selection through osgFX::Outline |
|
594 |
{ |
||
595 |
✓✗✓✗ |
1 |
osgFX::Outline* outline = new osgFX::Outline; |
596 |
|||
597 |
✓✗ | 1 |
outline->setWidth(8); |
598 |
✓✗ | 1 |
outline->setColor(osg::Vec4(1, 1, 0, 1)); |
599 |
1 |
outline->setDataVariance(osg::Object::STATIC); |
|
600 |
1 |
return outline; |
|
601 |
} break; |
||
602 |
1 |
case 8: /// Selection through osgFX::Outline |
|
603 |
{ |
||
604 |
✓✗✓✗ |
1 |
osgFX::Scribe* scribe = new osgFX::Scribe; |
605 |
|||
606 |
✓✗ | 1 |
scribe->setWireframeLineWidth(1); |
607 |
✓✗ | 1 |
scribe->setWireframeColor(osg::Vec4(1, 1, 0, 1)); |
608 |
1 |
scribe->setDataVariance(osg::Object::STATIC); |
|
609 |
1 |
return scribe; |
|
610 |
} break; |
||
611 |
case 0: |
||
612 |
default: |
||
613 |
break; |
||
614 |
} |
||
615 |
✓✗✓✗ |
6 |
osg::Group* node = new ::osg::Group; |
616 |
✓✗ | 6 |
node->setStateSet(ss); |
617 |
6 |
node->setDataVariance(osg::Object::STATIC); |
|
618 |
6 |
return node; |
|
619 |
} |
||
620 |
|||
621 |
void Node::setHighlightState(unsigned int state) { |
||
622 |
if (!highlight_enabled_) return; |
||
623 |
if (state != selected_highlight_ && state < highlight_nodes_.size()) { |
||
624 |
hl_switch_node_ptr_->replaceChild(highlight_nodes_[selected_highlight_], |
||
625 |
highlight_nodes_[state]); |
||
626 |
// Update the child |
||
627 |
selected_highlight_ = state; |
||
628 |
dirty_ = true; |
||
629 |
} |
||
630 |
} |
||
631 |
|||
632 |
void Node::setAlpha(const float& alpha) { |
||
633 |
if (geode_ptr_.get() == NULL) { |
||
634 |
log() << "You must initialize a Geode on " << id_name_ << " to use Alpha" |
||
635 |
<< std::endl; |
||
636 |
return; |
||
637 |
} |
||
638 |
osg::StateSet* ss = geode_ptr_.get()->getStateSet(); |
||
639 |
if (ss) { |
||
640 |
alpha_ = alpha; |
||
641 |
osg::Material* mat; |
||
642 |
if (ss->getAttribute(osg::StateAttribute::MATERIAL)) |
||
643 |
mat = dynamic_cast<osg::Material*>( |
||
644 |
ss->getAttribute(osg::StateAttribute::MATERIAL)); |
||
645 |
else { |
||
646 |
mat = new osg::Material; |
||
647 |
ss->setAttribute(mat, osg::StateAttribute::OFF); |
||
648 |
} |
||
649 |
mat->setAlpha(osg::Material::FRONT_AND_BACK, alpha); |
||
650 |
setTransparentRenderingBin(alpha_ < TransparencyRenderingBinThreshold); |
||
651 |
dirty_ = true; |
||
652 |
} |
||
653 |
} |
||
654 |
|||
655 |
float Node::getAlpha() const { return alpha_; } |
||
656 |
|||
657 |
void Node::setTransparency(const float& transparency) { |
||
658 |
setAlpha(1.f - transparency); |
||
659 |
} |
||
660 |
|||
661 |
float Node::getTransparency() const { return 1.f - getAlpha(); } |
||
662 |
|||
663 |
1 |
void Node::setTransparentRenderingBin(bool transparent, osg::StateSet* ss) { |
|
664 |
✓✗ | 1 |
if (ss == NULL) { |
665 |
✗✓ | 1 |
if (geode_ptr_.get() == NULL) { |
666 |
log() << "You must initialize a Geode on " << id_name_ << " to use Alpha" |
||
667 |
<< std::endl; |
||
668 |
return; |
||
669 |
} |
||
670 |
1 |
ss = geode_ptr_.get()->getStateSet(); |
|
671 |
✗✓ | 1 |
if (ss == NULL) return; |
672 |
} |
||
673 |
bool isTransparent = |
||
674 |
1 |
(ss->getRenderingHint() == osg::StateSet::TRANSPARENT_BIN); |
|
675 |
✓✗ | 1 |
if (transparent == isTransparent) return; |
676 |
if (transparent) |
||
677 |
ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); |
||
678 |
else |
||
679 |
ss->setRenderingHint(osg::StateSet::DEFAULT_BIN); |
||
680 |
dirty_ = true; |
||
681 |
} |
||
682 |
|||
683 |
2 |
Node::~Node() { |
|
684 |
/* Proper deletion */ |
||
685 |
/* deleting the top most node (switch_node_ptr_) will delete everything else. |
||
686 |
* Loop over the parents of switch_node_ptr_ and remove references to it. |
||
687 |
*/ |
||
688 |
typedef ::osg::Node::ParentList PL_t; |
||
689 |
4 |
PL_t parents = switch_node_ptr_->getParents(); |
|
690 |
✗✓ | 2 |
for (PL_t::const_iterator _p = parents.begin(); _p != parents.end(); ++_p) |
691 |
(*_p)->removeChild(switch_node_ptr_); |
||
692 |
} |
||
693 |
|||
694 |
2 |
const Configuration& Node::getGlobalTransform() const { return M_.value; } |
|
695 |
|||
696 |
void Node::traverse(NodeVisitor& /*visitor*/) {} |
||
697 |
|||
698 |
osg::ref_ptr<osg::Node> Node::getOsgNode() const { return geode_ptr_.get(); } |
||
699 |
|||
700 |
/* End of declaration of public function members */ |
||
701 |
|||
702 |
} /* namespace viewer */ |
||
703 |
|||
704 |
} /* namespace gepetto */ |
Generated by: GCOVR (Version 4.2) |