Allow OSG to recalculate terrain normals.
This commit is contained in:
committed by
James Turner
parent
27907c5e6f
commit
259c1314de
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user