source: osgVisual/trunk/src/util/terrainQuery.cpp @ 338

Last change on this file since 338 was 305, checked in by Torben Dannhauer, 13 years ago
File size: 5.5 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2011 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15*/
16
17#include <osg/CoordinateSystemNode>
18#include <terrainQuery.h>
19
20#include <osg/Notify>
21#include <osgUtil/LineSegmentIntersector>
22
23using namespace osgVisual;
24using namespace osgSim;
25
26terrainQuery::terrainQuery()
27{
28    _lowestHeight = -1000.0;
29   
30        setDatabaseCacheReadCallback(new DatabaseCacheReadCallback);
31}
32
33void terrainQuery::clear()
34{
35    _HATList.clear();
36}
37
38unsigned int terrainQuery::addPoint(const osg::Vec3d& point)
39{
40    unsigned int index = _HATList.size();
41    _HATList.push_back(HAT(point));
42    return index;
43}
44
45void terrainQuery::computeIntersections(osg::Node* scene, osg::Node::NodeMask traversalMask)
46{
47    osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(scene);
48    osg::EllipsoidModel* em = csn ? csn->getEllipsoidModel() : 0;
49
50    osg::ref_ptr<osgUtil::IntersectorGroup> intersectorGroup = new osgUtil::IntersectorGroup();
51
52    for(HATList::iterator itr = _HATList.begin();
53        itr != _HATList.end();
54        ++itr)
55    {
56        if (em)
57        {
58       
59            osg::Vec3d start = itr->_point;
60            osg::Vec3d upVector = em->computeLocalUpVector(start.x(), start.y(), start.z());
61
62            double latitude, longitude, height;
63            em->convertXYZToLatLongHeight(start.x(), start.y(), start.z(), latitude, longitude, height);
64            osg::Vec3d end = start - upVector * (height - _lowestHeight);           
65           
66            itr->_hat = height;
67
68            OSG_NOTICE<<"lat = "<<latitude<<" longitude = "<<longitude<<" height = "<<height<<std::endl;
69
70            osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(start, end);
71            intersectorGroup->addIntersector( intersector.get() );
72        }
73        else
74        {
75            osg::Vec3d start = itr->_point;
76            osg::Vec3d upVector (0.0, 0.0, 1.0);
77           
78            double height = start.z();
79            osg::Vec3d end = start - upVector * (height - _lowestHeight);           
80
81            itr->_hat = height;
82
83            osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector( start, end);
84            intersectorGroup->addIntersector( intersector.get() );
85        }
86    }
87   
88    _intersectionVisitor.reset();
89    _intersectionVisitor.setTraversalMask(traversalMask);
90    _intersectionVisitor.setIntersector( intersectorGroup.get() );
91   
92    scene->accept(_intersectionVisitor);
93   
94    unsigned int index = 0;
95    osgUtil::IntersectorGroup::Intersectors& intersectors = intersectorGroup->getIntersectors();
96    for(osgUtil::IntersectorGroup::Intersectors::iterator intersector_itr = intersectors.begin();
97        intersector_itr != intersectors.end();
98        ++intersector_itr, ++index)
99    {
100        osgUtil::LineSegmentIntersector* lsi = dynamic_cast<osgUtil::LineSegmentIntersector*>(intersector_itr->get());
101        if (lsi)
102        {
103            osgUtil::LineSegmentIntersector::Intersections& intersections = lsi->getIntersections();
104            if (!intersections.empty())
105            {
106                const osgUtil::LineSegmentIntersector::Intersection& intersection = *intersections.begin();
107                osg::Vec3d intersectionPoint = intersection.matrix.valid() ? intersection.localIntersectionPoint * (*intersection.matrix) :
108                                               intersection.localIntersectionPoint;
109                // HAT
110                                _HATList[index]._hat = (_HATList[index]._point - intersectionPoint).length();
111
112                                // HOT
113                                if (em)
114                                {
115                                        double latitude, longitude, height;
116                                        em->convertXYZToLatLongHeight(intersectionPoint.x(), intersectionPoint.y(), intersectionPoint.z(), latitude, longitude, height);
117                                        _HATList[index]._hot = height;
118                                }
119                                else
120                                {
121                                        _HATList[index]._hot = intersectionPoint.z();
122                                }
123
124            }
125        }
126    }
127   
128}
129
130double terrainQuery::computeHeightAboveTerrain(osg::Node* scene, const osg::Vec3d& point, DataSource pagingBehaviour, osg::Node::NodeMask traversalMask)
131{
132    terrainQuery qt;
133        /*if(!loadHighestLOD)
134                qt.setDatabaseCacheReadCallback(0);*/
135    unsigned int index = qt.addPoint(point);
136    qt.computeIntersections(scene, traversalMask);
137    return qt.getHeightAboveTerrain(index);
138}
139
140double terrainQuery::computeHeightOfTerrain(osg::Node* scene, const osg::Vec3d& point, DataSource pagingBehaviour, osg::Node::NodeMask traversalMask)
141{
142        terrainQuery qt;
143    unsigned int index = qt.addPoint(point);
144    qt.computeIntersections(scene, traversalMask);
145    return qt.getHeightOfTerrain(index);
146}
147
148void terrainQuery::setDatabaseCacheReadCallback(DatabaseCacheReadCallback* dcrc)
149{
150    _dcrc = dcrc;
151    _intersectionVisitor.setReadCallback(dcrc);
152}
Note: See TracBrowser for help on using the repository browser.