File: ShapeScale.cpp

package info (click to toggle)
pivy 0.6.10-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,216 kB
  • sloc: python: 36,331; cpp: 787; ansic: 733; makefile: 30; sh: 27; objc: 5
file content (94 lines) | stat: -rw-r--r-- 2,824 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright (C) 1998-2005 by Systems in Motion. All rights reserved.

//  The ShapeScale class is used for scaling a shape based on
//  projected size.
//
//  This nodekit can be inserted in your scene graph to add for
//  instance 3D markers that will be of a constant projected size.
//
//  The marker shape is stored in the "shape" part. Any kind of node
//  can be used, even group nodes with several shapes, but the
//  marker shape should be approximately of unit size, and with a
//  center position in (0, 0, 0).


//  SoSFFloat ShapeScale::active
//  Turns the scaling on/off. Default value is TRUE.


//  SoSFFloat ShapeScale::projectedSize
//  The requested projected size of the shape. Default value is 5.0.

#include "ShapeScale.h"

#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/nodes/SoShape.h>
#include <Inventor/nodes/SoScale.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/elements/SoViewVolumeElement.h>
#include <Inventor/elements/SoViewportRegionElement.h>
#include <Inventor/elements/SoModelMatrixElement.h>

SO_KIT_SOURCE(ShapeScale);


//  Constructor.
ShapeScale::ShapeScale(void) 
{
  SO_KIT_CONSTRUCTOR(ShapeScale);

  SO_KIT_ADD_FIELD(active, (TRUE));
  SO_KIT_ADD_FIELD(projectedSize, (5.0f));  

  SO_KIT_ADD_CATALOG_ENTRY(topSeparator, SoSeparator, FALSE, this, \x0, FALSE);
  SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(shape, SoNode, SoCube, TRUE, topSeparator, \x0, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(scale, SoScale, FALSE, topSeparator, shape, FALSE);
  
  SO_KIT_INIT_INSTANCE();
}
  
  
// Destructor.
ShapeScale::~ShapeScale()
{
}
  
// Initializes this class. Call before using it.

void
ShapeScale::initClass(void)
{
  SO_KIT_INIT_CLASS(ShapeScale, SoBaseKit, "BaseKit");
}

static void 
update_scale(SoScale * scale, const SbVec3f & v)
{
  // only write to field when scaling has changed.
  if (scale->scaleFactor.getValue() != v) {
    scale->scaleFactor = v;
  }
}

// Overridden to (re)initialize scaling before rendering marker.
void 
ShapeScale::GLRender(SoGLRenderAction * action)
{
  SoState * state = action->getState();

  SoScale * scale = (SoScale*) this->getAnyPart(SbName("scale"), TRUE);
  if (!this->active.getValue()) {
    update_scale(scale, SbVec3f(1.0f, 1.0f, 1.0f));
  }
  else {
    const SbViewportRegion & vp = SoViewportRegionElement::get(state);
    const SbViewVolume & vv = SoViewVolumeElement::get(state);
    SbVec3f center(0.0f, 0.0f, 0.0f);
    float nsize = this->projectedSize.getValue() / float(vp.getViewportSizePixels()[1]);
    SoModelMatrixElement::get(state).multVecMatrix(center, center); // transform to WCS
    float scalefactor = vv.getWorldToScreenScale(center, nsize);
    update_scale(scale, SbVec3f(scalefactor, scalefactor, scalefactor));
  }
  inherited::GLRender(action);
}