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