OpenSceneGraph/include/osg/Shape
Robert Osfield f36bc69c58 Made the more of the OSG's referenced object desctructors protected to ensure
that they arn't created on the stack inappropriately.

Split the implemention of Matrix up so that it is a simple no referenced counted
class and can be safefly created on the stack.  To support referenced counting a
seperate subclass now exists, this is RefMatrix which inherits from both Matrix and
Object.
2003-01-10 09:25:42 +00:00

556 lines
15 KiB
Plaintext

//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_SHAPE
#define OSG_SHAPE 1
#include <osg/Object>
#include <osg/Vec3>
#include <osg/Quat>
#include <osg/Plane>
#include <osg/Array>
namespace osg {
// forward decare visitors.
class ShapeVisitor;
class ConstShapeVisitor;
/** META_StateAttribute macro define the standard clone, isSameKindAs,
* className and getType methods.
* Use when subclassing from Object to make it more convinient to define
* the standard pure virtual methods which are required for all Object
* subclasses.*/
#define META_Shape(library,name) \
virtual osg::Object* cloneType() const { return new name(); } \
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const name *>(obj)!=NULL; } \
virtual const char* libraryName() const { return #library; } \
virtual const char* className() const { return #name; } \
virtual void accept(osg::ShapeVisitor& sv) { sv.apply(*this); } \
virtual void accept(osg::ConstShapeVisitor& csv) const { csv.apply(*this); }
/** Base class for all shape types.
* Shapes are used to either for culling and collision detection or
* to define the geometric shape of procedurally generate Geometry.
*/
class SG_EXPORT Shape : public Object
{
public:
Shape() {}
Shape(const Shape& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Object(sa,copyop) {}
/** Clone the type of an attribute, with Object* return type.
Must be defined by derived classes.*/
virtual Object* cloneType() const = 0;
/** Clone an attribute, with Object* return type.
Must be defined by derived classes.*/
virtual Object* clone(const CopyOp&) const = 0;
/** return true if this and obj are of the same kind of object.*/
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Shape*>(obj)!=NULL; }
/** return the name of the attribute's library.*/
virtual const char* libraryName() const { return "osg"; }
/** return the name of the attribute's class type.*/
virtual const char* className() const { return "Shape"; }
/** accept a non const shape visitor which can be used on non const shape objects.
Must be defined by derived classes.*/
virtual void accept(ShapeVisitor&)=0;
/** accept a const shape visitor which can be used on const shape objects.
Must be defined by derived classes.*/
virtual void accept(ConstShapeVisitor&) const =0;
protected:
virtual ~Shape() {}
};
// forward declartions of Shape types.
class Sphere;
class Box;
class Cone;
class Cylinder;
class InfinitePlane;
class TriangleMesh;
class ConvexHull;
class HeightField;
class CompositeShape;
class ShapeVisitor
{
public:
ShapeVisitor() {}
virtual void apply(Sphere&) {}
virtual void apply(Box&) {}
virtual void apply(Cone&) {}
virtual void apply(Cylinder&) {}
virtual void apply(InfinitePlane&) {}
virtual void apply(TriangleMesh&) {}
virtual void apply(ConvexHull&) {}
virtual void apply(HeightField&) {}
virtual void apply(CompositeShape&) {}
};
class ConstShapeVisitor
{
public:
ConstShapeVisitor() {}
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&) {}
};
class Sphere : public Shape
{
public:
Sphere():
_center(0.0f,0.0f,0.0f),
_radius(1.0f) {}
Sphere(const osg::Vec3& center,float radius):
_center(center),
_radius(radius) {}
Sphere(const Sphere& sphere,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(sphere,copyop),
_center(sphere._center),
_radius(sphere._radius) {}
META_Shape(osg, Sphere)
inline bool valid() const { return _radius>=0.0f; }
inline void set(const Vec3& center,float radius)
{
_center = center;
_radius = radius;
}
inline void setCenter(const Vec3& center) { _center = center; }
inline const Vec3& getCenter() const { return _center; }
inline void setRadius(float radius) { _radius = radius; }
inline float getRadius() const { return _radius; }
protected:
virtual ~Sphere() {}
Vec3 _center;
float _radius;
};
class Box : public Shape
{
public:
Box():
_center(0.0f,0.0f,0.0f),
_halfLengths(0.5f,0.5f,0.5f) {}
Box(const osg::Vec3& center,float width):
_center(center),
_halfLengths(width*0.5f,width*0.5f,width*0.5f) {}
Box(const osg::Vec3& center,float lengthX,float lengthY, float lengthZ):
_center(center),
_halfLengths(lengthX*0.5f,lengthY*0.5f,lengthZ*0.5f) {}
Box(const Box& box,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(box,copyop),
_center(box._center),
_halfLengths(box._halfLengths),
_rotation(box._rotation) {}
META_Shape(osg, Box)
inline bool valid() const { return _halfLengths.x()>=0.0f; }
inline void set(const Vec3& center,const Vec3& halfLengths)
{
_center = center;
_halfLengths = halfLengths;
}
inline void setCenter(const Vec3& center) { _center = center; }
inline const Vec3& getCenter() const { return _center; }
inline void setHalfLengths(const Vec3& halfLengths) { _halfLengths = halfLengths; }
inline const Vec3& getHalfLengths() const { return _halfLengths; }
inline void setRotation(const Quat& quat) { _rotation = quat; }
inline const Quat& getRotation() const { return _rotation; }
inline Matrix getRotationMatrix() const { Matrix matrix; _rotation.get(matrix); return matrix; }
inline bool zeroRotation() const { return _rotation.zeroRotation(); }
protected:
virtual ~Box() {}
Vec3 _center;
Vec3 _halfLengths;
Quat _rotation;
};
class Cone : public Shape
{
public:
Cone():
_center(0.0f,0.0f,0.0f),
_radius(1.0f),
_height(1.0f) {}
Cone(const osg::Vec3& center,float radius,float height):
_center(center),
_radius(radius),
_height(height) {}
Cone(const Cone& cone,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(cone,copyop),
_center(cone._center),
_radius(cone._radius),
_height(cone._height),
_rotation(cone._rotation) {}
META_Shape(osg, Cone)
inline bool valid() const { return _radius>=0.0f; }
inline void set(const Vec3& center,float radius, float height)
{
_center = center;
_radius = radius;
_height = height;
}
inline void setCenter(const Vec3& center) { _center = center; }
inline const Vec3& getCenter() const { return _center; }
inline void setRadius(float radius) { _radius = radius; }
inline float getRadius() const { return _radius; }
inline void setHeight(float height) { _height = height; }
inline float getHeight() const { return _height; }
inline void setRotation(const Quat& quat) { _rotation = quat; }
inline const Quat& getRotation() const { return _rotation; }
inline Matrix getRotationMatrix() const { Matrix matrix; _rotation.get(matrix); return matrix; }
inline bool zeroRotation() const { return _rotation.zeroRotation(); }
inline float getBaseOffsetFactor() const { return 0.25f; }
inline float getBaseOffset() const { return -getBaseOffsetFactor()*getHeight(); }
protected:
virtual ~Cone() {}
Vec3 _center;
float _radius;
float _height;
Quat _rotation;
};
class Cylinder : public Shape
{
public:
Cylinder():
_center(0.0f,0.0f,0.0f),
_radius(1.0f),
_height(1.0f) {}
Cylinder(const osg::Vec3& center,float radius,float height):
_center(center),
_radius(radius),
_height(height) {}
Cylinder(const Cylinder& cylinder,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(cylinder,copyop),
_center(cylinder._center),
_radius(cylinder._radius),
_height(cylinder._height),
_rotation(cylinder._rotation) {}
META_Shape(osg, Cylinder)
inline bool valid() const { return _radius>=0.0f; }
inline void set(const Vec3& center,float radius, float height)
{
_center = center;
_radius = radius;
_height = height;
}
inline void setCenter(const Vec3& center) { _center = center; }
inline const Vec3& getCenter() const { return _center; }
inline void setRadius(float radius) { _radius = radius; }
inline float getRadius() const { return _radius; }
inline void setHeight(float height) { _height = height; }
inline float getHeight() const { return _height; }
inline void setRotation(const Quat& quat) { _rotation = quat; }
inline const Quat& getRotation() const { return _rotation; }
inline Matrix getRotationMatrix() const { Matrix matrix; _rotation.get(matrix); return matrix; }
bool zeroRotation() const { return _rotation.zeroRotation(); }
protected:
virtual ~Cylinder() {}
Vec3 _center;
float _radius;
float _height;
Quat _rotation;
};
class InfinitePlane : public Shape, public Plane
{
public:
InfinitePlane() {}
InfinitePlane(const InfinitePlane& plane,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(plane,copyop),
Plane(plane) {}
META_Shape(osg, InfinitePlane)
protected:
virtual ~InfinitePlane() {}
};
class TriangleMesh : public Shape
{
public:
TriangleMesh() {}
TriangleMesh(const TriangleMesh& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(mesh,copyop),
_vertices(mesh._vertices),
_indices(mesh._indices) {}
META_Shape(osg, TriangleMesh)
void setVertices(Vec3Array* vertices) { _vertices = vertices; }
Vec3Array* getVertices() { return _vertices.get(); }
const Vec3Array* getVertices() const { return _vertices.get(); }
void setIndices(IndexArray* indices) { _indices = indices; }
IndexArray* getIndices() { return _indices.get(); }
const IndexArray* getIndices() const { return _indices.get(); }
protected:
~TriangleMesh() {}
ref_ptr<Vec3Array> _vertices;
ref_ptr<IndexArray> _indices;
};
class ConvexHull : public TriangleMesh
{
public:
ConvexHull() {}
ConvexHull(const ConvexHull& hull,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
TriangleMesh(hull,copyop) {}
META_Shape(osg, TriangleMesh)
protected:
~ConvexHull() {}
};
class SG_EXPORT HeightField : public Shape
{
public:
HeightField() {}
HeightField(const HeightField& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(mesh,copyop),
_columns(0),
_rows(0),
_origin(0.0f,0.0f,0.0f),
_dx(1.0f),
_dy(1.0f) {}
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const HeightField*>(obj)!=NULL; }
virtual const char* libraryName() const { return "osg"; }
virtual const char* className() const { return "HeightField"; }
virtual void accept(osg::ShapeVisitor& sv) { sv.apply(*this); }
virtual void accept(osg::ConstShapeVisitor& csv) const { csv.apply(*this); }
inline unsigned int getNumColumns() const { return _columns; }
inline unsigned int getNumRows() const { return _rows; }
inline void setOrigin(const osg::Vec3& origin) { _origin = origin; }
inline const osg::Vec3& getOrigin() const { return _origin; }
inline void setXInterval(float dx) { _dx = dx; }
inline float getXInterval() const { return _dx; }
inline void setYInterval(float dy) { _dy = dy; }
inline float getYInterval() const { return _dy; }
virtual float getHeight(unsigned int c,unsigned int r) const = 0;
virtual Vec3 getNormal(unsigned int c,unsigned int r) const;
inline void setRotation(const Quat& quat) { _rotation = quat; }
inline const Quat& getRotation() const { return _rotation; }
inline Matrix getRotationMatrix() const { Matrix matrix; _rotation.get(matrix); return matrix; }
inline bool zeroRotation() const { return _rotation.zeroRotation(); }
protected:
~HeightField() {}
unsigned int _columns,_rows;
osg::Vec3 _origin;
float _dx;
float _dy;
Quat _rotation;
};
class SG_EXPORT Grid : public HeightField
{
public:
Grid();
Grid(const Grid& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Shape(osg,Grid)
void allocateGrid(unsigned int numColumns,unsigned int numRows);
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];
}
protected:
~Grid();
typedef std::vector<float> HeightList;
HeightList _heights;
};
class CompositeShape : public Shape
{
public:
typedef std::vector< ref_ptr<Shape> > ChildList;
CompositeShape() {}
CompositeShape(const CompositeShape& cs,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
Shape(cs,copyop),
_children(cs._children) {}
META_Shape(osg, CompositeShape)
/** Set the shape that encloses all of the children.*/
void setShape(Shape* shape) { _shape = shape; }
/** Get the shape that encloses all of the children.*/
Shape* getShape() { return _shape.get(); }
/** Get the const shape that encloses all of the children.*/
const Shape* getShape() const { return _shape.get(); }
/** Get the number of children of this composite shape.*/
unsigned int getNumChildren() const { return _children.size(); }
/** Get a child.*/
Shape* getChild(unsigned int i) { return _children[i].get(); }
/** Get a const child.*/
const Shape* getChild(unsigned int i) const { return _children[i].get(); }
/** Add a child to the list.*/
void addChild(Shape* shape) { _children.push_back(shape); }
/** remove a child from the list.*/
void removeChild(unsigned int i) { _children.erase(_children.begin()+i); }
/** find the index number of child, if child is not found then it returns getNumChildren(),
* so should be used in similar sytle of STL's result!=end().*/
unsigned int findChildNo(Shape* shape) const
{
for (unsigned int childNo=0;childNo<_children.size();++childNo)
{
if (_children[childNo]==shape) return childNo;
}
return _children.size(); // node not found.
}
protected:
~CompositeShape() {}
ref_ptr<Shape> _shape;
ChildList _children;
};
}
#endif