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 /***************************************************************************
29 octreenode.cpp  -  description
30 -------------------
31 begin                : Fri Sep 27 2002
32 copyright            : (C) 2002 by Jon Anderson
33 email                : janders@users.sf.net
34 
35 ***************************************************************************/
36 
37 #include "OgreOctreeNode.h"
38 #include "OgreOctreeSceneManager.h"
39 
40 namespace Ogre
41 {
42 unsigned long green = 0xFFFFFFFF;
43 
44 unsigned short OctreeNode::mIndexes[ 24 ] = {0, 1, 1, 2, 2, 3, 3, 0,       //back
45         0, 6, 6, 5, 5, 1,             //left
46         3, 7, 7, 4, 4, 2,             //right
47         6, 7, 5, 4 };          //front
48 unsigned long OctreeNode::mColors[ 8 ] = {green, green, green, green, green, green, green, green };
49 
OctreeNode(SceneManager * creator)50 OctreeNode::OctreeNode( SceneManager* creator ) : SceneNode( creator )
51 {
52     mOctant = 0;
53 }
54 
OctreeNode(SceneManager * creator,const String & name)55 OctreeNode::OctreeNode( SceneManager* creator, const String& name ) : SceneNode( creator, name )
56 {
57     mOctant = 0;
58 }
59 
~OctreeNode()60 OctreeNode::~OctreeNode()
61 {}
_removeNodeAndChildren()62 void OctreeNode::_removeNodeAndChildren( )
63 {
64     static_cast< OctreeSceneManager * > ( mCreator ) -> _removeOctreeNode( this );
65     //remove all the children nodes as well from the octree.
66     ChildNodeMap::iterator it = mChildren.begin();
67     while( it != mChildren.end() )
68     {
69         static_cast<OctreeNode *>( *it ) -> _removeNodeAndChildren();
70         ++it;
71     }
72 }
removeChild(unsigned short index)73 Node * OctreeNode::removeChild( unsigned short index )
74 {
75     OctreeNode *on = static_cast<OctreeNode* >( SceneNode::removeChild( index ) );
76     on -> _removeNodeAndChildren();
77     return on;
78 }
removeChild(Node * child)79 Node * OctreeNode::removeChild( Node* child )
80 {
81     OctreeNode *on = static_cast<OctreeNode* >( SceneNode::removeChild( child ) );
82     on -> _removeNodeAndChildren();
83     return on;
84 }
removeAllChildren()85 void OctreeNode::removeAllChildren()
86 {
87     ChildNodeMap::iterator i, iend;
88     iend = mChildren.end();
89     for (i = mChildren.begin(); i != iend; ++i)
90     {
91         OctreeNode* on = static_cast<OctreeNode*>(*i);
92         on->setParent(0);
93         on->_removeNodeAndChildren();
94     }
95     mChildren.clear();
96     mChildrenToUpdate.clear();
97 
98 }
99 
removeChild(const String & name)100 Node * OctreeNode::removeChild( const String & name )
101 {
102     OctreeNode *on = static_cast< OctreeNode * >( SceneNode::removeChild(  name ) );
103     on -> _removeNodeAndChildren( );
104     return on;
105 }
106 
107 //same as SceneNode, only it doesn't care about children...
_updateBounds(void)108 void OctreeNode::_updateBounds( void )
109 {
110     mWorldAABB.setNull();
111     mLocalAABB.setNull();
112 
113     // Update bounds from own attached objects
114     ObjectMap::iterator i = mObjectsByName.begin();
115     AxisAlignedBox bx;
116 
117     while ( i != mObjectsByName.end() )
118     {
119 
120         // Get local bounds of object
121         bx = (*i)->getBoundingBox();
122 
123         mLocalAABB.merge( bx );
124 
125         mWorldAABB.merge( (*i)->getWorldBoundingBox(true) );
126         ++i;
127     }
128 
129 
130     //update the OctreeSceneManager that things might have moved.
131     // if it hasn't been added to the octree, add it, and if has moved
132     // enough to leave it's current node, we'll update it.
133     if ( ! mWorldAABB.isNull() && mIsInSceneGraph )
134     {
135         static_cast < OctreeSceneManager * > ( mCreator ) -> _updateOctreeNode( this );
136     }
137 
138 }
139 
140 /** Since we are loose, only check the center.
141 */
_isIn(AxisAlignedBox & box)142 bool OctreeNode::_isIn( AxisAlignedBox &box )
143 {
144     // Always fail if not in the scene graph or box is null
145     if (!mIsInSceneGraph || box.isNull()) return false;
146 
147     // Always succeed if AABB is infinite
148     if (box.isInfinite())
149         return true;
150 
151     Vector3 center = mWorldAABB.getMaximum().midPoint( mWorldAABB.getMinimum() );
152 
153     Vector3 bmin = box.getMinimum();
154     Vector3 bmax = box.getMaximum();
155 
156     bool centre = ( bmax > center && bmin < center );
157     if (!centre)
158         return false;
159 
160     // Even if covering the centre line, need to make sure this BB is not large
161     // enough to require being moved up into parent. When added, bboxes would
162     // end up in parent due to cascade but when updating need to deal with
163     // bbox growing too large for this child
164     Vector3 octreeSize = bmax - bmin;
165     Vector3 nodeSize = mWorldAABB.getMaximum() - mWorldAABB.getMinimum();
166     return nodeSize < octreeSize;
167 
168 }
169 
170 /** Adds the attached objects of this OctreeScene node into the queue. */
_addToRenderQueue(Camera * cam,RenderQueue * queue,bool onlyShadowCasters,VisibleObjectsBoundsInfo * visibleBounds)171 void OctreeNode::_addToRenderQueue( Camera* cam, RenderQueue *queue,
172     bool onlyShadowCasters, VisibleObjectsBoundsInfo* visibleBounds )
173 {
174     ObjectMap::iterator mit = mObjectsByName.begin();
175 
176     while ( mit != mObjectsByName.end() )
177     {
178         MovableObject * mo = *mit;
179 
180         queue->processVisibleObject(mo, cam, onlyShadowCasters, visibleBounds);
181 
182         ++mit;
183     }
184 
185 }
186 
187 
getRenderOperation(RenderOperation & rend)188 void OctreeNode::getRenderOperation( RenderOperation& rend )
189 {
190 
191     /* TODO
192     rend.useIndexes = true;
193     rend.numTextureCoordSets = 0; // no textures
194     rend.vertexOptions = LegacyRenderOperation::VO_DIFFUSE_COLOURS;
195     rend.operationType = LegacyRenderOperation::OT_LINE_LIST;
196     rend.numVertices = 8;
197     rend.numIndexes = 24;
198 
199     rend.pVertices = mCorners;
200     rend.pIndexes = mIndexes;
201     rend.pDiffuseColour = mColors;
202 
203     const Vector3 * corners = _getLocalAABB().getAllCorners();
204 
205     int index = 0;
206 
207     for ( int i = 0; i < 8; i++ )
208     {
209         rend.pVertices[ index ] = corners[ i ].x;
210         index++;
211         rend.pVertices[ index ] = corners[ i ].y;
212         index++;
213         rend.pVertices[ index ] = corners[ i ].z;
214         index++;
215     }
216     */
217 
218 
219 }
220 }
221