GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/node.cpp Lines: 215 418 51.4 %
Date: 2020-05-14 11:23:33 Branches: 267 736 36.3 %

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.h>
10
11
#include <climits>
12
13
#include <osg/Material>
14
#include <osg/LineWidth>
15
#include <osgFX/Outline>
16
#include <osgFX/Scribe>
17
18
#include <gepetto/viewer/window-manager.h>
19
#include <gepetto/viewer/node-visitor.h>
20
21
namespace gepetto {
22
namespace viewer {
23
  namespace {
24
    const osg::StateSetRefPtr& getVisibleStateSet (const LightingMode& mode)
25
    {
26
      static osg::StateSetRefPtr ssOn, ssOff;
27
      switch (mode) {
28
        case LIGHT_INFLUENCE_ON:
29
          if (false && !ssOn) { // Disable because this is the default.
30
            ssOn = osg::StateSetRefPtr(new osg::StateSet());
31
            ssOn->setRenderBinToInherit();
32
            ssOn->setMode(GL_DEPTH_TEST, ::osg::StateAttribute::ON  | ::osg::StateAttribute::PROTECTED);
33
            ssOn->setMode(GL_CULL_FACE , ::osg::StateAttribute::OFF | ::osg::StateAttribute::PROTECTED);
34
            ssOn->setMode(GL_LIGHTING  , ::osg::StateAttribute::ON  | ::osg::StateAttribute::PROTECTED);
35
          }
36
          return ssOn;
37
        case LIGHT_INFLUENCE_OFF:
38
          if (!ssOff) {
39
            ssOff = osg::StateSetRefPtr(new osg::StateSet());
40
            ssOff->setRenderBinToInherit();
41
            ssOff->setMode(GL_DEPTH_TEST, ::osg::StateAttribute::ON  | ::osg::StateAttribute::PROTECTED);
42
            ssOff->setMode(GL_CULL_FACE , ::osg::StateAttribute::OFF | ::osg::StateAttribute::PROTECTED);
43
            ssOff->setMode(GL_LIGHTING  , ::osg::StateAttribute::OFF | ::osg::StateAttribute::PROTECTED);
44
          }
45
          return ssOff;
46
        default:
47
          ASSERT(false, "LightingMode is not well defined");
48
          break;
49
      };
50
    }
51
52
    const osg::StateSetRefPtr& getAlwaysOnTopStateSet (const LightingMode& mode)
53
    {
54
      static osg::StateSetRefPtr ssOn, ssOff;
55
      switch (mode) {
56
        case LIGHT_INFLUENCE_ON:
57
          if (!ssOn) { // Disable because this is the default.
58
            ssOn = osg::StateSetRefPtr(new osg::StateSet());
59
            ssOn->setRenderBinDetails(INT_MAX, "DepthSortedBin");
60
            ssOn->setMode(GL_DEPTH_TEST, ::osg::StateAttribute::OFF | ::osg::StateAttribute::PROTECTED);
61
            ssOn->setMode(GL_CULL_FACE , ::osg::StateAttribute::ON  | ::osg::StateAttribute::PROTECTED);
62
            ssOn->setMode(GL_LIGHTING  , ::osg::StateAttribute::ON  | ::osg::StateAttribute::PROTECTED);
63
          }
64
          return ssOn;
65
        case LIGHT_INFLUENCE_OFF:
66
          if (!ssOff) {
67
            ssOff = osg::StateSetRefPtr(new osg::StateSet());
68
            ssOff->setRenderBinDetails(INT_MAX, "DepthSortedBin");
69
            ssOff->setMode(GL_DEPTH_TEST, ::osg::StateAttribute::OFF | ::osg::StateAttribute::PROTECTED);
70
            ssOff->setMode(GL_CULL_FACE , ::osg::StateAttribute::ON  | ::osg::StateAttribute::PROTECTED);
71
            ssOff->setMode(GL_LIGHTING  , ::osg::StateAttribute::OFF | ::osg::StateAttribute::PROTECTED);
72
          }
73
          return ssOff;
74
        default:
75
          ASSERT(false, "LightingMode is not well defined");
76
          break;
77
      };
78
    }
79
80
1
    const osg::StateSetRefPtr& getWireframeStateSet ()
81
    {
82

1
      static osg::StateSetRefPtr ss;
83
1
      if (!ss) {
84

1
        ss = osg::StateSetRefPtr(new osg::StateSet());
85
86
        /* Allowing wireframe mode */
87

2
        osg::PolygonModeRefPtr polygon_mode_ptr = new ::osg::PolygonMode;
88
1
        polygon_mode_ptr->setMode( ::osg::PolygonMode::FRONT_AND_BACK, ::osg::PolygonMode::LINE );
89
1
        polygon_mode_ptr->setDataVariance (osg::Object::STATIC);
90
91

2
        ::osg::MaterialRefPtr material_wireframe_ptr = new osg::Material;
92
1
        material_wireframe_ptr->setColorMode(osg::Material::DIFFUSE);
93
1
        material_wireframe_ptr->setDiffuse(osg::Material::FRONT_AND_BACK, osgVector4(1.,1.,1.,1.));
94
1
        material_wireframe_ptr->setDataVariance (osg::Object::STATIC);
95
96
1
        ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF | ::osg::StateAttribute::PROTECTED ); // PROTECTED attribut allows wireframe node to not be influenced by alpha
97
1
        ss->setAttributeAndModes(polygon_mode_ptr, ::osg::StateAttribute::PROTECTED | ::osg::StateAttribute::ON );
98
1
        ss->setAttributeAndModes(material_wireframe_ptr, ::osg::StateAttribute::ON | ::osg::StateAttribute::PROTECTED );
99
      }
100
1
      return ss;
101
    }
102
103
    template <unsigned int state>
104
6
    const osg::StateSetRefPtr& getHighlightStateSet ()
105
    {
106






6
      static osg::StateSetRefPtr ss;
107
      if (state == 0) return ss;
108



6
      if (!ss) {
109









6
        ss = osg::StateSetRefPtr(new osg::StateSet());
110






12
        ::osg::MaterialRefPtr material_switch_ptr = new osg::Material;
111
6
        int glModeValue = ::osg::StateAttribute::INHERIT;
112
        /// Some color codes are taken from
113
        /// http://devernay.free.fr/cours/opengl/materials.html
114
        switch (state) {
115
          case 1: /// collision
116
1
            glModeValue = ::osg::StateAttribute::ON | ::osg::StateAttribute::OVERRIDE;
117
1
            material_switch_ptr->setColorMode (osg::Material::AMBIENT);
118
1
            material_switch_ptr->setDiffuse  (osg::Material::FRONT_AND_BACK, osgVector4(1.0f,0.f,0.f,1.f));
119
1
            material_switch_ptr->setTransparency(osg::Material::FRONT_AND_BACK, 0.5f);
120
1
            break;
121
          case 2: /// selection
122
1
            glModeValue = ::osg::StateAttribute::ON | ::osg::StateAttribute::OVERRIDE | ::osg::StateAttribute::PROTECTED;
123
            /// Blue
124
1
            material_switch_ptr->setAmbient  (osg::Material::FRONT_AND_BACK, osgVector4(0.f,0.f,0.f,1.f));
125
1
            material_switch_ptr->setDiffuse  (osg::Material::FRONT_AND_BACK, osgVector4(0.f,0.f,1.f,1.f));
126
1
            material_switch_ptr->setSpecular (osg::Material::FRONT_AND_BACK, osgVector4(0.6f,0.6f,0.7f,1.f));
127
1
            material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 128.f);
128
1
            break;
129
          case 3: /// selection
130
1
            glModeValue = ::osg::StateAttribute::ON | ::osg::StateAttribute::OVERRIDE | ::osg::StateAttribute::PROTECTED;
131
            /// Red
132
1
            material_switch_ptr->setAmbient  (osg::Material::FRONT_AND_BACK, osgVector4(0.f,0.f,0.f,1.f));
133
1
            material_switch_ptr->setDiffuse  (osg::Material::FRONT_AND_BACK, osgVector4(1.0f,0.f,0.f,1.f));
134
1
            material_switch_ptr->setSpecular (osg::Material::FRONT_AND_BACK, osgVector4(0.7f,0.6f,0.6f,1.f));
135
1
            material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 96.f);
136
1
            break;
137
          case 4: /// selection
138
1
            glModeValue = ::osg::StateAttribute::ON | ::osg::StateAttribute::OVERRIDE | ::osg::StateAttribute::PROTECTED;
139
            /// Red plastic
140
1
            material_switch_ptr->setAmbient  (osg::Material::FRONT_AND_BACK, osgVector4(0.f,0.f,0.f,1.f));
141
1
            material_switch_ptr->setDiffuse  (osg::Material::FRONT_AND_BACK, osgVector4(0.5f,0.f,0.f,1.f));
142
1
            material_switch_ptr->setSpecular (osg::Material::FRONT_AND_BACK, osgVector4(0.7f,0.6f,0.6f,1.f));
143
1
            material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 32.f);
144
1
            break;
145
          case 5: /// selection
146
1
            glModeValue = ::osg::StateAttribute::ON | ::osg::StateAttribute::OVERRIDE | ::osg::StateAttribute::PROTECTED;
147
            /// Bronze
148
1
            material_switch_ptr->setAmbient  (osg::Material::FRONT_AND_BACK, osgVector4(0.2125f,0.1275f,0.054f,1.f));
149
1
            material_switch_ptr->setDiffuse  (osg::Material::FRONT_AND_BACK, osgVector4(0.714f,0.4284f,0.18144f,1.f));
150
1
            material_switch_ptr->setSpecular (osg::Material::FRONT_AND_BACK, osgVector4(0.393548f,0.271906f,0.166721f,1.f));
151
1
            material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 26.f);
152
1
            break;
153
          case 6: /// selection
154
1
            glModeValue = ::osg::StateAttribute::ON | ::osg::StateAttribute::OVERRIDE | ::osg::StateAttribute::PROTECTED;
155
            /// Red rubber
156
1
            material_switch_ptr->setAmbient  (osg::Material::FRONT_AND_BACK, osgVector4(0.05f,0.f,0.f,1.f));
157
1
            material_switch_ptr->setDiffuse  (osg::Material::FRONT_AND_BACK, osgVector4(0.5f,0.5f,0.4f,1.f));
158
1
            material_switch_ptr->setSpecular (osg::Material::FRONT_AND_BACK, osgVector4(0.7f,0.04f,0.04f,1.f));
159
1
            material_switch_ptr->setShininess(osg::Material::FRONT_AND_BACK, 10.f);
160
1
            break;
161
          default:
162
            ASSERT(false, "HighlightState is not well defined");
163
            break;
164
        }
