root/OpenSceneGraph/trunk/src/osgTerrain/GeometryTechnique.cpp @ 12597

Revision 12597, 55.4 kB (checked in by robert, 3 years ago)

Resolved warnings reported by g++ 4.6's -Wunused-but-set-variable.

Warnings were:

/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osg/ShapeDrawable.cpp: In member function ‘void PrimitiveShapeVisitor::createHalfSphere(unsigned int, unsigned int, float, int, float, const Matrix&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osg/ShapeDrawable.cpp:1409:11: warning: variable ‘nzBase’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osg/ShapeDrawable.cpp:1410:11: warning: variable ‘nRatioBase’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgUtil/DelaunayTriangulator.cpp: In function ‘osgUtil::Triangle_list osgUtil::fillHole(osg::Vec3Array*, std::vector<unsigned int, std::allocator<unsigned int> >)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgUtil/DelaunayTriangulator.cpp:569:27: warning: variable ‘ptest’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgUtil/DelaunayTriangulator.cpp: In member function ‘bool osgUtil::DelaunayTriangulator::triangulate()’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgUtil/DelaunayTriangulator.cpp:979:45: warning: variable ‘curp’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgUtil/RenderStage.cpp: In member function ‘void osgUtil::RenderStage::runCameraSetUp(osg::RenderInfo?&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgUtil/RenderStage.cpp:631:18: warning: variable ‘stencilAttached’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgText/FadeText.cpp: In member function ‘void FadeTextPolytopeData::buildPolytope()’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgText/FadeText.cpp:74:20: warning: variable ‘edge23’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgText/FadeText.cpp:75:20: warning: variable ‘edge30’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgText/Text.cpp: In member function ‘void osgText::Text::computeBackdropPositions(unsigned int) const’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgText/Text.cpp:747:10: warning: variable ‘is_valid_size’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgGA/NodeTrackerManipulator.cpp: In member function ‘virtual bool osgGA::NodeTrackerManipulator::performMovementLeftMouseButton(double, double, double)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgGA/NodeTrackerManipulator.cpp:257:21: warning: variable ‘lookVector’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgGA/NodeTrackerManipulator.cpp:259:21: warning: variable ‘upVector’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgGA/TerrainManipulator.cpp: In member function ‘virtual bool osgGA::TerrainManipulator::performMovementMiddleMouseButton(double, double, double)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgGA/TerrainManipulator.cpp:217:11: warning: variable ‘lookVector’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgGA/TerrainManipulator.cpp:219:11: warning: variable ‘upVector’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgVolume/FixedFunctionTechnique.cpp: In member function ‘virtual void osgVolume::FixedFunctionTechnique::init()’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgVolume/FixedFunctionTechnique.cpp:124:30: warning: variable ‘tf’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgParticle/FluidProgram.cpp: In member function ‘virtual void osgParticle::FluidProgram::execute(double)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgParticle/FluidProgram.cpp:38:23: warning: variable ‘velBefore’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgShadow/ParallelSplitShadowMap.cpp: In member function ‘virtual void osgShadow::ParallelSplitShadowMap::cull(osgUtil::CullVisitor?&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgShadow/ParallelSplitShadowMap.cpp:593:22: warning: variable ‘bb’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgTerrain/GeometryTechnique.cpp: In member function ‘virtual void osgTerrain::GeometryTechnique::generateGeometry(osgTerrain::GeometryTechnique::BufferData?&, osgTerrain::Locator*, const osg::Vec3d&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgTerrain/GeometryTechnique.cpp:777:12: warning: variable ‘i_sampleFactor’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgTerrain/GeometryTechnique.cpp:778:12: warning: variable ‘j_sampleFactor’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/dds/ReaderWriterDDS.cpp: In function ‘osg::Image* ReadDDSFile(std::istream&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/dds/ReaderWriterDDS.cpp:314:10: warning: variable ‘is3dImage’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/dds/ReaderWriterDDS.cpp: In function ‘bool WriteDDSFile(const osg::Image*, std::ostream&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/dds/ReaderWriterDDS.cpp:721:10: warning: variable ‘is3dImage’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/hdr/hdrloader.cpp: In static member function ‘static bool HDRLoader::load(const char*, bool, HDRLoaderResult&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/hdr/hdrloader.cpp:101:10: warning: variable ‘cmd’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/vtf/ReaderWriterVTF.cpp: In function ‘osg::Image* ReadVTFFile(std::istream&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/vtf/ReaderWriterVTF.cpp:360:23: warning: variable ‘base’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/jp2/ReaderWriterJP2.cpp: In function ‘int putdata(jas_stream_t*, jas_image_t*, int)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/jp2/ReaderWriterJP2.cpp:41:13: warning: variable ‘linelen’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/Inventor/ConvertToInventor.cpp: In member function ‘void ConvertToInventor::processGeometry(const osg::Geometry*, ConvertToInventor::InventorState?*)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/Inventor/ConvertToInventor.cpp:1639:10: warning: variable ‘ok’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/Inventor/ConvertFromInventor.cpp: In member function ‘virtual SbBool? SoVRMLImageTextureOsg::readInstance(SoInput?*, short unsigned int)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/Inventor/ConvertFromInventor.cpp:1264:16: warning: variable ‘retval’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/OpenFlight/GeometryRecords.cpp: In member function ‘virtual void flt::Face::readRecord(flt::RecordInputStream?&, flt::Document&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/OpenFlight/GeometryRecords.cpp:369:19: warning: variable ‘secondaryPackedColor’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/OpenFlight/GeometryRecords.cpp: In member function ‘virtual void flt::Mesh::readRecord(flt::RecordInputStream?&, flt::Document&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/OpenFlight/GeometryRecords.cpp:942:19: warning: variable ‘secondaryPackedColor’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp: In member function ‘virtual osgDB::ReaderWriter::ReadResult? FLTReaderWriter::readNode(std::istream&, const Options*) const’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp:427:40: warning: variable ‘pos’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/ive/ShapeAttributeList.cpp: In member function ‘void ive::ShapeAttributeList::write(ive::DataOutputStream?*)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/ive/ShapeAttributeList.cpp:31:48: warning: variable ‘it’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/ac/Geode.cpp: In member function ‘void ac3d::Geode::ProcessGeometry?(std::ostream&, unsigned int)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/ac/Geode.cpp:806:35: warning: variable ‘fRep_s’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/ac/Geode.cpp:806:43: warning: variable ‘fRep_t’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/ac/Geode.cpp:807:35: warning: variable ‘fOffset_s’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/ac/Geode.cpp:807:46: warning: variable ‘fOffset_t’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/ac/Geode.cpp:932:38: warning: variable ‘primLength’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/txp/trpage_geom.cpp: In member function ‘virtual bool trpgGeometry::Write(trpgWriteBuffer&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/txp/trpage_geom.cpp:615:19: warning: variable ‘u’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/txp/trpage_material.cpp: In member function ‘int trpgMatTable::AddMaterial?(const trpgMaterial&, bool)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/txp/trpage_material.cpp:103:10: warning: variable ‘spaceInTable’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/txp/trpage_rarchive.cpp: In member function ‘virtual bool trpgr_Archive::ReadHeader?(bool)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/txp/trpage_rarchive.cpp:261:14: warning: variable ‘headerHasTexTable’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/zip/unzip.cpp: In member function ‘ZRESULT TUnzip::Get(int, ZIPENTRY*)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/zip/unzip.cpp:4055:8: warning: variable ‘hidden’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/zip/unzip.cpp:4055:22: warning: variable ‘system’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/zip/unzip.cpp:4055:36: warning: variable ‘archive’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/zip/ZipArchive.cpp: In member function ‘virtual bool ZipArchive::getFileNames(osgDB::Archive::FileNameList?&) const’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/zip/ZipArchive.cpp:91:37: warning: variable ‘iterEnd’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/pvr/ReaderWriterPVR.cpp: In member function ‘osgDB::ReaderWriter::ReadResult? ReaderWriterPVR::readPVRStream(std::istream&) const’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/pvr/ReaderWriterPVR.cpp:155:14: warning: variable ‘hasAlpha’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgViewer/View.cpp: In function ‘osg::Geometry* create3DSphericalDisplayDistortionMesh(const Vec3&, const Vec3&, const Vec3&, double, double, osg::Image*, const Matrix&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgViewer/View.cpp:737:15: warning: variable ‘cursor’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgViewer/View.cpp: In function ‘osg::Geometry* createParoramicSphericalDisplayDistortionMesh(const Vec3&, const Vec3&, const Vec3&, double, double, osg::Image*, const Matrix&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgViewer/View.cpp:1130:19: warning: variable ‘cursor’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgViewer/View.cpp:1118:15: warning: variable ‘dx’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgViewer/GraphicsWindowX11.cpp: In member function ‘virtual void osgViewer::GraphicsWindowX11::checkEvents()’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgViewer/GraphicsWindowX11.cpp:1181:10: warning: variable ‘destroyWindowRequested’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/cfg/ConfigParser.cpp: In member function ‘bool osgProducer::CameraConfig::parseFile(const string&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/cfg/ConfigParser.cpp:2247:13: warning: variable ‘result’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgQt/QGraphicsViewAdapter.cpp: In member function ‘bool osgQt::QGraphicsViewAdapter::handlePointerEvent(int, int, int)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgQt/QGraphicsViewAdapter.cpp:344:17: warning: variable ‘viewportGeometry’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgdistortion/osgdistortion.cpp: In function ‘osg::Node* createDistortionSubgraph(osg::Node*, const Vec4&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgdistortion/osgdistortion.cpp:125:19: warning: variable ‘cursor’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgdistortion/osgdistortion.cpp:126:19: warning: variable ‘texcoord’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgdistortion/osgdistortion.cpp: In function ‘osg::Geometry* createDomeDistortionMesh(const Vec3&, const Vec3&, const Vec3&, osg::ArgumentParser?&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgdistortion/osgdistortion.cpp:358:15: warning: variable ‘cursor’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgposter/osgposter.cpp: In function ‘int main(int, char**)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgposter/osgposter.cpp:253:31: warning: variable ‘outputTiles’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgthreadedterrain/osgthreadedterrain.cpp: In function ‘int main(int, char**)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgthreadedterrain/osgthreadedterrain.cpp:669:10: warning: variable ‘readParameter’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgtext3D/TextNode.cpp: In member function ‘virtual void osgText::Layout::layout(osgText::TextNode?&) const’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgtext3D/TextNode.cpp:80:11: warning: variable ‘characterHeightScale’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgvolume/osgvolume.cpp: In function ‘int main(int, char**)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgvolume/osgvolume.cpp:678:38: warning: variable ‘internalFormatMode’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgwidgetcanvas/osgwidgetcanvas.cpp: In function ‘bool windowMouseOver(osgWidget::Event&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgwidgetcanvas/osgwidgetcanvas.cpp:27:24: warning: variable ‘xy’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgwidgetcanvas/osgwidgetcanvas.cpp: In function ‘bool widgetMouseOver(osgWidget::Event&)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/examples/osgwidgetcanvas/osgwidgetcanvas.cpp:35:24: warning: variable ‘xy’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/p3d/ReaderWriterP3D.cpp: In member function ‘osg::Node* ReaderWriterP3DXML::parseXmlGraph(osgDB::XmlNode?*, bool, osgDB::Options*) const’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/src/osgPlugins/p3d/ReaderWriterP3D.cpp:2121:10: warning: variable ‘readSlide’ set but not used [-Wunused-but-set-variable]
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/applications/present3D/present3D.cpp: In function ‘int main(int, char**)’:
/home/stephan/Dev/LibSources/OpenSceneGraph-3.0.0-rc2/applications/present3D/present3D.cpp:639:10: warning: variable ‘sizesSpecified’ set but not used [-Wunused-but-set-variable]

  • Property svn:eol-style set to native
Line 
1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is 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 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <osgTerrain/GeometryTechnique>
15#include <osgTerrain/TerrainTile>
16#include <osgTerrain/Terrain>
17
18#include <osgUtil/MeshOptimizers>
19
20#include <osgDB/FileUtils>
21
22#include <osg/io_utils>
23#include <osg/Texture2D>
24#include <osg/Texture1D>
25#include <osg/TexEnvCombine>
26#include <osg/Program>
27#include <osg/Math>
28#include <osg/Timer>
29
30using namespace osgTerrain;
31
32GeometryTechnique::GeometryTechnique()
33{
34    setFilterBias(0);
35    setFilterWidth(0.1);
36    setFilterMatrixAs(GAUSSIAN);
37   
38}
39
40GeometryTechnique::GeometryTechnique(const GeometryTechnique& gt,const osg::CopyOp& copyop):
41    TerrainTechnique(gt,copyop)
42{
43    setFilterBias(gt._filterBias);
44    setFilterWidth(gt._filterWidth);
45    setFilterMatrix(gt._filterMatrix);
46}
47
48GeometryTechnique::~GeometryTechnique()
49{
50}
51
52void GeometryTechnique::setFilterBias(float filterBias)
53{
54    _filterBias = filterBias;
55    if (!_filterBiasUniform) _filterBiasUniform = new osg::Uniform("filterBias",_filterBias);
56    else _filterBiasUniform->set(filterBias);
57}
58
59void GeometryTechnique::setFilterWidth(float filterWidth)
60{
61    _filterWidth = filterWidth;
62    if (!_filterWidthUniform) _filterWidthUniform = new osg::Uniform("filterWidth",_filterWidth);
63    else _filterWidthUniform->set(filterWidth);
64}
65
66void GeometryTechnique::setFilterMatrix(const osg::Matrix3& matrix)
67{
68    _filterMatrix = matrix;
69    if (!_filterMatrixUniform) _filterMatrixUniform = new osg::Uniform("filterMatrix",_filterMatrix);
70    else _filterMatrixUniform->set(_filterMatrix);
71}
72
73void GeometryTechnique::setFilterMatrixAs(FilterType filterType)
74{
75    switch(filterType)
76    {
77        case(SMOOTH):
78            setFilterMatrix(osg::Matrix3(0.0, 0.5/2.5, 0.0,
79                                         0.5/2.5, 0.5/2.5, 0.5/2.5,
80                                         0.0, 0.5/2.5, 0.0));
81            break;
82        case(GAUSSIAN):
83            setFilterMatrix(osg::Matrix3(0.0, 1.0/8.0, 0.0,
84                                         1.0/8.0, 4.0/8.0, 1.0/8.0,
85                                         0.0, 1.0/8.0, 0.0));
86            break;
87        case(SHARPEN):
88            setFilterMatrix(osg::Matrix3(0.0, -1.0, 0.0,
89                                         -1.0, 5.0, -1.0,
90                                         0.0, -1.0, 0.0));
91            break;
92
93    };
94}
95
96void GeometryTechnique::init(int dirtyMask, bool assumeMultiThreaded)
97{
98    OSG_INFO<<"Doing GeometryTechnique::init()"<<std::endl;
99   
100    if (!_terrainTile) return;
101
102    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_writeBufferMutex);
103
104    // take a temporary referecen
105    osg::ref_ptr<TerrainTile> tile = _terrainTile;
106
107    if (dirtyMask==0) return;
108
109    osg::ref_ptr<BufferData> buffer = new BufferData;
110
111    Locator* masterLocator = computeMasterLocator();
112
113    osg::Vec3d centerModel = computeCenterModel(*buffer, masterLocator);
114
115    if ((dirtyMask & TerrainTile::IMAGERY_DIRTY)==0)
116    {
117        generateGeometry(*buffer, masterLocator, centerModel);
118
119        osg::ref_ptr<BufferData> read_buffer = _currentBufferData;
120
121        osg::StateSet* stateset = read_buffer->_geode->getStateSet();
122        if (stateset)
123        {
124            // OSG_NOTICE<<"Reusing StateSet"<<std::endl;
125            buffer->_geode->setStateSet(stateset);
126        }
127        else
128        {
129            applyColorLayers(*buffer);
130            applyTransparency(*buffer);
131        }
132    }
133    else
134    {
135        generateGeometry(*buffer, masterLocator, centerModel);
136        applyColorLayers(*buffer);
137        applyTransparency(*buffer);
138    }
139
140    if (buffer->_transform.valid()) buffer->_transform->setThreadSafeRefUnref(true);
141
142    if (!_currentBufferData || !assumeMultiThreaded)
143    {
144        // no currentBufferData so we must be the first init to be applied
145        _currentBufferData = buffer;
146    }
147    else
148    {
149        // there is already an active _currentBufferData so we'll request that this gets swapped on next frame.
150        _newBufferData = buffer;
151        if (_terrainTile->getTerrain()) _terrainTile->getTerrain()->updateTerrainTileOnNextFrame(_terrainTile);
152    }
153
154    _terrainTile->setDirtyMask(0);
155}
156
157Locator* GeometryTechnique::computeMasterLocator()
158{
159    osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
160    osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
161
162    Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
163    Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
164   
165    Locator* masterLocator = elevationLocator ? elevationLocator : colorLocator;
166    if (!masterLocator)
167    {
168        OSG_NOTICE<<"Problem, no locator found in any of the terrain layers"<<std::endl;
169        return 0;
170    }
171   
172    return masterLocator;
173}
174
175osg::Vec3d GeometryTechnique::computeCenterModel(BufferData& buffer, Locator* masterLocator)
176{
177    if (!masterLocator) return osg::Vec3d(0.0,0.0,0.0);
178
179    osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
180    osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
181
182    Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
183    Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
184   
185    if (!elevationLocator) elevationLocator = masterLocator;
186    if (!colorLocator) colorLocator = masterLocator;
187
188    osg::Vec3d bottomLeftNDC(DBL_MAX, DBL_MAX, 0.0);
189    osg::Vec3d topRightNDC(-DBL_MAX, -DBL_MAX, 0.0);
190   
191    if (elevationLayer)
192    {
193        if (elevationLocator!= masterLocator)
194        {
195            masterLocator->computeLocalBounds(*elevationLocator, bottomLeftNDC, topRightNDC);
196        }
197        else
198        {
199            bottomLeftNDC.x() = osg::minimum(bottomLeftNDC.x(), 0.0);
200            bottomLeftNDC.y() = osg::minimum(bottomLeftNDC.y(), 0.0);
201            topRightNDC.x() = osg::maximum(topRightNDC.x(), 1.0);
202            topRightNDC.y() = osg::maximum(topRightNDC.y(), 1.0);
203        }
204    }
205
206    if (colorLayer)
207    {
208        if (colorLocator!= masterLocator)
209        {
210            masterLocator->computeLocalBounds(*colorLocator, bottomLeftNDC, topRightNDC);
211        }
212        else
213        {
214            bottomLeftNDC.x() = osg::minimum(bottomLeftNDC.x(), 0.0);
215            bottomLeftNDC.y() = osg::minimum(bottomLeftNDC.y(), 0.0);
216            topRightNDC.x() = osg::maximum(topRightNDC.x(), 1.0);
217            topRightNDC.y() = osg::maximum(topRightNDC.y(), 1.0);
218        }
219    }
220
221    OSG_INFO<<"bottomLeftNDC = "<<bottomLeftNDC<<std::endl;
222    OSG_INFO<<"topRightNDC = "<<topRightNDC<<std::endl;
223
224    buffer._transform = new osg::MatrixTransform;
225
226    osg::Vec3d centerNDC = (bottomLeftNDC + topRightNDC)*0.5;
227    osg::Vec3d centerModel = (bottomLeftNDC + topRightNDC)*0.5;
228    masterLocator->convertLocalToModel(centerNDC, centerModel);
229   
230    buffer._transform->setMatrix(osg::Matrix::translate(centerModel));
231   
232    return centerModel;
233}
234
235class VertexNormalGenerator
236{
237    public:
238
239        typedef std::vector<int> Indices;
240        typedef std::pair< osg::ref_ptr<osg::Vec2Array>, Locator* > TexCoordLocatorPair;
241        typedef std::map< Layer*, TexCoordLocatorPair > LayerToTexCoordMap;
242
243        VertexNormalGenerator(Locator* masterLocator, const osg::Vec3d& centerModel, int numRows, int numColmns, float scaleHeight, bool createSkirt);
244
245        void populateCenter(osgTerrain::Layer* elevationLayer, LayerToTexCoordMap& layerToTexCoordMap);
246        void populateLeftBoundary(osgTerrain::Layer* elevationLayer);
247        void populateRightBoundary(osgTerrain::Layer* elevationLayer);
248        void populateAboveBoundary(osgTerrain::Layer* elevationLayer);
249        void populateBelowBoundary(osgTerrain::Layer* elevationLayer);
250
251        void computeNormals();
252
253        unsigned int capacity() const { return _vertices->capacity(); }
254
255        inline void setVertex(int c, int r, const osg::Vec3& v, const osg::Vec3& n)
256        {
257            int& i = index(c,r);
258            if (i==0)
259            {
260                if (r<0 || r>=_numRows || c<0 || c>=_numColumns)
261                {
262                    i = -(1+static_cast<int>(_boundaryVertices->size()));
263                    _boundaryVertices->push_back(v);
264                    // OSG_NOTICE<<"setVertex("<<c<<", "<<r<<", ["<<v<<"], ["<<n<<"]), i="<<i<<" _boundaryVertices["<<-i-1<<"]="<<(*_boundaryVertices)[-i-1]<<"]"<<std::endl;
265                }
266                else
267                {
268                    i = _vertices->size() + 1;
269                    _vertices->push_back(v);
270                    _normals->push_back(n);
271                    // OSG_NOTICE<<"setVertex("<<c<<", "<<r<<", ["<<v<<"], ["<<n<<"]), i="<<i<<" _vertices["<<i-1<<"]="<<(*_vertices)[i-1]<<"]"<<std::endl;
272                }
273            }
274            else if (i<0)
275            {
276                (*_boundaryVertices)[-i-1] = v;
277                // OSG_NOTICE<<"setVertex("<<c<<", "<<r<<", ["<<v<<"], ["<<n<<"] _boundaryVertices["<<-i-1<<"]="<<(*_boundaryVertices)[-i-1]<<"]"<<std::endl;
278            }
279            else
280            {
281                // OSG_NOTICE<<"Overwriting setVertex("<<c<<", "<<r<<", ["<<v<<"], ["<<n<<"]"<<std::endl;
282                // OSG_NOTICE<<"     previous values ( vertex ["<<(*_vertices)[i-1]<<"], normal (*_normals)[i-1] ["<<n<<"]"<<std::endl;
283                // (*_vertices)[i-1] = v;
284
285                // average the vertex positions
286                (*_vertices)[i-1] = ((*_vertices)[i-1] + v)*0.5f;
287
288                (*_normals)[i-1] = n;
289            }
290        }
291
292        inline int& index(int c, int r) { return _indices[(r+1)*(_numColumns+2)+c+1]; }
293
294        inline int index(int c, int r) const { return _indices[(r+1)*(_numColumns+2)+c+1]; }
295
296        inline int vertex_index(int c, int r) const { int i = _indices[(r+1)*(_numColumns+2)+c+1]; return i-1; }
297
298        inline bool vertex(int c, int r, osg::Vec3& v) const
299        {
300            int i = index(c,r);
301            if (i==0) return false;
302            if (i<0) v = (*_boundaryVertices)[-i-1];
303            else v = (*_vertices)[i-1];
304            return true;
305        }
306
307        inline bool computeNormal(int c, int r, osg::Vec3& n) const
308        {
309#if 1
310            return computeNormalWithNoDiagonals(c,r,n);
311#else
312            return computeNormalWithDiagonals(c,r,n);
313#endif
314        }
315
316        inline bool computeNormalWithNoDiagonals(int c, int r, osg::Vec3& n) const
317        {
318            osg::Vec3 center;
319            bool center_valid  = vertex(c, r,  center);
320            if (!center_valid) return false;
321
322            osg::Vec3 left, right, top,  bottom;
323            bool left_valid  = vertex(c-1, r,  left);
324            bool right_valid = vertex(c+1, r,   right);
325            bool bottom_valid = vertex(c,   r-1, bottom);
326            bool top_valid = vertex(c,   r+1, top);
327
328            osg::Vec3 dx(0.0f,0.0f,0.0f);
329            osg::Vec3 dy(0.0f,0.0f,0.0f);
330            osg::Vec3 zero(0.0f,0.0f,0.0f);
331            if (left_valid)
332            {
333                dx = center-left;
334            }
335            if (right_valid)
336            {
337                dx = right-center;
338            }
339            if (bottom_valid)
340            {
341                dy += center-bottom;
342            }
343            if (top_valid)
344            {
345                dy += top-center;
346            }
347
348            if (dx==zero || dy==zero) return false;
349
350            n = dx ^ dy;
351            return n.normalize() != 0.0f;
352        }
353
354        inline bool computeNormalWithDiagonals(int c, int r, osg::Vec3& n) const
355        {
356            osg::Vec3 center;
357            bool center_valid  = vertex(c, r,  center);
358            if (!center_valid) return false;
359
360            osg::Vec3 top_left, top_right, bottom_left, bottom_right;
361            bool top_left_valid  = vertex(c-1, r+1,  top_left);
362            bool top_right_valid  = vertex(c+1, r+1,  top_right);
363            bool bottom_left_valid  = vertex(c-1, r-1,  bottom_left);
364            bool bottom_right_valid  = vertex(c+1, r-1,  bottom_right);
365
366            osg::Vec3 left, right, top,  bottom;
367            bool left_valid  = vertex(c-1, r,  left);
368            bool right_valid = vertex(c+1, r,   right);
369            bool bottom_valid = vertex(c,   r-1, bottom);
370            bool top_valid = vertex(c,   r+1, top);
371
372            osg::Vec3 dx(0.0f,0.0f,0.0f);
373            osg::Vec3 dy(0.0f,0.0f,0.0f);
374            osg::Vec3 zero(0.0f,0.0f,0.0f);
375            const float ratio = 0.5f;
376            if (left_valid)
377            {
378                dx = center-left;
379                if (top_left_valid) dy += (top_left-left)*ratio;
380                if (bottom_left_valid) dy += (left-bottom_left)*ratio;
381            }
382            if (right_valid)
383            {
384                dx = right-center;
385                if (top_right_valid) dy += (top_right-right)*ratio;
386                if (bottom_right_valid) dy += (right-bottom_right)*ratio;
387            }
388            if (bottom_valid)
389            {
390                dy += center-bottom;
391                if (bottom_left_valid) dx += (bottom-bottom_left)*ratio;
392                if (bottom_right_valid) dx += (bottom_right-bottom)*ratio;
393            }
394            if (top_valid)
395            {
396                dy += top-center;
397                if (top_left_valid) dx += (top-top_left)*ratio;
398                if (top_right_valid) dx += (top_right-top)*ratio;
399            }
400
401            if (dx==zero || dy==zero) return false;
402
403            n = dx ^ dy;
404            return n.normalize() != 0.0f;
405        }
406
407        Locator*                        _masterLocator;
408        const osg::Vec3d                _centerModel;
409        int                             _numRows;
410        int                             _numColumns;
411        float                           _scaleHeight;
412
413        Indices                         _indices;
414
415        osg::ref_ptr<osg::Vec3Array>    _vertices;
416        osg::ref_ptr<osg::Vec3Array>    _normals;
417        osg::ref_ptr<osg::FloatArray>   _elevations;
418
419        osg::ref_ptr<osg::Vec3Array>    _boundaryVertices;
420
421};
422
423VertexNormalGenerator::VertexNormalGenerator(Locator* masterLocator, const osg::Vec3d& centerModel, int numRows, int numColumns, float scaleHeight, bool createSkirt):
424    _masterLocator(masterLocator),
425    _centerModel(centerModel),
426    _numRows(numRows),
427    _numColumns(numColumns),
428    _scaleHeight(scaleHeight)
429{
430    int numVerticesInBody = numColumns*numRows;
431    int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0;
432    int numVertices = numVerticesInBody+numVerticesInSkirt;
433
434    _indices.resize((_numRows+2)*(_numColumns+2),0);
435
436    _vertices = new osg::Vec3Array;
437    _vertices->reserve(numVertices);
438
439    _normals = new osg::Vec3Array;
440    _normals->reserve(numVertices);
441
442    _elevations = new osg::FloatArray;
443    _elevations->reserve(numVertices);
444
445    _boundaryVertices = new osg::Vec3Array;
446    _boundaryVertices->reserve(_numRows*2 + _numColumns*2 + 4);
447}
448
449void VertexNormalGenerator::populateCenter(osgTerrain::Layer* elevationLayer, LayerToTexCoordMap& layerToTexCoordMap)
450{
451    // OSG_NOTICE<<std::endl<<"VertexNormalGenerator::populateCenter("<<elevationLayer<<")"<<std::endl;
452
453    bool sampled = elevationLayer &&
454                   ( (elevationLayer->getNumRows()!=static_cast<unsigned int>(_numRows)) ||
455                     (elevationLayer->getNumColumns()!=static_cast<unsigned int>(_numColumns)) );
456
457    for(int j=0; j<_numRows; ++j)
458    {
459        for(int i=0; i<_numColumns; ++i)
460        {
461            osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0);
462
463            bool validValue = true;
464            if (elevationLayer)
465            {
466                float value = 0.0f;
467                if (sampled) validValue = elevationLayer->getInterpolatedValidValue(ndc.x(), ndc.y(), value);
468                else validValue = elevationLayer->getValidValue(i,j,value);
469                ndc.z() = value*_scaleHeight;
470            }
471
472            if (validValue)
473            {
474                osg::Vec3d model;
475                _masterLocator->convertLocalToModel(ndc, model);
476
477                for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
478                    itr != layerToTexCoordMap.end();
479                    ++itr)
480                {
481                    osg::Vec2Array* texcoords = itr->second.first.get();
482                    osgTerrain::ImageLayer* imageLayer(dynamic_cast<osgTerrain::ImageLayer*>(itr->first));
483
484                    if (imageLayer != NULL)
485                    {
486                        Locator* colorLocator = itr->second.second;
487                        if (colorLocator != _masterLocator)
488                        {
489                            osg::Vec3d color_ndc;
490                            Locator::convertLocalCoordBetween(*_masterLocator, ndc, *colorLocator, color_ndc);
491                            (*texcoords).push_back(osg::Vec2(color_ndc.x(), color_ndc.y()));
492                        }
493                        else
494                        {
495                            (*texcoords).push_back(osg::Vec2(ndc.x(), ndc.y()));
496                        }
497                    }
498                    else
499                    {
500                        osgTerrain::ContourLayer* contourLayer(dynamic_cast<osgTerrain::ContourLayer*>(itr->first));
501
502                        bool texCoordSet = false;
503                        if (contourLayer)
504                        {
505                            osg::TransferFunction1D* transferFunction = contourLayer->getTransferFunction();
506                            if (transferFunction)
507                            {
508                                float difference = transferFunction->getMaximum()-transferFunction->getMinimum();
509                                if (difference != 0.0f)
510                                {
511                                    osg::Vec3d           color_ndc;
512                                    osgTerrain::Locator* colorLocator(itr->second.second);
513
514                                    if (colorLocator != _masterLocator)
515                                    {
516                                        Locator::convertLocalCoordBetween(*_masterLocator,ndc,*colorLocator,color_ndc);
517                                    }
518                                    else
519                                    {
520                                        color_ndc = ndc;
521                                    }
522
523                                    color_ndc[2] /= _scaleHeight;
524
525                                    (*texcoords).push_back(osg::Vec2((color_ndc[2]-transferFunction->getMinimum())/difference,0.0f));
526                                    texCoordSet = true;
527                                }
528                            }
529                        }
530                        if (!texCoordSet)
531                        {
532                            (*texcoords).push_back(osg::Vec2(0.0f,0.0f));
533                        }
534                    }
535                }
536
537                if (_elevations.valid())
538                {
539                    (*_elevations).push_back(ndc.z());
540                }
541
542                // compute the local normal
543                osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0;
544                osg::Vec3d model_one;
545                _masterLocator->convertLocalToModel(ndc_one, model_one);
546                model_one = model_one - model;
547                model_one.normalize();
548
549                setVertex(i, j, osg::Vec3(model-_centerModel), model_one);
550            }
551        }
552    }
553}
554
555void VertexNormalGenerator::populateLeftBoundary(osgTerrain::Layer* elevationLayer)
556{
557    // OSG_NOTICE<<"   VertexNormalGenerator::populateLeftBoundary("<<elevationLayer<<")"<<std::endl;
558
559    if (!elevationLayer) return;
560
561    bool sampled = elevationLayer &&
562                   ( (elevationLayer->getNumRows()!=static_cast<unsigned int>(_numRows)) ||
563                     (elevationLayer->getNumColumns()!=static_cast<unsigned int>(_numColumns)) );
564
565    for(int j=0; j<_numRows; ++j)
566    {
567        for(int i=-1; i<=0; ++i)
568        {
569            osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0);
570            osg::Vec3d left_ndc( 1.0+ndc.x(), ndc.y(), 0.0);
571
572            bool validValue = true;
573            if (elevationLayer)
574            {
575                float value = 0.0f;
576                if (sampled) validValue = elevationLayer->getInterpolatedValidValue(left_ndc.x(), left_ndc.y(), value);
577                else validValue = elevationLayer->getValidValue((_numColumns-1)+i,j,value);
578                ndc.z() = value*_scaleHeight;
579
580                ndc.z() += 0.f;
581            }
582            if (validValue)
583            {
584                osg::Vec3d model;
585                _masterLocator->convertLocalToModel(ndc, model);
586
587                // compute the local normal
588                osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0;
589                osg::Vec3d model_one;
590                _masterLocator->convertLocalToModel(ndc_one, model_one);
591                model_one = model_one - model;
592                model_one.normalize();
593
594                setVertex(i, j, osg::Vec3(model-_centerModel), model_one);
595                // OSG_NOTICE<<"       setVertex("<<i<<", "<<j<<"..)"<<std::endl;
596            }
597        }
598    }
599}
600
601void VertexNormalGenerator::populateRightBoundary(osgTerrain::Layer* elevationLayer)
602{
603    // OSG_NOTICE<<"   VertexNormalGenerator::populateRightBoundary("<<elevationLayer<<")"<<std::endl;
604
605    if (!elevationLayer) return;
606
607    bool sampled = elevationLayer &&
608                   ( (elevationLayer->getNumRows()!=static_cast<unsigned int>(_numRows)) ||
609                     (elevationLayer->getNumColumns()!=static_cast<unsigned int>(_numColumns)) );
610
611    for(int j=0; j<_numRows; ++j)
612    {
613        for(int i=_numColumns-1; i<_numColumns+1; ++i)
614        {
615            osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0);
616            osg::Vec3d right_ndc(ndc.x()-1.0, ndc.y(), 0.0);
617
618            bool validValue = true;
619            if (elevationLayer)
620            {
621                float value = 0.0f;
622                if (sampled) validValue = elevationLayer->getInterpolatedValidValue(right_ndc.x(), right_ndc.y(), value);
623                else validValue = elevationLayer->getValidValue(i-(_numColumns-1),j,value);
624                ndc.z() = value*_scaleHeight;
625            }
626
627            if (validValue)
628            {
629                osg::Vec3d model;
630                _masterLocator->convertLocalToModel(ndc, model);
631
632                // compute the local normal
633                osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0;
634                osg::Vec3d model_one;
635                _masterLocator->convertLocalToModel(ndc_one, model_one);
636                model_one = model_one - model;
637                model_one.normalize();
638
639                setVertex(i, j, osg::Vec3(model-_centerModel), model_one);
640                // OSG_NOTICE<<"       setVertex("<<i<<", "<<j<<"..)"<<std::endl;
641            }
642        }
643    }
644}
645
646void VertexNormalGenerator::populateAboveBoundary(osgTerrain::Layer* elevationLayer)
647{
648    // OSG_NOTICE<<"   VertexNormalGenerator::populateAboveBoundary("<<elevationLayer<<")"<<std::endl;
649
650    if (!elevationLayer) return;
651
652    bool sampled = elevationLayer &&
653                   ( (elevationLayer->getNumRows()!=static_cast<unsigned int>(_numRows)) ||
654                     (elevationLayer->getNumColumns()!=static_cast<unsigned int>(_numColumns)) );
655
656    for(int j=_numRows-1; j<_numRows+1; ++j)
657    {
658        for(int i=0; i<_numColumns; ++i)
659        {
660            osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0);
661            osg::Vec3d above_ndc( ndc.x(), ndc.y()-1.0, 0.0);
662
663            bool validValue = true;
664            if (elevationLayer)
665            {
666                float value = 0.0f;
667                if (sampled) validValue = elevationLayer->getInterpolatedValidValue(above_ndc.x(), above_ndc.y(), value);
668                else validValue = elevationLayer->getValidValue(i,j-(_numRows-1),value);
669                ndc.z() = value*_scaleHeight;
670            }
671
672            if (validValue)
673            {
674                osg::Vec3d model;
675                _masterLocator->convertLocalToModel(ndc, model);
676
677                // compute the local normal
678                osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0;
679                osg::Vec3d model_one;
680                _masterLocator->convertLocalToModel(ndc_one, model_one);
681                model_one = model_one - model;
682                model_one.normalize();
683
684                setVertex(i, j, osg::Vec3(model-_centerModel), model_one);
685                // OSG_NOTICE<<"       setVertex("<<i<<", "<<j<<"..)"<<std::endl;
686            }
687        }
688    }
689}
690
691void VertexNormalGenerator::populateBelowBoundary(osgTerrain::Layer* elevationLayer)
692{
693    // OSG_NOTICE<<"   VertexNormalGenerator::populateBelowBoundary("<<elevationLayer<<")"<<std::endl;
694
695    if (!elevationLayer) return;
696
697    bool sampled = elevationLayer &&
698                   ( (elevationLayer->getNumRows()!=static_cast<unsigned int>(_numRows)) ||
699                     (elevationLayer->getNumColumns()!=static_cast<unsigned int>(_numColumns)) );
700
701    for(int j=-1; j<=0; ++j)
702    {
703        for(int i=0; i<_numColumns; ++i)
704        {
705            osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0);
706            osg::Vec3d below_ndc( ndc.x(), 1.0+ndc.y(), 0.0);
707
708            bool validValue = true;
709            if (elevationLayer)
710            {
711                float value = 0.0f;
712                if (sampled) validValue = elevationLayer->getInterpolatedValidValue(below_ndc.x(), below_ndc.y(), value);
713                else validValue = elevationLayer->getValidValue(i,(_numRows-1)+j,value);
714                ndc.z() = value*_scaleHeight;
715            }
716
717            if (validValue)
718            {
719                osg::Vec3d model;
720                _masterLocator->convertLocalToModel(ndc, model);
721
722                // compute the local normal
723                osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0;
724                osg::Vec3d model_one;
725                _masterLocator->convertLocalToModel(ndc_one, model_one);
726                model_one = model_one - model;
727                model_one.normalize();
728
729                setVertex(i, j, osg::Vec3(model-_centerModel), model_one);
730                // OSG_NOTICE<<"       setVertex("<<i<<", "<<j<<"..)"<<std::endl;
731            }
732        }
733    }
734}
735
736
737void VertexNormalGenerator::computeNormals()
738{
739    // compute normals for the center section
740    for(int j=0; j<_numRows; ++j)
741    {
742        for(int i=0; i<_numColumns; ++i)
743        {
744            int vi = vertex_index(i, j);
745            if (vi>=0) computeNormal(i, j, (*_normals)[vi]);
746            else OSG_NOTICE<<"Not computing normal, vi="<<vi<<std::endl;
747        }
748    }
749}
750
751void GeometryTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator, const osg::Vec3d& centerModel)
752{
753    Terrain* terrain = _terrainTile->getTerrain();
754    osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
755
756
757    buffer._geode = new osg::Geode;
758    if(buffer._transform.valid())
759        buffer._transform->addChild(buffer._geode.get());
760
761    buffer._geometry = new osg::Geometry;
762    buffer._geode->addDrawable(buffer._geometry.get());
763
764    osg::Geometry* geometry = buffer._geometry.get();
765
766    unsigned int numRows = 20;
767    unsigned int numColumns = 20;
768
769    if (elevationLayer)
770    {
771        numColumns = elevationLayer->getNumColumns();
772        numRows = elevationLayer->getNumRows();
773    }
774
775    float sampleRatio = terrain ? terrain->getSampleRatio() : 1.0f;
776
777    // OSG_NOTICE<<"Sample ratio="<<sampleRatio<<std::endl;
778
779    unsigned int minimumNumColumns = 16u;
780    unsigned int minimumNumRows = 16u;
781
782    if ((sampleRatio!=1.0f) && (numColumns>minimumNumColumns) && (numRows>minimumNumRows))
783    {
784        unsigned int originalNumColumns = numColumns;
785        unsigned int originalNumRows = numRows;
786   
787        numColumns = std::max((unsigned int) (float(originalNumColumns)*sqrtf(sampleRatio)), minimumNumColumns);
788        numRows = std::max((unsigned int) (float(originalNumRows)*sqrtf(sampleRatio)),minimumNumRows);
789    }
790   
791   
792
793    bool treatBoundariesToValidDataAsDefaultValue = _terrainTile->getTreatBoundariesToValidDataAsDefaultValue();
794    OSG_INFO<<"TreatBoundariesToValidDataAsDefaultValue="<<treatBoundariesToValidDataAsDefaultValue<<std::endl;
795   
796    float skirtHeight = 0.0f;
797    HeightFieldLayer* hfl = dynamic_cast<HeightFieldLayer*>(elevationLayer);
798    if (hfl && hfl->getHeightField())
799    {
800        skirtHeight = hfl->getHeightField()->getSkirtHeight();
801    }
802   
803    bool createSkirt = skirtHeight != 0.0f;
804
805
806    float scaleHeight = terrain ? terrain->getVerticalScale() : 1.0f;
807
808    // construct the VertexNormalGenerator which will manage the generation and the vertices and normals
809    VertexNormalGenerator VNG(masterLocator, centerModel, numRows, numColumns, scaleHeight, createSkirt);
810
811    unsigned int numVertices = VNG.capacity();
812
813    // allocate and assign vertices
814    geometry->setVertexArray(VNG._vertices.get());
815
816    // allocate and assign normals
817    geometry->setNormalArray(VNG._normals.get());
818    geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
819
820
821    // allocate and assign tex coords
822    // typedef std::pair< osg::ref_ptr<osg::Vec2Array>, Locator* > TexCoordLocatorPair;
823    // typedef std::map< Layer*, TexCoordLocatorPair > LayerToTexCoordMap;
824
825    VertexNormalGenerator::LayerToTexCoordMap layerToTexCoordMap;
826    for(unsigned int layerNum=0; layerNum<_terrainTile->getNumColorLayers(); ++layerNum)
827    {
828        osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(layerNum);
829        if (colorLayer)
830        {
831            VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.find(colorLayer);
832            if (itr!=layerToTexCoordMap.end())
833            {
834                geometry->setTexCoordArray(layerNum, itr->second.first.get());
835            }
836            else
837            {
838
839                Locator* locator = colorLayer->getLocator();
840                if (!locator)
841                {
842                    osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(colorLayer);
843                    if (switchLayer)
844                    {
845                        if (switchLayer->getActiveLayer()>=0 &&
846                            static_cast<unsigned int>(switchLayer->getActiveLayer())<switchLayer->getNumLayers() &&
847                            switchLayer->getLayer(switchLayer->getActiveLayer()))
848                        {
849                            locator = switchLayer->getLayer(switchLayer->getActiveLayer())->getLocator();
850                        }
851                    }
852                }
853
854                VertexNormalGenerator::TexCoordLocatorPair& tclp = layerToTexCoordMap[colorLayer];
855                tclp.first = new osg::Vec2Array;
856                tclp.first->reserve(numVertices);
857                tclp.second = locator ? locator : masterLocator;
858                geometry->setTexCoordArray(layerNum, tclp.first.get());
859            }
860        }
861    }
862
863    // allocate and assign color
864    osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
865    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
866   
867    geometry->setColorArray(colors.get());
868    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
869
870    //
871    // populate vertex and tex coord arrays
872    //
873    VNG.populateCenter(elevationLayer, layerToTexCoordMap);
874
875    if (terrain && terrain->getEqualizeBoundaries())
876    {
877        TileID tileID = _terrainTile->getTileID();
878
879        osg::ref_ptr<TerrainTile> left_tile  = terrain->getTile(TileID(tileID.level, tileID.x-1, tileID.y));
880        osg::ref_ptr<TerrainTile> right_tile = terrain->getTile(TileID(tileID.level, tileID.x+1, tileID.y));
881        osg::ref_ptr<TerrainTile> top_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y+1));
882        osg::ref_ptr<TerrainTile> bottom_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y-1));
883
884#if 0
885        osg::ref_ptr<TerrainTile> top_left_tile  = terrain->getTile(TileID(tileID.level, tileID.x-1, tileID.y+1));
886        osg::ref_ptr<TerrainTile> top_right_tile = terrain->getTile(TileID(tileID.level, tileID.x+1, tileID.y+1));
887        osg::ref_ptr<TerrainTile> bottom_left_tile = terrain->getTile(TileID(tileID.level, tileID.x-1, tileID.y-1));
888        osg::ref_ptr<TerrainTile> bottom_right_tile = terrain->getTile(TileID(tileID.level, tileID.x+1, tileID.y-1));
889#endif
890        VNG.populateLeftBoundary(left_tile.valid() ? left_tile->getElevationLayer() : 0);
891        VNG.populateRightBoundary(right_tile.valid() ? right_tile->getElevationLayer() : 0);
892        VNG.populateAboveBoundary(top_tile.valid() ? top_tile->getElevationLayer() : 0);
893        VNG.populateBelowBoundary(bottom_tile.valid() ? bottom_tile->getElevationLayer() : 0);
894
895        _neighbours.clear();
896
897        bool updateNeighboursImmediately = false;
898
899        if (left_tile.valid())   addNeighbour(left_tile.get());
900        if (right_tile.valid())  addNeighbour(right_tile.get());
901        if (top_tile.valid())    addNeighbour(top_tile.get());
902        if (bottom_tile.valid()) addNeighbour(bottom_tile.get());
903
904#if 0
905        if (bottom_left_tile.valid()) addNeighbour(bottom_left_tile.get());
906        if (bottom_right_tile.valid()) addNeighbour(bottom_right_tile.get());
907        if (top_left_tile.valid()) addNeighbour(top_left_tile.get());
908        if (top_right_tile.valid()) addNeighbour(top_right_tile.get());
909#endif
910
911        if (left_tile.valid())
912        {
913            if (!(left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
914            {
915                int dirtyMask = left_tile->getDirtyMask() | TerrainTile::LEFT_EDGE_DIRTY;
916                if (updateNeighboursImmediately) left_tile->init(dirtyMask, true);
917                else left_tile->setDirtyMask(dirtyMask);
918            }
919        }
920        if (right_tile.valid())
921        {
922            if (!(right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
923            {
924                int dirtyMask = right_tile->getDirtyMask() | TerrainTile::RIGHT_EDGE_DIRTY;
925                if (updateNeighboursImmediately) right_tile->init(dirtyMask, true);
926                else right_tile->setDirtyMask(dirtyMask);
927            }
928        }
929        if (top_tile.valid())
930        {
931            if (!(top_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
932            {
933                int dirtyMask = top_tile->getDirtyMask() | TerrainTile::TOP_EDGE_DIRTY;
934                if (updateNeighboursImmediately) top_tile->init(dirtyMask, true);
935                else top_tile->setDirtyMask(dirtyMask);
936            }
937        }
938
939        if (bottom_tile.valid())
940        {
941            if (!(bottom_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
942            {
943                int dirtyMask = bottom_tile->getDirtyMask() | TerrainTile::BOTTOM_EDGE_DIRTY;
944                if (updateNeighboursImmediately) bottom_tile->init(dirtyMask, true);
945                else bottom_tile->setDirtyMask(dirtyMask);
946            }
947        }
948
949#if 0
950        if (bottom_left_tile.valid())
951        {
952            if (!(bottom_left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
953            {
954                int dirtyMask = bottom_left_tile->getDirtyMask() | TerrainTile::BOTTOM_LEFT_CORNER_DIRTY;
955                if (updateNeighboursImmediately) bottom_left_tile->init(dirtyMask, true);
956                else bottom_left_tile->setDirtyMask(dirtyMask);
957            }
958        }
959
960        if (bottom_right_tile.valid())
961        {
962            if (!(bottom_right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
963            {
964                int dirtyMask = bottom_right_tile->getDirtyMask() | TerrainTile::BOTTOM_RIGHT_CORNER_DIRTY;
965                if (updateNeighboursImmediately) bottom_right_tile->init(dirtyMask, true);
966                else bottom_right_tile->setDirtyMask(dirtyMask);
967            }
968        }
969
970        if (top_right_tile.valid())
971        {
972            if (!(top_right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
973            {
974                int dirtyMask = top_right_tile->getDirtyMask() | TerrainTile::TOP_RIGHT_CORNER_DIRTY;
975                if (updateNeighboursImmediately) top_right_tile->init(dirtyMask, true);
976                else top_right_tile->setDirtyMask(dirtyMask);
977            }
978        }
979
980        if (top_left_tile.valid())
981        {
982            if (!(top_left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
983            {
984                int dirtyMask = top_left_tile->getDirtyMask() | TerrainTile::TOP_LEFT_CORNER_DIRTY;
985                if (updateNeighboursImmediately) top_left_tile->init(dirtyMask, true);
986                else top_left_tile->setDirtyMask(dirtyMask);
987            }
988        }
989#endif
990    }
991
992
993    osg::ref_ptr<osg::Vec3Array> skirtVectors = new osg::Vec3Array((*VNG._normals));
994    VNG.computeNormals();
995
996    //
997    // populate the primitive data
998    //
999    bool swapOrientation = !(masterLocator->orientationOpenGL());
1000    bool smallTile = numVertices <= 16384;
1001
1002    // OSG_NOTICE<<"smallTile = "<<smallTile<<std::endl;
1003
1004    osg::ref_ptr<osg::DrawElements> elements = smallTile ?
1005        static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_TRIANGLES)) :
1006        static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_TRIANGLES));
1007
1008    elements->reserveElements((numRows-1) * (numColumns-1) * 6);
1009
1010    geometry->addPrimitiveSet(elements.get());
1011
1012
1013    unsigned int i, j;
1014    for(j=0; j<numRows-1; ++j)
1015    {
1016        for(i=0; i<numColumns-1; ++i)
1017        {
1018            // remap indices to final vertex positions
1019            int i00 = VNG.vertex_index(i,   j);
1020            int i01 = VNG.vertex_index(i,   j+1);
1021            int i10 = VNG.vertex_index(i+1, j);
1022            int i11 = VNG.vertex_index(i+1, j+1);
1023
1024            if (swapOrientation)
1025            {
1026                std::swap(i00,i01);
1027                std::swap(i10,i11);
1028            }
1029
1030            unsigned int numValid = 0;
1031            if (i00>=0) ++numValid;
1032            if (i01>=0) ++numValid;
1033            if (i10>=0) ++numValid;
1034            if (i11>=0) ++numValid;
1035
1036            if (numValid==4)
1037            {
1038                // optimize which way to put the diagonal by choosing to
1039                // place it between the two corners that have the least curvature
1040                // relative to each other.
1041                float dot_00_11 = (*VNG._normals)[i00] * (*VNG._normals)[i11];
1042                float dot_01_10 = (*VNG._normals)[i01] * (*VNG._normals)[i10];
1043                if (dot_00_11 > dot_01_10)
1044                {
1045                    elements->addElement(i01);
1046                    elements->addElement(i00);
1047                    elements->addElement(i11);
1048
1049                    elements->addElement(i00);
1050                    elements->addElement(i10);
1051                    elements->addElement(i11);
1052                }
1053                else
1054                {
1055                    elements->addElement(i01);
1056                    elements->addElement(i00);
1057                    elements->addElement(i10);
1058
1059                    elements->addElement(i01);
1060                    elements->addElement(i10);
1061                    elements->addElement(i11);
1062                }
1063            }
1064            else if (numValid==3)
1065            {
1066                if (i00>=0) elements->addElement(i00);
1067                if (i01>=0) elements->addElement(i01);
1068                if (i11>=0) elements->addElement(i11);
1069                if (i10>=0) elements->addElement(i10);
1070            }
1071        }
1072    }
1073
1074
1075    if (createSkirt)
1076    {
1077        osg::ref_ptr<osg::Vec3Array> vertices = VNG._vertices.get();
1078        osg::ref_ptr<osg::Vec3Array> normals = VNG._normals.get();
1079
1080        osg::ref_ptr<osg::DrawElements> skirtDrawElements = smallTile ?
1081            static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
1082            static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
1083
1084        // create bottom skirt vertices
1085        int r,c;
1086        r=0;
1087        for(c=0;c<static_cast<int>(numColumns);++c)
1088        {
1089            int orig_i = VNG.vertex_index(c,r);
1090            if (orig_i>=0)
1091            {
1092                unsigned int new_i = vertices->size(); // index of new index of added skirt point
1093                osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
1094                (*vertices).push_back(new_v);
1095                if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
1096
1097                for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
1098                    itr != layerToTexCoordMap.end();
1099                    ++itr)
1100                {
1101                    itr->second.first->push_back((*itr->second.first)[orig_i]);
1102                }
1103
1104                skirtDrawElements->addElement(orig_i);
1105                skirtDrawElements->addElement(new_i);
1106            }
1107            else
1108            {
1109                if (skirtDrawElements->getNumIndices()!=0)
1110                {
1111                    geometry->addPrimitiveSet(skirtDrawElements.get());
1112                    skirtDrawElements = smallTile ?
1113                        static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
1114                        static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
1115                }
1116
1117            }
1118        }
1119
1120        if (skirtDrawElements->getNumIndices()!=0)
1121        {
1122            geometry->addPrimitiveSet(skirtDrawElements.get());
1123            skirtDrawElements = smallTile ?
1124                        static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
1125                        static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
1126        }
1127
1128        // create right skirt vertices
1129        c=numColumns-1;
1130        for(r=0;r<static_cast<int>(numRows);++r)
1131        {
1132            int orig_i = VNG.vertex_index(c,r); // index of original vertex of grid
1133            if (orig_i>=0)
1134            {
1135                unsigned int new_i = vertices->size(); // index of new index of added skirt point
1136                osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
1137                (*vertices).push_back(new_v);
1138                if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
1139                for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
1140                    itr != layerToTexCoordMap.end();
1141                    ++itr)
1142                {
1143                    itr->second.first->push_back((*itr->second.first)[orig_i]);
1144                }
1145
1146                skirtDrawElements->addElement(orig_i);
1147                skirtDrawElements->addElement(new_i);
1148            }
1149            else
1150            {
1151                if (skirtDrawElements->getNumIndices()!=0)
1152                {
1153                    geometry->addPrimitiveSet(skirtDrawElements.get());
1154                    skirtDrawElements = smallTile ?
1155                        static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
1156                        static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
1157                }
1158
1159            }
1160        }
1161
1162        if (skirtDrawElements->getNumIndices()!=0)
1163        {
1164            geometry->addPrimitiveSet(skirtDrawElements.get());
1165            skirtDrawElements = smallTile ?
1166                        static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
1167                        static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
1168        }
1169
1170        // create top skirt vertices
1171        r=numRows-1;
1172        for(c=numColumns-1;c>=0;--c)
1173        {
1174            int orig_i = VNG.vertex_index(c,r); // index of original vertex of grid
1175            if (orig_i>=0)
1176            {
1177                unsigned int new_i = vertices->size(); // index of new index of added skirt point
1178                osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
1179                (*vertices).push_back(new_v);
1180                if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
1181                for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
1182                    itr != layerToTexCoordMap.end();
1183                    ++itr)
1184                {
1185                    itr->second.first->push_back((*itr->second.first)[orig_i]);
1186                }
1187
1188                skirtDrawElements->addElement(orig_i);
1189                skirtDrawElements->addElement(new_i);
1190            }
1191            else
1192            {
1193                if (skirtDrawElements->getNumIndices()!=0)
1194                {
1195                    geometry->addPrimitiveSet(skirtDrawElements.get());
1196                    skirtDrawElements = smallTile ?
1197                        static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
1198                        static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
1199                }
1200
1201            }
1202        }
1203
1204        if (skirtDrawElements->getNumIndices()!=0)
1205        {
1206            geometry->addPrimitiveSet(skirtDrawElements.get());
1207            skirtDrawElements = smallTile ?
1208                        static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
1209                        static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
1210        }
1211
1212        // create left skirt vertices
1213        c=0;
1214        for(r=numRows-1;r>=0;--r)
1215        {
1216            int orig_i = VNG.vertex_index(c,r); // index of original vertex of grid
1217            if (orig_i>=0)
1218            {
1219                unsigned int new_i = vertices->size(); // index of new index of added skirt point
1220                osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
1221                (*vertices).push_back(new_v);
1222                if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
1223                for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
1224                    itr != layerToTexCoordMap.end();
1225                    ++itr)
1226                {
1227                    itr->second.first->push_back((*itr->second.first)[orig_i]);
1228                }
1229
1230                skirtDrawElements->addElement(orig_i);
1231                skirtDrawElements->addElement(new_i);
1232            }
1233            else
1234            {
1235                if (skirtDrawElements->getNumIndices()!=0)
1236                {
1237                    geometry->addPrimitiveSet(skirtDrawElements.get());
1238                    skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
1239                }
1240            }
1241        }
1242
1243        if (skirtDrawElements->getNumIndices()!=0)
1244        {
1245            geometry->addPrimitiveSet(skirtDrawElements.get());
1246        }
1247    }
1248
1249
1250    geometry->setUseDisplayList(false);
1251    geometry->setUseVertexBufferObjects(true);
1252
1253#if 0
1254    {
1255        osgUtil::VertexCacheMissVisitor vcmv_before;
1256        osgUtil::VertexCacheMissVisitor vcmv_after;
1257        osgUtil::VertexCacheVisitor vcv;
1258        osgUtil::VertexAccessOrderVisitor vaov;
1259
1260        vcmv_before.doGeometry(*geometry);
1261        vcv.optimizeVertices(*geometry);
1262        vaov.optimizeOrder(*geometry);
1263        vcmv_after.doGeometry(*geometry);
1264#if 0
1265        OSG_NOTICE<<"vcmv_before.triangles="<<vcmv_before.triangles<<std::endl;
1266        OSG_NOTICE<<"vcmv_before.misses="<<vcmv_before.misses<<std::endl;
1267        OSG_NOTICE<<"vcmv_after.misses="<<vcmv_after.misses<<std::endl;
1268        OSG_NOTICE<<std::endl;
1269#endif
1270    }
1271#endif
1272
1273    if (osgDB::Registry::instance()->getBuildKdTreesHint()==osgDB::ReaderWriter::Options::BUILD_KDTREES &&
1274        osgDB::Registry::instance()->getKdTreeBuilder())
1275    {
1276
1277        //osg::Timer_t before = osg::Timer::instance()->tick();
1278        //OSG_NOTICE<<"osgTerrain::GeometryTechnique::build kd tree"<<std::endl;
1279        osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
1280        buffer._geode->accept(*builder);
1281        //osg::Timer_t after = osg::Timer::instance()->tick();
1282        //OSG_NOTICE<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
1283    }
1284}
1285
1286void GeometryTechnique::applyColorLayers(BufferData& buffer)
1287{
1288    typedef std::map<osgTerrain::Layer*, osg::Texture*> LayerToTextureMap;
1289    LayerToTextureMap layerToTextureMap;
1290   
1291    for(unsigned int layerNum=0; layerNum<_terrainTile->getNumColorLayers(); ++layerNum)
1292    {
1293        osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(layerNum);
1294        if (!colorLayer) continue;
1295
1296        osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(colorLayer);
1297        if (switchLayer)
1298        {
1299            if (switchLayer->getActiveLayer()<0 ||
1300                static_cast<unsigned int>(switchLayer->getActiveLayer())>=switchLayer->getNumLayers())
1301            {
1302                continue;
1303            }
1304
1305            colorLayer = switchLayer->getLayer(switchLayer->getActiveLayer());
1306            if (!colorLayer) continue;
1307        }
1308
1309        osg::Image* image = colorLayer->getImage();
1310        if (!image) continue;
1311
1312        osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(colorLayer);
1313        osgTerrain::ContourLayer* contourLayer = dynamic_cast<osgTerrain::ContourLayer*>(colorLayer);
1314        if (imageLayer)
1315        {
1316            osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
1317
1318            osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(layerToTextureMap[colorLayer]);
1319            if (!texture2D)
1320            {
1321                texture2D = new osg::Texture2D;
1322                texture2D->setImage(image);
1323                texture2D->setMaxAnisotropy(16.0f);
1324                texture2D->setResizeNonPowerOfTwoHint(false);
1325
1326                texture2D->setFilter(osg::Texture::MIN_FILTER, colorLayer->getMinFilter());
1327                texture2D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter());
1328
1329                texture2D->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
1330                texture2D->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
1331
1332                bool mipMapping = !(texture2D->getFilter(osg::Texture::MIN_FILTER)==osg::Texture::LINEAR || texture2D->getFilter(osg::Texture::MIN_FILTER)==osg::Texture::NEAREST);
1333                bool s_NotPowerOfTwo = image->s()==0 || (image->s() & (image->s() - 1));
1334                bool t_NotPowerOfTwo = image->t()==0 || (image->t() & (image->t() - 1));
1335
1336                if (mipMapping && (s_NotPowerOfTwo || t_NotPowerOfTwo))
1337                {
1338                    OSG_INFO<<"Disabling mipmapping for non power of two tile size("<<image->s()<<", "<<image->t()<<")"<<std::endl;
1339                    texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
1340                }
1341
1342
1343                layerToTextureMap[colorLayer] = texture2D;
1344
1345                // OSG_NOTICE<<"Creating new ImageLayer texture "<<layerNum<<" image->s()="<<image->s()<<"  image->t()="<<image->t()<<std::endl;
1346
1347            }
1348            else
1349            {
1350                // OSG_NOTICE<<"Reusing ImageLayer texture "<<layerNum<<std::endl;
1351            }
1352
1353            stateset->setTextureAttributeAndModes(layerNum, texture2D, osg::StateAttribute::ON);
1354           
1355        }
1356        else if (contourLayer)
1357        {
1358            osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
1359
1360            osg::Texture1D* texture1D = dynamic_cast<osg::Texture1D*>(layerToTextureMap[colorLayer]);
1361            if (!texture1D)
1362            {
1363                texture1D = new osg::Texture1D;
1364                texture1D->setImage(image);
1365                texture1D->setResizeNonPowerOfTwoHint(false);
1366                texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
1367                texture1D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter());
1368
1369                layerToTextureMap[colorLayer] = texture1D;
1370            }
1371           
1372            stateset->setTextureAttributeAndModes(layerNum, texture1D, osg::StateAttribute::ON);
1373
1374        }
1375    }
1376}
1377
1378void GeometryTechnique::applyTransparency(BufferData& buffer)
1379{
1380    TerrainTile::BlendingPolicy blendingPolicy = _terrainTile->getBlendingPolicy();
1381    if (blendingPolicy == TerrainTile::INHERIT && _terrainTile->getTerrain())
1382    {
1383        OSG_INFO<<"GeometryTechnique::applyTransparency() inheriting policy from Terrain"<<std::endl;
1384        blendingPolicy = _terrainTile->getTerrain()->getBlendingPolicy();
1385    }
1386
1387    if (blendingPolicy == TerrainTile::INHERIT)
1388    {
1389        OSG_INFO<<"GeometryTechnique::applyTransparency() policy is INHERIT, defaulting to ENABLE_BLENDING_WHEN_ALPHA_PRESENT"<<std::endl;
1390        blendingPolicy = TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT;
1391    }
1392
1393    if (blendingPolicy == TerrainTile::DO_NOT_SET_BLENDING)
1394    {
1395        OSG_INFO<<"blendingPolicy == TerrainTile::DO_NOT_SET_BLENDING"<<std::endl;
1396        return;
1397    }
1398
1399    bool enableBlending = false;
1400
1401    if (blendingPolicy == TerrainTile::ENABLE_BLENDING)
1402    {
1403        OSG_INFO<<"blendingPolicy == TerrainTile::ENABLE_BLENDING"<<std::endl;
1404        enableBlending = true;
1405    }
1406    else if (blendingPolicy == TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT)
1407    {
1408        OSG_INFO<<"blendingPolicy == TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT"<<std::endl;
1409        for(unsigned int i=0; i<_terrainTile->getNumColorLayers(); ++i)
1410        {
1411            osg::Image* image = (_terrainTile->getColorLayer(i)!=0) ? _terrainTile->getColorLayer(i)->getImage() : 0;
1412            if (image)
1413            {
1414                enableBlending = image->isImageTranslucent();
1415                break;
1416            }
1417        }
1418    }
1419
1420    if (enableBlending)
1421    {
1422        osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
1423        stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
1424        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
1425    }
1426
1427}
1428
1429void GeometryTechnique::update(osgUtil::UpdateVisitor* uv)
1430{
1431    if (_terrainTile) _terrainTile->osg::Group::traverse(*uv);
1432
1433    if (_newBufferData.valid())
1434    {
1435        _currentBufferData = _newBufferData;
1436        _newBufferData = 0;
1437    }
1438}
1439
1440
1441void GeometryTechnique::cull(osgUtil::CullVisitor* cv)
1442{
1443    if (_currentBufferData.valid())
1444    {
1445        if (_currentBufferData->_transform.valid())
1446        {
1447            _currentBufferData->_transform->accept(*cv);
1448        }
1449    }
1450}
1451
1452
1453void GeometryTechnique::traverse(osg::NodeVisitor& nv)
1454{
1455    if (!_terrainTile) return;
1456
1457    // if app traversal update the frame count.
1458    if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
1459    {
1460        if (_terrainTile->getDirty()) _terrainTile->init(_terrainTile->getDirtyMask(), false);
1461
1462        osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
1463        if (uv)
1464        {
1465            update(uv);
1466            return;
1467        }
1468    }
1469    else if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
1470    {
1471        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
1472        if (cv)
1473        {
1474            cull(cv);
1475            return;
1476        }
1477    }
1478
1479
1480    if (_terrainTile->getDirty())
1481    {
1482        OSG_INFO<<"******* Doing init ***********"<<std::endl;
1483        _terrainTile->init(_terrainTile->getDirtyMask(), false);
1484    }
1485
1486    if (_currentBufferData.valid())
1487    {
1488        if (_currentBufferData->_transform.valid()) _currentBufferData->_transform->accept(nv);
1489    }
1490}
1491
1492
1493void GeometryTechnique::cleanSceneGraph()
1494{
1495}
1496
1497void GeometryTechnique::releaseGLObjects(osg::State* state) const
1498{
1499    if (_currentBufferData.valid() && _currentBufferData->_transform.valid()) _currentBufferData->_transform->releaseGLObjects(state);
1500    if (_newBufferData.valid() && _newBufferData->_transform.valid()) _newBufferData->_transform->releaseGLObjects(state);
1501}
Note: See TracBrowser for help on using the browser.