a2ecb93c2b
it to be assigned as a vertex attribute array to an osg::Geometry. Removed the osgTerrain::ArrayLayer as its no longer required thanks to the above change which makes the osgTerrain::HeightFieldLayer more flexible. Updated wrappers
133 lines
3.1 KiB
C++
133 lines
3.1 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
|
*
|
|
* This library is open source and may be redistributed and/or modified under
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* OpenSceneGraph Public License for more details.
|
|
*/
|
|
#include <osg/Shape>
|
|
#include <algorithm>
|
|
|
|
using namespace osg;
|
|
|
|
Shape::~Shape()
|
|
{
|
|
}
|
|
|
|
HeightField::HeightField():
|
|
_columns(0),
|
|
_rows(0),
|
|
_origin(0.0f,0.0f,0.0f),
|
|
_dx(1.0f),
|
|
_dy(1.0f),
|
|
_skirtHeight(0.0f),
|
|
_borderWidth(0)
|
|
{
|
|
_heights = new osg::FloatArray;
|
|
}
|
|
|
|
HeightField::HeightField(const HeightField& mesh,const CopyOp& copyop):
|
|
Shape(mesh,copyop),
|
|
_columns(mesh._columns),
|
|
_rows(mesh._rows),
|
|
_origin(mesh._origin),
|
|
_dx(mesh._dx),
|
|
_dy(mesh._dy),
|
|
_skirtHeight(mesh._skirtHeight),
|
|
_borderWidth(mesh._borderWidth),
|
|
_heights(new osg::FloatArray(*mesh._heights))
|
|
{
|
|
}
|
|
|
|
HeightField::~HeightField()
|
|
{
|
|
}
|
|
|
|
|
|
void HeightField::allocate(unsigned int numColumns,unsigned int numRows)
|
|
{
|
|
if (_columns!=numColumns || _rows!=numRows)
|
|
{
|
|
_heights->resize(numColumns*numRows);
|
|
}
|
|
_columns=numColumns;
|
|
_rows=numRows;
|
|
}
|
|
|
|
Vec3 HeightField::getNormal(unsigned int c,unsigned int r) const
|
|
{
|
|
// four point normal generation.
|
|
float dz_dx;
|
|
if (c==0)
|
|
{
|
|
dz_dx = (getHeight(c+1,r)-getHeight(c,r))/getXInterval();
|
|
}
|
|
else if (c==getNumColumns()-1)
|
|
{
|
|
dz_dx = (getHeight(c,r)-getHeight(c-1,r))/getXInterval();
|
|
}
|
|
else // assume 0<c<_numColumns-1
|
|
{
|
|
dz_dx = 0.5f*(getHeight(c+1,r)-getHeight(c-1,r))/getXInterval();
|
|
}
|
|
|
|
float dz_dy;
|
|
if (r==0)
|
|
{
|
|
dz_dy = (getHeight(c,r+1)-getHeight(c,r))/getYInterval();
|
|
}
|
|
else if (r==getNumRows()-1)
|
|
{
|
|
dz_dy = (getHeight(c,r)-getHeight(c,r-1))/getYInterval();
|
|
}
|
|
else // assume 0<r<_numRows-1
|
|
{
|
|
dz_dy = 0.5f*(getHeight(c,r+1)-getHeight(c,r-1))/getYInterval();
|
|
}
|
|
|
|
Vec3 normal(-dz_dx,-dz_dy,1.0f);
|
|
normal.normalize();
|
|
|
|
return normal;
|
|
}
|
|
|
|
Vec2 HeightField::getHeightDelta(unsigned int c,unsigned int r) const
|
|
{
|
|
// four point normal generation.
|
|
Vec2 heightDelta;
|
|
if (c==0)
|
|
{
|
|
heightDelta.x() = (getHeight(c+1,r)-getHeight(c,r));
|
|
}
|
|
else if (c==getNumColumns()-1)
|
|
{
|
|
heightDelta.x() = (getHeight(c,r)-getHeight(c-1,r));
|
|
}
|
|
else // assume 0<c<_numColumns-1
|
|
{
|
|
heightDelta.x() = 0.5f*(getHeight(c+1,r)-getHeight(c-1,r));
|
|
}
|
|
|
|
if (r==0)
|
|
{
|
|
heightDelta.y() = (getHeight(c,r+1)-getHeight(c,r));
|
|
}
|
|
else if (r==getNumRows()-1)
|
|
{
|
|
heightDelta.y() = (getHeight(c,r)-getHeight(c,r-1));
|
|
}
|
|
else // assume 0<r<_numRows-1
|
|
{
|
|
heightDelta.y() = 0.5f*(getHeight(c,r+1)-getHeight(c,r-1));
|
|
}
|
|
|
|
return heightDelta;
|
|
}
|
|
|
|
|