From 574582f20613ae4a858306feb11108c564fb62a5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 18 Jan 2008 16:36:05 +0000 Subject: [PATCH] Added support for rendering skirts into osgTerrain::GeometryTechinque --- src/osgTerrain/GeometryTechnique.cpp | 177 +++++++++++++++++++++++++-- 1 file changed, 164 insertions(+), 13 deletions(-) diff --git a/src/osgTerrain/GeometryTechnique.cpp b/src/osgTerrain/GeometryTechnique.cpp index b6bd86904..6687188ab 100644 --- a/src/osgTerrain/GeometryTechnique.cpp +++ b/src/osgTerrain/GeometryTechnique.cpp @@ -116,7 +116,7 @@ void GeometryTechnique::init() applyTransparency(); - smoothGeometry(); + // smoothGeometry(); if (buffer._transform.valid()) buffer._transform->setThreadSafeRefUnref(true); @@ -248,11 +248,11 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 skirtHeight = hfl->getHeightField()->getSkirtHeight(); } - bool requiresSkirt = skirtHeight != 0.0f; - // osg::notify(osg::NOTICE)<<"Skirt height = "< Indices; - Indices indices(numColumns*numRows, -1); + Indices indices(numVertices, -1); // populate vertex and tex coord arrays - unsigned int j; + unsigned int i, j; for(j=0; jconvertLocalToModel(ndc_one, model_one); model_one = model_one - model; @@ -384,7 +384,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 } } } - + // populate primitive sets // bool optimizeOrientations = _elevations!=0; bool swapOrientation = !(masterLocator->orientationOpenGL()); @@ -394,9 +394,9 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 if (buffer._geometry.valid()) buffer._geometry->addPrimitiveSet(elements); - for(unsigned int j=0; j skirtVectors = new osg::Vec3Array((*_normals)); + + if (elevationLayer) + { + smoothGeometry(); + + _normals = dynamic_cast(buffer._geometry->getNormalArray()); + + if (!_normals) createSkirt = false; + } + + if (createSkirt) + { + osg::ref_ptr skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + + // create bottom skirt vertices + int r,c; + r=0; + for(c=0;c=0) + { + unsigned int new_i = _vertices->size(); // index of new index of added skirt point + osg::Vec3 new_v = (*_vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight; + (*_vertices).push_back(new_v); + (*_normals).push_back((*_normals)[orig_i]); + (*_texcoords).push_back((*_texcoords)[orig_i]); + + skirtDrawElements->push_back(orig_i); + skirtDrawElements->push_back(new_i); + } + else + { + if (!skirtDrawElements->empty()) + { + buffer._geometry->addPrimitiveSet(skirtDrawElements.get()); + skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + } + + } + } + + if (!skirtDrawElements->empty()) + { + buffer._geometry->addPrimitiveSet(skirtDrawElements.get()); + skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + } + + // create right skirt vertices + c=numColumns-1; + for(r=0;r=0) + { + unsigned int new_i = _vertices->size(); // index of new index of added skirt point + osg::Vec3 new_v = (*_vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight; + (*_vertices).push_back(new_v); + (*_normals).push_back((*_normals)[orig_i]); + (*_texcoords).push_back((*_texcoords)[orig_i]); + + skirtDrawElements->push_back(orig_i); + skirtDrawElements->push_back(new_i); + } + else + { + if (!skirtDrawElements->empty()) + { + buffer._geometry->addPrimitiveSet(skirtDrawElements.get()); + skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + } + + } + } + + if (!skirtDrawElements->empty()) + { + buffer._geometry->addPrimitiveSet(skirtDrawElements.get()); + skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + } + + // create top skirt vertices + r=numRows-1; + for(c=numColumns-1;c>=0;--c) + { + int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid + if (orig_i>=0) + { + unsigned int new_i = _vertices->size(); // index of new index of added skirt point + osg::Vec3 new_v = (*_vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight; + (*_vertices).push_back(new_v); + (*_normals).push_back((*_normals)[orig_i]); + (*_texcoords).push_back((*_texcoords)[orig_i]); + + skirtDrawElements->push_back(orig_i); + skirtDrawElements->push_back(new_i); + } + else + { + if (!skirtDrawElements->empty()) + { + buffer._geometry->addPrimitiveSet(skirtDrawElements.get()); + skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + } + + } + } + + if (!skirtDrawElements->empty()) + { + buffer._geometry->addPrimitiveSet(skirtDrawElements.get()); + skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + } + + // create left skirt vertices + c=0; + for(r=numRows-1;r>=0;--r) + { + int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid + if (orig_i>=0) + { + unsigned int new_i = _vertices->size(); // index of new index of added skirt point + osg::Vec3 new_v = (*_vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight; + (*_vertices).push_back(new_v); + (*_normals).push_back((*_normals)[orig_i]); + (*_texcoords).push_back((*_texcoords)[orig_i]); + + skirtDrawElements->push_back(orig_i); + skirtDrawElements->push_back(new_i); + } + else + { + if (!skirtDrawElements->empty()) + { + buffer._geometry->addPrimitiveSet(skirtDrawElements.get()); + skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + } + + } + } + + if (!skirtDrawElements->empty()) + { + buffer._geometry->addPrimitiveSet(skirtDrawElements.get()); + skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP); + } + } + + + // if (_terrainGeometry.valid()) _terrainGeometry->setUseDisplayList(false); if (buffer._geometry.valid()) buffer._geometry->setUseVertexBufferObjects(true); }