1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 #ifndef __Ogre_Volume_OctreeNode_H__ 29 #define __Ogre_Volume_OctreeNode_H__ 30 31 #include "OgreVolumePrerequisites.h" 32 #include "OgreVector3.h" 33 #include "OgreVector4.h" 34 35 namespace Ogre { 36 37 namespace Volume { 38 /** \addtogroup Optional 39 * @{ 40 */ 41 /** \addtogroup Volume 42 * @{ 43 */ 44 class OctreeNodeSplitPolicy; 45 class Source; 46 47 /** A node in the volume octree. 48 */ 49 class _OgreVolumeExport OctreeNode : public UtilityAlloc 50 { 51 protected: 52 53 /// Factor to the diagonal of the cell to decide whether this cell is near the isosurface or not. 54 static const Real NEAR_FACTOR; 55 56 /// To count some indices while creating the debug view and recursing through the instances. 57 static uint32 mGridPositionCount; 58 59 /// To give the debug manual object an unique name. 60 static size_t mNodeI; 61 62 /// The back lower left corner of the cell. 63 Vector3 mFrom; 64 65 /// The front upper right corner of the cell. 66 Vector3 mTo; 67 68 /// The children of this node. 69 OctreeNode **mChildren; 70 71 /// Holds the debug visualization of the octree. Just set in the root. 72 Entity* mOctreeGrid; 73 74 /// Density and gradient of the center. 75 Vector4 mCenterValue; 76 77 /** Method to actually add the lines of the octree cells to 78 the debug visualization. 79 @param manual 80 The manual object to add the lines to if this is a leaf in the octree. 81 */ 82 void buildOctreeGridLines(ManualObject *manual) const; 83 public: 84 85 /// Even in an OCtree, the amount of children should not be hardcoded. 86 static const size_t OCTREE_CHILDREN_COUNT; 87 88 /** Gets the center and width / height / depth vector of the children of a node. 89 @param from 90 The back lower left corner of the cell. 91 @param to 92 The front upper right corner of the cell. 93 @param center 94 Out parameter of the calculated center. 95 @param width 96 Out parameter of the width vector (width in x, rest zero). 97 @param height 98 Out parameter of the height vector (height in y, rest zero). 99 @param depth 100 Out parameter of the depth vector (depth in z, rest zero). 101 */ getChildrenDimensions(const Vector3 & from,const Vector3 & to,Vector3 & center,Vector3 & width,Vector3 & height,Vector3 & depth)102 static inline void getChildrenDimensions(const Vector3 &from, const Vector3 &to, Vector3 ¢er, Vector3 &width, Vector3 &height, Vector3 &depth) 103 { 104 center = (to - from) / (Real)2.0; 105 width.x = center.x; 106 width.y = (Real)0.0; 107 width.z = (Real)0.0; 108 height.x = (Real)0.0; 109 height.y = center.y; 110 height.z = (Real)0.0; 111 depth.x = (Real)0.0; 112 depth.y = (Real)0.0; 113 depth.z = center.z; 114 center += from; 115 } 116 117 /** Constructor. 118 @param from 119 The back lower left corner of the cell. 120 @param to 121 The front upper right corner of the cell. 122 */ 123 OctreeNode(const Vector3 &from = Vector3::ZERO, const Vector3 &to = Vector3::ZERO); 124 125 /** Destructor. 126 */ 127 virtual ~OctreeNode(void); 128 129 /** Factory method to create octree nodes. 130 @param from 131 The back lower left corner of the cell. 132 @param to 133 The front upper right corner of the cell. 134 @return 135 The created entity. Make sure to destroy it when you don't need it anymore. 136 */ 137 virtual OctreeNode* createInstance(const Vector3& from, const Vector3& to); 138 139 /** Splits this cell if the split policy says so. 140 @param splitPolicy 141 Defines the policy deciding whether to split this node or not. 142 @param src 143 The volume source. 144 @param geometricError 145 The accepted geometric error. 146 */ 147 void split(const OctreeNodeSplitPolicy *splitPolicy, const Source *src, const Real geometricError); 148 149 /** Getter for the octree debug visualization of the octree starting with 150 this node. 151 @param sceneManager 152 The scenemanager creating the actual entity. 153 @return 154 The lazily created debug visualization. 155 */ 156 Entity* getOctreeGrid(SceneManager *sceneManager); 157 158 /** Setter for the from-part of this cell. 159 @param from 160 The back lower left corner of the cell. 161 */ setFrom(Vector3 from)162 inline void setFrom(Vector3 from) 163 { 164 mFrom = from; 165 } 166 167 /** Setter for the to-part of this cell. 168 @param to 169 The front upper right corner of the cell. 170 */ setTo(Vector3 to)171 inline void setTo(Vector3 to) 172 { 173 mTo = to; 174 } 175 176 /** Gets whether this cell has any children. 177 @return 178 True if so. 179 */ isSubdivided(void)180 inline bool isSubdivided(void) const 181 { 182 return mChildren != 0; 183 } 184 185 /** Gets an octree child. Enumeration: 186 4 5 187 7 6 188 0 1 189 3 2 190 @param i 191 The child index. 192 @return 193 The child. 194 */ getChild(const size_t i)195 inline const OctreeNode* getChild(const size_t i) const 196 { 197 return mChildren[i]; 198 } 199 200 /** Gets the center of this cell. 201 @return 202 The center. 203 */ getCenter(void)204 inline const Vector3 getCenter(void) const 205 { 206 return (mFrom + mTo) / (Real)2.0; 207 } 208 209 /** Gets the back lower left corner of the cell. 210 @return 211 The back lower left corner of the cell. 212 */ getFrom(void)213 inline const Vector3& getFrom(void) const 214 { 215 return mFrom; 216 } 217 218 /** Gets the front upper right corner of the cell. 219 @return 220 The front upper right corner of the cell. 221 */ getTo(void)222 inline const Vector3& getTo(void) const 223 { 224 return mTo; 225 } 226 227 /** Gets whether this cell is at the left of the given root cell. 228 @param root 229 The octree root node to test against. 230 @return 231 true if so. 232 */ isBorderLeft(const OctreeNode & root)233 inline bool isBorderLeft(const OctreeNode &root) const 234 { 235 return mFrom.x == root.mFrom.x; 236 } 237 238 /** Gets whether this cell is at the right of the given root cell. 239 @param root 240 The octree root node to test against. 241 @return 242 true if so. 243 */ isBorderRight(const OctreeNode & root)244 inline bool isBorderRight(const OctreeNode &root) const 245 { 246 return mTo.x == root.mTo.x; 247 } 248 249 /** Gets whether this cell is at the bottom of the given root cell. 250 @param root 251 The octree root node to test against. 252 @return 253 true if so. 254 */ isBorderBottom(const OctreeNode & root)255 inline bool isBorderBottom(const OctreeNode &root) const 256 { 257 return mFrom.y == root.mFrom.y; 258 } 259 260 /** Gets whether this cell is at the top of the given root cell. 261 @param root 262 The octree root node to test against. 263 @return 264 true if so. 265 */ isBorderTop(const OctreeNode & root)266 inline bool isBorderTop(const OctreeNode &root) const 267 { 268 return mTo.y == root.mTo.y; 269 } 270 271 /** Gets whether this cell is at the back of the given root cell. 272 @param root 273 The octree root node to test against. 274 @return 275 true if so. 276 */ isBorderBack(const OctreeNode & root)277 inline bool isBorderBack(const OctreeNode &root) const 278 { 279 return mFrom.z == root.mFrom.z; 280 } 281 282 /** Gets whether this cell is at the front of the given root cell. 283 @param root 284 The octree root node to test against. 285 @return 286 true if so. 287 */ isBorderFront(const OctreeNode & root)288 inline bool isBorderFront(const OctreeNode &root) const 289 { 290 return mTo.z == root.mTo.z; 291 } 292 293 /** Gets the center of the corners 0, 1, 4, 5. 294 @return 295 The center. 296 */ getCenterBack(void)297 inline const Vector3 getCenterBack(void) const 298 { 299 return Vector3(mFrom.x + (mTo.x - mFrom.x) / (Real)2.0, mFrom.y + (mTo.y - mFrom.y) / (Real)2.0, mFrom.z); 300 } 301 302 /** Gets the center of the corners 2, 3, 6, 7. 303 @return 304 The center. 305 */ getCenterFront(void)306 inline const Vector3 getCenterFront(void) const 307 { 308 return Vector3(mFrom.x + (mTo.x - mFrom.x) / (Real)2.0, mFrom.y + (mTo.y - mFrom.y) / (Real)2.0, mTo.z); 309 } 310 311 /** Gets the center of the corners 0, 3, 4, 6. 312 @return 313 The center. 314 */ getCenterLeft(void)315 inline const Vector3 getCenterLeft(void) const 316 { 317 return Vector3(mFrom.x, mFrom.y + (mTo.y - mFrom.y) / (Real)2.0, mFrom.z + (mTo.z - mFrom.z) / (Real)2.0); 318 } 319 320 /** Gets the center of the corners 1, 2, 5, 6. 321 @return 322 The center. 323 */ getCenterRight(void)324 inline const Vector3 getCenterRight(void) const 325 { 326 return Vector3(mTo.x, mFrom.y + (mTo.y - mFrom.y) / (Real)2.0, mFrom.z + (mTo.z - mFrom.z) / (Real)2.0); 327 } 328 329 /** Gets the center of the corners 4, 5, 6, 7. 330 @return 331 The center. 332 */ getCenterTop(void)333 inline const Vector3 getCenterTop(void) const 334 { 335 return Vector3(mFrom.x + (mTo.x - mFrom.x) / (Real)2.0, mTo.y, mFrom.z + (mTo.z - mFrom.z) / (Real)2.0); 336 } 337 338 /** Gets the center of the corners 0, 1, 2, 3. 339 @return 340 The center. 341 */ getCenterBottom(void)342 inline const Vector3 getCenterBottom(void) const 343 { 344 return Vector3(mFrom.x + (mTo.x - mFrom.x) / (Real)2.0, mFrom.y, mFrom.z + (mTo.z - mFrom.z) / (Real)2.0); 345 } 346 347 /** Gets the center of the corners 4, 5. 348 @return 349 The center. 350 */ getCenterBackTop(void)351 inline const Vector3 getCenterBackTop(void) const 352 { 353 return Vector3(mFrom.x + (mTo.x - mFrom.x) / (Real)2.0, mTo.y, mFrom.z); 354 } 355 356 /** Gets the center of the corners 0, 1. 357 @return 358 The center. 359 */ getCenterBackBottom(void)360 inline const Vector3 getCenterBackBottom(void) const 361 { 362 return Vector3(mFrom.x + (mTo.x - mFrom.x) / (Real)2.0, mFrom.y, mFrom.z); 363 } 364 365 /** Gets the center of the corners 6, 7. 366 @return 367 The center. 368 */ getCenterFrontTop(void)369 inline const Vector3 getCenterFrontTop(void) const 370 { 371 return Vector3(mFrom.x + (mTo.x - mFrom.x) / (Real)2.0, mTo.y, mTo.z); 372 } 373 374 /** Gets the center of the corners 2, 3. 375 @return 376 The center. 377 */ getCenterFrontBottom(void)378 inline const Vector3 getCenterFrontBottom(void) const 379 { 380 return Vector3(mFrom.x + (mTo.x - mFrom.x) / (Real)2.0, mFrom.y, mTo.z); 381 } 382 383 /** Gets the center of the corners 4, 7. 384 @return 385 The center. 386 */ getCenterLeftTop(void)387 inline const Vector3 getCenterLeftTop(void) const 388 { 389 return Vector3(mFrom.x, mTo.y, mFrom.z + (mTo.z - mFrom.z) / (Real)2.0); 390 } 391 392 /** Gets the center of the corners 0, 3. 393 @return 394 The center. 395 */ getCenterLeftBottom(void)396 inline const Vector3 getCenterLeftBottom(void) const 397 { 398 return Vector3(mFrom.x, mFrom.y, mFrom.z + (mTo.z - mFrom.z) / (Real)2.0); 399 } 400 401 /** Gets the center of the corners 5, 6. 402 @return 403 The center. 404 */ getCenterRightTop(void)405 inline const Vector3 getCenterRightTop(void) const 406 { 407 return Vector3(mTo.x, mTo.y, mFrom.z + (mTo.z - mFrom.z) / (Real)2.0); 408 } 409 410 /** Gets the center of the corners 1, 2. 411 @return 412 The center. 413 */ getCenterRightBottom(void)414 inline const Vector3 getCenterRightBottom(void) const 415 { 416 return Vector3(mTo.x, mFrom.y, mFrom.z + (mTo.z - mFrom.z) / (Real)2.0); 417 } 418 419 /** Gets the center of the corners 0, 4. 420 @return 421 The center. 422 */ getCenterBackLeft(void)423 inline const Vector3 getCenterBackLeft(void) const 424 { 425 return Vector3(mFrom.x, mFrom.y + (mTo.y - mFrom.y) / (Real)2.0, mFrom.z); 426 } 427 428 /** Gets the center of the corners 3, 7. 429 @return 430 The center. 431 */ getCenterFrontLeft(void)432 inline const Vector3 getCenterFrontLeft(void) const 433 { 434 return Vector3(mFrom.x, mFrom.y + (mTo.y - mFrom.y) / (Real)2.0, mTo.z); 435 } 436 437 /** Gets the center of the corners 1, 5. 438 @return 439 The center. 440 */ getCenterBackRight(void)441 inline const Vector3 getCenterBackRight(void) const 442 { 443 return Vector3(mTo.x, mFrom.y + (mTo.y - mFrom.y) / (Real)2.0, mFrom.z); 444 } 445 446 /** Gets the center of the corners 2, 6. 447 @return 448 The center. 449 */ getCenterFrontRight(void)450 inline const Vector3 getCenterFrontRight(void) const 451 { 452 return Vector3(mTo.x, mFrom.y + (mTo.y - mFrom.y) / (Real)2.0, mTo.z); 453 } 454 455 /** Gets the coordinate of corner 1. 456 @return 457 The corner. 458 */ getCorner1(void)459 inline const Vector3 getCorner1(void) const 460 { 461 return Vector3(mTo.x, mFrom.y, mFrom.z); 462 } 463 464 /** Gets the coordinate of corner 2. 465 @return 466 The corner. 467 */ getCorner2(void)468 inline const Vector3 getCorner2(void) const 469 { 470 return Vector3(mTo.x, mFrom.y, mTo.z); 471 } 472 473 /** Gets the coordinate of corner 3. 474 @return 475 The corner. 476 */ getCorner3(void)477 inline const Vector3 getCorner3(void) const 478 { 479 return Vector3(mFrom.x, mFrom.y, mTo.z); 480 } 481 482 /** Gets the coordinate of corner 4. 483 @return 484 The corner. 485 */ getCorner4(void)486 inline const Vector3 getCorner4(void) const 487 { 488 return Vector3(mFrom.x, mTo.y, mFrom.z); 489 } 490 491 /** Gets the coordinate of corner 5. 492 @return 493 The corner. 494 */ getCorner5(void)495 inline const Vector3 getCorner5(void) const 496 { 497 return Vector3(mTo.x, mTo.y, mFrom.z); 498 } 499 500 /** Gets the coordinate of corner 7. 501 @return 502 The corner. 503 */ getCorner7(void)504 inline const Vector3 getCorner7(void) const 505 { 506 return Vector3(mFrom.x, mTo.y, mTo.z); 507 } 508 509 /** Raw setter for the center value. 510 @param value 511 The density value. 512 */ setCenterValue(Vector4 value)513 inline void setCenterValue(Vector4 value) 514 { 515 mCenterValue = value; 516 } 517 518 /** Gets the center value. 519 @return 520 The center value, one Vector4 consisting of gradient (x, y, z) and density (w). 521 */ getCenterValue(void)522 inline const Vector4 getCenterValue(void) const 523 { 524 return mCenterValue; 525 } 526 527 /** Gets whether the isosurface is somewhat near to this node. 528 @return 529 true if somewhat near. 530 */ isIsoSurfaceNear(void)531 inline bool isIsoSurfaceNear(void) const 532 { 533 if (mCenterValue.w == (Real)0.0) 534 { 535 return true; 536 } 537 return Math::Abs(mCenterValue.w) < (mFrom - mTo).length() * NEAR_FACTOR; 538 } 539 }; 540 /** @} */ 541 /** @} */ 542 } 543 } 544 545 #endif 546