165
6
        material_switch_ptr->setDataVariance(osg::Object::STATIC);
166



6
        ss->setAttributeAndModes(material_switch_ptr, glModeValue);
167
      }
168
6
      return ss;
169
    }
170
171
    int getNodeVisibilityMode (Node* node) { return node->getVisibilityMode(); }
172
    void setNodeVisibilityMode (Node* node, const int& v) { node->setVisibilityMode((VisibilityMode)v); }
173
174
    int getNodeWireFrameMode (Node* node) { return node->getWireFrameMode(); }
175
    void setNodeWireFrameMode (Node* node, const int& v) { node->setWireFrameMode((WireFrameMode)v); }
176
177
    int getNodeLightingMode (Node* node) { return node->getLightingMode(); }
178
    void setNodeLightingMode (Node* node, const int& v) { node->setLightingMode((LightingMode)v); }
179
180
    void setNodeLandmark (Node* node, bool enable) {
181
      if (enable) node->addLandmark (0.05f);
182
      else        node->deleteLandmark();
183
    }
184
185
    int getNodeHighlightState (Node* node) { return (int)node->getHighlightState(); }
186
    void setNodeHighlightState (Node* node, const int& v) { node->setHighlightState(v); }
187
188
1
    MetaEnum* highlightStateEnum ()
