Added osg::Grid shape class, and added an example of its use into the

hang glide demo.
This commit is contained in:
Robert Osfield
2002-10-31 10:36:11 +00:00
parent 85af8cc4ba
commit 21ee9e4cb7
5 changed files with 176 additions and 20 deletions

View File

@@ -400,7 +400,6 @@ class HeightField : public Shape
HeightField(const HeightField& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(mesh,copyop),
_zeroRotation(true),
_columns(0),
_rows(0),
_origin(0.0f,0.0f,0.0f),
@@ -413,8 +412,6 @@ class HeightField : public Shape
virtual void accept(osg::ShapeVisitor& sv) { sv.apply(*this); }
virtual void accept(osg::ConstShapeVisitor& csv) const { csv.apply(*this); }
virtual void setNumColumnsAndRows(unsigned int col,unsigned int rows) = 0;
inline unsigned int getNumColumns() const { return _columns; }
inline unsigned int getNumRows() const { return _rows; }
@@ -427,18 +424,9 @@ class HeightField : public Shape
inline void setYInterval(float dy) { _dy = dy; }
inline float getYInterval() const { return _dy; }
virtual void setHeight(unsigned int c,unsigned int r) const = 0;
virtual float getHeight(unsigned int c,unsigned int r) const = 0;
virtual void setNormal(unsigned int c,unsigned int r,const osg::Vec3& normal) const = 0;
virtual Vec3 getNormal(unsigned int c,unsigned int r) const = 0;
inline Vec3 getVertex(unsigned int c,unsigned int r) const
{
return Vec3(_origin.x()+_dx*(float)c,
_origin.y()+_dy*(float)r,
_origin.z()+getHeight(c,r));
}
inline void setRotation(const Quat& quat) { _rotation = quat; }
inline const Quat& getRotation() const { return _rotation; }
@@ -448,8 +436,6 @@ class HeightField : public Shape
protected:
~HeightField() {}
bool _zeroRotation;
unsigned int _columns,_rows;
@@ -461,6 +447,44 @@ class HeightField : public Shape
};
class SG_EXPORT Grid : public HeightField
{
public:
Grid();
Grid(const Grid& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Shape(osg,Grid)
void allocGrid(unsigned int numColumns,unsigned int numRows, float value=0.0f);
void populateGrid(float minValue,float maxValue);
void setHeight(unsigned int c,unsigned int r,float value)
{
_heights[c+r*_columns] = value;
}
virtual float getHeight(unsigned int c,unsigned int r) const
{
return _heights[c+r*_columns];
}
virtual Vec3 getNormal(unsigned int,unsigned int) const
{
return osg::Vec3(0.0f,0.0f,1.0f);
}
protected:
~Grid();
typedef std::vector<float> HeightList;
HeightList _heights;
};
class CompositeShape : public Shape
{
public:

View File

@@ -12,6 +12,8 @@
#include <osg/Math>
#include "../osghangglide/terrain_coords.h"
osg::Geode* createShapes()
{
osg::Geode* geode = osgNew osg::Geode();
@@ -39,6 +41,27 @@ osg::Geode* createShapes()
geode->addDrawable(new osg::ProceduralGeometry(osgNew osg::Box(osg::Vec3(2.0f,0.0f,0.0f),2*radius)));
geode->addDrawable(new osg::ProceduralGeometry(osgNew osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height)));
geode->addDrawable(new osg::ProceduralGeometry(osgNew osg::Cylinder(osg::Vec3(6.0f,0.0f,0.0f),radius,height)));
// osg::Grid* grid = new osg::Grid;
// grid->allocGrid(100,100,0.0f);
// grid->setXInterval(0.2f);
// grid->setYInterval(0.2f);
// grid->populateGrid(-0.2f,0.2f);
// geode->addDrawable(new osg::ProceduralGeometry(grid));
osg::Grid* grid = new osg::Grid;
grid->allocGrid(38,39);
grid->setXInterval(0.28f);
grid->setYInterval(0.28f);
for(unsigned int r=0;r<39;++r)
{
for(unsigned int c=0;c<38;++c)
{
grid->setHeight(c,r,vertex[r+c*39][2]);
}
}
geode->addDrawable(new osg::ProceduralGeometry(grid));
return geode;
}

View File

@@ -369,8 +369,6 @@ void DrawShapeVisitor::apply(const Cylinder& cylinder)
float texCoordDelta = 1.0/(float)numSegments;
osg::Vec3 top(0.0f,0.0f,cylinder.getHeight());
float r = cylinder.getRadius();
float h = cylinder.getHeight();
@@ -487,7 +485,57 @@ void DrawShapeVisitor::apply(const ConvexHull& hull)
void DrawShapeVisitor::apply(const HeightField& field)
{
std::cout << "draw a field "<<&field<<std::endl;
if (field.getNumColumns()==0 || field.getNumRows()==0) return;
glPushMatrix();
glTranslatef(field.getOrigin().x(),field.getOrigin().y(),field.getOrigin().z());
if (!field.zeroRotation())
{
Matrix rotation(field.getRotationMatrix());
glMultMatrixf(rotation.ptr());
}
float dx = field.getXInterval();
float dy = field.getYInterval();
float du = 1.0f/((float)field.getNumColumns()-1.0f);
float dv = 1.0f/((float)field.getNumRows()-1.0f);
float vBase = 0.0f;
for(unsigned int row=0;row<field.getNumRows()-1;++row,vBase+=dv)
{
float vTop = vBase+dv;
float u = 0.0f;
glBegin(GL_QUAD_STRIP);
for(unsigned int col=0;col<field.getNumColumns();++col,u+=du)
{
Vec3 vertTop(dx*(float)col,dy*(float)row+dy,field.getHeight(col,row+1));
Vec3 normTop(field.getNormal(col,row+1));
Vec3 vertBase(dx*(float)col,dy*(float)row,field.getHeight(col,row));
Vec3 normBase(field.getNormal(col,row));
glTexCoord2f(u,vTop);
glNormal3fv(normTop.ptr());
glVertex3fv(vertTop.ptr());
glTexCoord2f(u,vBase);
glNormal3fv(normBase.ptr());
glVertex3fv(vertBase.ptr());
}
glEnd();
}
glPopMatrix();
}
void DrawShapeVisitor::apply(const CompositeShape& composite)
@@ -639,8 +687,28 @@ void ComputeBoundShapeVisitor::apply(const ConvexHull& hull)
apply((const TriangleMesh&)hull);
}
void ComputeBoundShapeVisitor::apply(const HeightField&)
void ComputeBoundShapeVisitor::apply(const HeightField& field)
{
float zMin=FLT_MAX;
float zMax=-FLT_MAX;
for(unsigned int row=0;row<field.getNumRows();++row)
{
for(unsigned int col=0;col<field.getNumColumns();++col)
{
float z = field.getHeight(col,row);
if (z<zMin) zMin = z;
if (z>zMax) zMax = z;
}
}
_bb.set(field.getOrigin()+osg::Vec3(0.0f,0.0f,zMin),
field.getOrigin()+osg::Vec3(field.getXInterval()*field.getNumColumns(),field.getYInterval()*field.getNumRows(),zMax));
cout << "_bb.min"<<_bb._min;
cout << "_bb.max"<<_bb._max;
}
void ComputeBoundShapeVisitor::apply(const CompositeShape&)

