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 &center, 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