189
    {
190

1
      static MetaEnum hs;
191
1
      if (hs.type.size() == 0) {
192
1
        hs.type = "HighlightState";
193

1
        hs.names .push_back ("None"  ); hs.values.push_back (0);
194

1
        hs.names .push_back ("1"     ); hs.values.push_back (1);
195

1
        hs.names .push_back ("2"     ); hs.values.push_back (2);
196

1
        hs.names .push_back ("3"     ); hs.values.push_back (3);
197

1
        hs.names .push_back ("4"     ); hs.values.push_back (4);
198

1
        hs.names .push_back ("5"     ); hs.values.push_back (5);
199

1
        hs.names .push_back ("6"     ); hs.values.push_back (6);
200

1
        hs.names .push_back ("7"     ); hs.values.push_back (7);
201

1
        hs.names .push_back ("8"     ); hs.values.push_back (8);
202
      }
203
1
      return &hs;
204
    }
205
  }
206
  using ::osg::Matrix;
207
208
  const float Node::TransparencyRenderingBinThreshold = 0.99f;
209
210
  /* Declaration of private function members */
211
1
  void Node::init ()
212
  {
213
    /* Build local conformation
214
       <- wireframe_node_ptr_
215
       connected to the parent <- switch_node_ptr_                           <- auto_transform_ptr_ <- connection of children here
216
       <- normal_node_ptr_
217
    */
218
1
    scale_.value = osgVector3 (1, 1, 1);
219
1
    scale_.min = 0.f;
220
1
    scale_.step = 0.1f;
221
1
    scale_.adaptiveDecimal = true;
222

1
    scale_.callback(boost::bind(&Node::updateTransform, this));
223
224
1
    M_.callback(scale_.callback());
225
226

1
    switch_node_ptr_ = new ::osg::Group;
227

1
    hl_switch_node_ptr_ = new ::osg::Group;
228

1
    transform_ptr_ = new ::osg::MatrixTransform;
229
1
    transform_ptr_ ->setName ("positionInParentNode");
230
231
1
    switch_node_ptr_->setNodeMask(NodeBit | IntersectionBit);
232
1
    switch_node_ptr_->setName (id_name_);
233
1
    wireframe_modes_.resize(2);
234

1
    wireframe_modes_[FILL]      = new ::osg::Group;
235
1
    wireframe_modes_[FILL]      ->setName ("wireframe: FILL");
236

1
    wireframe_modes_[WIREFRAME] = new ::osg::Group;
237
1
    wireframe_modes_[WIREFRAME] ->setName ("wireframe: WIREFRAME");
238
239
    /* Building hierarchie */
240
1
    selected_wireframe_ = FILL;
241
1
    switch_node_ptr_->addChild(wireframe_modes_[FILL]);
242
1
    wireframe_modes_[FILL]->addChild(hl_switch_node_ptr_);
243
1
    wireframe_modes_[FILL]->setDataVariance (osg::Object::STATIC);
244
245
    // Setup highlight states
246
1
    highlight_nodes_.resize(9);
247
1
    selected_highlight_ = 0;
248
1
    highlight_enabled_ = true;
249
1
    highlight_nodes_[0] = transform_ptr_;
250
9
    for (unsigned int i = 1; i < 9; ++i) {
251

8
      highlight_nodes_[i] = setupHighlightState (i);
252
8
      highlight_nodes_[i]->addChild(transform_ptr_);
253
    }
254
    // setHighlightState(0);
255
1
    hl_switch_node_ptr_->addChild(highlight_nodes_[selected_highlight_]);
256
1
    hl_switch_node_ptr_->setName ("highlight switch");
257
258

1
    wireframe_modes_[WIREFRAME]->setStateSet(getWireframeStateSet());
259
1
    wireframe_modes_[WIREFRAME]->setDataVariance (osg::Object::STATIC);
260
1
    geode_ptr_ = NULL;
261
1
    alpha_ = 1.;
262
263
1
    visibilityMode_ = VISIBILITY_ON;
264
1
    lightingMode_   = LIGHT_INFLUENCE_ON;
265
266
2
    addProperty(
267

2
        EnumProperty::create("Highlight/State", highlightStateEnum(),
268

2
          EnumProperty::Getter_t(boost::bind(getNodeHighlightState, this)),
269

2
          EnumProperty::Setter_t(boost::bind(setNodeHighlightState, this, _1))));
270
2
    addProperty(
271

2
        BoolProperty::create("Highlight/Enable", this,
272
          &Node::getHighlightEnabled, &Node::setHighlightEnabled));
273
2
    addProperty(
274

2
        EnumProperty::create("Visibility", visibilityModeEnum(),
275

2
          EnumProperty::Getter_t(boost::bind(getNodeVisibilityMode, this)),
276

2
          EnumProperty::Setter_t(boost::bind(setNodeVisibilityMode, this, _1))));
277
2
    addProperty(
278

2
        EnumProperty::create("WireframeMode", wireFrameModeEnum(),
279

2
          EnumProperty::Getter_t(boost::bind(getNodeWireFrameMode, this)),
280

2
          EnumProperty::Setter_t(boost::bind(setNodeWireFrameMode, this, _1))));
281
2
    addProperty(
282

2
        EnumProperty::create("LightingMode", lightingModeEnum(),
283

2
          EnumProperty::Getter_t(boost::bind(getNodeLightingMode, this)),
284

2
          EnumProperty::Setter_t(boost::bind(setNodeLightingMode, this, _1))));
285
2
    addProperty(
286

2
        BoolProperty::create("Landmark",
287
2
          BoolProperty::getterFromMemberFunction (this, &Node::hasLandmark),
288

2
          BoolProperty::Setter_t(boost::bind(setNodeLandmark, this, _1))));
289

1
    addProperty(StringProperty::createRO("Name", this, &Node::getID));
290

1
    addProperty(Vector4Property::createWO("Color", this, &Node::setColor));
291
292
    RangedFloatProperty::Ptr_t alphaProp =
293

2
      RangedFloatProperty::create("Alpha", this, &Node::getAlpha, &Node::setAlpha);
294
1
    alphaProp->setRange(0.f, 1.f, 0.1f);
295
1
    addProperty(alphaProp);
296
297
1
    addProperty(&scale_);
298
1
    addProperty(&M_);
299
1
  }