View File

@@ -1,5 +1,43 @@
#include <osg/Shape>
#include <algorithm>
using namespace osg;
Grid::Grid()
{
}
Grid::Grid(const Grid& mesh,const CopyOp& copyop):
HeightField(mesh,copyop)
{
_heights = mesh._heights;
}
Grid::~Grid()
{
}
void Grid::allocGrid(unsigned int numColumns,unsigned int numRows, float value)
{
if (_columns!=numColumns || _rows!=numRows)
{
_heights.resize(numColumns*numRows);
}
_columns=numColumns;
_rows=numRows;
//_heights.fill(value);
}
void Grid::populateGrid(float minValue,float maxValue)
{
float offset=minValue;
float gain=(maxValue-minValue)/(float)RAND_MAX;
for(unsigned int row=0;row<_rows;++row)
{
for(unsigned int col=0;col<_columns;++col)
{
setHeight(col,row,rand()*gain+offset);
}
}
}

View File

@@ -70,7 +70,10 @@ Registry::Registry()
addFileExtensionAlias("tif", "tiff");
addFileExtensionAlias("geo", "lwo");
// remove geo to lwo alias as the new Carbon Graphics GEO format
// also uses the .geo. It is still possible to load light wave .geo
// files via loading the lwo plugin explicitly and then doing a readNodeFile.
//addFileExtensionAlias("geo", "lwo");
addFileExtensionAlias("lw", "lwo");
addFileExtensionAlias("wrl", "iv");