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

Revision 9388, 28.9 kB (checked in by robert, 6 years ago)

Fixed warnings

RevLine 
[7003]1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
[6385]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>
[7999]15#include <osgTerrain/TerrainTile>
[8186]16#include <osgTerrain/Terrain>
[6438]17
18#include <osgUtil/SmoothingVisitor>
19
[6443]20#include <osgDB/FileUtils>
21
[6426]22#include <osg/io_utils>
[6440]23#include <osg/Texture2D>
[6443]24#include <osg/Texture1D>
25#include <osg/TexEnvCombine>
26#include <osg/Program>
[6583]27#include <osg/Math>
[8541]28#include <osg/Timer>
[6385]29
30using namespace osgTerrain;
31
[7872]32#define NEW_COORD_CODE
33
[7111]34GeometryTechnique::GeometryTechnique():
35    _currentReadOnlyBuffer(1),
36    _currentWriteBuffer(0)
37   
[6385]38{
[7010]39    setFilterBias(0);
[7003]40    setFilterWidth(0.1);
41    setFilterMatrixAs(GAUSSIAN);
[7137]42   
[6385]43}
44
45GeometryTechnique::GeometryTechnique(const GeometryTechnique& gt,const osg::CopyOp& copyop):
[9358]46    TerrainTechnique(gt,copyop),
47    _currentReadOnlyBuffer(1),
48    _currentWriteBuffer(0)
[6385]49{
[9358]50    setFilterBias(gt._filterBias);
51    setFilterWidth(gt._filterWidth);
52    setFilterMatrix(gt._filterMatrix);
[6385]53}
54
55GeometryTechnique::~GeometryTechnique()
56{
57}
58
[7111]59void GeometryTechnique::swapBuffers()
60{
61    std::swap(_currentReadOnlyBuffer,_currentWriteBuffer);
62}
63
[7010]64void GeometryTechnique::setFilterBias(float filterBias)
65{
66    _filterBias = filterBias;
67    if (!_filterBiasUniform) _filterBiasUniform = new osg::Uniform("filterBias",_filterBias);
68    else _filterBiasUniform->set(filterBias);
69}
70
[7003]71void GeometryTechnique::setFilterWidth(float filterWidth)
72{
73    _filterWidth = filterWidth;
74    if (!_filterWidthUniform) _filterWidthUniform = new osg::Uniform("filterWidth",_filterWidth);
75    else _filterWidthUniform->set(filterWidth);
76}
77
78void GeometryTechnique::setFilterMatrix(const osg::Matrix3& matrix)
79{
80    _filterMatrix = matrix;
81    if (!_filterMatrixUniform) _filterMatrixUniform = new osg::Uniform("filterMatrix",_filterMatrix);
82    else _filterMatrixUniform->set(_filterMatrix);
83}
84
85void GeometryTechnique::setFilterMatrixAs(FilterType filterType)
86{
87    switch(filterType)
88    {
89        case(SMOOTH):
90            setFilterMatrix(osg::Matrix3(0.0, 0.5/2.5, 0.0,
91                                         0.5/2.5, 0.5/2.5, 0.5/2.5,
92                                         0.0, 0.5/2.5, 0.0));
93            break;
94        case(GAUSSIAN):
95            setFilterMatrix(osg::Matrix3(0.0, 1.0/8.0, 0.0,
96                                         1.0/8.0, 4.0/8.0, 1.0/8.0,
97                                         0.0, 1.0/8.0, 0.0));
98            break;
99        case(SHARPEN):
100            setFilterMatrix(osg::Matrix3(0.0, -1.0, 0.0,
101                                         -1.0, 5.0, -1.0,
102                                         0.0, -1.0, 0.0));
103            break;
104
105    };
106}
107
[6413]108void GeometryTechnique::init()
[6385]109{
[8367]110    osg::notify(osg::INFO)<<"Doing GeometryTechnique::init()"<<std::endl;
[6385]111   
[8000]112    if (!_terrainTile) return;
[6426]113
[7111]114    BufferData& buffer = getWriteBuffer();
[7241]115   
116    Locator* masterLocator = computeMasterLocator();
117   
118    osg::Vec3d centerModel = computeCenterModel(masterLocator);
119   
120    generateGeometry(masterLocator, centerModel);
121   
122    applyColorLayers();
123    applyTransparency();
124   
[7810]125    // smoothGeometry();
[7111]126
[7241]127    if (buffer._transform.valid()) buffer._transform->setThreadSafeRefUnref(true);
128
129    swapBuffers();
130}
131
132Locator* GeometryTechnique::computeMasterLocator()
133{
[8000]134    osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
135    osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
[6451]136
[6426]137    Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
138    Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
139   
140    Locator* masterLocator = elevationLocator ? elevationLocator : colorLocator;
141    if (!masterLocator)
142    {
143        osg::notify(osg::NOTICE)<<"Problem, no locator found in any of the terrain layers"<<std::endl;
[7241]144        return 0;
[6426]145    }
146   
[7241]147    return masterLocator;
148}
149
[7242]150osg::Vec3d GeometryTechnique::computeCenterModel(Locator* masterLocator)
[7241]151{
[7293]152    if (!masterLocator) return osg::Vec3d(0.0,0.0,0.0);
153
[7241]154    BufferData& buffer = getWriteBuffer();
155   
[8000]156    osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
157    osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
[7241]158
159    Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
160    Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
161   
[6426]162    if (!elevationLocator) elevationLocator = masterLocator;
163    if (!colorLocator) colorLocator = masterLocator;
[7241]164
[6426]165    osg::Vec3d bottomLeftNDC(DBL_MAX, DBL_MAX, 0.0);
166    osg::Vec3d topRightNDC(-DBL_MAX, -DBL_MAX, 0.0);
167   
168    if (elevationLayer)
169    {
170        if (elevationLocator!= masterLocator)
171        {
172            masterLocator->computeLocalBounds(*elevationLocator, bottomLeftNDC, topRightNDC);
173        }
174        else
175        {
176            bottomLeftNDC.x() = osg::minimum(bottomLeftNDC.x(), 0.0);
177            bottomLeftNDC.y() = osg::minimum(bottomLeftNDC.y(), 0.0);
178            topRightNDC.x() = osg::maximum(topRightNDC.x(), 1.0);
179            topRightNDC.y() = osg::maximum(topRightNDC.y(), 1.0);
180        }
181    }
182
183    if (colorLayer)
184    {
185        if (colorLocator!= masterLocator)
186        {
187            masterLocator->computeLocalBounds(*colorLocator, bottomLeftNDC, topRightNDC);
188        }
189        else
190        {
191            bottomLeftNDC.x() = osg::minimum(bottomLeftNDC.x(), 0.0);
192            bottomLeftNDC.y() = osg::minimum(bottomLeftNDC.y(), 0.0);
193            topRightNDC.x() = osg::maximum(topRightNDC.x(), 1.0);
194            topRightNDC.y() = osg::maximum(topRightNDC.y(), 1.0);
195        }
196    }
197
[7290]198    osg::notify(osg::INFO)<<"bottomLeftNDC = "<<bottomLeftNDC<<std::endl;
199    osg::notify(osg::INFO)<<"topRightNDC = "<<topRightNDC<<std::endl;
[6426]200
[7111]201    buffer._transform = new osg::MatrixTransform;
[6566]202
203    osg::Vec3d centerNDC = (bottomLeftNDC + topRightNDC)*0.5;
204    osg::Vec3d centerModel = (bottomLeftNDC + topRightNDC)*0.5;
205    masterLocator->convertLocalToModel(centerNDC, centerModel);
206   
[7111]207    buffer._transform->setMatrix(osg::Matrix::translate(centerModel));
[6566]208   
[7241]209    return centerModel;
210}
211
212void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3d& centerModel)
213{
214    BufferData& buffer = getWriteBuffer();
215   
[8000]216    osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
[7241]217
218    buffer._geode = new osg::Geode;
219    if(buffer._transform.valid())
220        buffer._transform->addChild(buffer._geode.get());
221   
[7111]222    buffer._geometry = new osg::Geometry;
[7872]223    buffer._geode->addDrawable(buffer._geometry.get());
224       
225    osg::Geometry* geometry = buffer._geometry.get();
226
[7789]227    unsigned int numRows = 20;
228    unsigned int numColumns = 20;
[6438]229   
230    if (elevationLayer)
231    {
232        numColumns = elevationLayer->getNumColumns();
233        numRows = elevationLayer->getNumRows();
234    }
235   
[8186]236    float sampleRatio = _terrainTile->getTerrain() ? _terrainTile->getTerrain()->getSampleRatio() : 1.0f;
[7989]237   
238    double i_sampleFactor = 1.0;
239    double j_sampleFactor = 1.0;
240
[8544]241    // osg::notify(osg::NOTICE)<<"Sample ratio="<<sampleRatio<<std::endl;
[8541]242
[8186]243    if (sampleRatio!=1.0f)
[7989]244    {
[8186]245   
[7989]246        unsigned int originalNumColumns = numColumns;
247        unsigned int originalNumRows = numRows;
248   
[8186]249        numColumns = std::max((unsigned int) (float(originalNumColumns)*sqrtf(sampleRatio)), 4u);
250        numRows = std::max((unsigned int) (float(originalNumRows)*sqrtf(sampleRatio)),4u);
[7989]251
252        i_sampleFactor = double(originalNumColumns-1)/double(numColumns-1);
253        j_sampleFactor = double(originalNumRows-1)/double(numRows-1);
254    }
255   
[8186]256   
[7989]257
[8000]258    bool treatBoundariesToValidDataAsDefaultValue = _terrainTile->getTreatBoundariesToValidDataAsDefaultValue();
[7290]259    osg::notify(osg::INFO)<<"TreatBoundariesToValidDataAsDefaultValue="<<treatBoundariesToValidDataAsDefaultValue<<std::endl;
[6438]260   
[7807]261    float skirtHeight = 0.0f;
262    HeightFieldLayer* hfl = dynamic_cast<HeightFieldLayer*>(elevationLayer);
263    if (hfl && hfl->getHeightField())
264    {
265        skirtHeight = hfl->getHeightField()->getSkirtHeight();
266    }
267   
[7810]268    bool createSkirt = skirtHeight != 0.0f;
269 
270    unsigned int numVerticesInBody = numColumns*numRows;
271    unsigned int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0;
272    unsigned int numVertices = numVerticesInBody+numVerticesInSkirt;
[6413]273
[6433]274    // allocate and assign vertices
[7871]275    osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
[7872]276    vertices->reserve(numVertices);
277    geometry->setVertexArray(vertices.get());
[6426]278
[6433]279    // allocate and assign normals
[7871]280    osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
[7872]281    if (normals.valid()) normals->reserve(numVertices);
282    geometry->setNormalArray(normals.get());
283    geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
[6451]284   
[6444]285
[9388]286    //float minHeight = 0.0;
[8365]287    float scaleHeight = _terrainTile->getTerrain() ? _terrainTile->getTerrain()->getVerticalScale() : 1.0f;
[6444]288
[6433]289    // allocate and assign tex coords
[7872]290    typedef std::pair< osg::ref_ptr<osg::Vec2Array>, Locator* > TexCoordLocatorPair;
291    typedef std::map< Layer*, TexCoordLocatorPair > LayerToTexCoordMap;
[6451]292
[7872]293    LayerToTexCoordMap layerToTexCoordMap;
[8000]294    for(unsigned int layerNum=0; layerNum<_terrainTile->getNumColorLayers(); ++layerNum)
[6451]295    {
[8000]296        osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(layerNum);
[7872]297        if (colorLayer)
[6451]298        {
[7872]299            LayerToTexCoordMap::iterator itr = layerToTexCoordMap.find(colorLayer);
300            if (itr!=layerToTexCoordMap.end())
301            {
302                geometry->setTexCoordArray(layerNum, itr->second.first.get());
303            }
304            else
305            {
[8845]306
307                Locator* locator = colorLayer->getLocator();
308                if (!locator)
309                {           
310                    osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(colorLayer);
311                    if (switchLayer)
312                    {
313                        if (switchLayer->getActiveLayer()>=0 &&
[9388]314                            static_cast<unsigned int>(switchLayer->getActiveLayer())<switchLayer->getNumLayers() &&
[8845]315                            switchLayer->getLayer(switchLayer->getActiveLayer()))
316                        {
317                            locator = switchLayer->getLayer(switchLayer->getActiveLayer())->getLocator();
318                        }
319                    }
320                }           
321           
[7872]322                TexCoordLocatorPair& tclp = layerToTexCoordMap[colorLayer];
323                tclp.first = new osg::Vec2Array;
324                tclp.first->reserve(numVertices);
[8845]325                tclp.second = locator ? locator : masterLocator;
[7872]326                geometry->setTexCoordArray(layerNum, tclp.first.get());
327            }
[6451]328        }
329    }
330
[7872]331    osg::ref_ptr<osg::FloatArray> elevations = new osg::FloatArray;
[7871]332    if (elevations.valid()) elevations->reserve(numVertices);
[6440]333       
[7872]334
[6433]335    // allocate and assign color
[7871]336    osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
337    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
[6433]338   
[7872]339    geometry->setColorArray(colors.get());
340    geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
[6651]341
342
343    typedef std::vector<int> Indices;
[7810]344    Indices indices(numVertices, -1);
[6508]345   
[6433]346    // populate vertex and tex coord arrays
[7810]347    unsigned int i, j;
[6433]348    for(j=0; j<numRows; ++j)
349    {
[7810]350        for(i=0; i<numColumns; ++i)
[6433]351        {
352            unsigned int iv = j*numColumns + i;
[6477]353            osg::Vec3d ndc( ((double)i)/(double)(numColumns-1), ((double)j)/(double)(numRows-1), 0.0);
[6651]354     
355            bool validValue = true;
356     
[6438]357           
[7989]358            unsigned int i_equiv = i_sampleFactor==1.0 ? i : (unsigned int) (double(i)*i_sampleFactor);
359            unsigned int j_equiv = i_sampleFactor==1.0 ? j : (unsigned int) (double(j)*j_sampleFactor);
360           
[6438]361            if (elevationLayer)
362            {
363                float value = 0.0f;
[7989]364                validValue = elevationLayer->getValidValue(i_equiv,j_equiv, value);
[7290]365                // osg::notify(osg::INFO)<<"i="<<i<<" j="<<j<<" z="<<value<<std::endl;
[8365]366                ndc.z() = value*scaleHeight;
[6438]367            }
368           
[6651]369            if (validValue)
370            {
[7871]371                indices[iv] = vertices->size();
[6651]372           
373                osg::Vec3d model;
374                masterLocator->convertLocalToModel(ndc, model);
[6433]375
[7871]376                (*vertices).push_back(model - centerModel);
[6433]377
[7872]378                for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
379                    itr != layerToTexCoordMap.end();
380                    ++itr)
[6440]381                {
[7872]382                    osg::Vec2Array* texcoords = itr->second.first.get();
383                    Locator* colorLocator = itr->second.second;
384                    if (colorLocator != masterLocator)
[6651]385                    {
386                        osg::Vec3d color_ndc;
387                        Locator::convertLocalCoordBetween(*masterLocator, ndc, *colorLocator, color_ndc);
[7871]388                        (*texcoords).push_back(osg::Vec2(color_ndc.x(), color_ndc.y()));
[6651]389                    }
390                    else
391                    {
[7871]392                        (*texcoords).push_back(osg::Vec2(ndc.x(), ndc.y()));
[6651]393                    }
[6440]394                }
[6651]395
[7871]396                if (elevations.valid())
[6440]397                {
[8365]398                    (*elevations).push_back(ndc.z());
[6440]399                }
400
[6651]401                // compute the local normal
[7810]402                osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0;
[6651]403                osg::Vec3d model_one;
404                masterLocator->convertLocalToModel(ndc_one, model_one);
405                model_one = model_one - model;
406                model_one.normalize();           
[7871]407                (*normals).push_back(model_one);
[6440]408            }
[6651]409            else
[6444]410            {
[6651]411                indices[iv] = -1;
[6444]412            }
[6433]413        }
414    }
[7810]415   
[6433]416    // populate primitive sets
[7871]417//    bool optimizeOrientations = elevations!=0;
[6594]418    bool swapOrientation = !(masterLocator->orientationOpenGL());
[6583]419   
[7818]420    osg::ref_ptr<osg::DrawElementsUInt> elements = new osg::DrawElementsUInt(GL_TRIANGLES);
[6651]421    elements->reserve((numRows-1) * (numColumns-1) * 6);
422
[7872]423    geometry->addPrimitiveSet(elements.get());
[6651]424
[7810]425    for(j=0; j<numRows-1; ++j)
[6433]426    {
[7810]427        for(i=0; i<numColumns-1; ++i)
[6433]428        {
[6651]429            int i00;
430            int i01;
431            if (swapOrientation)
[6583]432            {
[6651]433                i01 = j*numColumns + i;
434                i00 = i01+numColumns;
[6583]435            }
[6651]436            else
437            {
438                i00 = j*numColumns + i;
439                i01 = i00+numColumns;
440            }
[6583]441
[6651]442            int i10 = i00+1;
443            int i11 = i01+1;
[6583]444
[6651]445            // remap indices to final vertex positions
446            i00 = indices[i00];
447            i01 = indices[i01];
448            i10 = indices[i10];
449            i11 = indices[i11];
450           
451            unsigned int numValid = 0;
452            if (i00>=0) ++numValid;
453            if (i01>=0) ++numValid;
454            if (i10>=0) ++numValid;
455            if (i11>=0) ++numValid;
456           
457            if (numValid==4)
[6583]458            {
[7871]459                float e00 = (*elevations)[i00];
460                float e10 = (*elevations)[i10];
461                float e01 = (*elevations)[i01];
462                float e11 = (*elevations)[i11];
[6651]463
[6583]464                if (fabsf(e00-e11)<fabsf(e01-e10))
465                {
466                    elements->push_back(i01);
467                    elements->push_back(i00);
468                    elements->push_back(i11);
469
470                    elements->push_back(i00);
471                    elements->push_back(i10);
472                    elements->push_back(i11);
473                }
474                else
475                {
476                    elements->push_back(i01);
477                    elements->push_back(i00);
478                    elements->push_back(i10);
479
480                    elements->push_back(i01);
481                    elements->push_back(i10);
482                    elements->push_back(i11);
483                }
484            }
[6651]485            else if (numValid==3)
486            {
487                if (i00>=0) elements->push_back(i00);
488                if (i01>=0) elements->push_back(i01);
489                if (i11>=0) elements->push_back(i11);
490                if (i10>=0) elements->push_back(i10);
491            }
492           
[6583]493        }
[6433]494    }
[7241]495   
[7871]496    osg::ref_ptr<osg::Vec3Array> skirtVectors = new osg::Vec3Array((*normals));
[7810]497   
498    if (elevationLayer)
499    {
500        smoothGeometry();
501       
[7872]502        normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
[7810]503       
[7871]504        if (!normals) createSkirt = false;
[7810]505    }
506
507    if (createSkirt)
508    {
509        osg::ref_ptr<osg::DrawElementsUShort> skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
510
511        // create bottom skirt vertices
512        int r,c;
513        r=0;
[8222]514        for(c=0;c<static_cast<int>(numColumns);++c)
[7810]515        {
516            int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
517            if (orig_i>=0)
518            {
[7871]519                unsigned int new_i = vertices->size(); // index of new index of added skirt point
520                osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
521                (*vertices).push_back(new_v);
522                if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
[7872]523
524                for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
525                    itr != layerToTexCoordMap.end();
526                    ++itr)
527                {
528                    itr->second.first->push_back((*itr->second.first)[orig_i]);
529                }
[7810]530               
531                skirtDrawElements->push_back(orig_i);
532                skirtDrawElements->push_back(new_i);
533            }
534            else
535            {
536                if (!skirtDrawElements->empty())
537                {
[7872]538                    geometry->addPrimitiveSet(skirtDrawElements.get());
[7810]539                    skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
540                }
541               
542            }
543        }
544
545        if (!skirtDrawElements->empty())
546        {
[7872]547            geometry->addPrimitiveSet(skirtDrawElements.get());
[7810]548            skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
549        }
550
551        // create right skirt vertices
552        c=numColumns-1;
[8222]553        for(r=0;r<static_cast<int>(numRows);++r)
[7810]554        {
555            int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
556            if (orig_i>=0)
557            {
[7871]558                unsigned int new_i = vertices->size(); // index of new index of added skirt point
559                osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
560                (*vertices).push_back(new_v);
561                if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
[7872]562                for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
563                    itr != layerToTexCoordMap.end();
564                    ++itr)
565                {
566                    itr->second.first->push_back((*itr->second.first)[orig_i]);
567                }
[7810]568               
569                skirtDrawElements->push_back(orig_i);
570                skirtDrawElements->push_back(new_i);
571            }
572            else
573            {
574                if (!skirtDrawElements->empty())
575                {
[7872]576                    geometry->addPrimitiveSet(skirtDrawElements.get());
[7810]577                    skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
578                }
579               
580            }
581        }
582
583        if (!skirtDrawElements->empty())
584        {
[7872]585            geometry->addPrimitiveSet(skirtDrawElements.get());
[7810]586            skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
587        }
588
589        // create top skirt vertices
590        r=numRows-1;
591        for(c=numColumns-1;c>=0;--c)
592        {
593            int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
594            if (orig_i>=0)
595            {
[7871]596                unsigned int new_i = vertices->size(); // index of new index of added skirt point
597                osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
598                (*vertices).push_back(new_v);
599                if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
[7872]600                for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
601                    itr != layerToTexCoordMap.end();
602                    ++itr)
603                {
604                    itr->second.first->push_back((*itr->second.first)[orig_i]);
605                }
[7810]606               
607                skirtDrawElements->push_back(orig_i);
608                skirtDrawElements->push_back(new_i);
609            }
610            else
611            {
612                if (!skirtDrawElements->empty())
613                {
[7872]614                    geometry->addPrimitiveSet(skirtDrawElements.get());
[7810]615                    skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
616                }
617               
618            }
619        }
620
621        if (!skirtDrawElements->empty())
622        {
[7872]623            geometry->addPrimitiveSet(skirtDrawElements.get());
[7810]624            skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
625        }
626
627        // create left skirt vertices
628        c=0;
629        for(r=numRows-1;r>=0;--r)
630        {
631            int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid
632            if (orig_i>=0)
633            {
[7871]634                unsigned int new_i = vertices->size(); // index of new index of added skirt point
635                osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
636                (*vertices).push_back(new_v);
637                if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
[7872]638                for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
639                    itr != layerToTexCoordMap.end();
640                    ++itr)
641                {
642                    itr->second.first->push_back((*itr->second.first)[orig_i]);
643                }
[7810]644               
645                skirtDrawElements->push_back(orig_i);
646                skirtDrawElements->push_back(new_i);
647            }
648            else
649            {
650                if (!skirtDrawElements->empty())
651                {
[7872]652                    geometry->addPrimitiveSet(skirtDrawElements.get());
[7810]653                    skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
654                }
655               
656            }
657        }
658
659        if (!skirtDrawElements->empty())
660        {
[7872]661            geometry->addPrimitiveSet(skirtDrawElements.get());
[7810]662            skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
663        }
664    }
665
666
[7989]667    //geometry->setUseDisplayList(false);
[7872]668    geometry->setUseVertexBufferObjects(true);
[8535]669   
670   
671    if (osgDB::Registry::instance()->getBuildKdTreesHint()==osgDB::ReaderWriter::Options::BUILD_KDTREES &&
672        osgDB::Registry::instance()->getKdTreeBuilder())
673    {
[8541]674   
675       
[8544]676        //osg::Timer_t before = osg::Timer::instance()->tick();
[8535]677        //osg::notify(osg::NOTICE)<<"osgTerrain::GeometryTechnique::build kd tree"<<std::endl;
[8541]678        osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
679        buffer._geode->accept(*builder);
[8544]680        //osg::Timer_t after = osg::Timer::instance()->tick();
681        //osg::notify(osg::NOTICE)<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
[8535]682    }
[7241]683}
[6433]684
[7241]685void GeometryTechnique::applyColorLayers()
686{
687    BufferData& buffer = getWriteBuffer();
[7872]688
689    typedef std::map<osgTerrain::Layer*, osg::Texture*> LayerToTextureMap;
690    LayerToTextureMap layerToTextureMap;
[7241]691   
[8000]692    for(unsigned int layerNum=0; layerNum<_terrainTile->getNumColorLayers(); ++layerNum)
[6440]693    {
[8000]694        osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(layerNum);
[7872]695        if (!colorLayer) continue;
696
[8845]697        osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(colorLayer);
698        if (switchLayer)
699        {
[9388]700            if (switchLayer->getActiveLayer()<0 ||
701                static_cast<unsigned int>(switchLayer->getActiveLayer())>=switchLayer->getNumLayers())
[8845]702            {
703                continue;
704            }
705           
706            colorLayer = switchLayer->getLayer(switchLayer->getActiveLayer());
707            if (!colorLayer) continue;
708        }
709
[7872]710        osg::Image* image = colorLayer->getImage();
711        if (!image) continue;
712
[6440]713        osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(colorLayer);
[7872]714        osgTerrain::ContourLayer* contourLayer = dynamic_cast<osgTerrain::ContourLayer*>(colorLayer);
[6440]715        if (imageLayer)
716        {
[7111]717            osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
[6443]718
[7872]719            osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(layerToTextureMap[colorLayer]);
720            if (!texture2D)
[6451]721            {
[7872]722                texture2D = new osg::Texture2D;
723                texture2D->setImage(image);
[8009]724                texture2D->setMaxAnisotropy(16.0f);
[7872]725                texture2D->setResizeNonPowerOfTwoHint(false);
[9037]726
727                texture2D->setFilter(osg::Texture::MIN_FILTER, colorLayer->getMinFilter());
728                texture2D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter());
729               
[7872]730                texture2D->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
731                texture2D->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
[6444]732
[7872]733                layerToTextureMap[colorLayer] = texture2D;
[6444]734
[9037]735                // osg::notify(osg::NOTICE)<<"Creating new ImageLayer texture "<<layerNum<<" image->s()="<<image->s()<<"  image->t()="<<image->t()<<std::endl;
[6443]736
[6451]737            }
738            else
739            {
[7872]740                // osg::notify(osg::NOTICE)<<"Reusing ImageLayer texture "<<layerNum<<std::endl;
[6451]741            }
742
[7872]743            stateset->setTextureAttributeAndModes(layerNum, texture2D, osg::StateAttribute::ON);
744           
745        }
746        else if (contourLayer)
747        {
748            osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
749
750            osg::Texture1D* texture1D = dynamic_cast<osg::Texture1D*>(layerToTextureMap[colorLayer]);
751            if (!texture1D)
[6451]752            {
[7872]753                texture1D = new osg::Texture1D;
754                texture1D->setImage(image);
755                texture1D->setResizeNonPowerOfTwoHint(false);
756                texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
[9037]757                texture1D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter());
[7872]758
759                layerToTextureMap[colorLayer] = texture1D;
[6451]760            }
[7872]761           
762            stateset->setTextureAttributeAndModes(layerNum, texture1D, osg::StateAttribute::ON);
[6451]763
[6444]764        }
[6440]765    }
[7241]766}
767
768void GeometryTechnique::applyTransparency()
769{
770    BufferData& buffer = getWriteBuffer();
[6640]771   
[7241]772    bool containsTransparency = false;
[8000]773    for(unsigned int i=0; i<_terrainTile->getNumColorLayers(); ++i)
[7241]774    {
[8000]775        osg::Image* image = _terrainTile->getColorLayer(i)->getImage();
[7872]776        if (image)
[7789]777        {
[7872]778            containsTransparency = image->isImageTranslucent();
779            break;
780        }       
[7241]781    }
782   
[6640]783    if (containsTransparency)
784    {
[7111]785        osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
[6640]786        stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
787        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
788    }
[6440]789
[7241]790}
[6461]791
[7241]792void GeometryTechnique::smoothGeometry()
793{
794    BufferData& buffer = getWriteBuffer();
795   
[7111]796    if (buffer._geometry.valid())
[6564]797    {
798        osgUtil::SmoothingVisitor smoother;
[7111]799        smoother.smooth(*buffer._geometry);
[6564]800    }
[6385]801}
802
[7068]803void GeometryTechnique::update(osgUtil::UpdateVisitor* uv)
[6385]804{
[8000]805    if (_terrainTile) _terrainTile->osg::Group::traverse(*uv);
[6385]806}
807
808
[7068]809void GeometryTechnique::cull(osgUtil::CullVisitor* cv)
[6385]810{
[7111]811    BufferData& buffer = getReadOnlyBuffer();
812
[7068]813#if 0
[8000]814    if (buffer._terrainTile) buffer._terrainTile->osg::Group::traverse(*cv);
[7068]815#else
[7111]816    if (buffer._transform.valid())
[6385]817    {
[7111]818        buffer._transform->accept(*cv);
[6385]819    }
[7068]820#endif   
[6385]821}
[6413]822
[7132]823
824void GeometryTechnique::traverse(osg::NodeVisitor& nv)
825{
[8000]826    if (!_terrainTile) return;
[7132]827
828    // if app traversal update the frame count.
829    if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
830    {
[8367]831        if (_terrainTile->getDirty()) _terrainTile->init();
[7132]832
833        osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
834        if (uv)
835        {
836            update(uv);
837            return;
838        }       
839       
840    }
841    else if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
842    {
843        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
844        if (cv)
845        {
846            cull(cv);
847            return;
848        }
849    }
850
851
[8367]852    if (_terrainTile->getDirty())
[7137]853    {
[7290]854        osg::notify(osg::INFO)<<"******* Doing init ***********"<<std::endl;
[8000]855        _terrainTile->init();
[7137]856    }
[7132]857
858    BufferData& buffer = getReadOnlyBuffer();
859    if (buffer._transform.valid()) buffer._transform->accept(nv);
860}
861
862
[6413]863void GeometryTechnique::cleanSceneGraph()
864{
865}
Note: See TracBrowser for help on using the browser.