300
301
1
  Node::Node (const std::string& name) :
302
    id_name_(name),
303
    dirty_ (true),
304
    scale_ ("Scale"),
305



1
    M_ ("Transform")
306
  {
307
1
    init();
308
1
  }
309
310
  Node::Node (const Node &other) :
311
    id_name_(other.getID()),
312
    dirty_ (true),
313
    scale_ ("Scale"),
314
    M_ ("Transform")
315
  {
316
    init();
317
  }
318
319
5
  void Node::updateTransform ()
320
  {
321
10
    osg::Matrixf M;
322
5
    M.setRotate (M_.value.quat);
323
5
    M.setTrans  (M_.value.position);
324
325



5
    transform_ptr_->setMatrix (::osg::Matrix::scale(scale_.value)*Ms_*M);
326
5
    dirty_ = true;
327
5
  }
328
329
2
  void Node::setStaticTransform(const osgVector3 & position, const osgQuat & quat)
330
  {
331
2
    Ms_.setRotate (quat);
332
2
    Ms_.setTrans  (position);
333
334
2
    updateTransform ();
335
2
  }
336
337
2
  osgQuat Node::getStaticRotation() const
338
  {
339
2
    osgQuat q, so; osgVector3 t, s;
340
2
    Ms_.decompose(t, q, s, so);
341
2
    return q;
342
  }
