Allow OSG to recalculate terrain normals.

This commit is contained in:
James.Hester
2020-06-18 09:11:52 +01:00
committed by James Turner
parent 27907c5e6f
commit 259c1314de
4 changed files with 36 additions and 20 deletions
+3
View File
@@ -18,6 +18,9 @@ if(COMMAND cmake_policy)
if(POLICY CMP0093) if(POLICY CMP0093)
cmake_policy(SET CMP0093 NEW) cmake_policy(SET CMP0093 NEW)
endif()
if(POLICY CMP0072)
cmake_policy(SET CMP0072 NEW)
endif() endif()
endif() endif()
+15 -12
View File
@@ -72,37 +72,40 @@ void EffectGeode::releaseGLObjects(osg::State* state) const
// Generates tangent space vectors or other data from geom, as defined by effect // Generates tangent space vectors or other data from geom, as defined by effect
void EffectGeode::runGenerators(osg::Geometry *geometry) void EffectGeode::runGenerators(osg::Geometry *geometry)
{ {
if(geometry && _effect.valid()) { if(geometry && _effect.valid()) {
// Generate tangent vectors for the geometry // Generate tangent vectors for the geometry
osg::ref_ptr<osgUtil::TangentSpaceGenerator> tsg = new osgUtil::TangentSpaceGenerator; osg::ref_ptr<osgUtil::TangentSpaceGenerator> tsg = new osgUtil::TangentSpaceGenerator;
tsg->generate(geometry,0);
// Generating only tangent vector should be enough // Generating only tangent vector should be enough
// since the binormal is a cross product of normal and tangent // since the binormal is a cross product of normal and tangent
// This saves a bit of memory & memory bandwidth! // This saves a bit of memory & memory bandwidth!
int n = _effect->getGenerator(Effect::TANGENT); int n = _effect->getGenerator(Effect::TANGENT);
tsg->generate(geometry, 0); // 0 is normal_unit, but I have no idea what that is! if (n != -1 && !geometry->getVertexAttribArray(n)) {
if (n != -1 && !geometry->getVertexAttribArray(n))
#if OSG_MIN_VERSION_REQUIRED(3,1,8) #if OSG_MIN_VERSION_REQUIRED(3,1,8)
geometry->setVertexAttribArray(n, tsg->getTangentArray(), osg::Array::BIND_PER_VERTEX); geometry->setVertexAttribArray(n, tsg->getTangentArray(), osg::Array::BIND_PER_VERTEX);
#else #else
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getTangentArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE)); geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getTangentArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
#endif #endif
}
n = _effect->getGenerator(Effect::BINORMAL); n = _effect->getGenerator(Effect::BINORMAL);
if (n != -1 && !geometry->getVertexAttribArray(n)) if (n != -1 && !geometry->getVertexAttribArray(n))
#if OSG_MIN_VERSION_REQUIRED(3,1,8) #if OSG_MIN_VERSION_REQUIRED(3,1,8)
geometry->setVertexAttribArray(n, tsg->getBinormalArray(), osg::Array::BIND_PER_VERTEX); geometry->setVertexAttribArray(n, tsg->getBinormalArray(), osg::Array::BIND_PER_VERTEX);
#else #else
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getBinormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE)); geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getBinormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
#endif #endif
n = _effect->getGenerator(Effect::NORMAL); n = _effect->getGenerator(Effect::NORMAL);
if (n != -1 && !geometry->getVertexAttribArray(n)) if (n != -1 && !geometry->getVertexAttribArray(n)) {
// Provide the tsg-generated normals to the geometry
Vec4Array * new_normals = tsg->getNormalArray();
geometry->setNormalArray(new_normals,osg::Array::BIND_PER_VERTEX);
#if OSG_MIN_VERSION_REQUIRED(3,1,8) #if OSG_MIN_VERSION_REQUIRED(3,1,8)
geometry->setVertexAttribArray(n, tsg->getNormalArray(), osg::Array::BIND_PER_VERTEX); geometry->setVertexAttribArray(n, new_normals, osg::Array::BIND_PER_VERTEX);
#else #else
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getNormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE)); geometry->setVertexAttribData(n, osg::Geometry::ArrayData(new_normals, osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
#endif #endif
}
} }
} }
+10 -6
View File
@@ -348,7 +348,7 @@ public:
} }
} }
void addRandomPoints(double coverage, void addRandomPoints(double coverage,
double spacing, double spacing,
osg::Texture2D* object_mask, osg::Texture2D* object_mask,
std::vector<std::pair<SGVec3f, float> >& points) std::vector<std::pair<SGVec3f, float> >& points)
@@ -421,7 +421,9 @@ public:
} }
} }
osg::Geometry* buildGeometry(const TriangleVector& triangles, bool useVBOs) const // If include_norms is true, normals from the input vertices are added to the geometry. If false,
// they should be generated during geometry initialisation.
osg::Geometry* buildGeometry(const TriangleVector& triangles, bool useVBOs, bool include_norms) const
{ {
// Do not build anything if there is nothing in here ... // Do not build anything if there is nothing in here ...
if (empty() || triangles.empty()) if (empty() || triangles.empty())
@@ -444,8 +446,10 @@ public:
geometry->setDataVariance(osg::Object::STATIC); geometry->setDataVariance(osg::Object::STATIC);
geometry->setVertexArray(vertices); geometry->setVertexArray(vertices);
geometry->setNormalArray(normals); if (include_norms) {
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); geometry->setNormalArray(normals);
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
}
geometry->setColorArray(colors); geometry->setColorArray(colors);
geometry->setColorBinding(osg::Geometry::BIND_OVERALL); geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
if ( has_sec_tcs ) { if ( has_sec_tcs ) {
@@ -499,8 +503,8 @@ public:
return geometry; return geometry;
} }
osg::Geometry* buildGeometry(bool useVBOs) const osg::Geometry* buildGeometry(bool useVBOs, bool include_norms) const
{ return buildGeometry(getTriangles(), useVBOs); } { return buildGeometry(getTriangles(), useVBOs, include_norms); }
int getTextureIndex() const int getTextureIndex() const
{ {
+8 -2
View File
@@ -275,7 +275,6 @@ public:
//osg::Geode* geode = new osg::Geode; //osg::Geode* geode = new osg::Geode;
SGMaterialTriangleMap::const_iterator i; SGMaterialTriangleMap::const_iterator i;
for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) { for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
osg::Geometry* geometry = i->second.buildGeometry(useVBOs);
SGMaterial *mat = NULL; SGMaterial *mat = NULL;
if (matcache) { if (matcache) {
mat = matcache->find(i->first); mat = matcache->find(i->first);
@@ -288,8 +287,15 @@ public:
} else { } else {
eg->setMaterial(NULL); eg->setMaterial(NULL);
} }
eg->addDrawable(geometry); // If effect requests normal generation, we do not include terragear
// normals in the geometry
bool include_normals = true;
int n = eg->getEffect()->getGenerator(Effect::NORMAL);
if (n != -1)
include_normals = false;
osg::Geometry* geometry = i->second.buildGeometry(useVBOs, include_normals);
eg->runGenerators(geometry); // Generate extra data needed by effect eg->runGenerators(geometry); // Generate extra data needed by effect
eg->addDrawable(geometry);
if (group) { if (group) {
group->addChild(eg); group->addChild(eg);
} }