diff --git a/include/osg/Shape b/include/osg/Shape index c3a233861..7b39ce2ce 100644 --- a/include/osg/Shape +++ b/include/osg/Shape @@ -457,9 +457,7 @@ class SG_EXPORT Grid : public HeightField META_Shape(osg,Grid) - void allocGrid(unsigned int numColumns,unsigned int numRows, float value=0.0f); - - void populateGrid(float minValue,float maxValue); + void allocateGrid(unsigned int numColumns,unsigned int numRows); void setHeight(unsigned int c,unsigned int r,float value) { @@ -486,7 +484,7 @@ class CompositeShape : public Shape typedef std::vector< ref_ptr > ChildList; - CompositeShape(); + CompositeShape() {} CompositeShape(const CompositeShape& cs,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Shape(cs,copyop), diff --git a/src/Demos/osgshape/osgshape.cpp b/src/Demos/osgshape/osgshape.cpp index 342d5f1f8..4110f9f10 100644 --- a/src/Demos/osgshape/osgshape.cpp +++ b/src/Demos/osgshape/osgshape.cpp @@ -43,7 +43,7 @@ osg::Geode* createShapes() 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(38,39); + grid->allocateGrid(38,39); grid->setXInterval(0.28f); grid->setYInterval(0.28f); @@ -58,22 +58,27 @@ osg::Geode* createShapes() osg::ConvexHull* mesh = new osg::ConvexHull; osg::Vec3Array* vertices = new osg::Vec3Array(4); - (*vertices)[0].set(0.0f,0.0f,4.0f); - (*vertices)[1].set(0.0f,0.0f,0.0f); - (*vertices)[2].set(4.0f,0.0f,0.0f); - (*vertices)[3].set(4.0f,0.0f,4.0f); - osg::UByteArray* indices = new osg::UByteArray(6); + (*vertices)[0].set(7.0+0.0f,-1.0f+2.0f,-1.0f+0.0f); + (*vertices)[1].set(7.0+1.0f,-1.0f+0.0f,-1.0f+0.0f); + (*vertices)[2].set(7.0+2.0f,-1.0f+2.0f,-1.0f+0.0f); + (*vertices)[3].set(7.0+1.0f,-1.0f+1.0f,-1.0f+2.0f); + osg::UByteArray* indices = new osg::UByteArray(12); (*indices)[0]=0; - (*indices)[1]=1; - (*indices)[2]=2; + (*indices)[1]=2; + (*indices)[2]=1; (*indices)[3]=0; - (*indices)[4]=2; + (*indices)[4]=1; (*indices)[5]=3; + (*indices)[6]=1; + (*indices)[7]=2; + (*indices)[8]=3; + (*indices)[9]=2; + (*indices)[10]=0; + (*indices)[11]=3; mesh->setVertices(vertices); mesh->setIndices(indices); geode->addDrawable(new osg::ProceduralGeometry(mesh)); - return geode; } diff --git a/src/osg/ProceduralGeometry.cpp b/src/osg/ProceduralGeometry.cpp index 74bfd8d90..20bfd4119 100644 --- a/src/osg/ProceduralGeometry.cpp +++ b/src/osg/ProceduralGeometry.cpp @@ -478,12 +478,29 @@ void DrawShapeVisitor::apply(const TriangleMesh& mesh) const Vec3Array* vertices = mesh.getVertices(); const IndexArray* indices = mesh.getIndices(); - if (vertices && indices) - { - glNormal3f(0.0f,0.0f,1.0f); - _state.setVertexPointer(3,GL_FLOAT,0,vertices->getDataPointer()); - glDrawElements(GL_TRIANGLES,indices->getNumElements(),indices->getDataType(),indices->getDataPointer()); - } + if (vertices && indices) + { + glBegin(GL_TRIANGLES); + + for(unsigned int i=0;igetNumElements();i+=3) + { + const osg::Vec3& v1=(*vertices)[indices->index(i)]; + const osg::Vec3& v2=(*vertices)[indices->index(i+1)]; + const osg::Vec3& v3=(*vertices)[indices->index(i+2)]; + Vec3 normal = (v2-v1)^(v3-v2); + normal.normalize(); + + glNormal3fv(normal.ptr()); + glVertex3fv(v1.ptr()); + glVertex3fv(v2.ptr()); + glVertex3fv(v3.ptr()); + + } + + glEnd(); + } + + } void DrawShapeVisitor::apply(const ConvexHull& hull) @@ -546,12 +563,17 @@ void DrawShapeVisitor::apply(const HeightField& field) } -void DrawShapeVisitor::apply(const CompositeShape& composite) +void DrawShapeVisitor::apply(const CompositeShape& group) { - std::cout << "draw a composite "<<&composite<accept(*this); + } } + + /////////////////////////////////////////////////////////////////////////////// // // Compute bounding of shape @@ -582,14 +604,16 @@ class ComputeBoundShapeVisitor : public ConstShapeVisitor void ComputeBoundShapeVisitor::apply(const Sphere& sphere) { Vec3 halfLengths(sphere.getRadius(),sphere.getRadius(),sphere.getRadius()); - _bb.set(sphere.getCenter()-halfLengths,sphere.getCenter()+halfLengths); + _bb.expandBy(sphere.getCenter()-halfLengths); + _bb.expandBy(sphere.getCenter()+halfLengths); } void ComputeBoundShapeVisitor::apply(const Box& box) { if (box.zeroRotation()) { - _bb.set(box.getCenter()-box.getHalfLengths(),box.getCenter()+box.getHalfLengths()); + _bb.expandBy(box.getCenter()-box.getHalfLengths()); + _bb.expandBy(box.getCenter()+box.getHalfLengths()); } else { @@ -624,9 +648,8 @@ void ComputeBoundShapeVisitor::apply(const Cone& cone) { if (cone.zeroRotation()) { - Vec3 halfLengths(cone.getRadius(),cone.getRadius(),cone.getHeight()*0.5f); - _bb.set(cone.getCenter()+Vec3(-cone.getRadius(),-cone.getRadius(),cone.getBaseOffset()), - cone.getCenter()+Vec3(cone.getRadius(),cone.getRadius(),cone.getHeight()+cone.getBaseOffset())); + _bb.expandBy(cone.getCenter()+Vec3(-cone.getRadius(),-cone.getRadius(),cone.getBaseOffset())); + _bb.expandBy(cone.getCenter()+Vec3(cone.getRadius(),cone.getRadius(),cone.getHeight()+cone.getBaseOffset())); } else @@ -651,7 +674,8 @@ void ComputeBoundShapeVisitor::apply(const Cylinder& cylinder) if (cylinder.zeroRotation()) { Vec3 halfLengths(cylinder.getRadius(),cylinder.getRadius(),cylinder.getHeight()*0.5f); - _bb.set(cylinder.getCenter()-halfLengths,cylinder.getCenter()+halfLengths); + _bb.expandBy(cylinder.getCenter()-halfLengths); + _bb.expandBy(cylinder.getCenter()+halfLengths); } else @@ -684,10 +708,22 @@ void ComputeBoundShapeVisitor::apply(const Cylinder& cylinder) void ComputeBoundShapeVisitor::apply(const InfinitePlane&) { + // can't compute the bounding box of an infinite plane!!! :-) } -void ComputeBoundShapeVisitor::apply(const TriangleMesh&) +void ComputeBoundShapeVisitor::apply(const TriangleMesh& mesh) { + const Vec3Array* vertices = mesh.getVertices(); + const IndexArray* indices = mesh.getIndices(); + + if (vertices && indices) + { + for(unsigned int i=0;igetNumElements();++i) + { + const osg::Vec3& v=(*vertices)[indices->index(i)]; + _bb.expandBy(v); + } + } } void ComputeBoundShapeVisitor::apply(const ConvexHull& hull) @@ -711,17 +747,496 @@ void ComputeBoundShapeVisitor::apply(const HeightField& field) } } - _bb.set(field.getOrigin()+osg::Vec3(0.0f,0.0f,zMin), - field.getOrigin()+osg::Vec3(field.getXInterval()*field.getNumColumns(),field.getYInterval()*field.getNumRows(),zMax)); + if (field.zeroRotation()) + { + _bb.expandBy(field.getOrigin()+osg::Vec3(0.0f,0.0f,zMin)); + _bb.expandBy(field.getOrigin()+osg::Vec3(field.getXInterval()*field.getNumColumns(),field.getYInterval()*field.getNumRows(),zMax)); + } + else + { + float x = field.getXInterval()*field.getNumColumns(); + float y = field.getYInterval()*field.getNumRows(); + + Vec3 base_1(field.getOrigin()+Vec3(0,0,zMin)); + Vec3 base_2(field.getOrigin()+Vec3(x,0,zMin)); + Vec3 base_3(field.getOrigin()+Vec3(x,y,zMin)); + Vec3 base_4(field.getOrigin()+Vec3(0,y,zMin)); + + Vec3 top_1(field.getOrigin()+Vec3(0,0,zMax)); + Vec3 top_2(field.getOrigin()+Vec3(x,0,zMax)); + Vec3 top_3(field.getOrigin()+Vec3(x,y,zMax)); + Vec3 top_4(field.getOrigin()+Vec3(0,y,zMax)); + + Matrix matrix = field.getRotationMatrix(); + _bb.expandBy(base_1*matrix); + _bb.expandBy(base_2*matrix); + _bb.expandBy(base_3*matrix); + _bb.expandBy(base_4*matrix); + + _bb.expandBy(top_1*matrix); + _bb.expandBy(top_2*matrix); + _bb.expandBy(top_3*matrix); + _bb.expandBy(top_4*matrix); + } + } -void ComputeBoundShapeVisitor::apply(const CompositeShape&) +void ComputeBoundShapeVisitor::apply(const CompositeShape& group) { + for(unsigned int i=0;iaccept(*this); + } } + +/////////////////////////////////////////////////////////////////////////////// +// +// Accept a primtive functor for each of the shapes. +// + +class PrimitiveShapeVisitor : public ConstShapeVisitor +{ + public: + + PrimitiveShapeVisitor(Drawable::PrimitiveFunctor& functor,TessellationHints* hints): + _functor(functor), + _hints(hints) {} + + virtual void apply(const Sphere&); + virtual void apply(const Box&); + virtual void apply(const Cone&); + virtual void apply(const Cylinder&); + virtual void apply(const InfinitePlane&); + + virtual void apply(const TriangleMesh&); + virtual void apply(const ConvexHull&); + virtual void apply(const HeightField&); + + virtual void apply(const CompositeShape&); + + Drawable::PrimitiveFunctor& _functor; + TessellationHints* _hints; +}; + + + + +void PrimitiveShapeVisitor::apply(const Sphere& sphere) +{ + + float tx = sphere.getCenter().x(); + float ty = sphere.getCenter().y(); + float tz = sphere.getCenter().z(); + + unsigned int numSegments = 40; + unsigned int numRows = 20; + + float lDelta = osg::PI/(float)numRows; + float vDelta = 1.0f/(float)numRows; + + float angleDelta = osg::PI*2.0f/(float)numSegments; + float texCoordHorzDelta = 1.0f/(float)numSegments; + + float lBase=-osg::PI*0.5f; + float rBase=0.0f; + float zBase=-sphere.getRadius(); + float vBase=0.0f; + float nzBase=-1.0f; + float nRatioBase=0.0f; + + for(unsigned int rowi=0; + rowigetNumElements();i+=3) + { + _functor.vertex((*vertices)[indices->index(i)]); + _functor.vertex((*vertices)[indices->index(i+1)]); + _functor.vertex((*vertices)[indices->index(i+2)]); + } + + _functor.end(); + } + + +} + +void PrimitiveShapeVisitor::apply(const ConvexHull& hull) +{ + apply((const TriangleMesh&)hull); +} + +void PrimitiveShapeVisitor::apply(const HeightField& field) +{ + if (field.getNumColumns()==0 || field.getNumRows()==0) return; + + Matrix matrix = field.getRotationMatrix(); + matrix.setTrans(field.getOrigin()); + + 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;rowaccept(*this); + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// ProceduralGeometry itself.. +// + + ProceduralGeometry::ProceduralGeometry() { } @@ -749,12 +1264,17 @@ void ProceduralGeometry::drawImmediateMode(State& state) } } -void ProceduralGeometry::accept(AttributeFunctor& af) +void ProceduralGeometry::accept(AttributeFunctor&) { } void ProceduralGeometry::accept(PrimitiveFunctor& pf) { + if (_shape.valid()) + { + PrimitiveShapeVisitor psv(pf,_tessellationHints.get()); + _shape->accept(psv); + } } diff --git a/src/osg/Shape.cpp b/src/osg/Shape.cpp index d04b3b221..57e5cb1f1 100644 --- a/src/osg/Shape.cpp +++ b/src/osg/Shape.cpp @@ -3,45 +3,6 @@ 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); - } - } -} - Vec3 HeightField::getNormal(unsigned int c,unsigned int r) const { // four point normal generation. @@ -79,3 +40,28 @@ Vec3 HeightField::getNormal(unsigned int c,unsigned int r) const return normal; } + +Grid::Grid() +{ +} + +Grid::Grid(const Grid& mesh,const CopyOp& copyop): + HeightField(mesh,copyop) +{ + _heights = mesh._heights; +} + +Grid::~Grid() +{ +} + +void Grid::allocateGrid(unsigned int numColumns,unsigned int numRows) +{ + if (_columns!=numColumns || _rows!=numRows) + { + _heights.resize(numColumns*numRows); + } + _columns=numColumns; + _rows=numRows; +} +