343
344
2
  osgVector3 Node::getStaticPosition() const
345
  {
346
2
    osgQuat q, so; osgVector3 t, s;
347
2
    Ms_.decompose(t, q, s, so);
348
2
    return t;
349
  }
350
351
  void Node::setVisibilityMode (const VisibilityMode& mode)
352
  {
353
    if (visibilityMode_ == mode) return;
354
    visibilityMode_ = mode;
355
    switch (mode) {
356
      case VISIBILITY_ON:
357
        transform_ptr_->setNodeMask(0xffffffff);
358
        transform_ptr_->setStateSet (getVisibleStateSet(lightingMode_));
359
        break;
360
      case VISIBILITY_OFF:
361
        transform_ptr_->setNodeMask(0x0);
362
        transform_ptr_->setStateSet (getVisibleStateSet(lightingMode_));
363
        break;
364
      case ALWAYS_ON_TOP:
365
        transform_ptr_->setNodeMask(0xffffffff);
366
        transform_ptr_->setStateSet (getAlwaysOnTopStateSet(lightingMode_));
367
        break;
368
369
      default:
370
        ASSERT(false, "mode is not well defined");
371
        break;
372
    }
373
    dirty_ = true;
374
  }
375
376
  void Node::setLightingMode (const LightingMode& mode)
