GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/gui/point-intersector.cc Lines: 0 66 0.0 %
Date: 2024-04-14 11:13:22 Branches: 0 145 0.0 %

Line Branch Exec Source
1
/* -*-c++-*- OpenSceneGraph Cookbook
2
 * Chapter 10 Recipe 7
3
 * Author: Wang Rui <wangray84 at gmail dot com>
4
 */
5
6
#include "point-intersector.hh"
7
8
#include <osg/Geometry>
9
#include <osg/TemplatePrimitiveFunctor>
10
#include <osg/Version>
11
12
namespace gepetto {
13
namespace gui {
14
15
PointIntersector::PointIntersector()
16
    : osgUtil::LineSegmentIntersector(MODEL, 0.0, 0.0), _pickBias(2.0f) {}
17
18
PointIntersector::PointIntersector(const osg::Vec3& start, const osg::Vec3& end)
19
    : osgUtil::LineSegmentIntersector(start, end), _pickBias(2.0f) {}
20
21
PointIntersector::PointIntersector(CoordinateFrame cf, double x, double y)
22
    : osgUtil::LineSegmentIntersector(cf, x, y), _pickBias(2.0f) {}
23
24
osgUtil::Intersector* PointIntersector::clone(
25
    osgUtil::IntersectionVisitor& iv) {
26
  if (_coordinateFrame == MODEL && iv.getModelMatrix() == 0) {
27
    osg::ref_ptr<PointIntersector> cloned = new PointIntersector(_start, _end);
28
    cloned->_parent = this;
29
    cloned->_pickBias = _pickBias;
30
    return cloned.release();
31
  }
32
33
  osg::Matrix matrix;
34
  switch (_coordinateFrame) {
35
    case WINDOW:
36
      if (iv.getWindowMatrix()) matrix.preMult(*iv.getWindowMatrix());
37
      if (iv.getProjectionMatrix()) matrix.preMult(*iv.getProjectionMatrix());
38
      if (iv.getViewMatrix()) matrix.preMult(*iv.getViewMatrix());
39
      if (iv.getModelMatrix()) matrix.preMult(*iv.getModelMatrix());
40
      break;
41
    case PROJECTION:
42
      if (iv.getProjectionMatrix()) matrix.preMult(*iv.getProjectionMatrix());
43
      if (iv.getViewMatrix()) matrix.preMult(*iv.getViewMatrix());
44
      if (iv.getModelMatrix()) matrix.preMult(*iv.getModelMatrix());
45
      break;
46
    case VIEW:
47
      if (iv.getViewMatrix()) matrix.preMult(*iv.getViewMatrix());
48
      if (iv.getModelMatrix()) matrix.preMult(*iv.getModelMatrix());
49
      break;
50
    case MODEL:
51
      if (iv.getModelMatrix()) matrix = *iv.getModelMatrix();
52
      break;
53
  }
54
55
  osg::Matrix inverse = osg::Matrix::inverse(matrix);
56
  osg::ref_ptr<PointIntersector> cloned =
57
      new PointIntersector(_start * inverse, _end * inverse);
58
  cloned->_parent = this;
59
  cloned->_pickBias = _pickBias;
60
  return cloned.release();
61
}
62
63
void PointIntersector::intersect(osgUtil::IntersectionVisitor& iv,
64
                                 osg::Drawable* drawable) {
65
  osg::BoundingBox bb =
66
#if OSG_VERSION_LESS_THAN(3, 3, 3)
67
      drawable->getBound();
68
#else
69
      drawable->getBoundingBox();
70
#endif
71
  bb.xMin() -= _pickBias;
72
  bb.xMax() += _pickBias;
73
  bb.yMin() -= _pickBias;
74
  bb.yMax() += _pickBias;
75
  bb.zMin() -= _pickBias;
76
  bb.zMax() += _pickBias;
77
78
  osg::Vec3d s(_start), e(_end);
79
  if (!intersectAndClip(s, e, bb)) return;
80
  if (iv.getDoDummyTraversal()) return;
81
82
  osg::Geometry* geometry = drawable->asGeometry();
83
  if (geometry) {
84
    osg::Vec3Array* vertices =
85
        dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
86
    if (!vertices) return;
87
88
    osg::Vec3d dir = e - s;
89
    double invLength = 1.0 / dir.length();
90
    for (unsigned int i = 0; i < vertices->size(); ++i) {
91
      double distance = fabs((((*vertices)[i] - s) ^ dir).length());
92
      distance *= invLength;
93
      if (_pickBias < distance) continue;
94
95
      Intersection hit;
96
      hit.ratio = distance;
97
      hit.nodePath = iv.getNodePath();
98
      hit.drawable = drawable;
99
      hit.matrix = iv.getModelMatrix();
100
      hit.localIntersectionPoint = (*vertices)[i];
101
      hit.primitiveIndex = i;
102
      insertIntersection(hit);
103
    }
104
  }
105
}
106
107
}  // namespace gui
108
}  // namespace gepetto