/src/ogre/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManager.cpp
Line | Count | Source |
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 | | octreescenemanager.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 "OgreOctreeSceneManager.h" |
38 | | #include "OgreOctreeSceneQuery.h" |
39 | | #include "OgreOctreeNode.h" |
40 | | #include "OgreOctreeCamera.h" |
41 | | #include "OgreWireBoundingBox.h" |
42 | | |
43 | | namespace Ogre |
44 | | { |
45 | | enum Intersection |
46 | | { |
47 | | OUTSIDE=0, |
48 | | INSIDE=1, |
49 | | INTERSECT=2 |
50 | | }; |
51 | | int OctreeSceneManager::intersect_call = 0; |
52 | | |
53 | | static Intersection intersect( const Ray &one, const AxisAlignedBox &two ) |
54 | 0 | { |
55 | 0 | OctreeSceneManager::intersect_call++; |
56 | | // Null box? |
57 | 0 | if (two.isNull()) return OUTSIDE; |
58 | | // Infinite box? |
59 | 0 | if (two.isInfinite()) return INTERSECT; |
60 | | |
61 | 0 | bool inside = true; |
62 | 0 | const Vector3& twoMin = two.getMinimum(); |
63 | 0 | const Vector3& twoMax = two.getMaximum(); |
64 | 0 | Vector3 origin = one.getOrigin(); |
65 | 0 | Vector3 dir = one.getDirection(); |
66 | |
|
67 | 0 | Vector3 maxT(-1, -1, -1); |
68 | |
|
69 | 0 | int i = 0; |
70 | 0 | for(i=0; i<3; i++ ) |
71 | 0 | { |
72 | 0 | if( origin[i] < twoMin[i] ) |
73 | 0 | { |
74 | 0 | inside = false; |
75 | 0 | if( dir[i] > 0 ) |
76 | 0 | { |
77 | 0 | maxT[i] = (twoMin[i] - origin[i])/ dir[i]; |
78 | 0 | } |
79 | 0 | } |
80 | 0 | else if( origin[i] > twoMax[i] ) |
81 | 0 | { |
82 | 0 | inside = false; |
83 | 0 | if( dir[i] < 0 ) |
84 | 0 | { |
85 | 0 | maxT[i] = (twoMax[i] - origin[i]) / dir[i]; |
86 | 0 | } |
87 | 0 | } |
88 | 0 | } |
89 | |
|
90 | 0 | if( inside ) |
91 | 0 | { |
92 | 0 | return INTERSECT; |
93 | 0 | } |
94 | 0 | int whichPlane = 0; |
95 | 0 | if( maxT[1] > maxT[whichPlane]) |
96 | 0 | whichPlane = 1; |
97 | 0 | if( maxT[2] > maxT[whichPlane]) |
98 | 0 | whichPlane = 2; |
99 | |
|
100 | 0 | if( ((int)maxT[whichPlane]) & 0x80000000 ) |
101 | 0 | { |
102 | 0 | return OUTSIDE; |
103 | 0 | } |
104 | 0 | for(i=0; i<3; i++ ) |
105 | 0 | { |
106 | 0 | if( i!= whichPlane ) |
107 | 0 | { |
108 | 0 | float f = origin[i] + maxT[whichPlane] * dir[i]; |
109 | 0 | if ( f < (twoMin[i] - 0.00001f) || |
110 | 0 | f > (twoMax[i] +0.00001f ) ) |
111 | 0 | { |
112 | 0 | return OUTSIDE; |
113 | 0 | } |
114 | 0 | } |
115 | 0 | } |
116 | | |
117 | 0 | return INTERSECT; |
118 | |
|
119 | 0 | } |
120 | | |
121 | | |
122 | | /** Checks how the second box intersects with the first. |
123 | | */ |
124 | | static Intersection intersect( const PlaneBoundedVolume &one, const AxisAlignedBox &two ) |
125 | 0 | { |
126 | 0 | OctreeSceneManager::intersect_call++; |
127 | | // Null box? |
128 | 0 | if (two.isNull()) return OUTSIDE; |
129 | | // Infinite box? |
130 | 0 | if (two.isInfinite()) return INTERSECT; |
131 | | |
132 | | // Get centre of the box |
133 | 0 | Vector3 centre = two.getCenter(); |
134 | | // Get the half-size of the box |
135 | 0 | Vector3 halfSize = two.getHalfSize(); |
136 | | |
137 | | // For each plane, see if all points are on the negative side |
138 | | // If so, object is not visible. |
139 | | // If one or more are, it's partial. |
140 | | // If all aren't, full |
141 | 0 | bool all_inside = true; |
142 | 0 | PlaneList::const_iterator i, iend; |
143 | 0 | iend = one.planes.end(); |
144 | 0 | for (i = one.planes.begin(); i != iend; ++i) |
145 | 0 | { |
146 | 0 | const Plane& plane = *i; |
147 | |
|
148 | 0 | Plane::Side side = plane.getSide(centre, halfSize); |
149 | 0 | if(side == one.outside) |
150 | 0 | return OUTSIDE; |
151 | 0 | if(side == Plane::BOTH_SIDE) |
152 | 0 | all_inside = false; |
153 | 0 | } |
154 | | |
155 | 0 | if ( all_inside ) |
156 | 0 | return INSIDE; |
157 | 0 | else |
158 | 0 | return INTERSECT; |
159 | |
|
160 | 0 | } |
161 | | |
162 | | |
163 | | /** Checks how the second box intersects with the first. |
164 | | */ |
165 | | static Intersection intersect( const AxisAlignedBox &one, const AxisAlignedBox &two ) |
166 | 0 | { |
167 | 0 | OctreeSceneManager::intersect_call++; |
168 | | // Null box? |
169 | 0 | if (one.isNull() || two.isNull()) return OUTSIDE; |
170 | 0 | if (one.isInfinite()) return INSIDE; |
171 | 0 | if (two.isInfinite()) return INTERSECT; |
172 | | |
173 | | |
174 | 0 | const Vector3& insideMin = two.getMinimum(); |
175 | 0 | const Vector3& insideMax = two.getMaximum(); |
176 | |
|
177 | 0 | const Vector3& outsideMin = one.getMinimum(); |
178 | 0 | const Vector3& outsideMax = one.getMaximum(); |
179 | |
|
180 | 0 | if ( insideMax.x < outsideMin.x || |
181 | 0 | insideMax.y < outsideMin.y || |
182 | 0 | insideMax.z < outsideMin.z || |
183 | 0 | insideMin.x > outsideMax.x || |
184 | 0 | insideMin.y > outsideMax.y || |
185 | 0 | insideMin.z > outsideMax.z ) |
186 | 0 | { |
187 | 0 | return OUTSIDE; |
188 | 0 | } |
189 | | |
190 | 0 | bool full = ( insideMin.x > outsideMin.x && |
191 | 0 | insideMin.y > outsideMin.y && |
192 | 0 | insideMin.z > outsideMin.z && |
193 | 0 | insideMax.x < outsideMax.x && |
194 | 0 | insideMax.y < outsideMax.y && |
195 | 0 | insideMax.z < outsideMax.z ); |
196 | |
|
197 | 0 | if ( full ) |
198 | 0 | return INSIDE; |
199 | 0 | else |
200 | 0 | return INTERSECT; |
201 | |
|
202 | 0 | } |
203 | | |
204 | | /** Checks how the box intersects with the sphere. |
205 | | */ |
206 | | static Intersection intersect( const Sphere &one, const AxisAlignedBox &two ) |
207 | 0 | { |
208 | 0 | OctreeSceneManager::intersect_call++; |
209 | | // Null box? |
210 | 0 | if (two.isNull()) return OUTSIDE; |
211 | 0 | if (two.isInfinite()) return INTERSECT; |
212 | | |
213 | 0 | float sradius = one.getRadius(); |
214 | |
|
215 | 0 | sradius *= sradius; |
216 | |
|
217 | 0 | Vector3 scenter = one.getCenter(); |
218 | |
|
219 | 0 | const Vector3& twoMin = two.getMinimum(); |
220 | 0 | const Vector3& twoMax = two.getMaximum(); |
221 | |
|
222 | 0 | float s, d = 0; |
223 | |
|
224 | 0 | Vector3 mndistance = ( twoMin - scenter ); |
225 | 0 | Vector3 mxdistance = ( twoMax - scenter ); |
226 | |
|
227 | 0 | if ( mndistance.squaredLength() < sradius && |
228 | 0 | mxdistance.squaredLength() < sradius ) |
229 | 0 | { |
230 | 0 | return INSIDE; |
231 | 0 | } |
232 | | |
233 | | //find the square of the distance |
234 | | //from the sphere to the box |
235 | 0 | for ( int i = 0 ; i < 3 ; i++ ) |
236 | 0 | { |
237 | 0 | if ( scenter[ i ] < twoMin[ i ] ) |
238 | 0 | { |
239 | 0 | s = scenter[ i ] - twoMin[ i ]; |
240 | 0 | d += s * s; |
241 | 0 | } |
242 | | |
243 | 0 | else if ( scenter[ i ] > twoMax[ i ] ) |
244 | 0 | { |
245 | 0 | s = scenter[ i ] - twoMax[ i ]; |
246 | 0 | d += s * s; |
247 | 0 | } |
248 | |
|
249 | 0 | } |
250 | |
|
251 | 0 | bool partial = ( d <= sradius ); |
252 | |
|
253 | 0 | if ( !partial ) |
254 | 0 | { |
255 | 0 | return OUTSIDE; |
256 | 0 | } |
257 | | |
258 | 0 | else |
259 | 0 | { |
260 | 0 | return INTERSECT; |
261 | 0 | } |
262 | | |
263 | |
|
264 | 0 | } |
265 | | |
266 | | unsigned long white = 0xFFFFFFFF; |
267 | | |
268 | | unsigned short OctreeSceneManager::mIndexes[ 24 ] = {0, 1, 1, 2, 2, 3, 3, 0, //back |
269 | | 0, 6, 6, 5, 5, 1, //left |
270 | | 3, 7, 7, 4, 4, 2, //right |
271 | | 6, 7, 5, 4 }; //front |
272 | | unsigned long OctreeSceneManager::mColors[ 8 ] = {white, white, white, white, white, white, white, white }; |
273 | | |
274 | | |
275 | 0 | OctreeSceneManager::OctreeSceneManager(const String& name) : SceneManager(name) |
276 | 0 | { |
277 | 0 | AxisAlignedBox b( -10000, -10000, -10000, 10000, 10000, 10000 ); |
278 | 0 | int depth = 8; |
279 | 0 | mOctree = 0; |
280 | 0 | init( b, depth ); |
281 | 0 | } |
282 | | |
283 | | OctreeSceneManager::OctreeSceneManager(const String& name, AxisAlignedBox &box, int max_depth ) |
284 | 0 | : SceneManager(name) |
285 | 0 | { |
286 | 0 | mOctree = 0; |
287 | 0 | init( box, max_depth ); |
288 | 0 | } |
289 | | |
290 | | const String& OctreeSceneManager::getTypeName(void) const |
291 | 0 | { |
292 | 0 | return OctreeSceneManagerFactory::FACTORY_TYPE_NAME; |
293 | 0 | } |
294 | | |
295 | | void OctreeSceneManager::init( AxisAlignedBox &box, int depth ) |
296 | 0 | { |
297 | |
|
298 | 0 | if ( mOctree != 0 ) |
299 | 0 | OGRE_DELETE mOctree; |
300 | |
|
301 | 0 | mOctree = OGRE_NEW Octree( 0 ); |
302 | |
|
303 | 0 | mMaxDepth = depth; |
304 | 0 | mBox = box; |
305 | |
|
306 | 0 | mOctree -> mBox = box; |
307 | |
|
308 | 0 | Vector3 min = box.getMinimum(); |
309 | |
|
310 | 0 | Vector3 max = box.getMaximum(); |
311 | |
|
312 | 0 | mOctree -> mHalfSize = ( max - min ) / 2; |
313 | | |
314 | |
|
315 | 0 | mShowBoxes = false; |
316 | |
|
317 | 0 | mNumObjects = 0; |
318 | |
|
319 | 0 | Vector3 v( 1.5, 1.5, 1.5 ); |
320 | |
|
321 | 0 | mScaleFactor.setScale( v ); |
322 | | |
323 | | |
324 | | |
325 | | // setDisplaySceneNodes( true ); |
326 | | // setShowBoxes( true ); |
327 | | |
328 | | // |
329 | | //mSceneRoot isn't put into the octree since it has no volume. |
330 | |
|
331 | 0 | } |
332 | | |
333 | | OctreeSceneManager::~OctreeSceneManager() |
334 | 0 | { |
335 | |
|
336 | 0 | if ( mOctree ) |
337 | 0 | { |
338 | 0 | OGRE_DELETE mOctree; |
339 | 0 | mOctree = 0; |
340 | 0 | } |
341 | 0 | } |
342 | | |
343 | | Camera * OctreeSceneManager::createCamera( const String &name ) |
344 | 0 | { |
345 | | // Check name not used |
346 | 0 | if (mCameras.find(name) != mCameras.end()) |
347 | 0 | { |
348 | 0 | OGRE_EXCEPT( |
349 | 0 | Exception::ERR_DUPLICATE_ITEM, |
350 | 0 | "A camera with the name " + name + " already exists", |
351 | 0 | "OctreeSceneManager::createCamera" ); |
352 | 0 | } |
353 | | |
354 | 0 | Camera * c = OGRE_NEW OctreeCamera( name, this ); |
355 | 0 | mCameras.emplace(name, c); |
356 | | |
357 | | // create visible bounds aab map entry |
358 | 0 | mCamVisibleObjectsMap[c] = VisibleObjectsBoundsInfo(); |
359 | | |
360 | 0 | return c; |
361 | 0 | } |
362 | | |
363 | | void OctreeSceneManager::destroySceneNode( SceneNode* sn ) |
364 | 0 | { |
365 | 0 | OctreeNode * on = static_cast < OctreeNode* > ( sn ); |
366 | |
|
367 | 0 | if ( on != 0 ) |
368 | 0 | _removeOctreeNode( on ); |
369 | |
|
370 | 0 | SceneManager::destroySceneNode( sn ); |
371 | 0 | } |
372 | | |
373 | | bool OctreeSceneManager::getOptionValues( const String & key, StringVector &refValueList ) |
374 | 0 | { |
375 | 0 | return SceneManager::getOptionValues( key, refValueList ); |
376 | 0 | } |
377 | | |
378 | | bool OctreeSceneManager::getOptionKeys( StringVector & refKeys ) |
379 | 0 | { |
380 | 0 | SceneManager::getOptionKeys( refKeys ); |
381 | 0 | refKeys.push_back( "Size" ); |
382 | 0 | refKeys.push_back( "ShowOctree" ); |
383 | 0 | refKeys.push_back( "Depth" ); |
384 | |
|
385 | 0 | return true; |
386 | 0 | } |
387 | | |
388 | | |
389 | | void OctreeSceneManager::_updateOctreeNode( OctreeNode * onode ) |
390 | 0 | { |
391 | 0 | const AxisAlignedBox& box = onode -> _getWorldAABB(); |
392 | |
|
393 | 0 | if ( box.isNull() ) |
394 | 0 | return ; |
395 | | |
396 | | // Skip if octree has been destroyed (shutdown conditions) |
397 | 0 | if (!mOctree) |
398 | 0 | return; |
399 | | |
400 | 0 | if ( onode -> getOctant() == 0 ) |
401 | 0 | { |
402 | | //if outside the octree, force into the root node. |
403 | 0 | if ( ! onode -> _isIn( mOctree -> mBox ) ) |
404 | 0 | mOctree->_addNode( onode ); |
405 | 0 | else |
406 | 0 | _addOctreeNode( onode, mOctree ); |
407 | 0 | return ; |
408 | 0 | } |
409 | | |
410 | 0 | if ( ! onode -> _isIn( onode -> getOctant() -> mBox ) ) |
411 | 0 | { |
412 | 0 | _removeOctreeNode( onode ); |
413 | | |
414 | | //if outside the octree, force into the root node. |
415 | 0 | if ( ! onode -> _isIn( mOctree -> mBox ) ) |
416 | 0 | mOctree->_addNode( onode ); |
417 | 0 | else |
418 | 0 | _addOctreeNode( onode, mOctree ); |
419 | 0 | } |
420 | 0 | } |
421 | | |
422 | | /** Only removes the node from the octree. It leaves the octree, even if it's empty. |
423 | | */ |
424 | | void OctreeSceneManager::_removeOctreeNode( OctreeNode * n ) |
425 | 0 | { |
426 | | // Skip if octree has been destroyed (shutdown conditions) |
427 | 0 | if (!mOctree) |
428 | 0 | return; |
429 | | |
430 | 0 | Octree * oct = n -> getOctant(); |
431 | |
|
432 | 0 | if ( oct ) |
433 | 0 | { |
434 | 0 | oct -> _removeNode( n ); |
435 | 0 | } |
436 | |
|
437 | 0 | n->setOctant(0); |
438 | 0 | } |
439 | | |
440 | | |
441 | | void OctreeSceneManager::_addOctreeNode( OctreeNode * n, Octree *octant, int depth ) |
442 | 0 | { |
443 | | |
444 | | // Skip if octree has been destroyed (shutdown conditions) |
445 | 0 | if (!mOctree) |
446 | 0 | return; |
447 | | |
448 | 0 | const AxisAlignedBox& bx = n -> _getWorldAABB(); |
449 | | |
450 | | |
451 | | //if the octree is twice as big as the scene node, |
452 | | //we will add it to a child. |
453 | 0 | if ( ( depth < mMaxDepth ) && octant -> _isTwiceSize( bx ) ) |
454 | 0 | { |
455 | 0 | int x, y, z; |
456 | 0 | octant -> _getChildIndexes( bx, &x, &y, &z ); |
457 | |
|
458 | 0 | if ( octant -> mChildren[ x ][ y ][ z ] == 0 ) |
459 | 0 | { |
460 | 0 | octant -> mChildren[ x ][ y ][ z ] = OGRE_NEW Octree( octant ); |
461 | 0 | const Vector3& octantMin = octant -> mBox.getMinimum(); |
462 | 0 | const Vector3& octantMax = octant -> mBox.getMaximum(); |
463 | 0 | Vector3 min, max; |
464 | |
|
465 | 0 | if ( x == 0 ) |
466 | 0 | { |
467 | 0 | min.x = octantMin.x; |
468 | 0 | max.x = ( octantMin.x + octantMax.x ) / 2; |
469 | 0 | } |
470 | | |
471 | 0 | else |
472 | 0 | { |
473 | 0 | min.x = ( octantMin.x + octantMax.x ) / 2; |
474 | 0 | max.x = octantMax.x; |
475 | 0 | } |
476 | |
|
477 | 0 | if ( y == 0 ) |
478 | 0 | { |
479 | 0 | min.y = octantMin.y; |
480 | 0 | max.y = ( octantMin.y + octantMax.y ) / 2; |
481 | 0 | } |
482 | | |
483 | 0 | else |
484 | 0 | { |
485 | 0 | min.y = ( octantMin.y + octantMax.y ) / 2; |
486 | 0 | max.y = octantMax.y; |
487 | 0 | } |
488 | |
|
489 | 0 | if ( z == 0 ) |
490 | 0 | { |
491 | 0 | min.z = octantMin.z; |
492 | 0 | max.z = ( octantMin.z + octantMax.z ) / 2; |
493 | 0 | } |
494 | | |
495 | 0 | else |
496 | 0 | { |
497 | 0 | min.z = ( octantMin.z + octantMax.z ) / 2; |
498 | 0 | max.z = octantMax.z; |
499 | 0 | } |
500 | |
|
501 | 0 | octant -> mChildren[ x ][ y ][ z ] -> mBox.setExtents( min, max ); |
502 | 0 | octant -> mChildren[ x ][ y ][ z ] -> mHalfSize = ( max - min ) / 2; |
503 | 0 | } |
504 | |
|
505 | 0 | _addOctreeNode( n, octant -> mChildren[ x ][ y ][ z ], ++depth ); |
506 | |
|
507 | 0 | } |
508 | | |
509 | 0 | else |
510 | 0 | { |
511 | 0 | octant -> _addNode( n ); |
512 | 0 | } |
513 | 0 | } |
514 | | |
515 | | |
516 | | SceneNode * OctreeSceneManager::createSceneNodeImpl( void ) |
517 | 0 | { |
518 | 0 | return OGRE_NEW OctreeNode( this ); |
519 | 0 | } |
520 | | |
521 | | SceneNode * OctreeSceneManager::createSceneNodeImpl( const String &name ) |
522 | 0 | { |
523 | 0 | return OGRE_NEW OctreeNode( this, name ); |
524 | 0 | } |
525 | | |
526 | | void OctreeSceneManager::_updateSceneGraph( Camera * cam ) |
527 | 0 | { |
528 | 0 | SceneManager::_updateSceneGraph( cam ); |
529 | 0 | } |
530 | | |
531 | | void OctreeSceneManager::_findVisibleObjects(Camera * cam, |
532 | | VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters ) |
533 | 0 | { |
534 | |
|
535 | 0 | getRenderQueue()->clear(); |
536 | 0 | mBoxes.clear(); |
537 | 0 | mVisible.clear(); |
538 | |
|
539 | 0 | mNumObjects = 0; |
540 | | |
541 | | //walk the octree, adding all visible Octreenodes nodes to the render queue. |
542 | 0 | walkOctree( static_cast < OctreeCamera * > ( cam ), getRenderQueue(), mOctree, |
543 | 0 | visibleBounds, false, onlyShadowCasters ); |
544 | | |
545 | | // Show the octree boxes & cull camera if required |
546 | 0 | if ( mShowBoxes ) |
547 | 0 | { |
548 | 0 | for ( BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it ) |
549 | 0 | { |
550 | 0 | getRenderQueue()->addRenderable(*it); |
551 | 0 | } |
552 | 0 | } |
553 | 0 | } |
554 | | |
555 | | void OctreeSceneManager::walkOctree( OctreeCamera *camera, RenderQueue *queue, |
556 | | Octree *octant, VisibleObjectsBoundsInfo* visibleBounds, |
557 | | bool foundvisible, bool onlyShadowCasters ) |
558 | 0 | { |
559 | | |
560 | | //return immediately if nothing is in the node. |
561 | 0 | if ( octant -> numNodes() == 0 ) |
562 | 0 | return ; |
563 | | |
564 | 0 | OctreeCamera::Visibility v = OctreeCamera::NONE; |
565 | |
|
566 | 0 | if ( foundvisible ) |
567 | 0 | { |
568 | 0 | v = OctreeCamera::FULL; |
569 | 0 | } |
570 | | |
571 | 0 | else if ( octant == mOctree ) |
572 | 0 | { |
573 | 0 | v = OctreeCamera::PARTIAL; |
574 | 0 | } |
575 | | |
576 | 0 | else |
577 | 0 | { |
578 | 0 | AxisAlignedBox box; |
579 | 0 | octant -> _getCullBounds( &box ); |
580 | 0 | v = camera -> getVisibility( box ); |
581 | 0 | } |
582 | | |
583 | | |
584 | | // if the octant is visible, or if it's the root node... |
585 | 0 | if ( v != OctreeCamera::NONE ) |
586 | 0 | { |
587 | | |
588 | | //Add stuff to be rendered; |
589 | 0 | Octree::NodeList::iterator it = octant -> mNodes.begin(); |
590 | |
|
591 | 0 | if ( mShowBoxes ) |
592 | 0 | { |
593 | 0 | mBoxes.push_back( octant->getWireBoundingBox() ); |
594 | 0 | } |
595 | |
|
596 | 0 | bool vis = true; |
597 | |
|
598 | 0 | while ( it != octant -> mNodes.end() ) |
599 | 0 | { |
600 | 0 | OctreeNode * sn = *it; |
601 | | |
602 | | // if this octree is partially visible, manually cull all |
603 | | // scene nodes attached directly to this level. |
604 | |
|
605 | 0 | if ( v == OctreeCamera::PARTIAL ) |
606 | 0 | vis = camera -> isVisible( sn -> _getWorldAABB() ); |
607 | |
|
608 | 0 | if ( vis ) |
609 | 0 | { |
610 | |
|
611 | 0 | mNumObjects++; |
612 | 0 | sn -> _addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds ); |
613 | |
|
614 | 0 | mVisible.push_back( sn ); |
615 | |
|
616 | 0 | if (getDebugDrawer()) |
617 | 0 | getDebugDrawer()->drawSceneNode(sn); |
618 | 0 | } |
619 | |
|
620 | 0 | ++it; |
621 | 0 | } |
622 | |
|
623 | 0 | Octree* child; |
624 | 0 | bool childfoundvisible = (v == OctreeCamera::FULL); |
625 | 0 | if ( (child = octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) |
626 | 0 | walkOctree( camera, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters ); |
627 | |
|
628 | 0 | if ( (child = octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) |
629 | 0 | walkOctree( camera, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters ); |
630 | |
|
631 | 0 | if ( (child = octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) |
632 | 0 | walkOctree( camera, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters ); |
633 | |
|
634 | 0 | if ( (child = octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) |
635 | 0 | walkOctree( camera, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters ); |
636 | |
|
637 | 0 | if ( (child = octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) |
638 | 0 | walkOctree( camera, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters ); |
639 | |
|
640 | 0 | if ( (child = octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) |
641 | 0 | walkOctree( camera, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters ); |
642 | |
|
643 | 0 | if ( (child = octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) |
644 | 0 | walkOctree( camera, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters ); |
645 | |
|
646 | 0 | if ( (child = octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) |
647 | 0 | walkOctree( camera, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters ); |
648 | |
|
649 | 0 | } |
650 | |
|
651 | 0 | } |
652 | | |
653 | | // --- non template versions |
654 | | static void _findNodes( const AxisAlignedBox &t, std::list< SceneNode * > &list, SceneNode *exclude, bool full, Octree *octant ) |
655 | 0 | { |
656 | |
|
657 | 0 | if ( !full ) |
658 | 0 | { |
659 | 0 | AxisAlignedBox obox; |
660 | 0 | octant -> _getCullBounds( &obox ); |
661 | |
|
662 | 0 | Intersection isect = intersect( t, obox ); |
663 | |
|
664 | 0 | if ( isect == OUTSIDE ) |
665 | 0 | return ; |
666 | | |
667 | 0 | full = ( isect == INSIDE ); |
668 | 0 | } |
669 | | |
670 | | |
671 | 0 | Octree::NodeList::iterator it = octant -> mNodes.begin(); |
672 | |
|
673 | 0 | while ( it != octant -> mNodes.end() ) |
674 | 0 | { |
675 | 0 | OctreeNode * on = ( *it ); |
676 | |
|
677 | 0 | if ( on != exclude ) |
678 | 0 | { |
679 | 0 | if ( full ) |
680 | 0 | { |
681 | 0 | list.push_back( on ); |
682 | 0 | } |
683 | | |
684 | 0 | else |
685 | 0 | { |
686 | 0 | Intersection nsect = intersect( t, on -> _getWorldAABB() ); |
687 | |
|
688 | 0 | if ( nsect != OUTSIDE ) |
689 | 0 | { |
690 | 0 | list.push_back( on ); |
691 | 0 | } |
692 | 0 | } |
693 | |
|
694 | 0 | } |
695 | |
|
696 | 0 | ++it; |
697 | 0 | } |
698 | |
|
699 | 0 | Octree* child; |
700 | |
|
701 | 0 | if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) |
702 | 0 | _findNodes( t, list, exclude, full, child ); |
703 | |
|
704 | 0 | if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) |
705 | 0 | _findNodes( t, list, exclude, full, child ); |
706 | |
|
707 | 0 | if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) |
708 | 0 | _findNodes( t, list, exclude, full, child ); |
709 | |
|
710 | 0 | if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) |
711 | 0 | _findNodes( t, list, exclude, full, child ); |
712 | |
|
713 | 0 | if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) |
714 | 0 | _findNodes( t, list, exclude, full, child ); |
715 | |
|
716 | 0 | if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) |
717 | 0 | _findNodes( t, list, exclude, full, child ); |
718 | |
|
719 | 0 | if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) |
720 | 0 | _findNodes( t, list, exclude, full, child ); |
721 | |
|
722 | 0 | if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) |
723 | 0 | _findNodes( t, list, exclude, full, child ); |
724 | |
|
725 | 0 | } |
726 | | |
727 | | static void _findNodes( const Sphere &t, std::list< SceneNode * > &list, SceneNode *exclude, bool full, Octree *octant ) |
728 | 0 | { |
729 | |
|
730 | 0 | if ( !full ) |
731 | 0 | { |
732 | 0 | AxisAlignedBox obox; |
733 | 0 | octant -> _getCullBounds( &obox ); |
734 | |
|
735 | 0 | Intersection isect = intersect( t, obox ); |
736 | |
|
737 | 0 | if ( isect == OUTSIDE ) |
738 | 0 | return ; |
739 | | |
740 | 0 | full = ( isect == INSIDE ); |
741 | 0 | } |
742 | | |
743 | | |
744 | 0 | Octree::NodeList::iterator it = octant -> mNodes.begin(); |
745 | |
|
746 | 0 | while ( it != octant -> mNodes.end() ) |
747 | 0 | { |
748 | 0 | OctreeNode * on = ( *it ); |
749 | |
|
750 | 0 | if ( on != exclude ) |
751 | 0 | { |
752 | 0 | if ( full ) |
753 | 0 | { |
754 | 0 | list.push_back( on ); |
755 | 0 | } |
756 | | |
757 | 0 | else |
758 | 0 | { |
759 | 0 | Intersection nsect = intersect( t, on -> _getWorldAABB() ); |
760 | |
|
761 | 0 | if ( nsect != OUTSIDE ) |
762 | 0 | { |
763 | 0 | list.push_back( on ); |
764 | 0 | } |
765 | 0 | } |
766 | |
|
767 | 0 | } |
768 | |
|
769 | 0 | ++it; |
770 | 0 | } |
771 | |
|
772 | 0 | Octree* child; |
773 | |
|
774 | 0 | if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) |
775 | 0 | _findNodes( t, list, exclude, full, child ); |
776 | |
|
777 | 0 | if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) |
778 | 0 | _findNodes( t, list, exclude, full, child ); |
779 | |
|
780 | 0 | if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) |
781 | 0 | _findNodes( t, list, exclude, full, child ); |
782 | |
|
783 | 0 | if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) |
784 | 0 | _findNodes( t, list, exclude, full, child ); |
785 | |
|
786 | 0 | if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) |
787 | 0 | _findNodes( t, list, exclude, full, child ); |
788 | |
|
789 | 0 | if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) |
790 | 0 | _findNodes( t, list, exclude, full, child ); |
791 | |
|
792 | 0 | if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) |
793 | 0 | _findNodes( t, list, exclude, full, child ); |
794 | |
|
795 | 0 | if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) |
796 | 0 | _findNodes( t, list, exclude, full, child ); |
797 | |
|
798 | 0 | } |
799 | | |
800 | | |
801 | | static void _findNodes( const PlaneBoundedVolume &t, std::list< SceneNode * > &list, SceneNode *exclude, bool full, Octree *octant ) |
802 | 0 | { |
803 | |
|
804 | 0 | if ( !full ) |
805 | 0 | { |
806 | 0 | AxisAlignedBox obox; |
807 | 0 | octant -> _getCullBounds( &obox ); |
808 | |
|
809 | 0 | Intersection isect = intersect( t, obox ); |
810 | |
|
811 | 0 | if ( isect == OUTSIDE ) |
812 | 0 | return ; |
813 | | |
814 | 0 | full = ( isect == INSIDE ); |
815 | 0 | } |
816 | | |
817 | | |
818 | 0 | Octree::NodeList::iterator it = octant -> mNodes.begin(); |
819 | |
|
820 | 0 | while ( it != octant -> mNodes.end() ) |
821 | 0 | { |
822 | 0 | OctreeNode * on = ( *it ); |
823 | |
|
824 | 0 | if ( on != exclude ) |
825 | 0 | { |
826 | 0 | if ( full ) |
827 | 0 | { |
828 | 0 | list.push_back( on ); |
829 | 0 | } |
830 | | |
831 | 0 | else |
832 | 0 | { |
833 | 0 | Intersection nsect = intersect( t, on -> _getWorldAABB() ); |
834 | |
|
835 | 0 | if ( nsect != OUTSIDE ) |
836 | 0 | { |
837 | 0 | list.push_back( on ); |
838 | 0 | } |
839 | 0 | } |
840 | |
|
841 | 0 | } |
842 | |
|
843 | 0 | ++it; |
844 | 0 | } |
845 | |
|
846 | 0 | Octree* child; |
847 | |
|
848 | 0 | if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) |
849 | 0 | _findNodes( t, list, exclude, full, child ); |
850 | |
|
851 | 0 | if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) |
852 | 0 | _findNodes( t, list, exclude, full, child ); |
853 | |
|
854 | 0 | if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) |
855 | 0 | _findNodes( t, list, exclude, full, child ); |
856 | |
|
857 | 0 | if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) |
858 | 0 | _findNodes( t, list, exclude, full, child ); |
859 | |
|
860 | 0 | if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) |
861 | 0 | _findNodes( t, list, exclude, full, child ); |
862 | |
|
863 | 0 | if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) |
864 | 0 | _findNodes( t, list, exclude, full, child ); |
865 | |
|
866 | 0 | if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) |
867 | 0 | _findNodes( t, list, exclude, full, child ); |
868 | |
|
869 | 0 | if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) |
870 | 0 | _findNodes( t, list, exclude, full, child ); |
871 | |
|
872 | 0 | } |
873 | | |
874 | | static void _findNodes( const Ray &t, std::list< SceneNode * > &list, SceneNode *exclude, bool full, Octree *octant ) |
875 | 0 | { |
876 | |
|
877 | 0 | if ( !full ) |
878 | 0 | { |
879 | 0 | AxisAlignedBox obox; |
880 | 0 | octant -> _getCullBounds( &obox ); |
881 | |
|
882 | 0 | Intersection isect = intersect( t, obox ); |
883 | |
|
884 | 0 | if ( isect == OUTSIDE ) |
885 | 0 | return ; |
886 | | |
887 | 0 | full = ( isect == INSIDE ); |
888 | 0 | } |
889 | | |
890 | | |
891 | 0 | Octree::NodeList::iterator it = octant -> mNodes.begin(); |
892 | |
|
893 | 0 | while ( it != octant -> mNodes.end() ) |
894 | 0 | { |
895 | 0 | OctreeNode * on = ( *it ); |
896 | |
|
897 | 0 | if ( on != exclude ) |
898 | 0 | { |
899 | 0 | if ( full ) |
900 | 0 | { |
901 | 0 | list.push_back( on ); |
902 | 0 | } |
903 | | |
904 | 0 | else |
905 | 0 | { |
906 | 0 | Intersection nsect = intersect( t, on -> _getWorldAABB() ); |
907 | |
|
908 | 0 | if ( nsect != OUTSIDE ) |
909 | 0 | { |
910 | 0 | list.push_back( on ); |
911 | 0 | } |
912 | 0 | } |
913 | |
|
914 | 0 | } |
915 | |
|
916 | 0 | ++it; |
917 | 0 | } |
918 | |
|
919 | 0 | Octree* child; |
920 | |
|
921 | 0 | if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) |
922 | 0 | _findNodes( t, list, exclude, full, child ); |
923 | |
|
924 | 0 | if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) |
925 | 0 | _findNodes( t, list, exclude, full, child ); |
926 | |
|
927 | 0 | if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) |
928 | 0 | _findNodes( t, list, exclude, full, child ); |
929 | |
|
930 | 0 | if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) |
931 | 0 | _findNodes( t, list, exclude, full, child ); |
932 | |
|
933 | 0 | if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) |
934 | 0 | _findNodes( t, list, exclude, full, child ); |
935 | |
|
936 | 0 | if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) |
937 | 0 | _findNodes( t, list, exclude, full, child ); |
938 | |
|
939 | 0 | if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) |
940 | 0 | _findNodes( t, list, exclude, full, child ); |
941 | |
|
942 | 0 | if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) |
943 | 0 | _findNodes( t, list, exclude, full, child ); |
944 | |
|
945 | 0 | } |
946 | | |
947 | | void OctreeSceneManager::findNodesIn( const AxisAlignedBox &box, std::list< SceneNode * > &list, SceneNode *exclude ) |
948 | 0 | { |
949 | 0 | _findNodes( box, list, exclude, false, mOctree ); |
950 | 0 | } |
951 | | |
952 | | void OctreeSceneManager::findNodesIn( const Sphere &sphere, std::list< SceneNode * > &list, SceneNode *exclude ) |
953 | 0 | { |
954 | 0 | _findNodes( sphere, list, exclude, false, mOctree ); |
955 | 0 | } |
956 | | |
957 | | void OctreeSceneManager::findNodesIn( const PlaneBoundedVolume &volume, std::list< SceneNode * > &list, SceneNode *exclude ) |
958 | 0 | { |
959 | 0 | _findNodes( volume, list, exclude, false, mOctree ); |
960 | 0 | } |
961 | | |
962 | | void OctreeSceneManager::findNodesIn( const Ray &r, std::list< SceneNode * > &list, SceneNode *exclude ) |
963 | 0 | { |
964 | 0 | _findNodes( r, list, exclude, false, mOctree ); |
965 | 0 | } |
966 | | |
967 | | void OctreeSceneManager::resize( const AxisAlignedBox &box ) |
968 | 0 | { |
969 | 0 | std::list< SceneNode * > nodes; |
970 | 0 | std::list< SceneNode * > ::iterator it; |
971 | |
|
972 | 0 | _findNodes( mOctree->mBox, nodes, 0, true, mOctree ); |
973 | |
|
974 | 0 | OGRE_DELETE mOctree; |
975 | |
|
976 | 0 | mOctree = OGRE_NEW Octree( 0 ); |
977 | 0 | mOctree->mBox = box; |
978 | |
|
979 | 0 | const Vector3 &min = box.getMinimum(); |
980 | 0 | const Vector3 &max = box.getMaximum(); |
981 | 0 | mOctree->mHalfSize = ( max - min ) * 0.5f; |
982 | |
|
983 | 0 | it = nodes.begin(); |
984 | |
|
985 | 0 | while ( it != nodes.end() ) |
986 | 0 | { |
987 | 0 | OctreeNode * on = static_cast < OctreeNode * > ( *it ); |
988 | 0 | on -> setOctant( 0 ); |
989 | 0 | _updateOctreeNode( on ); |
990 | 0 | ++it; |
991 | 0 | } |
992 | |
|
993 | 0 | } |
994 | | |
995 | | bool OctreeSceneManager::setOption( const String & key, const void * val ) |
996 | 0 | { |
997 | 0 | if ( key == "Size" ) |
998 | 0 | { |
999 | 0 | resize( * static_cast < const AxisAlignedBox * > ( val ) ); |
1000 | 0 | return true; |
1001 | 0 | } |
1002 | | |
1003 | 0 | else if ( key == "Depth" ) |
1004 | 0 | { |
1005 | 0 | mMaxDepth = * static_cast < const int * > ( val ); |
1006 | | // copy the box since resize will delete mOctree and reference won't work |
1007 | 0 | AxisAlignedBox box = mOctree->mBox; |
1008 | 0 | resize(box); |
1009 | 0 | return true; |
1010 | 0 | } |
1011 | | |
1012 | 0 | else if ( key == "ShowOctree" ) |
1013 | 0 | { |
1014 | 0 | mShowBoxes = * static_cast < const bool * > ( val ); |
1015 | 0 | return true; |
1016 | 0 | } |
1017 | | |
1018 | | |
1019 | 0 | return SceneManager::setOption( key, val ); |
1020 | | |
1021 | |
|
1022 | 0 | } |
1023 | | |
1024 | | bool OctreeSceneManager::getOption( const String & key, void *val ) |
1025 | 0 | { |
1026 | 0 | if ( key == "Size" ) |
1027 | 0 | { |
1028 | 0 | AxisAlignedBox * b = static_cast < AxisAlignedBox * > ( val ); |
1029 | 0 | b -> setExtents( mOctree->mBox.getMinimum(), mOctree->mBox.getMaximum() ); |
1030 | 0 | return true; |
1031 | 0 | } |
1032 | | |
1033 | 0 | else if ( key == "Depth" ) |
1034 | 0 | { |
1035 | 0 | * static_cast < int * > ( val ) = mMaxDepth; |
1036 | 0 | return true; |
1037 | 0 | } |
1038 | | |
1039 | 0 | else if ( key == "ShowOctree" ) |
1040 | 0 | { |
1041 | |
|
1042 | 0 | * static_cast < bool * > ( val ) = mShowBoxes; |
1043 | 0 | return true; |
1044 | 0 | } |
1045 | | |
1046 | | |
1047 | 0 | return SceneManager::getOption( key, val ); |
1048 | |
|
1049 | 0 | } |
1050 | | |
1051 | | void OctreeSceneManager::clearScene(void) |
1052 | 0 | { |
1053 | 0 | SceneManager::clearScene(); |
1054 | 0 | init(mBox, mMaxDepth); |
1055 | |
|
1056 | 0 | } |
1057 | | |
1058 | | //--------------------------------------------------------------------- |
1059 | | AxisAlignedBoxSceneQuery* |
1060 | | OctreeSceneManager::createAABBQuery(const AxisAlignedBox& box, uint32 mask) |
1061 | 0 | { |
1062 | 0 | OctreeAxisAlignedBoxSceneQuery* q = OGRE_NEW OctreeAxisAlignedBoxSceneQuery(this); |
1063 | 0 | q->setBox(box); |
1064 | 0 | q->setQueryMask(mask); |
1065 | 0 | return q; |
1066 | 0 | } |
1067 | | //--------------------------------------------------------------------- |
1068 | | SphereSceneQuery* |
1069 | | OctreeSceneManager::createSphereQuery(const Sphere& sphere, uint32 mask) |
1070 | 0 | { |
1071 | 0 | OctreeSphereSceneQuery* q = OGRE_NEW OctreeSphereSceneQuery(this); |
1072 | 0 | q->setSphere(sphere); |
1073 | 0 | q->setQueryMask(mask); |
1074 | 0 | return q; |
1075 | 0 | } |
1076 | | //--------------------------------------------------------------------- |
1077 | | PlaneBoundedVolumeListSceneQuery* |
1078 | | OctreeSceneManager::createPlaneBoundedVolumeQuery(const PlaneBoundedVolumeList& volumes, |
1079 | | uint32 mask) |
1080 | 0 | { |
1081 | 0 | OctreePlaneBoundedVolumeListSceneQuery* q = OGRE_NEW OctreePlaneBoundedVolumeListSceneQuery(this); |
1082 | 0 | q->setVolumes(volumes); |
1083 | 0 | q->setQueryMask(mask); |
1084 | 0 | return q; |
1085 | 0 | } |
1086 | | |
1087 | | //--------------------------------------------------------------------- |
1088 | | RaySceneQuery* |
1089 | | OctreeSceneManager::createRayQuery(const Ray& ray, uint32 mask) |
1090 | 0 | { |
1091 | 0 | OctreeRaySceneQuery* q = OGRE_NEW OctreeRaySceneQuery(this); |
1092 | 0 | q->setRay(ray); |
1093 | 0 | q->setQueryMask(mask); |
1094 | 0 | return q; |
1095 | 0 | } |
1096 | | //--------------------------------------------------------------------- |
1097 | | IntersectionSceneQuery* |
1098 | | OctreeSceneManager::createIntersectionQuery(uint32 mask) |
1099 | 0 | { |
1100 | | |
1101 | | // Octree implementation performs WORSE for < 500 objects |
1102 | | // TODO: optimise it so it's better in all cases |
1103 | | //OctreeIntersectionSceneQuery* q = OGRE_NEW OctreeIntersectionSceneQuery(this); |
1104 | 0 | DefaultIntersectionSceneQuery* q = OGRE_NEW DefaultIntersectionSceneQuery(this); |
1105 | 0 | q->setQueryMask(mask); |
1106 | 0 | return q; |
1107 | 0 | } |
1108 | | //----------------------------------------------------------------------- |
1109 | | const String OctreeSceneManagerFactory::FACTORY_TYPE_NAME = "OctreeSceneManager"; |
1110 | | //----------------------------------------------------------------------- |
1111 | | SceneManager* OctreeSceneManagerFactory::createInstance( |
1112 | | const String& instanceName) |
1113 | 0 | { |
1114 | 0 | return OGRE_NEW OctreeSceneManager(instanceName); |
1115 | 0 | } |
1116 | | |
1117 | | } |