377
  {
378
    if (mode == lightingMode_) return;
379
    lightingMode_ = mode;
380
    switch (visibilityMode_) {
381
      case VISIBILITY_ON:
382
      case VISIBILITY_OFF:
383
        transform_ptr_->setStateSet (getVisibleStateSet(lightingMode_));
384
        break;
385
      case ALWAYS_ON_TOP:
386
        transform_ptr_->setStateSet (getAlwaysOnTopStateSet(lightingMode_));
387
        break;
388
      default:
389
        ASSERT(false, "mode is not well defined");
390
        break;
391
    }
392
    dirty_ = true;
393
  }
394
395
  LightingMode Node::getLightingMode () const
396
  {
397
    return lightingMode_;
398
  }
399
400
  void Node::setWireFrameMode (const WireFrameMode& mode)
401
  {
402
    if (mode == selected_wireframe_) return;
403
    bool fillSelected = (selected_wireframe_ == FILL     ) || (selected_wireframe_ == FILL_AND_WIREFRAME);
404
    bool wireSelected = (selected_wireframe_ == WIREFRAME) || (selected_wireframe_ == FILL_AND_WIREFRAME);
405
    // 0: keep as it is
406
    // 1: select
407
    // 2: deselect
408
    int selectFill = 0, selectWire = 0;
409
    switch (mode) {
410
    case FILL:
411
      if ( wireSelected) selectWire = 2;
412
      if (!fillSelected) selectFill = 1;
413
      break;
414
    case WIREFRAME:
415
      if (!wireSelected) selectWire = 1;
416
      if ( fillSelected) selectFill = 2;
417
      break;
418
    case FILL_AND_WIREFRAME:
419
      if (!wireSelected) selectWire = 1;
420
      if (!fillSelected) selectFill = 1;
421
      break;
422
    default:
423
      ASSERT(false, "WireFrameMode set with bad option");
424
      break;
425
    }
426
    switch (selectFill) {
427
      case 0: break;
428
      case 1:
429
              wireframe_modes_[FILL]->addChild(hl_switch_node_ptr_);
430
              switch_node_ptr_->addChild(wireframe_modes_[FILL]);
431
              break;
432
      case 2:
433
              wireframe_modes_[FILL]->removeChild(hl_switch_node_ptr_);
434
              switch_node_ptr_->removeChild(wireframe_modes_[FILL]);
435
              break;
436
      default:
437
              assert(false && "Wrong action");
438
    };
439
    switch (selectWire) {
440
      case 0: break;
441
      case 1:
442
              wireframe_modes_[WIREFRAME]->addChild(hl_switch_node_ptr_);
443
              switch_node_ptr_->addChild(wireframe_modes_[WIREFRAME]);
444
              break;
445
      case 2:
446
              wireframe_modes_[WIREFRAME]->removeChild(hl_switch_node_ptr_);
447
              switch_node_ptr_->removeChild(wireframe_modes_[WIREFRAME]);
448
              break;
449
      default:
450
              assert(false && "Wrong action");
451
    };
452
    selected_wireframe_ = mode;
453
    dirty_ = true;
454
  }
455
456
  void Node::addLandmark(const float& size)
