| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| 2 | * |
|---|
| 3 | * This library is open source and may be redistributed and/or modified under |
|---|
| 4 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|---|
| 5 | * (at your option) any later version. The full license is in LICENSE file |
|---|
| 6 | * included with this distribution, and on the openscenegraph.org website. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | * OpenSceneGraph Public License for more details. |
|---|
| 12 | */ |
|---|
| 13 | |
|---|
| 14 | #ifndef OSG_SHAPE |
|---|
| 15 | #define OSG_SHAPE 1 |
|---|
| 16 | |
|---|
| 17 | #include <osg/Object> |
|---|
| 18 | #include <osg/Vec3> |
|---|
| 19 | #include <osg/Quat> |
|---|
| 20 | #include <osg/Plane> |
|---|
| 21 | #include <osg/Array> |
|---|
| 22 | |
|---|
| 23 | namespace osg { |
|---|
| 24 | |
|---|
| 25 | // forward decare visitors. |
|---|
| 26 | class ShapeVisitor; |
|---|
| 27 | class ConstShapeVisitor; |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | /** META_StateAttribute macro define the standard clone, isSameKindAs, |
|---|
| 31 | * className and getType methods. |
|---|
| 32 | * Use when subclassing from Object to make it more convenient to define |
|---|
| 33 | * the standard pure virtual methods which are required for all Object |
|---|
| 34 | * subclasses.*/ |
|---|
| 35 | #define META_Shape(library,name) \ |
|---|
| 36 | virtual osg::Object* cloneType() const { return new name(); } \ |
|---|
| 37 | virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \ |
|---|
| 38 | virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const name *>(obj)!=NULL; } \ |
|---|
| 39 | virtual const char* libraryName() const { return #library; } \ |
|---|
| 40 | virtual const char* className() const { return #name; } \ |
|---|
| 41 | virtual void accept(osg::ShapeVisitor& sv) { sv.apply(*this); } \ |
|---|
| 42 | virtual void accept(osg::ConstShapeVisitor& csv) const { csv.apply(*this); } |
|---|
| 43 | |
|---|
| 44 | /** Base class for all shape types. |
|---|
| 45 | * Shapes are used to either for culling and collision detection or |
|---|
| 46 | * to define the geometric shape of procedurally generate Geometry. |
|---|
| 47 | */ |
|---|
| 48 | class OSG_EXPORT Shape : public Object |
|---|
| 49 | { |
|---|
| 50 | public: |
|---|
| 51 | |
|---|
| 52 | Shape() {} |
|---|
| 53 | |
|---|
| 54 | Shape(const Shape& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 55 | Object(sa,copyop) {} |
|---|
| 56 | |
|---|
| 57 | /** Clone the type of an attribute, with Object* return type. |
|---|
| 58 | Must be defined by derived classes.*/ |
|---|
| 59 | virtual Object* cloneType() const = 0; |
|---|
| 60 | |
|---|
| 61 | /** Clone an attribute, with Object* return type. |
|---|
| 62 | Must be defined by derived classes.*/ |
|---|
| 63 | virtual Object* clone(const CopyOp&) const = 0; |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | /** return true if this and obj are of the same kind of object.*/ |
|---|
| 67 | virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Shape*>(obj)!=NULL; } |
|---|
| 68 | |
|---|
| 69 | /** return the name of the attribute's library.*/ |
|---|
| 70 | virtual const char* libraryName() const { return "osg"; } |
|---|
| 71 | |
|---|
| 72 | /** return the name of the attribute's class type.*/ |
|---|
| 73 | virtual const char* className() const { return "Shape"; } |
|---|
| 74 | |
|---|
| 75 | /** accept a non const shape visitor which can be used on non const shape objects. |
|---|
| 76 | Must be defined by derived classes.*/ |
|---|
| 77 | virtual void accept(ShapeVisitor&)=0; |
|---|
| 78 | |
|---|
| 79 | /** accept a const shape visitor which can be used on const shape objects. |
|---|
| 80 | Must be defined by derived classes.*/ |
|---|
| 81 | virtual void accept(ConstShapeVisitor&) const =0; |
|---|
| 82 | |
|---|
| 83 | protected: |
|---|
| 84 | |
|---|
| 85 | virtual ~Shape(); |
|---|
| 86 | }; |
|---|
| 87 | |
|---|
| 88 | // forward declarations of Shape types. |
|---|
| 89 | class Sphere; |
|---|
| 90 | class Box; |
|---|
| 91 | class Cone; |
|---|
| 92 | class Cylinder; |
|---|
| 93 | class Capsule; |
|---|
| 94 | class InfinitePlane; |
|---|
| 95 | |
|---|
| 96 | class TriangleMesh; |
|---|
| 97 | class ConvexHull; |
|---|
| 98 | class HeightField; |
|---|
| 99 | |
|---|
| 100 | class CompositeShape; |
|---|
| 101 | |
|---|
| 102 | class OSG_EXPORT ShapeVisitor |
|---|
| 103 | { |
|---|
| 104 | public: |
|---|
| 105 | |
|---|
| 106 | ShapeVisitor() {} |
|---|
| 107 | virtual ~ShapeVisitor(); |
|---|
| 108 | |
|---|
| 109 | virtual void apply(Shape&) {} |
|---|
| 110 | virtual void apply(Sphere&) {} |
|---|
| 111 | virtual void apply(Box&) {} |
|---|
| 112 | virtual void apply(Cone&) {} |
|---|
| 113 | virtual void apply(Cylinder&) {} |
|---|
| 114 | virtual void apply(Capsule&) {} |
|---|
| 115 | virtual void apply(InfinitePlane&) {} |
|---|
| 116 | |
|---|
| 117 | virtual void apply(TriangleMesh&) {} |
|---|
| 118 | virtual void apply(ConvexHull&) {} |
|---|
| 119 | virtual void apply(HeightField&) {} |
|---|
| 120 | |
|---|
| 121 | virtual void apply(CompositeShape&) {} |
|---|
| 122 | }; |
|---|
| 123 | |
|---|
| 124 | class OSG_EXPORT ConstShapeVisitor |
|---|
| 125 | { |
|---|
| 126 | public: |
|---|
| 127 | |
|---|
| 128 | ConstShapeVisitor() {} |
|---|
| 129 | virtual ~ConstShapeVisitor(); |
|---|
| 130 | |
|---|
| 131 | virtual void apply(const Shape&) {} |
|---|
| 132 | virtual void apply(const Sphere&) {} |
|---|
| 133 | virtual void apply(const Box&) {} |
|---|
| 134 | virtual void apply(const Cone&) {} |
|---|
| 135 | virtual void apply(const Cylinder&) {} |
|---|
| 136 | virtual void apply(const Capsule&) {} |
|---|
| 137 | virtual void apply(const InfinitePlane&) {} |
|---|
| 138 | |
|---|
| 139 | virtual void apply(const TriangleMesh&) {} |
|---|
| 140 | virtual void apply(const ConvexHull&) {} |
|---|
| 141 | virtual void apply(const HeightField&) {} |
|---|
| 142 | |
|---|
| 143 | virtual void apply(const CompositeShape&) {} |
|---|
| 144 | }; |
|---|
| 145 | |
|---|
| 146 | class OSG_EXPORT Sphere : public Shape |
|---|
| 147 | { |
|---|
| 148 | public: |
|---|
| 149 | |
|---|
| 150 | Sphere(): |
|---|
| 151 | _center(0.0f,0.0f,0.0f), |
|---|
| 152 | _radius(1.0f) {} |
|---|
| 153 | |
|---|
| 154 | Sphere(const osg::Vec3& center,float radius): |
|---|
| 155 | _center(center), |
|---|
| 156 | _radius(radius) {} |
|---|
| 157 | |
|---|
| 158 | Sphere(const Sphere& sphere,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 159 | Shape(sphere,copyop), |
|---|
| 160 | _center(sphere._center), |
|---|
| 161 | _radius(sphere._radius) {} |
|---|
| 162 | |
|---|
| 163 | META_Shape(osg, Sphere); |
|---|
| 164 | |
|---|
| 165 | inline bool valid() const { return _radius>=0.0f; } |
|---|
| 166 | |
|---|
| 167 | inline void set(const Vec3& center,float radius) |
|---|
| 168 | { |
|---|
| 169 | _center = center; |
|---|
| 170 | _radius = radius; |
|---|
| 171 | } |
|---|
| 172 | |
|---|
| 173 | inline void setCenter(const Vec3& center) { _center = center; } |
|---|
| 174 | inline const Vec3& getCenter() const { return _center; } |
|---|
| 175 | |
|---|
| 176 | inline void setRadius(float radius) { _radius = radius; } |
|---|
| 177 | inline float getRadius() const { return _radius; } |
|---|
| 178 | |
|---|
| 179 | protected: |
|---|
| 180 | |
|---|
| 181 | virtual ~Sphere(); |
|---|
| 182 | |
|---|
| 183 | Vec3 _center; |
|---|
| 184 | float _radius; |
|---|
| 185 | |
|---|
| 186 | }; |
|---|
| 187 | |
|---|
| 188 | class OSG_EXPORT Box : public Shape |
|---|
| 189 | { |
|---|
| 190 | public: |
|---|
| 191 | |
|---|
| 192 | Box(): |
|---|
| 193 | _center(0.0f,0.0f,0.0f), |
|---|
| 194 | _halfLengths(0.5f,0.5f,0.5f) {} |
|---|
| 195 | |
|---|
| 196 | Box(const osg::Vec3& center,float width): |
|---|
| 197 | _center(center), |
|---|
| 198 | _halfLengths(width*0.5f,width*0.5f,width*0.5f) {} |
|---|
| 199 | |
|---|
| 200 | Box(const osg::Vec3& center,float lengthX,float lengthY, float lengthZ): |
|---|
| 201 | _center(center), |
|---|
| 202 | _halfLengths(lengthX*0.5f,lengthY*0.5f,lengthZ*0.5f) {} |
|---|
| 203 | |
|---|
| 204 | Box(const Box& box,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 205 | Shape(box,copyop), |
|---|
| 206 | _center(box._center), |
|---|
| 207 | _halfLengths(box._halfLengths), |
|---|
| 208 | _rotation(box._rotation) {} |
|---|
| 209 | |
|---|
| 210 | META_Shape(osg, Box); |
|---|
| 211 | |
|---|
| 212 | inline bool valid() const { return _halfLengths.x()>=0.0f; } |
|---|
| 213 | |
|---|
| 214 | inline void set(const Vec3& center,const Vec3& halfLengths) |
|---|
| 215 | { |
|---|
| 216 | _center = center; |
|---|
| 217 | _halfLengths = halfLengths; |
|---|
| 218 | } |
|---|
| 219 | |
|---|
| 220 | inline void setCenter(const Vec3& center) { _center = center; } |
|---|
| 221 | inline const Vec3& getCenter() const { return _center; } |
|---|
| 222 | |
|---|
| 223 | inline void setHalfLengths(const Vec3& halfLengths) { _halfLengths = halfLengths; } |
|---|
| 224 | inline const Vec3& getHalfLengths() const { return _halfLengths; } |
|---|
| 225 | |
|---|
| 226 | inline void setRotation(const Quat& quat) { _rotation = quat; } |
|---|
| 227 | inline const Quat& getRotation() const { return _rotation; } |
|---|
| 228 | inline Matrix computeRotationMatrix() const { return Matrix(_rotation); } |
|---|
| 229 | inline bool zeroRotation() const { return _rotation.zeroRotation(); } |
|---|
| 230 | |
|---|
| 231 | protected: |
|---|
| 232 | |
|---|
| 233 | virtual ~Box(); |
|---|
| 234 | |
|---|
| 235 | Vec3 _center; |
|---|
| 236 | Vec3 _halfLengths; |
|---|
| 237 | Quat _rotation; |
|---|
| 238 | |
|---|
| 239 | }; |
|---|
| 240 | |
|---|
| 241 | |
|---|
| 242 | |
|---|
| 243 | class OSG_EXPORT Cone : public Shape |
|---|
| 244 | { |
|---|
| 245 | public: |
|---|
| 246 | |
|---|
| 247 | Cone(): |
|---|
| 248 | _center(0.0f,0.0f,0.0f), |
|---|
| 249 | _radius(1.0f), |
|---|
| 250 | _height(1.0f) {} |
|---|
| 251 | |
|---|
| 252 | Cone(const osg::Vec3& center,float radius,float height): |
|---|
| 253 | _center(center), |
|---|
| 254 | _radius(radius), |
|---|
| 255 | _height(height) {} |
|---|
| 256 | |
|---|
| 257 | Cone(const Cone& cone,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 258 | Shape(cone,copyop), |
|---|
| 259 | _center(cone._center), |
|---|
| 260 | _radius(cone._radius), |
|---|
| 261 | _height(cone._height), |
|---|
| 262 | _rotation(cone._rotation) {} |
|---|
| 263 | |
|---|
| 264 | META_Shape(osg, Cone); |
|---|
| 265 | |
|---|
| 266 | inline bool valid() const { return _radius>=0.0f; } |
|---|
| 267 | |
|---|
| 268 | inline void set(const Vec3& center,float radius, float height) |
|---|
| 269 | { |
|---|
| 270 | _center = center; |
|---|
| 271 | _radius = radius; |
|---|
| 272 | _height = height; |
|---|
| 273 | } |
|---|
| 274 | |
|---|
| 275 | inline void setCenter(const Vec3& center) { _center = center; } |
|---|
| 276 | inline const Vec3& getCenter() const { return _center; } |
|---|
| 277 | |
|---|
| 278 | inline void setRadius(float radius) { _radius = radius; } |
|---|
| 279 | inline float getRadius() const { return _radius; } |
|---|
| 280 | |
|---|
| 281 | inline void setHeight(float height) { _height = height; } |
|---|
| 282 | inline float getHeight() const { return _height; } |
|---|
| 283 | |
|---|
| 284 | inline void setRotation(const Quat& quat) { _rotation = quat; } |
|---|
| 285 | inline const Quat& getRotation() const { return _rotation; } |
|---|
| 286 | inline Matrix computeRotationMatrix() const { return Matrix(_rotation); } |
|---|
| 287 | inline bool zeroRotation() const { return _rotation.zeroRotation(); } |
|---|
| 288 | |
|---|
| 289 | inline float getBaseOffsetFactor() const { return 0.25f; } |
|---|
| 290 | inline float getBaseOffset() const { return -getBaseOffsetFactor()*getHeight(); } |
|---|
| 291 | |
|---|
| 292 | protected: |
|---|
| 293 | |
|---|
| 294 | virtual ~Cone(); |
|---|
| 295 | |
|---|
| 296 | Vec3 _center; |
|---|
| 297 | float _radius; |
|---|
| 298 | float _height; |
|---|
| 299 | |
|---|
| 300 | Quat _rotation; |
|---|
| 301 | }; |
|---|
| 302 | |
|---|
| 303 | class OSG_EXPORT Cylinder : public Shape |
|---|
| 304 | { |
|---|
| 305 | public: |
|---|
| 306 | |
|---|
| 307 | Cylinder(): |
|---|
| 308 | _center(0.0f,0.0f,0.0f), |
|---|
| 309 | _radius(1.0f), |
|---|
| 310 | _height(1.0f) {} |
|---|
| 311 | |
|---|
| 312 | Cylinder(const osg::Vec3& center,float radius,float height): |
|---|
| 313 | _center(center), |
|---|
| 314 | _radius(radius), |
|---|
| 315 | _height(height) {} |
|---|
| 316 | |
|---|
| 317 | Cylinder(const Cylinder& cylinder,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 318 | Shape(cylinder,copyop), |
|---|
| 319 | _center(cylinder._center), |
|---|
| 320 | _radius(cylinder._radius), |
|---|
| 321 | _height(cylinder._height), |
|---|
| 322 | _rotation(cylinder._rotation) {} |
|---|
| 323 | |
|---|
| 324 | META_Shape(osg, Cylinder); |
|---|
| 325 | |
|---|
| 326 | inline bool valid() const { return _radius>=0.0f; } |
|---|
| 327 | |
|---|
| 328 | inline void set(const Vec3& center,float radius, float height) |
|---|
| 329 | { |
|---|
| 330 | _center = center; |
|---|
| 331 | _radius = radius; |
|---|
| 332 | _height = height; |
|---|
| 333 | } |
|---|
| 334 | |
|---|
| 335 | inline void setCenter(const Vec3& center) { _center = center; } |
|---|
| 336 | inline const Vec3& getCenter() const { return _center; } |
|---|
| 337 | |
|---|
| 338 | inline void setRadius(float radius) { _radius = radius; } |
|---|
| 339 | inline float getRadius() const { return _radius; } |
|---|
| 340 | |
|---|
| 341 | inline void setHeight(float height) { _height = height; } |
|---|
| 342 | inline float getHeight() const { return _height; } |
|---|
| 343 | |
|---|
| 344 | inline void setRotation(const Quat& quat) { _rotation = quat; } |
|---|
| 345 | inline const Quat& getRotation() const { return _rotation; } |
|---|
| 346 | inline Matrix computeRotationMatrix() const { return Matrix(_rotation); } |
|---|
| 347 | bool zeroRotation() const { return _rotation.zeroRotation(); } |
|---|
| 348 | |
|---|
| 349 | protected: |
|---|
| 350 | |
|---|
| 351 | virtual ~Cylinder(); |
|---|
| 352 | |
|---|
| 353 | Vec3 _center; |
|---|
| 354 | float _radius; |
|---|
| 355 | float _height; |
|---|
| 356 | Quat _rotation; |
|---|
| 357 | }; |
|---|
| 358 | |
|---|
| 359 | class OSG_EXPORT Capsule : public Shape |
|---|
| 360 | { |
|---|
| 361 | public: |
|---|
| 362 | |
|---|
| 363 | Capsule(): |
|---|
| 364 | _center(0.0f,0.0f,0.0f), |
|---|
| 365 | _radius(1.0f), |
|---|
| 366 | _height(1.0f) {} |
|---|
| 367 | |
|---|
| 368 | Capsule(const osg::Vec3& center,float radius,float height): |
|---|
| 369 | _center(center), |
|---|
| 370 | _radius(radius), |
|---|
| 371 | _height(height) {} |
|---|
| 372 | |
|---|
| 373 | Capsule(const Capsule& capsule,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 374 | Shape(capsule,copyop), |
|---|
| 375 | _center(capsule._center), |
|---|
| 376 | _radius(capsule._radius), |
|---|
| 377 | _height(capsule._height), |
|---|
| 378 | _rotation(capsule._rotation) {} |
|---|
| 379 | |
|---|
| 380 | META_Shape(osg, Capsule); |
|---|
| 381 | |
|---|
| 382 | inline bool valid() const { return _radius>=0.0f; } |
|---|
| 383 | |
|---|
| 384 | inline void set(const Vec3& center,float radius, float height) |
|---|
| 385 | { |
|---|
| 386 | _center = center; |
|---|
| 387 | _radius = radius; |
|---|
| 388 | _height = height; |
|---|
| 389 | } |
|---|
| 390 | |
|---|
| 391 | inline void setCenter(const Vec3& center) { _center = center; } |
|---|
| 392 | inline const Vec3& getCenter() const { return _center; } |
|---|
| 393 | |
|---|
| 394 | inline void setRadius(float radius) { _radius = radius; } |
|---|
| 395 | inline float getRadius() const { return _radius; } |
|---|
| 396 | |
|---|
| 397 | inline void setHeight(float height) { _height = height; } |
|---|
| 398 | inline float getHeight() const { return _height; } |
|---|
| 399 | |
|---|
| 400 | inline void setRotation(const Quat& quat) { _rotation = quat; } |
|---|
| 401 | inline const Quat& getRotation() const { return _rotation; } |
|---|
| 402 | inline Matrix computeRotationMatrix() const { return Matrix(_rotation); } |
|---|
| 403 | bool zeroRotation() const { return _rotation.zeroRotation(); } |
|---|
| 404 | |
|---|
| 405 | protected: |
|---|
| 406 | |
|---|
| 407 | virtual ~Capsule(); |
|---|
| 408 | |
|---|
| 409 | Vec3 _center; |
|---|
| 410 | float _radius; |
|---|
| 411 | float _height; |
|---|
| 412 | Quat _rotation; |
|---|
| 413 | }; |
|---|
| 414 | |
|---|
| 415 | class OSG_EXPORT InfinitePlane : public Shape, public Plane |
|---|
| 416 | { |
|---|
| 417 | public: |
|---|
| 418 | InfinitePlane() {} |
|---|
| 419 | |
|---|
| 420 | InfinitePlane(const InfinitePlane& plane,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 421 | Shape(plane,copyop), |
|---|
| 422 | Plane(plane) {} |
|---|
| 423 | |
|---|
| 424 | META_Shape(osg, InfinitePlane); |
|---|
| 425 | |
|---|
| 426 | protected: |
|---|
| 427 | |
|---|
| 428 | virtual ~InfinitePlane(); |
|---|
| 429 | }; |
|---|
| 430 | |
|---|
| 431 | /** Exists to support collision detection engines not for doing rendering, use \ref osg::Geometry instead. |
|---|
| 432 | */ |
|---|
| 433 | class OSG_EXPORT TriangleMesh : public Shape |
|---|
| 434 | { |
|---|
| 435 | public: |
|---|
| 436 | |
|---|
| 437 | TriangleMesh() {} |
|---|
| 438 | |
|---|
| 439 | TriangleMesh(const TriangleMesh& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 440 | Shape(mesh,copyop), |
|---|
| 441 | _vertices(mesh._vertices), |
|---|
| 442 | _indices(mesh._indices) {} |
|---|
| 443 | |
|---|
| 444 | META_Shape(osg, TriangleMesh); |
|---|
| 445 | |
|---|
| 446 | |
|---|
| 447 | void setVertices(Vec3Array* vertices) { _vertices = vertices; } |
|---|
| 448 | Vec3Array* getVertices() { return _vertices.get(); } |
|---|
| 449 | const Vec3Array* getVertices() const { return _vertices.get(); } |
|---|
| 450 | |
|---|
| 451 | |
|---|
| 452 | void setIndices(IndexArray* indices) { _indices = indices; } |
|---|
| 453 | IndexArray* getIndices() { return _indices.get(); } |
|---|
| 454 | const IndexArray* getIndices() const { return _indices.get(); } |
|---|
| 455 | |
|---|
| 456 | protected: |
|---|
| 457 | |
|---|
| 458 | virtual ~TriangleMesh(); |
|---|
| 459 | |
|---|
| 460 | ref_ptr<Vec3Array> _vertices; |
|---|
| 461 | ref_ptr<IndexArray> _indices; |
|---|
| 462 | |
|---|
| 463 | }; |
|---|
| 464 | |
|---|
| 465 | class OSG_EXPORT ConvexHull : public TriangleMesh |
|---|
| 466 | { |
|---|
| 467 | public: |
|---|
| 468 | |
|---|
| 469 | ConvexHull() {} |
|---|
| 470 | |
|---|
| 471 | ConvexHull(const ConvexHull& hull,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 472 | TriangleMesh(hull,copyop) {} |
|---|
| 473 | |
|---|
| 474 | META_Shape(osg, TriangleMesh); |
|---|
| 475 | |
|---|
| 476 | protected: |
|---|
| 477 | |
|---|
| 478 | virtual ~ConvexHull(); |
|---|
| 479 | }; |
|---|
| 480 | |
|---|
| 481 | class OSG_EXPORT HeightField : public Shape |
|---|
| 482 | { |
|---|
| 483 | public: |
|---|
| 484 | |
|---|
| 485 | HeightField(); |
|---|
| 486 | |
|---|
| 487 | HeightField(const HeightField& mesh,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 488 | |
|---|
| 489 | META_Shape(osg, HeightField); |
|---|
| 490 | |
|---|
| 491 | typedef std::vector<float> HeightList; |
|---|
| 492 | |
|---|
| 493 | void allocate(unsigned int numColumns,unsigned int numRows); |
|---|
| 494 | |
|---|
| 495 | inline unsigned int getNumColumns() const { return _columns; } |
|---|
| 496 | inline unsigned int getNumRows() const { return _rows; } |
|---|
| 497 | |
|---|
| 498 | inline void setOrigin(const osg::Vec3& origin) { _origin = origin; } |
|---|
| 499 | inline const osg::Vec3& getOrigin() const { return _origin; } |
|---|
| 500 | |
|---|
| 501 | inline void setXInterval(float dx) { _dx = dx; } |
|---|
| 502 | inline float getXInterval() const { return _dx; } |
|---|
| 503 | |
|---|
| 504 | inline void setYInterval(float dy) { _dy = dy; } |
|---|
| 505 | inline float getYInterval() const { return _dy; } |
|---|
| 506 | |
|---|
| 507 | /** Get the FloatArray height data.*/ |
|---|
| 508 | osg::FloatArray* getFloatArray() { return _heights.get(); } |
|---|
| 509 | |
|---|
| 510 | /** Get the const FloatArray height data.*/ |
|---|
| 511 | const osg::FloatArray* getFloatArray() const { return _heights.get(); } |
|---|
| 512 | |
|---|
| 513 | HeightList& getHeightList() { return _heights->asVector(); } |
|---|
| 514 | |
|---|
| 515 | const HeightList& getHeightList() const { return _heights->asVector(); } |
|---|
| 516 | |
|---|
| 517 | /** Set the height of the skirt to render around the edge of HeightField. |
|---|
| 518 | * The skirt is used as a means of disguising edge boundaries between adjacent HeightField, |
|---|
| 519 | * particularly of ones with different resolutions.*/ |
|---|
| 520 | void setSkirtHeight(float skirtHeight) { _skirtHeight = skirtHeight; } |
|---|
| 521 | |
|---|
| 522 | /** Get the height of the skirt to render around the edge of HeightField.*/ |
|---|
| 523 | float getSkirtHeight() const { return _skirtHeight; } |
|---|
| 524 | |
|---|
| 525 | /** Set the width in number of cells in from the edge that the height field should be rendered from. |
|---|
| 526 | * This exists to allow gradient and curvature continutity to be maintained between adjacent HeightField, where |
|---|
| 527 | * the border cells will overlap adjacent HeightField.*/ |
|---|
| 528 | void setBorderWidth(unsigned int borderWidth) { _borderWidth = borderWidth; } |
|---|
| 529 | |
|---|
| 530 | /** Get the width in number of cells in from the edge that the height field should be rendered from.*/ |
|---|
| 531 | unsigned int getBorderWidth() const { return _borderWidth; } |
|---|
| 532 | |
|---|
| 533 | inline void setRotation(const Quat& quat) { _rotation = quat; } |
|---|
| 534 | inline const Quat& getRotation() const { return _rotation; } |
|---|
| 535 | inline Matrix computeRotationMatrix() const { return Matrix(_rotation); } |
|---|
| 536 | inline bool zeroRotation() const { return _rotation.zeroRotation(); } |
|---|
| 537 | |
|---|
| 538 | /* set a single height point in the height field */ |
|---|
| 539 | inline void setHeight(unsigned int c,unsigned int r,float value) |
|---|
| 540 | { |
|---|
| 541 | (*_heights)[c+r*_columns] = value; |
|---|
| 542 | } |
|---|
| 543 | |
|---|
| 544 | /* Get address of single height point in the height field, allows user to change. */ |
|---|
| 545 | inline float& getHeight(unsigned int c,unsigned int r) |
|---|
| 546 | { |
|---|
| 547 | return (*_heights)[c+r*_columns]; |
|---|
| 548 | } |
|---|
| 549 | |
|---|
| 550 | /* Get value of single height point in the height field, not editable. */ |
|---|
| 551 | inline float getHeight(unsigned int c,unsigned int r) const |
|---|
| 552 | { |
|---|
| 553 | return (*_heights)[c+r*_columns]; |
|---|
| 554 | } |
|---|
| 555 | |
|---|
| 556 | inline Vec3 getVertex(unsigned int c,unsigned int r) const |
|---|
| 557 | { |
|---|
| 558 | return Vec3(_origin.x()+getXInterval()*(float)c, |
|---|
| 559 | _origin.y()+getYInterval()*(float)r, |
|---|
| 560 | _origin.z()+(*_heights)[c+r*_columns]); |
|---|
| 561 | } |
|---|
| 562 | |
|---|
| 563 | Vec3 getNormal(unsigned int c,unsigned int r) const; |
|---|
| 564 | |
|---|
| 565 | Vec2 getHeightDelta(unsigned int c,unsigned int r) const; |
|---|
| 566 | |
|---|
| 567 | protected: |
|---|
| 568 | |
|---|
| 569 | virtual ~HeightField(); |
|---|
| 570 | |
|---|
| 571 | unsigned int _columns,_rows; |
|---|
| 572 | |
|---|
| 573 | osg::Vec3 _origin; // _origin is the min value of the X and Y coordinates. |
|---|
| 574 | float _dx; |
|---|
| 575 | float _dy; |
|---|
| 576 | |
|---|
| 577 | float _skirtHeight; |
|---|
| 578 | unsigned int _borderWidth; |
|---|
| 579 | |
|---|
| 580 | Quat _rotation; |
|---|
| 581 | osg::ref_ptr<osg::FloatArray> _heights; |
|---|
| 582 | |
|---|
| 583 | }; |
|---|
| 584 | |
|---|
| 585 | typedef HeightField Grid; |
|---|
| 586 | |
|---|
| 587 | |
|---|
| 588 | class OSG_EXPORT CompositeShape : public Shape |
|---|
| 589 | { |
|---|
| 590 | public: |
|---|
| 591 | |
|---|
| 592 | |
|---|
| 593 | |
|---|
| 594 | typedef std::vector< ref_ptr<Shape> > ChildList; |
|---|
| 595 | |
|---|
| 596 | CompositeShape() {} |
|---|
| 597 | |
|---|
| 598 | CompositeShape(const CompositeShape& cs,const CopyOp& copyop=CopyOp::SHALLOW_COPY): |
|---|
| 599 | Shape(cs,copyop), |
|---|
| 600 | _children(cs._children) {} |
|---|
| 601 | |
|---|
| 602 | META_Shape(osg, CompositeShape); |
|---|
| 603 | |
|---|
| 604 | /** Set the shape that encloses all of the children.*/ |
|---|
| 605 | void setShape(Shape* shape) { _shape = shape; } |
|---|
| 606 | |
|---|
| 607 | /** Get the shape that encloses all of the children.*/ |
|---|
| 608 | Shape* getShape() { return _shape.get(); } |
|---|
| 609 | |
|---|
| 610 | /** Get the const shape that encloses all of the children.*/ |
|---|
| 611 | const Shape* getShape() const { return _shape.get(); } |
|---|
| 612 | |
|---|
| 613 | /** Get the number of children of this composite shape.*/ |
|---|
| 614 | unsigned int getNumChildren() const { return static_cast<unsigned int>(_children.size()); } |
|---|
| 615 | |
|---|
| 616 | /** Get a child.*/ |
|---|
| 617 | Shape* getChild(unsigned int i) { return _children[i].get(); } |
|---|
| 618 | |
|---|
| 619 | /** Get a const child.*/ |
|---|
| 620 | const Shape* getChild(unsigned int i) const { return _children[i].get(); } |
|---|
| 621 | |
|---|
| 622 | /** Add a child to the list.*/ |
|---|
| 623 | void addChild(Shape* shape) { _children.push_back(shape); } |
|---|
| 624 | |
|---|
| 625 | /** remove a child from the list.*/ |
|---|
| 626 | void removeChild(unsigned int i) { _children.erase(_children.begin()+i); } |
|---|
| 627 | |
|---|
| 628 | /** find the index number of child, if child is not found then it returns getNumChildren(), |
|---|
| 629 | * so should be used in similar style to STL's result!=end().*/ |
|---|
| 630 | unsigned int findChildNo(Shape* shape) const |
|---|
| 631 | { |
|---|
| 632 | for (unsigned int childNo=0;childNo<_children.size();++childNo) |
|---|
| 633 | { |
|---|
| 634 | if (_children[childNo]==shape) return childNo; |
|---|
| 635 | } |
|---|
| 636 | return static_cast<unsigned int>(_children.size()); // node not found. |
|---|
| 637 | |
|---|
| 638 | } |
|---|
| 639 | |
|---|
| 640 | protected: |
|---|
| 641 | |
|---|
| 642 | virtual ~CompositeShape(); |
|---|
| 643 | |
|---|
| 644 | ref_ptr<Shape> _shape; |
|---|
| 645 | ChildList _children; |
|---|
| 646 | |
|---|
| 647 | }; |
|---|
| 648 | |
|---|
| 649 | } |
|---|
| 650 | |
|---|
| 651 | #endif |
|---|