Added corner dirty options to TerrainTechnique, added experimental code paths in GeometryTechnique for accounting for neighbouring corner tiles - optionally compiled out in this check-in.
Changed the normal computation in GeometryTechnique so that it doesn't include diagonals, thus avoid normal jumps at corners.
This commit is contained in:
parent
d992f6e018
commit
fccda08491
@ -179,8 +179,13 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
|
|||||||
LEFT_EDGE_DIRTY = 1<<2,
|
LEFT_EDGE_DIRTY = 1<<2,
|
||||||
RIGHT_EDGE_DIRTY = 1<<3,
|
RIGHT_EDGE_DIRTY = 1<<3,
|
||||||
TOP_EDGE_DIRTY = 1<<4,
|
TOP_EDGE_DIRTY = 1<<4,
|
||||||
BOTTOM_EDGE_DIRTY = 1<<5,
|
TOP_LEFT_CORNER_DIRTY = 1<<5,
|
||||||
EDGES_DIRTY = LEFT_EDGE_DIRTY | RIGHT_EDGE_DIRTY | TOP_EDGE_DIRTY | BOTTOM_EDGE_DIRTY,
|
TOP_RIGHT_CORNER_DIRTY = 1<<6,
|
||||||
|
BOTTOM_EDGE_DIRTY = 1<<7,
|
||||||
|
BOTTOM_LEFT_CORNER_DIRTY = 1<<8,
|
||||||
|
BOTTOM_RIGHT_CORNER_DIRTY = 1<<9,
|
||||||
|
EDGES_DIRTY = LEFT_EDGE_DIRTY | RIGHT_EDGE_DIRTY | TOP_EDGE_DIRTY | BOTTOM_EDGE_DIRTY |
|
||||||
|
TOP_LEFT_CORNER_DIRTY | TOP_RIGHT_CORNER_DIRTY | BOTTOM_LEFT_CORNER_DIRTY | BOTTOM_RIGHT_CORNER_DIRTY,
|
||||||
ALL_DIRTY = IMAGERY_DIRTY | ELEVATION_DIRTY | EDGES_DIRTY
|
ALL_DIRTY = IMAGERY_DIRTY | ELEVATION_DIRTY | EDGES_DIRTY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -308,6 +308,53 @@ class VertexNormalGenerator
|
|||||||
|
|
||||||
inline bool computeNormal(int c, int r, osg::Vec3& n) const
|
inline bool computeNormal(int c, int r, osg::Vec3& n) const
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
return computeNormalWithNoDiagonals(c,r,n);
|
||||||
|
#else
|
||||||
|
return computeNormalWithDiagonals(c,r,n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool computeNormalWithNoDiagonals(int c, int r, osg::Vec3& n) const
|
||||||
|
{
|
||||||
|
osg::Vec3 center;
|
||||||
|
bool center_valid = vertex(c, r, center);
|
||||||
|
if (!center_valid) return false;
|
||||||
|
|
||||||
|
osg::Vec3 left, right, top, bottom;
|
||||||
|
bool left_valid = vertex(c-1, r, left);
|
||||||
|
bool right_valid = vertex(c+1, r, right);
|
||||||
|
bool bottom_valid = vertex(c, r-1, bottom);
|
||||||
|
bool top_valid = vertex(c, r+1, top);
|
||||||
|
|
||||||
|
osg::Vec3 dx(0.0f,0.0f,0.0f);
|
||||||
|
osg::Vec3 dy(0.0f,0.0f,0.0f);
|
||||||
|
osg::Vec3 zero(0.0f,0.0f,0.0f);
|
||||||
|
if (left_valid)
|
||||||
|
{
|
||||||
|
dx = center-left;
|
||||||
|
}
|
||||||
|
if (right_valid)
|
||||||
|
{
|
||||||
|
dx = right-center;
|
||||||
|
}
|
||||||
|
if (bottom_valid)
|
||||||
|
{
|
||||||
|
dy += center-bottom;
|
||||||
|
}
|
||||||
|
if (top_valid)
|
||||||
|
{
|
||||||
|
dy += top-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dx==zero || dy==zero) return false;
|
||||||
|
|
||||||
|
n = dx ^ dy;
|
||||||
|
return n.normalize() != 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool computeNormalWithDiagonals(int c, int r, osg::Vec3& n) const
|
||||||
|
{
|
||||||
osg::Vec3 center;
|
osg::Vec3 center;
|
||||||
bool center_valid = vertex(c, r, center);
|
bool center_valid = vertex(c, r, center);
|
||||||
if (!center_valid) return false;
|
if (!center_valid) return false;
|
||||||
@ -800,6 +847,12 @@ void GeometryTechnique::generateGeometry(BufferData& buffer, Locator* masterLoca
|
|||||||
osg::ref_ptr<TerrainTile> top_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y+1));
|
osg::ref_ptr<TerrainTile> top_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y+1));
|
||||||
osg::ref_ptr<TerrainTile> bottom_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y-1));
|
osg::ref_ptr<TerrainTile> bottom_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y-1));
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
osg::ref_ptr<TerrainTile> top_left_tile = terrain->getTile(TileID(tileID.level, tileID.x-1, tileID.y+1));
|
||||||
|
osg::ref_ptr<TerrainTile> top_right_tile = terrain->getTile(TileID(tileID.level, tileID.x+1, tileID.y+1));
|
||||||
|
osg::ref_ptr<TerrainTile> bottom_left_tile = terrain->getTile(TileID(tileID.level, tileID.x-1, tileID.y-1));
|
||||||
|
osg::ref_ptr<TerrainTile> bottom_right_tile = terrain->getTile(TileID(tileID.level, tileID.x+1, tileID.y-1));
|
||||||
|
#endif
|
||||||
VNG.populateLeftBoundary(left_tile.valid() ? left_tile->getElevationLayer() : 0);
|
VNG.populateLeftBoundary(left_tile.valid() ? left_tile->getElevationLayer() : 0);
|
||||||
VNG.populateRightBoundary(right_tile.valid() ? right_tile->getElevationLayer() : 0);
|
VNG.populateRightBoundary(right_tile.valid() ? right_tile->getElevationLayer() : 0);
|
||||||
VNG.populateAboveBoundary(top_tile.valid() ? top_tile->getElevationLayer() : 0);
|
VNG.populateAboveBoundary(top_tile.valid() ? top_tile->getElevationLayer() : 0);
|
||||||
@ -814,6 +867,12 @@ void GeometryTechnique::generateGeometry(BufferData& buffer, Locator* masterLoca
|
|||||||
if (top_tile.valid()) addNeighbour(top_tile.get());
|
if (top_tile.valid()) addNeighbour(top_tile.get());
|
||||||
if (bottom_tile.valid()) addNeighbour(bottom_tile.get());
|
if (bottom_tile.valid()) addNeighbour(bottom_tile.get());
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (bottom_left_tile.valid()) addNeighbour(bottom_left_tile.get());
|
||||||
|
if (bottom_right_tile.valid()) addNeighbour(bottom_right_tile.get());
|
||||||
|
if (top_left_tile.valid()) addNeighbour(top_left_tile.get());
|
||||||
|
if (top_right_tile.valid()) addNeighbour(top_right_tile.get());
|
||||||
|
#endif
|
||||||
|
|
||||||
if (left_tile.valid())
|
if (left_tile.valid())
|
||||||
{
|
{
|
||||||
@ -843,7 +902,7 @@ void GeometryTechnique::generateGeometry(BufferData& buffer, Locator* masterLoca
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bottom_tile)
|
if (bottom_tile.valid())
|
||||||
{
|
{
|
||||||
if (!(bottom_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
if (!(bottom_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||||
{
|
{
|
||||||
@ -852,6 +911,48 @@ void GeometryTechnique::generateGeometry(BufferData& buffer, Locator* masterLoca
|
|||||||
else bottom_tile->setDirtyMask(dirtyMask);
|
else bottom_tile->setDirtyMask(dirtyMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (bottom_left_tile.valid())
|
||||||
|
{
|
||||||
|
if (!(bottom_left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||||
|
{
|
||||||
|
int dirtyMask = bottom_left_tile->getDirtyMask() | TerrainTile::BOTTOM_LEFT_CORNER_DIRTY;
|
||||||
|
if (updateNeighboursImmediately) bottom_left_tile->init(dirtyMask, true);
|
||||||
|
else bottom_left_tile->setDirtyMask(dirtyMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottom_right_tile.valid())
|
||||||
|
{
|
||||||
|
if (!(bottom_right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||||
|
{
|
||||||
|
int dirtyMask = bottom_right_tile->getDirtyMask() | TerrainTile::BOTTOM_RIGHT_CORNER_DIRTY;
|
||||||
|
if (updateNeighboursImmediately) bottom_right_tile->init(dirtyMask, true);
|
||||||
|
else bottom_right_tile->setDirtyMask(dirtyMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top_right_tile.valid())
|
||||||
|
{
|
||||||
|
if (!(top_right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||||
|
{
|
||||||
|
int dirtyMask = top_right_tile->getDirtyMask() | TerrainTile::TOP_RIGHT_CORNER_DIRTY;
|
||||||
|
if (updateNeighboursImmediately) top_right_tile->init(dirtyMask, true);
|
||||||
|
else top_right_tile->setDirtyMask(dirtyMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top_left_tile.valid())
|
||||||
|
{
|
||||||
|
if (!(top_left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||||
|
{
|
||||||
|
int dirtyMask = top_left_tile->getDirtyMask() | TerrainTile::TOP_LEFT_CORNER_DIRTY;
|
||||||
|
if (updateNeighboursImmediately) top_left_tile->init(dirtyMask, true);
|
||||||
|
else top_left_tile->setDirtyMask(dirtyMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<osg::Vec3Array> skirtVectors = new osg::Vec3Array((*VNG._normals));
|
osg::ref_ptr<osg::Vec3Array> skirtVectors = new osg::Vec3Array((*VNG._normals));
|
||||||
|
Loading…
Reference in New Issue
Block a user