457
  {
458
    ::osg::GeometryRefPtr geom_ptr = new ::osg::Geometry();
459
460
    /* Define points of the beam */
461
    ::osg::Vec3ArrayRefPtr points_ptr = new ::osg::Vec3Array(6);
462
    points_ptr->at(0) = osgVector3(0.,0.,0.);
463
    points_ptr->at(1) = osgVector3(size,0.,0.);
464
    points_ptr->at(2) = osgVector3(0.,0.,0.);
465
    points_ptr->at(3) = osgVector3(0.,size,0.);
466
    points_ptr->at(4) = osgVector3(0.,0.,0.);
467
    points_ptr->at(5) = osgVector3(0.,0.,size);
468
469
470
    /* Define the color */
471
    ::osg::Vec4ArrayRefPtr color_ptr = new ::osg::Vec4Array(3);
472
    color_ptr->at(0) = osgVector4(1.,0.,0.,1.);
473
    color_ptr->at(1) = osgVector4(0.,1.,0.,1.);
474
    color_ptr->at(2) = osgVector4(0.,0.,1.,1.);
475
476
    geom_ptr->setVertexArray(points_ptr.get());
477
    geom_ptr->setColorArray(color_ptr   .get());
478
    geom_ptr->setColorBinding(::osg::Geometry::BIND_PER_PRIMITIVE_SET);
479
    geom_ptr->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,2));
480
    geom_ptr->addPrimitiveSet(new osg::DrawArrays(GL_LINES,2,2));
481
    geom_ptr->addPrimitiveSet(new osg::DrawArrays(GL_LINES,4,2));
482
483
    transform_ptr_->removeChild(landmark_geode_ptr_);
484
    landmark_geode_ptr_ = new osg::Geode();
485
    landmark_geode_ptr_->addDrawable(geom_ptr);
486
487
    //set Landmark as ALWAYS ON TOP
488
    landmark_geode_ptr_->setNodeMask(0xffffffff);
489
    landmark_geode_ptr_->setStateSet (getAlwaysOnTopStateSet (LIGHT_INFLUENCE_OFF));
490
491
    transform_ptr_->addChild(landmark_geode_ptr_);
492
    dirty_ = true;
493
  }
494
495
  bool Node::hasLandmark() const
496
  {
497
    return landmark_geode_ptr_;
498
  }
499
500
  void Node::deleteLandmark()
501
  {
502
    if (landmark_geode_ptr_) {
503
      transform_ptr_->removeChild(landmark_geode_ptr_);
504
      landmark_geode_ptr_.release();
505
      dirty_ = true;
506
    }
507
  }
508
509
8
  ::osg::Group* Node::setupHighlightState (unsigned int state)
510
  {
511
16
    osg::StateSetRefPtr ss;
512


8
    switch (state) {
513
1
      case 1: /// collision
514

1
        ss = getHighlightStateSet<1> ();
515
1
        break;
516
1
      case 2: /// selection
517

1
        ss = getHighlightStateSet<2> ();
518
1
        break;
519
1
      case 3: /// selection
520

1
        ss = getHighlightStateSet<3> ();
521
1
        break;
522
1
      case 4: /// selection
523

1
        ss = getHighlightStateSet<4> ();
524
1
        break;
525
1
      case 5: /// selection
526

1
        ss = getHighlightStateSet<5> ();
527
1
        break;
528
1
      case 6: /// selection
529

1
        ss = getHighlightStateSet<6> ();
530
1
        break;
531
1
      case 7: /// Selection through osgFX::Outline
532
        {
533

1
          osgFX::Outline* outline = new osgFX::Outline;
534
535
1
          outline->setWidth(8);
536
1
          outline->setColor(osg::Vec4(1,1,0,1));
537
1
          outline->setDataVariance(osg::Object::STATIC);
538
1
          return outline;
539
        }
540
        break;
541
1
      case 8: /// Selection through osgFX::Outline
542
        {
543

1
          osgFX::Scribe* scribe = new osgFX::Scribe;
544
545
1
          scribe->setWireframeLineWidth(1);
546
1
          scribe->setWireframeColor(osg::Vec4(1,1,0,1));
547
1
          scribe->setDataVariance(osg::Object::STATIC);
548
1
          return scribe;
549
        }
550
        break;
551
      case 0:
552
      default:
553
        break;
554
    }
555

6
    osg::Group* node = new ::osg::Group;
556
6
    node->setStateSet(ss);
557
6
    node->setDataVariance(osg::Object::STATIC);
558
6
    return node;
559
  }
