Bug fix: Check for a valid effect before dereference

Reported on the dev list as...
Crash with custom scenery
This commit is contained in:
Scott Giese
2020-07-03 13:23:23 -05:00
parent 6d8e9e5bbc
commit a3ffc77a9d
+40 -34
View File
@@ -18,7 +18,7 @@ typedef std::map<std::string,SGTexturedTriangleBin> SGMaterialTriangleMap;
// Class handling the initial BTG loading : should probably be in its own file // Class handling the initial BTG loading : should probably be in its own file
// it is very closely coupled with SGTexturedTriangleBin.hxx // it is very closely coupled with SGTexturedTriangleBin.hxx
// it was used to load fans, strips, and triangles. // it was used to load fans, strips, and triangles.
// WS2.0 no longer uses fans or strips, but people still use ws1.0, so we need // WS2.0 no longer uses fans or strips, but people still use ws1.0, so we need
// to keep this functionality. // to keep this functionality.
class SGTileGeometryBin : public osg::Referenced { class SGTileGeometryBin : public osg::Referenced {
public: public:
@@ -48,11 +48,11 @@ public:
return material->get_tex_coord_scale(); return material->get_tex_coord_scale();
} }
static void static void
addTriangleGeometry(SGTexturedTriangleBin& triangles, addTriangleGeometry(SGTexturedTriangleBin& triangles,
const SGBinObject& obj, unsigned grp, const SGBinObject& obj, unsigned grp,
const SGVec2f& tc0Scale, const SGVec2f& tc0Scale,
const SGVec2f& tc1Scale) const SGVec2f& tc1Scale)
{ {
const std::vector<SGVec3d>& vertices(obj.get_wgs84_nodes()); const std::vector<SGVec3d>& vertices(obj.get_wgs84_nodes());
@@ -61,22 +61,22 @@ public:
const int_list& tris_v(obj.get_tris_v()[grp]); const int_list& tris_v(obj.get_tris_v()[grp]);
const int_list& tris_n(obj.get_tris_n()[grp]); const int_list& tris_n(obj.get_tris_n()[grp]);
const tci_list& tris_tc(obj.get_tris_tcs()[grp]); const tci_list& tris_tc(obj.get_tris_tcs()[grp]);
bool num_norms_is_num_verts = true; bool num_norms_is_num_verts = true;
if (tris_v.size() != tris_n.size()) { if (tris_v.size() != tris_n.size()) {
// If the normal indices do not match, they should be inmplicitly // If the normal indices do not match, they should be inmplicitly
// the same than the vertex indices. // the same than the vertex indices.
num_norms_is_num_verts = false; num_norms_is_num_verts = false;
} }
if ( !tris_tc[1].empty() ) { if ( !tris_tc[1].empty() ) {
triangles.hasSecondaryTexCoord(true); triangles.hasSecondaryTexCoord(true);
} }
for (unsigned i = 2; i < tris_v.size(); i += 3) { for (unsigned i = 2; i < tris_v.size(); i += 3) {
SGVertNormTex v0; SGVertNormTex v0;
v0.SetVertex( toVec3f(vertices[tris_v[i-2]]) ); v0.SetVertex( toVec3f(vertices[tris_v[i-2]]) );
v0.SetNormal( num_norms_is_num_verts ? normals[tris_n[i-2]] : v0.SetNormal( num_norms_is_num_verts ? normals[tris_n[i-2]] :
normals[tris_v[i-2]] ); normals[tris_v[i-2]] );
v0.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i-2) ); v0.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i-2) );
if (!tris_tc[1].empty()) { if (!tris_tc[1].empty()) {
@@ -84,7 +84,7 @@ public:
} }
SGVertNormTex v1; SGVertNormTex v1;
v1.SetVertex( toVec3f(vertices[tris_v[i-1]]) ); v1.SetVertex( toVec3f(vertices[tris_v[i-1]]) );
v1.SetNormal( num_norms_is_num_verts ? normals[tris_n[i-1]] : v1.SetNormal( num_norms_is_num_verts ? normals[tris_n[i-1]] :
normals[tris_v[i-1]] ); normals[tris_v[i-1]] );
v1.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i-1) ); v1.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i-1) );
if (!tris_tc[1].empty()) { if (!tris_tc[1].empty()) {
@@ -92,13 +92,13 @@ public:
} }
SGVertNormTex v2; SGVertNormTex v2;
v2.SetVertex( toVec3f(vertices[tris_v[i]]) ); v2.SetVertex( toVec3f(vertices[tris_v[i]]) );
v2.SetNormal( num_norms_is_num_verts ? normals[tris_n[i]] : v2.SetNormal( num_norms_is_num_verts ? normals[tris_n[i]] :
normals[tris_v[i]] ); normals[tris_v[i]] );
v2.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i) ); v2.SetTexCoord( 0, getTexCoord(texCoords, tris_tc[0], tc0Scale, i) );
if (!tris_tc[1].empty()) { if (!tris_tc[1].empty()) {
v2.SetTexCoord( 1, getTexCoord(texCoords, tris_tc[1], tc1Scale, i) ); v2.SetTexCoord( 1, getTexCoord(texCoords, tris_tc[1], tc1Scale, i) );
} }
triangles.insert(v0, v1, v2); triangles.insert(v0, v1, v2);
} }
} }
@@ -106,7 +106,7 @@ public:
static void static void
addStripGeometry(SGTexturedTriangleBin& triangles, addStripGeometry(SGTexturedTriangleBin& triangles,
const SGBinObject& obj, unsigned grp, const SGBinObject& obj, unsigned grp,
const SGVec2f& tc0Scale, const SGVec2f& tc0Scale,
const SGVec2f& tc1Scale) const SGVec2f& tc1Scale)
{ {
const std::vector<SGVec3d>& vertices(obj.get_wgs84_nodes()); const std::vector<SGVec3d>& vertices(obj.get_wgs84_nodes());
@@ -115,22 +115,22 @@ public:
const int_list& strips_v(obj.get_strips_v()[grp]); const int_list& strips_v(obj.get_strips_v()[grp]);
const int_list& strips_n(obj.get_strips_n()[grp]); const int_list& strips_n(obj.get_strips_n()[grp]);
const tci_list& strips_tc(obj.get_strips_tcs()[grp]); const tci_list& strips_tc(obj.get_strips_tcs()[grp]);
bool num_norms_is_num_verts = true; bool num_norms_is_num_verts = true;
if (strips_v.size() != strips_n.size()) { if (strips_v.size() != strips_n.size()) {
// If the normal indices do not match, they should be inmplicitly // If the normal indices do not match, they should be inmplicitly
// the same than the vertex indices. // the same than the vertex indices.
num_norms_is_num_verts = false; num_norms_is_num_verts = false;
} }
if ( !strips_tc[1].empty() ) { if ( !strips_tc[1].empty() ) {
triangles.hasSecondaryTexCoord(true); triangles.hasSecondaryTexCoord(true);
} }
for (unsigned i = 2; i < strips_v.size(); ++i) { for (unsigned i = 2; i < strips_v.size(); ++i) {
SGVertNormTex v0; SGVertNormTex v0;
v0.SetVertex( toVec3f(vertices[strips_v[i-2]]) ); v0.SetVertex( toVec3f(vertices[strips_v[i-2]]) );
v0.SetNormal( num_norms_is_num_verts ? normals[strips_n[i-2]] : v0.SetNormal( num_norms_is_num_verts ? normals[strips_n[i-2]] :
normals[strips_v[i-2]] ); normals[strips_v[i-2]] );
v0.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[0], tc0Scale, i-2) ); v0.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[0], tc0Scale, i-2) );
if (!strips_tc[1].empty()) { if (!strips_tc[1].empty()) {
@@ -138,7 +138,7 @@ public:
} }
SGVertNormTex v1; SGVertNormTex v1;
v1.SetVertex( toVec3f(vertices[strips_v[i-1]]) ); v1.SetVertex( toVec3f(vertices[strips_v[i-1]]) );
v1.SetNormal( num_norms_is_num_verts ? normals[strips_n[i-1]] : v1.SetNormal( num_norms_is_num_verts ? normals[strips_n[i-1]] :
normals[strips_v[i-1]] ); normals[strips_v[i-1]] );
v1.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[1], tc0Scale, i-1) ); v1.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[1], tc0Scale, i-1) );
if (!strips_tc[1].empty()) { if (!strips_tc[1].empty()) {
@@ -146,7 +146,7 @@ public:
} }
SGVertNormTex v2; SGVertNormTex v2;
v2.SetVertex( toVec3f(vertices[strips_v[i]]) ); v2.SetVertex( toVec3f(vertices[strips_v[i]]) );
v2.SetNormal( num_norms_is_num_verts ? normals[strips_n[i]] : v2.SetNormal( num_norms_is_num_verts ? normals[strips_n[i]] :
normals[strips_v[i]] ); normals[strips_v[i]] );
v2.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[0], tc0Scale, i) ); v2.SetTexCoord( 0, getTexCoord(texCoords, strips_tc[0], tc0Scale, i) );
if (!strips_tc[1].empty()) { if (!strips_tc[1].empty()) {
@@ -162,7 +162,7 @@ public:
static void static void
addFanGeometry(SGTexturedTriangleBin& triangles, addFanGeometry(SGTexturedTriangleBin& triangles,
const SGBinObject& obj, unsigned grp, const SGBinObject& obj, unsigned grp,
const SGVec2f& tc0Scale, const SGVec2f& tc0Scale,
const SGVec2f& tc1Scale) const SGVec2f& tc1Scale)
{ {
const std::vector<SGVec3d>& vertices(obj.get_wgs84_nodes()); const std::vector<SGVec3d>& vertices(obj.get_wgs84_nodes());
@@ -171,21 +171,21 @@ public:
const int_list& fans_v(obj.get_fans_v()[grp]); const int_list& fans_v(obj.get_fans_v()[grp]);
const int_list& fans_n(obj.get_fans_n()[grp]); const int_list& fans_n(obj.get_fans_n()[grp]);
const tci_list& fans_tc(obj.get_fans_tcs()[grp]); const tci_list& fans_tc(obj.get_fans_tcs()[grp]);
bool num_norms_is_num_verts = true; bool num_norms_is_num_verts = true;
if (fans_v.size() != fans_n.size()) { if (fans_v.size() != fans_n.size()) {
// If the normal indices do not match, they should be inmplicitly // If the normal indices do not match, they should be inmplicitly
// the same than the vertex indices. // the same than the vertex indices.
num_norms_is_num_verts = false; num_norms_is_num_verts = false;
} }
if ( !fans_tc[1].empty() ) { if ( !fans_tc[1].empty() ) {
triangles.hasSecondaryTexCoord(true); triangles.hasSecondaryTexCoord(true);
} }
SGVertNormTex v0; SGVertNormTex v0;
v0.SetVertex( toVec3f(vertices[fans_v[0]]) ); v0.SetVertex( toVec3f(vertices[fans_v[0]]) );
v0.SetNormal( num_norms_is_num_verts ? normals[fans_n[0]] : v0.SetNormal( num_norms_is_num_verts ? normals[fans_n[0]] :
normals[fans_v[0]] ); normals[fans_v[0]] );
v0.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, 0) ); v0.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, 0) );
if (!fans_tc[1].empty()) { if (!fans_tc[1].empty()) {
@@ -193,7 +193,7 @@ public:
} }
SGVertNormTex v1; SGVertNormTex v1;
v1.SetVertex( toVec3f(vertices[fans_v[1]]) ); v1.SetVertex( toVec3f(vertices[fans_v[1]]) );
v1.SetNormal( num_norms_is_num_verts ? normals[fans_n[1]] : v1.SetNormal( num_norms_is_num_verts ? normals[fans_n[1]] :
normals[fans_v[1]] ); normals[fans_v[1]] );
v1.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, 1) ); v1.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, 1) );
if (!fans_tc[1].empty()) { if (!fans_tc[1].empty()) {
@@ -202,7 +202,7 @@ public:
for (unsigned i = 2; i < fans_v.size(); ++i) { for (unsigned i = 2; i < fans_v.size(); ++i) {
SGVertNormTex v2; SGVertNormTex v2;
v2.SetVertex( toVec3f(vertices[fans_v[i]]) ); v2.SetVertex( toVec3f(vertices[fans_v[i]]) );
v2.SetNormal( num_norms_is_num_verts ? normals[fans_n[i]] : v2.SetNormal( num_norms_is_num_verts ? normals[fans_n[i]] :
normals[fans_v[i]] ); normals[fans_v[i]] );
v2.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, i) ); v2.SetTexCoord( 0, getTexCoord(texCoords, fans_tc[0], tc0Scale, i) );
if (!fans_tc[1].empty()) { if (!fans_tc[1].empty()) {
@@ -271,7 +271,7 @@ public:
if (group) { if (group) {
group->setName("surfaceGeometryGroup"); group->setName("surfaceGeometryGroup");
} }
//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) {
@@ -287,12 +287,18 @@ public:
} else { } else {
eg->setMaterial(NULL); eg->setMaterial(NULL);
} }
// If effect requests normal generation, we do not include terragear // If effect requests normal generation, we do not include terragear
// normals in the geometry // normals in the geometry
bool include_normals = true; bool include_normals = true;
int n = eg->getEffect()->getGenerator(Effect::NORMAL);
if (n != -1) auto eff = eg->getEffect();
include_normals = false; if (eff) {
int n = eff->getGenerator(Effect::NORMAL);
if (n != -1)
include_normals = false;
}
osg::Geometry* geometry = i->second.buildGeometry(useVBOs, include_normals); 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); eg->addDrawable(geometry);
@@ -300,7 +306,7 @@ public:
group->addChild(eg); group->addChild(eg);
} }
} }
if (group) { if (group) {
return group; return group;
} else { } else {