560
561
  void Node::setHighlightState (unsigned int state)
562
  {
563
    if (!highlight_enabled_) return;
564
    if (state != selected_highlight_
565
        && state < highlight_nodes_.size()) {
566
      hl_switch_node_ptr_->replaceChild(highlight_nodes_[selected_highlight_],
567
                                        highlight_nodes_[state]);
568
      // Update the child
569
      selected_highlight_ = state;
570
      dirty_ = true;
571
    }
572
  }
573
574
  void Node::setAlpha (const float& alpha)
575
  {
576
    if (geode_ptr_.get() == NULL)
577
      {
578
	std::cout << "You must initialize a Geode on " << id_name_ << " to use Alpha" << std::endl;
579
	return ;
580
      }
581
    osg::StateSet* ss = geode_ptr_.get()->getStateSet();
582
    if (ss)
583
      {
584
	alpha_ = alpha;
585
	osg::Material *mat;
586
	if (ss->getAttribute(osg::StateAttribute::MATERIAL))
587
	  mat = dynamic_cast<osg::Material*>(ss->getAttribute(osg::StateAttribute::MATERIAL));
588
        else {
589
          mat = new osg::Material;
590
          ss->setAttribute(mat, osg::StateAttribute::OFF);
591
        }
592
        mat->setAlpha(osg::Material::FRONT_AND_BACK, alpha);
593
        setTransparentRenderingBin (alpha_<TransparencyRenderingBinThreshold);
594
        dirty_ = true;
595
      }
596
  }
597
598
  float Node::getAlpha() const
599
  {
600
    return alpha_;
601
  }
602
603
  void Node::setTransparency (const float& transparency)
604
  {
605
    setAlpha (1.f - transparency);
606
  }
607
608
  float Node::getTransparency() const
609
  {
610
    return 1.f - getAlpha();
611
  }
612
613
1
  void Node::setTransparentRenderingBin (bool transparent, osg::StateSet* ss)
614
  {
615
1
    if (ss == NULL) {
616
1
      if (geode_ptr_.get() == NULL) {
617
        std::cout << "You must initialize a Geode on " << id_name_ <<
618
          " to use Alpha" << std::endl;
619
        return;
620
      }
621
1
      ss = geode_ptr_.get()->getStateSet();
622
1
      if (ss == NULL) return;
623
    }
624
1
    bool isTransparent = (ss->getRenderingHint() == osg::StateSet::TRANSPARENT_BIN);
625
1
    if (transparent == isTransparent) return;
626
    if (transparent)
627
      ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
628
    else
629
      ss->setRenderingHint(osg::StateSet::DEFAULT_BIN);
630
    dirty_ = true;
631
  }
632
633
2
  Node::~Node ()
634
  {
635
    /* Proper deletion */
636
    /* deleting the top most node (switch_node_ptr_) will delete everything else.
637
     * Loop over the parents of switch_node_ptr_ and remove references to it.
638
     */
639
    typedef ::osg::Node::ParentList PL_t;
640
2
    PL_t parents = switch_node_ptr_->getParents();
641
1
    for (PL_t::const_iterator _p = parents.begin(); _p != parents.end(); ++_p)
642
      (*_p)->removeChild(switch_node_ptr_);
643
1
  }
644
645
2
  const Configuration& Node::getGlobalTransform() const
646
  {
647
2
    return M_.value;
648
  }
649
650
  void Node::traverse (NodeVisitor& /*visitor*/)
651
  {}
652
653
  osg::ref_ptr<osg::Node> Node::getOsgNode() const
654
  {
655
    return geode_ptr_.get();
656
  }
657
658
  /* End of declaration of public function members */
659
660
661
} /* namespace viewer */
662
663

3
} /* namespace gepetto */