~ubuntu-branches/debian/sid/ember/sid

« back to all changes in this revision

Viewing changes to src/components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreeSceneManager.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2009-07-23 07:46:40 UTC
  • Revision ID: james.westby@ubuntu.com-20090723074640-wh0ukzis0kda36qv
Tags: upstream-0.5.6
ImportĀ upstreamĀ versionĀ 0.5.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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-2006 The OGRE Team
 
8
Also see acknowledgements in Readme.html
 
9
 
 
10
This program is free software; you can redistribute it and/or modify it under
 
11
the terms of the GNU Lesser General Public License as published by the Free Software
 
12
Foundation; either version 2 of the License, or (at your option) any later
 
13
version.
 
14
 
 
15
This program is distributed in the hope that it will be useful, but WITHOUT
 
16
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
17
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 
18
 
 
19
You should have received a copy of the GNU Lesser General Public License along with
 
20
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
21
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
 
22
http://www.gnu.org/copyleft/lesser.txt.
 
23
-----------------------------------------------------------------------------
 
24
*/
 
25
/***************************************************************************
 
26
PagingLandScapeOctreescenemanager.cpp  -  description
 
27
-------------------
 
28
begin                : Fri Sep 27 2002
 
29
copyright            : (C) 2002 by Jon Anderson
 
30
email                : janders@users.sf.net
 
31
 
 
32
Enhancements 2003 - 2004 (C) The OGRE Team
 
33
 
 
34
***************************************************************************/
 
35
 
 
36
#include "OgrePagingLandScapePrecompiledHeaders.h"
 
37
 
 
38
#include "OgrePagingLandScapeOctreeSceneManager.h"
 
39
 
 
40
#include "OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.h"
 
41
#include "OgrePagingLandScapeOctreeIntersectionSceneQuery.h"
 
42
#include "OgrePagingLandScapeOctreePlaneBoundedVolumeListSceneQuery.h"
 
43
#include "OgrePagingLandScapeOctreeRaySceneQuery.h"
 
44
#include "OgrePagingLandScapeOctreeSphereSceneQuery.h"
 
45
#include "OgreRenderSystem.h"
 
46
#include "OgreWireBoundingBox.h"
 
47
#include "OgreRenderOperation.h"
 
48
#include "OgreStringConverter.h"
 
49
 
 
50
#include "OgreOverlayManager.h"
 
51
#include "OgreOverlayElement.h"
 
52
 
 
53
#include "OgrePagingLandScapeOctreeCamera.h"
 
54
#include "OgrePagingLandScapeOctree.h"
 
55
#include "OgrePagingLandScapeOctreeNode.h"
 
56
 
 
57
#include "OgreOcclusionBoundingBox.h"
 
58
#include "OgrePagingLandScapeOcclusionSorter.h"
 
59
#include "OgrePagingLandScapeOcclusionVisibilityData.h"
 
60
#include "OgrePagingLandScapeOcclusionTraversal.h"
 
61
#include "OgrePagingLandScapeOcclusionCameraTraversal.h"
 
62
#include "OgrePagingLandScapeOcclusionVFTraversal.h"
 
63
#include "OgrePagingLandScapeOcclusionSWTraversal.h"
 
64
#include "OgrePagingLandScapeOcclusionDebugTraversal.h"
 
65
 
 
66
 
 
67
 
 
68
extern "C"
 
69
{
 
70
    void findNodesInBox(Ogre::SceneManager *sm,
 
71
                         const Ogre::AxisAlignedBox &box,
 
72
                         std::list < Ogre::SceneNode * > &list,
 
73
                         const Ogre::SceneNode * const exclude)
 
74
    {
 
75
        static_cast<Ogre::PagingLandScapeOctreeSceneManager*>(sm)->findNodesIn(box, list, exclude);
 
76
    }
 
77
    void findNodesInSphere(Ogre::SceneManager *sm,
 
78
                            const Ogre::Sphere &sphere,
 
79
                            std::list < Ogre::SceneNode * > &list,
 
80
                            const Ogre::SceneNode * const exclude)
 
81
    {
 
82
        static_cast<Ogre::PagingLandScapeOctreeSceneManager*>(sm)->findNodesIn(sphere, list, exclude);
 
83
    }
 
84
}
 
85
 
 
86
namespace Ogre
 
87
{
 
88
    //---------------------------------------------------------------------
 
89
    enum Intersection
 
90
    {
 
91
        OUTSIDE=0,
 
92
        INSIDE=1,
 
93
        INTERSECT=2
 
94
    };
 
95
    int PagingLandScapeOctreeSceneManager::intersect_call = 0;
 
96
    //---------------------------------------------------------------------
 
97
    Intersection intersect(const Ray &ray, const AxisAlignedBox &box)
 
98
        {
 
99
                // Null box?
 
100
                if (box.isNull()) 
 
101
                        return OUTSIDE;
 
102
                // Infinite box?
 
103
                if (box.isInfinite()) 
 
104
                        return INTERSECT;
 
105
 
 
106
                const Vector3& min = box.getMinimum();
 
107
                const Vector3& max = box.getMaximum();
 
108
                const Vector3& rayorig = ray.getOrigin();
 
109
 
 
110
                // Check origin inside first
 
111
                if ( rayorig > min && rayorig < max )
 
112
                        return INSIDE;
 
113
 
 
114
                const Vector3& raydir = ray.getDirection();
 
115
 
 
116
                Real lowt = 0.0f;
 
117
                Real t;
 
118
                bool hit = false;
 
119
                Vector3 hitpoint;
 
120
 
 
121
                // Check each face in turn, only check closest 3
 
122
                // Min x
 
123
                if (rayorig.x < min.x && raydir.x > 0)
 
124
                {
 
125
                        t = (min.x - rayorig.x) / raydir.x;
 
126
                        if (t > 0)
 
127
                        {
 
128
                                // Substitute t back into ray and check bounds and dist
 
129
                                hitpoint = rayorig + raydir * t;
 
130
                                if (hitpoint.y >= min.y && hitpoint.y <= max.y &&
 
131
                                        hitpoint.z >= min.z && hitpoint.z <= max.z &&
 
132
                                        (!hit || t < lowt))
 
133
                                {
 
134
                                        return INTERSECT;
 
135
                                }
 
136
                        }
 
137
                }
 
138
                // Max x
 
139
                if (rayorig.x > max.x && raydir.x < 0)
 
140
                {
 
141
                        t = (max.x - rayorig.x) / raydir.x;
 
142
                        if (t > 0)
 
143
                        {
 
144
                                // Substitute t back into ray and check bounds and dist
 
145
                                hitpoint = rayorig + raydir * t;
 
146
                                if (hitpoint.y >= min.y && hitpoint.y <= max.y &&
 
147
                                        hitpoint.z >= min.z && hitpoint.z <= max.z &&
 
148
                                        (!hit || t < lowt))
 
149
                                {
 
150
                                        return INTERSECT;
 
151
                                }
 
152
                        }
 
153
                }
 
154
                // Min y
 
155
                if (rayorig.y < min.y && raydir.y > 0)
 
156
                {
 
157
                        t = (min.y - rayorig.y) / raydir.y;
 
158
                        if (t > 0)
 
159
                        {
 
160
                                // Substitute t back into ray and check bounds and dist
 
161
                                hitpoint = rayorig + raydir * t;
 
162
                                if (hitpoint.x >= min.x && hitpoint.x <= max.x &&
 
163
                                        hitpoint.z >= min.z && hitpoint.z <= max.z &&
 
164
                                        (!hit || t < lowt))
 
165
                                {
 
166
                                        return INTERSECT;
 
167
                                }
 
168
                        }
 
169
                }
 
170
                // Max y
 
171
                if (rayorig.y > max.y && raydir.y < 0)
 
172
                {
 
173
                        t = (max.y - rayorig.y) / raydir.y;
 
174
                        if (t > 0)
 
175
                        {
 
176
                                // Substitute t back into ray and check bounds and dist
 
177
                                hitpoint = rayorig + raydir * t;
 
178
                                if (hitpoint.x >= min.x && hitpoint.x <= max.x &&
 
179
                                        hitpoint.z >= min.z && hitpoint.z <= max.z &&
 
180
                                        (!hit || t < lowt))
 
181
                                {
 
182
                                        return INTERSECT;
 
183
                                }
 
184
                        }
 
185
                }
 
186
                // Min z
 
187
                if (rayorig.z < min.z && raydir.z > 0)
 
188
                {
 
189
                        t = (min.z - rayorig.z) / raydir.z;
 
190
                        if (t > 0)
 
191
                        {
 
192
                                // Substitute t back into ray and check bounds and dist
 
193
                                hitpoint = rayorig + raydir * t;
 
194
                                if (hitpoint.x >= min.x && hitpoint.x <= max.x &&
 
195
                                        hitpoint.y >= min.y && hitpoint.y <= max.y &&
 
196
                                        (!hit || t < lowt))
 
197
                                {
 
198
                                        return INTERSECT;
 
199
                                }
 
200
                        }
 
201
                }
 
202
                // Max z
 
203
                if (rayorig.z > max.z && raydir.z < 0)
 
204
                {
 
205
                        t = (max.z - rayorig.z) / raydir.z;
 
206
                        if (t > 0)
 
207
                        {
 
208
                                // Substitute t back into ray and check bounds and dist
 
209
                                hitpoint = rayorig + raydir * t;
 
210
                                if (hitpoint.x >= min.x && hitpoint.x <= max.x &&
 
211
                                        hitpoint.y >= min.y && hitpoint.y <= max.y &&
 
212
                                        (!hit || t < lowt))
 
213
                                {
 
214
                                        return INTERSECT;
 
215
                                }
 
216
                        }
 
217
                }
 
218
                return OUTSIDE;
 
219
        }
 
220
 
 
221
        //---------------------------------------------------------------------
 
222
        Intersection intersect2(const Ray &one, const AxisAlignedBox &two)
 
223
    {
 
224
        PagingLandScapeOctreeSceneManager::intersect_call++;
 
225
 
 
226
        // Null box?
 
227
        if (two.isNull()) 
 
228
            return OUTSIDE;
 
229
                // Infinite box?
 
230
                if (two.isInfinite()) 
 
231
                        return INTERSECT;
 
232
 
 
233
        const Vector3* const pCorners = two.getAllCorners();
 
234
        const Vector3 origin = one.getOrigin();
 
235
        const Vector3 dir = one.getDirection();
 
236
 
 
237
        Vector3 maxT (-1.0f, -1.0f, -1.0f);
 
238
 
 
239
        unsigned int i = 0;
 
240
        bool inside = true;
 
241
        for (i = 0; i < 3; i++)
 
242
        {
 
243
            if (origin[i] < pCorners[0][i])
 
244
            {
 
245
                inside = false;
 
246
                if(dir[i] > 0)
 
247
                    maxT[i] = (pCorners[0][i] - origin[i]) / dir[i];
 
248
            }
 
249
            else if (origin[i] > pCorners[4][i])
 
250
            {
 
251
                inside = false;
 
252
                if(dir[i] < 0)
 
253
                    maxT[i] = (pCorners[4][i] - origin[i]) / dir[i];
 
254
            }
 
255
        }
 
256
 
 
257
        if(inside)
 
258
        {
 
259
            return INTERSECT;
 
260
        }
 
261
        int whichPlane = 0;
 
262
        if(maxT[1] > maxT[whichPlane])
 
263
            whichPlane = 1;
 
264
        if(maxT[2] > maxT[whichPlane])
 
265
            whichPlane = 2;
 
266
 
 
267
        if(((int)maxT[whichPlane]) & 0x80000000)
 
268
        {
 
269
            return OUTSIDE;
 
270
        }
 
271
        const Real maxTThisPlane = maxT[whichPlane];
 
272
        for(i = 0; i < 3; i++)
 
273
        {
 
274
            if(i != whichPlane)
 
275
            {
 
276
                const Real f = origin[i] + maxTThisPlane * dir[i];
 
277
                if (f < (pCorners[0][i] - 0.00001f) ||
 
278
                        f > (pCorners[4][i] + 0.00001f))
 
279
                {
 
280
                    return OUTSIDE;
 
281
                }
 
282
            }
 
283
        }
 
284
 
 
285
        return INTERSECT;
 
286
 
 
287
    }
 
288
    //---------------------------------------------------------------------
 
289
    /** Checks how the second box intersects with the first.
 
290
    */
 
291
    Intersection intersect(const PlaneBoundedVolume &one, const AxisAlignedBox &two)
 
292
    {
 
293
        PagingLandScapeOctreeSceneManager::intersect_call++;
 
294
        // Null box?
 
295
        if (two.isNull()) 
 
296
                        return OUTSIDE;
 
297
                if (two.isInfinite()) 
 
298
                        return INTERSECT;
 
299
 
 
300
        // Get corners of the box
 
301
        const Vector3 * const pCorners = two.getAllCorners();
 
302
 
 
303
        // For each plane, see if all points are on the negative side
 
304
        // If so, object is not visible.
 
305
        // If one or more are, it's partial.
 
306
        // If all aren't, full
 
307
        static const int corners[ 8 ] = {0, 4, 3, 5, 2, 6, 1, 7};
 
308
 
 
309
        bool all_inside = true;
 
310
        PlaneList::const_iterator i, iend = one.planes.end();
 
311
        for (i = one.planes.begin(); i != iend; ++i)
 
312
        {
 
313
            const Plane& plane = *i;
 
314
            bool all_outside = true;
 
315
            for (unsigned int corner = 0; corner < 8; ++corner)
 
316
            {
 
317
                const Real distance = plane.getDistance(pCorners[ corners[ corner ] ]);
 
318
                all_outside = all_outside && (distance < 0);
 
319
                all_inside = all_inside && (distance >= 0);
 
320
 
 
321
                if (!all_outside && !all_inside)
 
322
                    break;
 
323
            }
 
324
 
 
325
            if (all_outside)
 
326
                return OUTSIDE;
 
327
        }
 
328
 
 
329
        if (all_inside)
 
330
            return INSIDE;
 
331
        else
 
332
            return INTERSECT;
 
333
 
 
334
    }
 
335
    //---------------------------------------------------------------------
 
336
    /** Checks how the second box intersects with the first.
 
337
    */
 
338
    Intersection intersect(const AxisAlignedBox &one, const AxisAlignedBox &two)
 
339
    {
 
340
        PagingLandScapeOctreeSceneManager::intersect_call++;
 
341
 
 
342
        // Null box?
 
343
        if (one.isNull() || two.isNull()) 
 
344
            return OUTSIDE;
 
345
                if (one.isInfinite()) 
 
346
                        return INSIDE;
 
347
                if (two.isInfinite()) 
 
348
                        return INTERSECT;
 
349
 
 
350
        const Vector3 * outside = one.getAllCorners();
 
351
        const Vector3 *inside = two.getAllCorners();
 
352
 
 
353
        if (inside[ 4 ].x < outside[ 0 ].x ||
 
354
                inside[ 4 ].y < outside[ 0 ].y ||
 
355
                inside[ 4 ].z < outside[ 0 ].z ||
 
356
                inside[ 0 ].x > outside[ 4 ].x ||
 
357
                inside[ 0 ].y > outside[ 4 ].y ||
 
358
                inside[ 0 ].z > outside[ 4 ].z)
 
359
        {
 
360
            return OUTSIDE;
 
361
        }
 
362
 
 
363
        const bool full = (inside[ 0 ].x > outside[ 0 ].x &&
 
364
                    inside[ 0 ].y > outside[ 0 ].y &&
 
365
                    inside[ 0 ].z > outside[ 0 ].z &&
 
366
                    inside[ 4 ].x < outside[ 4 ].x &&
 
367
                    inside[ 4 ].y < outside[ 4 ].y &&
 
368
                    inside[ 4 ].z < outside[ 4 ].z);
 
369
 
 
370
        if (full)
 
371
            return INSIDE;
 
372
        else
 
373
            return INTERSECT;
 
374
 
 
375
    }
 
376
    //---------------------------------------------------------------------
 
377
    /** Checks how the box intersects with the sphere.
 
378
    */
 
379
    Intersection intersect(const Sphere &one, const AxisAlignedBox &two)
 
380
    {
 
381
        PagingLandScapeOctreeSceneManager::intersect_call++;
 
382
 
 
383
        // Null box?
 
384
        if (two.isNull()) 
 
385
                        return OUTSIDE;
 
386
                if (two.isInfinite()) 
 
387
                        return INTERSECT;
 
388
 
 
389
 
 
390
        const Real sradius = Math::Sqr (one.getRadius());
 
391
        const Vector3 scenter = one.getCenter();
 
392
        const Vector3 * const corners = two.getAllCorners();
 
393
 
 
394
        const Vector3 mndistance = (corners[ 0 ] - scenter);
 
395
        const Vector3 mxdistance = (corners[ 4 ] - scenter);
 
396
 
 
397
 
 
398
        if (mndistance.squaredLength() < sradius &&
 
399
                mxdistance.squaredLength() < sradius)
 
400
        {
 
401
            return INSIDE;
 
402
        }
 
403
 
 
404
        //find the square of the distance
 
405
        //from the sphere to the box
 
406
        Real d = 0;
 
407
        for (unsigned int i = 0 ; i < 3 ; i++)
 
408
        {
 
409
            const Real sCenteri = scenter[ i ];
 
410
            if (sCenteri < corners[ 0 ][ i ])
 
411
            {
 
412
                const Real s = sCenteri - corners[ 0 ][ i ];
 
413
                d += s * s;
 
414
            }
 
415
            else if (sCenteri > corners[ 4 ][ i ])
 
416
            {
 
417
                const Real s = sCenteri - corners[ 4 ][ i ];
 
418
                d += s * s;
 
419
            }
 
420
 
 
421
        }
 
422
 
 
423
        const bool partial = (d <= sradius);
 
424
 
 
425
        if (!partial)
 
426
        {
 
427
            return OUTSIDE;
 
428
        }
 
429
 
 
430
        else
 
431
        {
 
432
            return INTERSECT;
 
433
        }
 
434
 
 
435
 
 
436
    }
 
437
    //-----------------------------------------------------------------------
 
438
    //-----------------------------------------------------------------------
 
439
    //-----------------------------------------------------------------------
 
440
    const String PagingLandScapeOctreeSceneManagerFactory::FACTORY_TYPE_NAME = "PagingLandScapeOctreeSceneManager";
 
441
    //-----------------------------------------------------------------------
 
442
    void PagingLandScapeOctreeSceneManagerFactory::initMetaData(void) const
 
443
    {
 
444
       mMetaData.typeName = FACTORY_TYPE_NAME;
 
445
       mMetaData.description = "Scene manager organising the scene on the basis of an octree, possibly using occlusion culling.";
 
446
       mMetaData.sceneTypeMask = ST_EXTERIOR_REAL_FAR; // support all types
 
447
       mMetaData.worldGeometrySupported = false;
 
448
    }
 
449
    //-----------------------------------------------------------------------
 
450
    SceneManager* PagingLandScapeOctreeSceneManagerFactory::createInstance(
 
451
        const String& instanceName)
 
452
    {
 
453
        return new PagingLandScapeOctreeSceneManager(instanceName);
 
454
    }
 
455
    //-----------------------------------------------------------------------
 
456
    void PagingLandScapeOctreeSceneManagerFactory::destroyInstance(SceneManager* instance)
 
457
    {
 
458
        delete instance;
 
459
    }
 
460
    //---------------------------------------------------------------------
 
461
    PagingLandScapeOctreeSceneManager::PagingLandScapeOctreeSceneManager(const String& name): 
 
462
        SceneManager(name),
 
463
                mPagingLandScapeOctree(0),
 
464
                mCurrentOptionCamera(0)
 
465
    {
 
466
        mOctreeSet.setPoolSize (64);
 
467
        AxisAlignedBox b(-10000, -10000, -10000, 10000, 10000, 10000);
 
468
        int depth = 8; 
 
469
        init(b, depth);
 
470
    }
 
471
    //---------------------------------------------------------------------
 
472
    PagingLandScapeOctreeSceneManager::PagingLandScapeOctreeSceneManager(const String& name, AxisAlignedBox &box, int max_depth) : 
 
473
        SceneManager(name),
 
474
        mPagingLandScapeOctree(0)
 
475
    {
 
476
        init(box, max_depth);
 
477
    }
 
478
    //---------------------------------------------------------------------
 
479
    const String& PagingLandScapeOctreeSceneManager::getTypeName(void) const
 
480
    {
 
481
        return PagingLandScapeOctreeSceneManagerFactory::FACTORY_TYPE_NAME;
 
482
    }
 
483
    //---------------------------------------------------------------------
 
484
    void PagingLandScapeOctreeSceneManager::init(const AxisAlignedBox &box, int depth)
 
485
    {
 
486
        delete mSceneRoot; //get rid of old root.
 
487
 
 
488
        // -- Changes by Steve
 
489
        // Don't do it this way, it will add it to the mSceneNodes which we don't want
 
490
        //mSceneRoot = createSceneNode("SceneRoot");
 
491
        mSceneRoot = new PagingLandScapeOctreeNode(this, "SceneRoot");
 
492
            mSceneRoot->_notifyRootNode();
 
493
        // -- End changes by Steve
 
494
 
 
495
 
 
496
        if (mPagingLandScapeOctree)
 
497
                deleteOctree (mPagingLandScapeOctree);
 
498
        mPagingLandScapeOctree = mOctreeSet.getPoolable();
 
499
        assert (mPagingLandScapeOctree);
 
500
        mPagingLandScapeOctree->setSceneManager (this);
 
501
 
 
502
        mMaxDepth = depth;
 
503
        mBox = box;
 
504
 
 
505
        //mSceneRoot isn't put into the PagingLandScapeOctree since it has no volume.   
 
506
        mPagingLandScapeOctree->setBoundingBox (box.getMinimum(), box.getMaximum());
 
507
 
 
508
        #ifdef _VISIBILITYDEBUG
 
509
            mShowBoxes = false;
 
510
            mCullCamera = false;
 
511
            //     setDisplaySceneNodes(true);
 
512
        #endif //_VISIBILITYDEBUG
 
513
        
 
514
     
 
515
        mOcclusion.init (this);
 
516
        mOcclusionDepth = 0;
 
517
 
 
518
    }
 
519
    //---------------------------------------------------------------------
 
520
    PagingLandScapeOctreeSceneManager::~PagingLandScapeOctreeSceneManager()
 
521
    {
 
522
        // -- Changed by Steve
 
523
        // Don't do this here, SceneManager will do it
 
524
        /*
 
525
        if(mSceneRoot)
 
526
        delete mSceneRoot;
 
527
        */ 
 
528
        // --End Changes by Steve
 
529
 
 
530
        if (mPagingLandScapeOctree)
 
531
        {
 
532
            deleteOctree (mPagingLandScapeOctree);
 
533
            mPagingLandScapeOctree = 0;
 
534
        }
 
535
        VisiblesPerCam::iterator i = mVisibles.begin ();
 
536
        while (i != mVisibles.end())
 
537
        {            
 
538
           delete (i->second);
 
539
           ++i;
 
540
        }
 
541
        mVisibles.clear();
 
542
        mOctreeSet.deletePool ();
 
543
    }
 
544
    //---------------------------------------------------------------------
 
545
    Camera * PagingLandScapeOctreeSceneManager::createCamera(const String &name)
 
546
    {
 
547
        if (mCameras.find(name) != mCameras.end())
 
548
        {
 
549
            OGRE_EXCEPT(
 
550
                Exception::ERR_DUPLICATE_ITEM,
 
551
                "A camera with the name " + name + " already exists",
 
552
                "PagingLandScapeSceneManager::createCamera");
 
553
        }
 
554
        Camera * c = new PagingLandScapeOctreeCamera(name, this);
 
555
        mCameras.insert(CameraList::value_type(name, c));
 
556
                addCamera (c);
 
557
        return c;
 
558
    }
 
559
    //-----------------------------------------------------------------------
 
560
    void PagingLandScapeOctreeSceneManager::addCamera(Camera *cam)
 
561
        {
 
562
                PagingLandScapeOctreeCamera *c = static_cast <PagingLandScapeOctreeCamera *> (cam);
 
563
                mVisibles[c->getId ()] = new MovableObjectList();
 
564
        if (!c->isRegisteredInOcclusionSystem()
 
565
                        && c->needRegistrationInOcclusionSystem())
 
566
        {
 
567
            mPagingLandScapeOctree->traversal(RegisterCameraTraversal(c), 0);
 
568
            c->setRegisteredInOcclusionSystem(true);
 
569
        }
 
570
                if (!mCurrentOptionCamera)
 
571
                        mCurrentOptionCamera = c;
 
572
        }
 
573
        //-----------------------------------------------------------------------
 
574
        void PagingLandScapeOctreeSceneManager::unregisterCamera(PagingLandScapeOctreeCamera *c)
 
575
        {
 
576
                VisiblesPerCam::iterator i = mVisibles.find (c->getId ());
 
577
                if (i != mVisibles.end())
 
578
                {            
 
579
                        delete (i->second);
 
580
                        mVisibles.erase(i);
 
581
                }
 
582
                if (c->isRegisteredInOcclusionSystem ())
 
583
                {
 
584
                        mPagingLandScapeOctree->traversal (UnregisterCameraTraversal(c), 0);
 
585
                        c->setRegisteredInOcclusionSystem (false);                   
 
586
                } 
 
587
                if (mCurrentOptionCamera == c)
 
588
                        c = 0;
 
589
        }
 
590
    //-----------------------------------------------------------------------
 
591
    void PagingLandScapeOctreeSceneManager::destroyCamera(Camera *cam)
 
592
    {
 
593
        SceneManager::destroyCamera(cam);
 
594
    }
 
595
    //-----------------------------------------------------------------------
 
596
    void PagingLandScapeOctreeSceneManager::destroyCamera(const String& name)
 
597
    {
 
598
                // Find in list
 
599
       CameraList::iterator i = mCameras.find(name);
 
600
       if (i != mCameras.end())
 
601
           {
 
602
                        unregisterCamera (static_cast <PagingLandScapeOctreeCamera *> (i->second));
 
603
          SceneManager::destroyCamera (name);
 
604
       }                  
 
605
    }
 
606
    //-----------------------------------------------------------------------
 
607
    void PagingLandScapeOctreeSceneManager::destroyAllCameras(void)
 
608
    {
 
609
                CameraList::iterator i = mCameras.begin();
 
610
                for (; i != mCameras.end(); ++i)
 
611
                {
 
612
                        unregisterCamera (static_cast <PagingLandScapeOctreeCamera *> (i->second));
 
613
                        // Notify render system
 
614
                        mDestRenderSystem->_notifyCameraRemoved(i->second);
 
615
                        delete i->second;
 
616
                }
 
617
        mCameras.clear ();
 
618
    } 
 
619
    //---------------------------------------------------------------------
 
620
    void PagingLandScapeOctreeSceneManager::destroySceneNode(const String &name)
 
621
    {
 
622
        PagingLandScapeOctreeNode * on = static_cast < PagingLandScapeOctreeNode* > (SceneManager::getSceneNode(name));
 
623
 
 
624
        if (on != 0)
 
625
            _removePagingLandScapeOctreeNode(on);
 
626
 
 
627
        SceneManager::destroySceneNode(name);
 
628
    }
 
629
    //---------------------------------------------------------------------
 
630
    bool PagingLandScapeOctreeSceneManager::getOptionValues(const String & key, StringVector  &refValueList)
 
631
    {
 
632
        return SceneManager::getOptionValues(key, refValueList);
 
633
    }
 
634
    //---------------------------------------------------------------------
 
635
    bool PagingLandScapeOctreeSceneManager::getOptionKeys(StringVector & refKeys)
 
636
    {
 
637
        SceneManager::getOptionKeys(refKeys);
 
638
 
 
639
        refKeys.push_back("CullCamera");
 
640
        refKeys.push_back("Size");
 
641
        refKeys.push_back("ShowPagingLandScapeOctree");
 
642
        refKeys.push_back("Depth");
 
643
 
 
644
        return true;
 
645
    }
 
646
    //---------------------------------------------------------------------
 
647
    void PagingLandScapeOctreeSceneManager::_updatePagingLandScapeOctreeNode(PagingLandScapeOctreeNode * onode)
 
648
    {
 
649
        const AxisAlignedBox box = onode->_getWorldAABB();
 
650
 
 
651
        if (box.isNull())
 
652
            return ;
 
653
 
 
654
        // Skip if octree has been destroyed (shutdown conditions)
 
655
        if (!mPagingLandScapeOctree)
 
656
            return;
 
657
 
 
658
        if (onode->getOctant() == 0)
 
659
        {
 
660
            //if outside the PagingLandScapeOctree, force into the root node.
 
661
            if (! onode->_isIn(mPagingLandScapeOctree->getBoundingBox()))
 
662
                mPagingLandScapeOctree->_addNode(onode);
 
663
            else
 
664
                _addPagingLandScapeOctreeNode(onode, mPagingLandScapeOctree);
 
665
            return ;
 
666
        }
 
667
 
 
668
        if (! onode->_isIn(onode->getOctant()->getBoundingBox()))
 
669
        {
 
670
            _removePagingLandScapeOctreeNode(onode);
 
671
 
 
672
            //if outside the PagingLandScapeOctree, force into the root node.
 
673
            if (! onode->_isIn(mPagingLandScapeOctree->getBoundingBox()))
 
674
                mPagingLandScapeOctree->_addNode(onode);
 
675
            else
 
676
                _addPagingLandScapeOctreeNode(onode, mPagingLandScapeOctree);
 
677
        }
 
678
    }
 
679
    //---------------------------------------------------------------------
 
680
    /** Only removes the node from the PagingLandScapeOctree.  It leaves the PagingLandScapeOctree, even if it's empty.
 
681
    */
 
682
    void PagingLandScapeOctreeSceneManager::_removePagingLandScapeOctreeNode(PagingLandScapeOctreeNode * n)
 
683
    {
 
684
        assert (n);
 
685
 
 
686
        // Skip if octree has been destroyed (shutdown conditions)
 
687
        if (!mPagingLandScapeOctree)
 
688
            return;
 
689
 
 
690
                PagingLandScapeOctree * oct = n->getOctant();
 
691
                if (oct)
 
692
                        oct->_removeNode (n);
 
693
                n->setOctant (0);
 
694
                unregisteredNodeInCamera (n);
 
695
    }
 
696
    //---------------------------------------------------------------------
 
697
    void PagingLandScapeOctreeSceneManager::_addPagingLandScapeOctreeMovableNode(PagingLandScapeOctreeNode * n, 
 
698
                                                                                 PagingLandScapeOctree *octant, 
 
699
                                                                                 int depth)
 
700
    {
 
701
        const AxisAlignedBox& bx(n->_getWorldAABB());
 
702
 
 
703
        //if the PagingLandScapeOctree is twice as big as the scene node,
 
704
        //we will add it to a child.
 
705
        if ((depth < mMaxDepth) && octant->_isTwiceSize (bx))
 
706
        {
 
707
            _addPagingLandScapeOctreeMovableNode(n, 
 
708
                                          octant->_getChildWhereBoxFits(bx, this), 
 
709
                                          ++depth);
 
710
        }
 
711
        else
 
712
        {  
 
713
                #ifdef _VISIBILITYDEBUG   
 
714
                    n ->setDebugCorners(this);
 
715
                #endif //_VISIBILITYDEBUG    
 
716
 
 
717
                #ifdef _DEBUG
 
718
                    std::cout << "Depth Placement " 
 
719
                        << StringConverter::toString (depth) 
 
720
                        << " \n";
 
721
                #endif //_DEBUG
 
722
 
 
723
            octant->_addNode(n);
 
724
        }
 
725
    }
 
726
    //---------------------------------------------------------------------
 
727
    void PagingLandScapeOctreeSceneManager::_addPagingLandScapeOctreeStaticNode(PagingLandScapeOctreeNode * n, 
 
728
                                                                                PagingLandScapeOctree *octant, 
 
729
                                                                                int depth)
 
730
    {
 
731
        const AxisAlignedBox bx = n->_getWorldAABB();
 
732
 
 
733
        //if the PagingLandScapeOctree is twice as big as the scene node,
 
734
        //we will add it to a child.
 
735
        if ((depth < mMaxDepth) && octant->_isTwiceCullSize (bx))
 
736
        {
 
737
            if (octant->_isNotCrossingAxes(bx))
 
738
                        {
 
739
                _addPagingLandScapeOctreeStaticNode(n, 
 
740
                                                    octant->_getCullChildWhereBoxFits(bx, this), 
 
741
                                                    ++depth);
 
742
                        }
 
743
            else
 
744
            {
 
745
                // re-insert it as a moving node, therefore avoiding crossing problem.
 
746
                n->setStaticCulling (false);
 
747
                _addPagingLandScapeOctreeMovableNode(n, 
 
748
                                                    mPagingLandScapeOctree, 
 
749
                                                    0);
 
750
            }
 
751
        }
 
752
        else
 
753
        {  
 
754
            #ifdef _VISIBILITYDEBUG   
 
755
                n ->setDebugCorners(this);
 
756
            #endif //_VISIBILITYDEBUG    
 
757
            octant->_addNode(n);
 
758
        }
 
759
    }
 
760
    //---------------------------------------------------------------------
 
761
    void PagingLandScapeOctreeSceneManager::_addPagingLandScapeOctreeNode(PagingLandScapeOctreeNode * n, PagingLandScapeOctree *octant, int depth)
 
762
    {
 
763
        assert (n && octant);
 
764
        if (n->isStaticNode ())
 
765
            _addPagingLandScapeOctreeStaticNode(n, octant, depth);
 
766
        else
 
767
                        _addPagingLandScapeOctreeMovableNode(n, octant, depth);
 
768
                registeredNodeInCamera (n);
 
769
    }
 
770
    //---------------------------------------------------------------------
 
771
    SceneNode * PagingLandScapeOctreeSceneManager::createSceneNode(void)
 
772
        {
 
773
        PagingLandScapeOctreeNode * on = new PagingLandScapeOctreeNode(this);
 
774
                mSceneNodes[ on->getName() ] = on; 
 
775
        return on;
 
776
    }
 
777
    //---------------------------------------------------------------------
 
778
    SceneNode * PagingLandScapeOctreeSceneManager::createSceneNode(const String &name)
 
779
    {
 
780
                // Check name not used
 
781
            if (mSceneNodes.find(name) != mSceneNodes.end())
 
782
            {
 
783
                    OGRE_EXCEPT(
 
784
                                Exception::ERR_DUPLICATE_ITEM,
 
785
                                "A scene node with the name " + name + " already exists",
 
786
                                "PagingLandScapeOctreeSceneManager::createSceneNode" );
 
787
                }
 
788
        PagingLandScapeOctreeNode * on = new PagingLandScapeOctreeNode(this, name);
 
789
                mSceneNodes[ on->getName() ] = on; 
 
790
        return on;
 
791
    }
 
792
    //---------------------------------------------------------------------
 
793
    void PagingLandScapeOctreeSceneManager::registeredNodeInCamera(OcclusionElement *on)
 
794
    {
 
795
         // register existing camera in nodes
 
796
        bool isRegistered = false;
 
797
        for (CameraList::iterator it = mCameras.begin(); it != mCameras.end(); ++it)
 
798
        {
 
799
            // Notify occlusion system
 
800
            PagingLandScapeOctreeCamera *c = static_cast <PagingLandScapeOctreeCamera *> (it->second);
 
801
            assert (c);
 
802
            if (c->isRegisteredInOcclusionSystem ())
 
803
            {
 
804
                on->traversal (RegisterCameraTraversal(c), 0);
 
805
                isRegistered = true;
 
806
            }
 
807
        }
 
808
        on->setRegisteredtoCam (isRegistered);      
 
809
        }
 
810
    //---------------------------------------------------------------------
 
811
    void PagingLandScapeOctreeSceneManager::unregisteredNodeInCamera(OcclusionElement *on)
 
812
    {
 
813
         // register existing camera in nodes
 
814
        for (CameraList::iterator it = mCameras.begin();it != mCameras.end(); ++it)
 
815
        {
 
816
            // Notify occlusion system
 
817
            PagingLandScapeOctreeCamera *c = static_cast <PagingLandScapeOctreeCamera *> (it->second);
 
818
            assert (c);
 
819
            if (c->isRegisteredInOcclusionSystem ())
 
820
                on->traversal (UnregisterCameraTraversal(c), 0);
 
821
        }   
 
822
        on->setRegisteredtoCam (false);               
 
823
        }
 
824
    //---------------------------------------------------------------------
 
825
    void PagingLandScapeOctreeSceneManager::_updateSceneGraph(Camera * cam)
 
826
    {
 
827
        SceneManager::_updateSceneGraph(cam);
 
828
    }
 
829
    //---------------------------------------------------------------------
 
830
    void PagingLandScapeOctreeSceneManager::enableHardwareOcclusionTests()
 
831
    { 
 
832
        Camera * const c_cam = mCameraInProgress;
 
833
 
 
834
        // make sure we always occlude in SOLID MODE
 
835
                mCamDetail =  c_cam->getPolygonMode ();
 
836
                if (mCamDetail != PM_SOLID)
 
837
                {                       
 
838
                        mOcclusion.setIfNotSolidScene   (true);
 
839
                        c_cam->setPolygonMode (PM_SOLID);
 
840
                }
 
841
                else 
 
842
                {
 
843
                        mOcclusion.setIfNotSolidScene   (false);
 
844
                }
 
845
 
 
846
        //#define HWOCCLUSIONRTT
 
847
        #ifdef HWOCCLUSIONRTT
 
848
 
 
849
                        const Viewport * const c_camViewPort = c_cam->getViewport();
 
850
                        assert (c_camViewPort);
 
851
            if (mOcclusionDepth == 0)
 
852
            {
 
853
                mOcclusionDepth = mDestRenderSystem->
 
854
                    createRenderTexture(
 
855
                    "OcclusionDepthTexture", 
 
856
                    c_camViewPort->getActualWidth() / 8, 
 
857
                    c_camViewPort->getActualHeight() / 8, 
 
858
                    TEX_TYPE_2D, 
 
859
                    PF_DEPTH);
 
860
 
 
861
 
 
862
                mOcclusionDepth->setAutoUpdated (false);
 
863
                mOcclusionDepth->setActive (false);
 
864
 
 
865
                mOcclusionCamera = createCamera ("OcclusionDepthTextureCamera");
 
866
                Viewport * const v = mOcclusionDepth->addViewport(mOcclusionCamera);
 
867
                                assert (v);
 
868
                v->setOverlaysEnabled (false);
 
869
                v->setClearEveryFrame(false);
 
870
                v->setBackgroundColour(ColourValue::Black);
 
871
 
 
872
#define RENDERCOLOR
 
873
#ifdef RENDERCOLOR
 
874
                    MaterialPtr mat = MaterialManager::getSingleton().create (
 
875
                                        "OcclusionDepthTextureMat",
 
876
                                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
 
877
                    mat->getTechnique(0)->getPass(0)->createTextureUnitState("OcclusionDepthTexture");
 
878
 
 
879
                    Overlay *OcclusionDepthOverlay = OverlayManager::getSingleton ().create("OcclusionDepthOverlay"); 
 
880
                    OverlayElement *OcclusionDepthPanel = 
 
881
                    OverlayManager::getSingleton ().createOverlayElement ("Panel", 
 
882
                                                                            "OcclusionDepthPanel", 
 
883
                                                                            false); 
 
884
                    OcclusionDepthPanel->setMaterialName ("OcclusionDepthTextureMat"); 
 
885
                    OcclusionDepthOverlay->add2D ((OverlayContainer *)OcclusionDepthPanel); 
 
886
                    OcclusionDepthOverlay->show ();
 
887
 
 
888
                    //OcclusionDepthOverlay->setScale (0.5f, 0.5f);
 
889
                    OcclusionDepthPanel->setPosition (0.8, 0.8);
 
890
#endif //RENDERCOLOR
 
891
 
 
892
                mOcclusionCamera->setNearClipDistance(c_cam->getNearClipDistance());
 
893
                mOcclusionCamera->setFarClipDistance(c_cam->getFarClipDistance());
 
894
                mOcclusionCamera->setAspectRatio(
 
895
                    (Real)c_camViewPort->getActualWidth() /  c_camViewPort->getActualHeight());
 
896
            }
 
897
 
 
898
            // copy camera characteristics to occlusion camera.
 
899
            mOcclusionCamera->setPosition (c_cam->getWorldPosition ());
 
900
            mOcclusionCamera->setOrientation (c_cam->getWorldOrientation ());
 
901
            mOcclusionCamera->setNearClipDistance(c_cam->getNearClipDistance());
 
902
            mOcclusionCamera->setFarClipDistance(c_cam->getFarClipDistance());  
 
903
 
 
904
 
 
905
            mDestRenderSystem->_setViewport(mOcclusionCamera->getViewport ());
 
906
            mDestRenderSystem->_setWorldMatrix(Matrix4::IDENTITY);
 
907
            mDestRenderSystem->_setViewMatrix(c_cam->getViewMatrix());
 
908
            mDestRenderSystem->_setProjectionMatrix(c_cam->getProjectionMatrix());
 
909
 
 
910
            mDestRenderSystem->_beginFrame();
 
911
 
 
912
            mDestRenderSystem->clearFrameBuffer (FBT_DEPTH | FBT_COLOUR, 
 
913
            mOcclusionCamera->getViewport ()->getBackgroundColour ());
 
914
 
 
915
        #else //HWOCCLUSIONRTT
 
916
 
 
917
                        assert (c_cam->getViewport());
 
918
            mDestRenderSystem->_setViewport(c_cam->getViewport());
 
919
            mDestRenderSystem->clearFrameBuffer (FBT_DEPTH | FBT_COLOUR, 
 
920
                                                c_cam->getViewport ()->getBackgroundColour (),//color
 
921
                                                1.0f,//depth
 
922
                                                0);//stencil
 
923
            mDestRenderSystem->_beginFrame();
 
924
            assert (c_cam->getViewport()->getClearEveryFrame () == false);
 
925
        #endif //HWOCCLUSIONRTT
 
926
 
 
927
                mDestRenderSystem->_beginGeometryCount();
 
928
 
 
929
    }
 
930
    //---------------------------------------------------------------------
 
931
    void PagingLandScapeOctreeSceneManager::disableHardwareOcclusionTests()
 
932
    {
 
933
        PagingLandScapeOctreeCamera * const octreeCam = static_cast <PagingLandScapeOctreeCamera *> (mCameraInProgress);
 
934
        
 
935
                assert (octreeCam->getViewport ());
 
936
        #ifdef HWOCCLUSIONRTT
 
937
 
 
938
                mDestRenderSystem->_endFrame();
 
939
                mDestRenderSystem->_setViewport(octreeCam->getViewport ());
 
940
 
 
941
        #else //HWOCCLUSIONRTT
 
942
                mDestRenderSystem->_endFrame();
 
943
                #endif //HWOCCLUSIONRTT
 
944
 
 
945
                if (mCamDetail != PM_SOLID)
 
946
                {
 
947
                        mDestRenderSystem->clearFrameBuffer (FBT_DEPTH | FBT_COLOUR, 
 
948
                                                                                                octreeCam->getViewport ()->getBackgroundColour (),//color
 
949
                                                                                                1.0f,//depth
 
950
                                                                                                0);//stencil
 
951
                }       
 
952
        
 
953
        // make sure we restore previous detail level.
 
954
        octreeCam->setPolygonMode (mCamDetail);
 
955
 
 
956
                // Notify camera or vis faces
 
957
                octreeCam->_addCHCRenderedFaces(mDestRenderSystem->_getFaceCount());
 
958
        }
 
959
    //---------------------------------------------------------------------
 
960
#ifdef PLSM2_EIHORT
 
961
    void PagingLandScapeOctreeSceneManager::_findVisibleObjects(Camera* cam, VisibleObjectsBoundsInfo * visibleBounds, bool onlyShadowCasters)
 
962
#else
 
963
    void PagingLandScapeOctreeSceneManager::_findVisibleObjects(Camera * cam, bool onlyShadowCasters)
 
964
#endif
 
965
    {
 
966
        RenderQueue *q = SceneManager::getRenderQueue();
 
967
 
 
968
 
 
969
                PagingLandScapeOctreeCamera * const octreeCam = static_cast <PagingLandScapeOctreeCamera *> (cam);
 
970
                
 
971
        assert (mVisibles.find(octreeCam->getId()) != mVisibles.end());
 
972
        mCamInProgressVisibles = mVisibles[octreeCam->getId()];
 
973
        assert (mCamInProgressVisibles);
 
974
 
 
975
        #ifdef _VISIBILITYDEBUG
 
976
            /*
 
977
                if (!octreeCam->isRegisteredInOcclusionSystem())
 
978
                {
 
979
                    mPagingLandScapeOctree->traversal(RegisterCameraTraversal(octreeCam));
 
980
                    octreeCam->setRegisteredInOcclusionSystem(true);
 
981
                }
 
982
            */
 
983
            mBoxes.clear();
 
984
            if (mCullCamera)
 
985
            {
 
986
                if (getCamera("CullCamera"))
 
987
                    cam = getCamera("CullCamera");
 
988
            }
 
989
        #endif // _VISIBILITYDEBUG
 
990
 
 
991
        if (mPagingLandScapeOctree->hasChildren ())
 
992
        {
 
993
            mNumObjects = 0;
 
994
 
 
995
            // should find a way to be sure that 
 
996
            // it's a new frame, and not just a camera change or something.
 
997
            if (mOcclusion.nextFrame (static_cast < PagingLandScapeOctreeCamera * > (cam),
 
998
                                      mCamInProgressVisibles,
 
999
                                      onlyShadowCasters, 
 
1000
                                      q))
 
1001
            {
 
1002
                switch (octreeCam->getOcclusionMode())
 
1003
                {
 
1004
                case CHC:
 
1005
                    {                     
 
1006
                        enableHardwareOcclusionTests();
 
1007
                        mOcclusion.CHCtraversal (mPagingLandScapeOctree, visibleBounds);
 
1008
                                                disableHardwareOcclusionTests();
 
1009
                                                q->clear();
 
1010
                                                #ifdef _VISIBILITYDEBUG
 
1011
                                                if (mCullDebug && cam->getViewport ())
 
1012
                                                {
 
1013
                            mDebugText =(
 
1014
                                "CHC = " + StringConverter::toString(mOcclusion.object_cnt) + ", t=" +
 
1015
                                StringConverter::toString(mOcclusion.traversed_nodes_cnt) + ", f=" +
 
1016
                                StringConverter::toString(mOcclusion.frustum_culled_nodes_cnt) + ", q=" +
 
1017
                                StringConverter::toString(mOcclusion.query_cnt)
 
1018
                                            );
 
1019
                                                }
 
1020
                        #endif //_VISIBILITYDEBUG
 
1021
                    }
 
1022
                    break;
 
1023
                case CHC_CONSERVATIVE:
 
1024
                    {                     
 
1025
                        enableHardwareOcclusionTests();
 
1026
                        mOcclusion.CHCtraversalConservative (mPagingLandScapeOctree, visibleBounds);
 
1027
                                                disableHardwareOcclusionTests();
 
1028
                                                q->clear();
 
1029
 
 
1030
                        #ifdef _VISIBILITYDEBUG
 
1031
                                                        if (mCullDebug && cam->getViewport ())
 
1032
                                                        {
 
1033
                                                        mDebugText =(
 
1034
                                                                        "CHC Conservative = " + StringConverter::toString(mOcclusion.object_cnt) + ", t=" +
 
1035
                                                                        StringConverter::toString(mOcclusion.traversed_nodes_cnt) + ", f=" +
 
1036
                                                                        StringConverter::toString(mOcclusion.frustum_culled_nodes_cnt) + ", q=" +
 
1037
                                                                        StringConverter::toString(mOcclusion.query_cnt)
 
1038
                                                                                                );
 
1039
                                                        }
 
1040
                                                #endif //_VISIBILITYDEBUG
 
1041
                    }
 
1042
                    break;
 
1043
//                    case STOP_AND_WAIT:
 
1044
//                        {     
 
1045
//                            enableHardwareOcclusionTests();
 
1046
//                            mOcclusion.initQueryPool ();
 
1047
//                            mPagingLandScapeOctree->traversal (SWTraversal (mOcclusion), visibleBounds);
 
1048
//                            disableHardwareOcclusionTests(); q->clear();
 
1049
//    
 
1050
//                           #ifdef _VISIBILITYDEBUG
 
1051
//                               if (mCullDebug && cam->getViewport ()) {cam->getViewport ()->getTarget ()->setDebugText(
 
1052
//                                        "SnW = " + StringConverter::toString(mOcclusion.object_cnt) + ", t=" +
 
1053
//                                        StringConverter::toString(mOcclusion.traversed_nodes_cnt) + ", f=" +
 
1054
//                                        StringConverter::toString(mOcclusion.frustum_culled_nodes_cnt) + ", q=" +
 
1055
//                                        StringConverter::toString(mOcclusion.query_cnt)
 
1056
//                                                      );}
 
1057
//                                
 
1058
//                                #endif //_VISIBILITYDEBUG
 
1059
//        
 
1060
//                        }
 
1061
//                         break;
 
1062
//                case VIEW_FRUSTUM:
 
1063
//                        {
 
1064
//                            mPagingLandScapeOctree->traversal (ViewFrustumCullingTraversal (mOcclusion), visibleBounds);
 
1065
//                                                      q->clear();
 
1066
//                            #ifdef _VISIBILITYDEBUG
 
1067
//                                                              if (mCullDebug && cam->getViewport ())
 
1068
//                              {  cam->getViewport ()->getTarget ()->setDebugText(
 
1069
//                                    "VF = " +  StringConverter::toString(mOcclusion.object_cnt) + ", t=" +
 
1070
//                                StringConverter::toString(mOcclusion.traversed_nodes_cnt) + ", f=" +
 
1071
//                                StringConverter::toString(mOcclusion.frustum_culled_nodes_cnt) + ", q=" +
 
1072
//                                StringConverter::toString(mOcclusion.query_cnt)
 
1073
//                                              );}
 
1074
//                             
 
1075
//                            #endif //_VISIBILITYDEBUG
 
1076
//                        }
 
1077
//                          break;  
 
1078
                case VIEW_FRUSTUM_DIRECT:
 
1079
                {
 
1080
                                        ViewFrustumCullingTraversalDirect temp (mOcclusion);
 
1081
                    mPagingLandScapeOctree->traversal (temp, visibleBounds);
 
1082
 
 
1083
                    #ifdef _VISIBILITYDEBUG
 
1084
                                                if (mCullDebug && cam->getViewport ())
 
1085
                                                { 
 
1086
                                                        mDebugText =(
 
1087
                                                                "VFD = " +  StringConverter::toString(mOcclusion.object_cnt) + ", t=" +
 
1088
                                                        StringConverter::toString(mOcclusion.traversed_nodes_cnt) + ", f=" +
 
1089
                                                        StringConverter::toString(mOcclusion.frustum_culled_nodes_cnt) + ", q=" +
 
1090
                                                        StringConverter::toString(mOcclusion.query_cnt)
 
1091
                                    ); 
 
1092
                                                }           
 
1093
                    #endif // _VISIBILITYDEBUG
 
1094
                }
 
1095
                                break;
 
1096
                    
 
1097
                        default:
 
1098
                    assert (0);
 
1099
                                break;
 
1100
            }
 
1101
            }
 
1102
 
 
1103
            if (!mCamInProgressVisibles->empty())
 
1104
            {
 
1105
                MovableObjectList::iterator movableIt = mCamInProgressVisibles->begin();
 
1106
                MovableObjectList::iterator mitend = mCamInProgressVisibles->end(); 
 
1107
                while (movableIt != mitend)
 
1108
                {
 
1109
                    (*movableIt)->_updateRenderQueue (q);
 
1110
                    ++movableIt;
 
1111
                }   
 
1112
            }
 
1113
 
 
1114
            #ifdef _VISIBILITYDEBUG
 
1115
                if (mCullDebug)
 
1116
                {   
 
1117
                    mPagingLandScapeOctree->traversal (TreeOverlayDebug (mOcclusion, this), visibleBounds);
 
1118
                }      
 
1119
            #endif // _VISIBILITYDEBUG
 
1120
        }
 
1121
    }
 
1122
    //---------------------------------------------------------------------
 
1123
    void PagingLandScapeOctreeSceneManager::addVisible(MovableObject *mo)
 
1124
    {   
 
1125
        mCamInProgressVisibles->push_back (mo);
 
1126
    }
 
1127
    //---------------------------------------------------------------------
 
1128
    void PagingLandScapeOctreeSceneManager::directRenderSingleQueue(RenderQueue *queue)
 
1129
    {  
 
1130
        RenderQueue *oldQueue = mRenderQueue;
 
1131
        mRenderQueue = queue;
 
1132
 
 
1133
        SceneManager::_renderVisibleObjects ();
 
1134
 
 
1135
        queue->clear ();
 
1136
        mRenderQueue = oldQueue;
 
1137
    }    
 
1138
    //---------------------------------------------------------------------
 
1139
    void PagingLandScapeOctreeSceneManager::directRenderSingleObject(Renderable *r)
 
1140
    {   
 
1141
          const Camera * const c_cam = mCameraInProgress;
 
1142
          mDestRenderSystem->_setWorldMatrix(Matrix4::IDENTITY);
 
1143
//        mDestRenderSystem->_setViewMatrix(c_cam->getViewMatrix());
 
1144
//        mDestRenderSystem->_setProjectionMatrix(c_cam->getProjectionMatrix());
 
1145
 
 
1146
                mDestRenderSystem->setCurrentPassIterationCount(1);
 
1147
        _setPass(r->getMaterial()->getBestTechnique()->getPass(0));
 
1148
        useRenderableViewProjMode (r);
 
1149
 
 
1150
        RenderOperation ro;
 
1151
        r->getRenderOperation (ro);
 
1152
        mDestRenderSystem->_render(ro);
 
1153
 
 
1154
    } 
 
1155
    //---------------------------------------------------------------------
 
1156
    void PagingLandScapeOctreeSceneManager::registerCamera (PagingLandScapeOctreeCamera *c)
 
1157
    {        
 
1158
       mPagingLandScapeOctree->traversal(RegisterCameraTraversal(c), 0);
 
1159
    }  
 
1160
    //---------------------------------------------------------------------
 
1161
     // --- non template versions
 
1162
    void _findNodes(const AxisAlignedBox &t, std::list < SceneNode * > &list, 
 
1163
                    const Ogre::SceneNode * const exclude, const bool full, PagingLandScapeOctree *octant)
 
1164
    {
 
1165
 
 
1166
        bool isFull = full;
 
1167
            if (!full)
 
1168
            {
 
1169
                    AxisAlignedBox obox;
 
1170
                    octant->_getCullBounds(&obox);
 
1171
 
 
1172
                    const Intersection isect = intersect(t, obox);
 
1173
 
 
1174
                    if (isect == OUTSIDE)
 
1175
                            return ;
 
1176
 
 
1177
                    isFull = (isect == INSIDE);
 
1178
            }
 
1179
 
 
1180
 
 
1181
        const bool b_full = isFull;
 
1182
            NodeList::iterator it = octant->mNodes.begin();
 
1183
 
 
1184
            while (it != octant->mNodes.end())
 
1185
            {
 
1186
                    PagingLandScapeOctreeNode * const on = (*it);
 
1187
 
 
1188
                    if (on != exclude)
 
1189
                    {
 
1190
                            if (b_full)
 
1191
                            {
 
1192
                                    list.push_back(on);
 
1193
                            }
 
1194
 
 
1195
                            else
 
1196
                            {
 
1197
                                    const Intersection nsect = intersect(t, on->_getWorldAABB());
 
1198
 
 
1199
                                    if (nsect != OUTSIDE)
 
1200
                                    {
 
1201
                                            list.push_back(on);
 
1202
                                    }
 
1203
                            }
 
1204
 
 
1205
                    }
 
1206
 
 
1207
                    ++it;
 
1208
            }
 
1209
 
 
1210
 
 
1211
 
 
1212
            if (octant->mChildren[ 0 ][ 0 ][ 0 ] != 0)
 
1213
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 0 ][ 0 ]);
 
1214
 
 
1215
            if (octant->mChildren[ 1 ][ 0 ][ 0 ] != 0)
 
1216
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 0 ][ 0 ]);
 
1217
 
 
1218
            if (octant->mChildren[ 0 ][ 1 ][ 0 ] != 0)
 
1219
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 1 ][ 0 ]);
 
1220
 
 
1221
            if (octant->mChildren[ 1 ][ 1 ][ 0 ] != 0)
 
1222
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 1 ][ 0 ]);
 
1223
 
 
1224
            if (octant->mChildren[ 0 ][ 0 ][ 1 ] != 0)
 
1225
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 0 ][ 1 ]);
 
1226
 
 
1227
            if (octant->mChildren[ 1 ][ 0 ][ 1 ] != 0)
 
1228
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 0 ][ 1 ]);
 
1229
 
 
1230
            if (octant->mChildren[ 0 ][ 1 ][ 1 ] != 0)
 
1231
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 1 ][ 1 ]);
 
1232
 
 
1233
            if (octant->mChildren[ 1 ][ 1 ][ 1 ] != 0)
 
1234
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 1 ][ 1 ]);
 
1235
 
 
1236
    }
 
1237
    //---------------------------------------------------------------------
 
1238
    void _findNodes(const Sphere &t, std::list < SceneNode * > &list, 
 
1239
                    const SceneNode * const exclude, 
 
1240
                    const bool full, PagingLandScapeOctree *octant)
 
1241
    {
 
1242
        bool isFull = full;
 
1243
            if (!full)
 
1244
            {
 
1245
                    AxisAlignedBox obox;
 
1246
                    octant->_getCullBounds(&obox);
 
1247
 
 
1248
                    const Intersection isect = intersect(t, obox);
 
1249
 
 
1250
                    if (isect == OUTSIDE)
 
1251
                            return ;
 
1252
 
 
1253
                    isFull = (isect == INSIDE);
 
1254
            }
 
1255
 
 
1256
        const bool b_full = isFull;
 
1257
            NodeList::iterator it = octant->mNodes.begin();
 
1258
 
 
1259
            while (it != octant->mNodes.end())
 
1260
            {
 
1261
                    PagingLandScapeOctreeNode * const on = (*it);
 
1262
 
 
1263
                    if (on != exclude)
 
1264
                    {
 
1265
                            if (b_full)
 
1266
                            {
 
1267
                                    list.push_back(on);
 
1268
                            }
 
1269
 
 
1270
                            else
 
1271
                            {
 
1272
                                    const Intersection nsect = intersect(t, on->_getWorldAABB());
 
1273
 
 
1274
                                    if (nsect != OUTSIDE)
 
1275
                                    {
 
1276
                                            list.push_back(on);
 
1277
                                    }
 
1278
                            }
 
1279
 
 
1280
                    }
 
1281
 
 
1282
                    ++it;
 
1283
            }
 
1284
 
 
1285
 
 
1286
 
 
1287
            if (octant->mChildren[ 0 ][ 0 ][ 0 ] != 0)
 
1288
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 0 ][ 0 ]);
 
1289
 
 
1290
            if (octant->mChildren[ 1 ][ 0 ][ 0 ] != 0)
 
1291
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 0 ][ 0 ]);
 
1292
 
 
1293
            if (octant->mChildren[ 0 ][ 1 ][ 0 ] != 0)
 
1294
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 1 ][ 0 ]);
 
1295
 
 
1296
            if (octant->mChildren[ 1 ][ 1 ][ 0 ] != 0)
 
1297
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 1 ][ 0 ]);
 
1298
 
 
1299
            if (octant->mChildren[ 0 ][ 0 ][ 1 ] != 0)
 
1300
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 0 ][ 1 ]);
 
1301
 
 
1302
            if (octant->mChildren[ 1 ][ 0 ][ 1 ] != 0)
 
1303
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 0 ][ 1 ]);
 
1304
 
 
1305
            if (octant->mChildren[ 0 ][ 1 ][ 1 ] != 0)
 
1306
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 1 ][ 1 ]);
 
1307
 
 
1308
            if (octant->mChildren[ 1 ][ 1 ][ 1 ] != 0)
 
1309
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 1 ][ 1 ]);
 
1310
 
 
1311
    }
 
1312
    //---------------------------------------------------------------------
 
1313
    void _findNodes(const PlaneBoundedVolume &t, std::list < SceneNode * > &list, 
 
1314
                const Ogre::SceneNode * const exclude, const bool full, PagingLandScapeOctree *octant)
 
1315
    {
 
1316
 
 
1317
        bool isFull = full;
 
1318
            if (!full)
 
1319
            {
 
1320
                    AxisAlignedBox obox;
 
1321
                    octant->_getCullBounds(&obox);
 
1322
 
 
1323
                    const Intersection isect = intersect(t, obox);
 
1324
 
 
1325
                    if (isect == OUTSIDE)
 
1326
                            return ;
 
1327
 
 
1328
                    isFull = (isect == INSIDE);
 
1329
            }
 
1330
 
 
1331
 
 
1332
        const bool b_full = isFull;
 
1333
            NodeList::iterator it = octant->mNodes.begin();
 
1334
 
 
1335
            while (it != octant->mNodes.end())
 
1336
            {
 
1337
                    PagingLandScapeOctreeNode * const on = (*it);
 
1338
                    if (on != exclude)
 
1339
                    {
 
1340
                            if (b_full)
 
1341
                            {
 
1342
                                    list.push_back(on);
 
1343
                            }
 
1344
                            else
 
1345
                            {
 
1346
                                    const Intersection nsect = intersect(t, on->_getWorldAABB());
 
1347
 
 
1348
                                    if (nsect != OUTSIDE)
 
1349
                                    {
 
1350
                                            list.push_back(on);
 
1351
                                    }
 
1352
                            }
 
1353
                    }
 
1354
                    ++it;
 
1355
            }
 
1356
 
 
1357
            if (octant->mChildren[ 0 ][ 0 ][ 0 ] != 0)
 
1358
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 0 ][ 0 ]);
 
1359
 
 
1360
            if (octant->mChildren[ 1 ][ 0 ][ 0 ] != 0)
 
1361
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 0 ][ 0 ]);
 
1362
 
 
1363
            if (octant->mChildren[ 0 ][ 1 ][ 0 ] != 0)
 
1364
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 1 ][ 0 ]);
 
1365
 
 
1366
            if (octant->mChildren[ 1 ][ 1 ][ 0 ] != 0)
 
1367
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 1 ][ 0 ]);
 
1368
 
 
1369
            if (octant->mChildren[ 0 ][ 0 ][ 1 ] != 0)
 
1370
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 0 ][ 1 ]);
 
1371
 
 
1372
            if (octant->mChildren[ 1 ][ 0 ][ 1 ] != 0)
 
1373
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 0 ][ 1 ]);
 
1374
 
 
1375
            if (octant->mChildren[ 0 ][ 1 ][ 1 ] != 0)
 
1376
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 1 ][ 1 ]);
 
1377
 
 
1378
            if (octant->mChildren[ 1 ][ 1 ][ 1 ] != 0)
 
1379
                    _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 1 ][ 1 ]);
 
1380
 
 
1381
    }
 
1382
    //---------------------------------------------------------------------
 
1383
    void _findNodes(const Ray &t, std::list < SceneNode * > &list, 
 
1384
                    const Ogre::SceneNode * const exclude, 
 
1385
                    const bool full, PagingLandScapeOctree *octant)
 
1386
    {
 
1387
        bool isFull = full;
 
1388
            if (!full)
 
1389
            {
 
1390
                    AxisAlignedBox obox;
 
1391
                    octant->_getCullBounds(&obox);
 
1392
 
 
1393
                    const Intersection isect = intersect(t, obox);
 
1394
 
 
1395
                    if (isect == OUTSIDE)
 
1396
                            return ;
 
1397
 
 
1398
                    isFull = (isect == INSIDE);
 
1399
            }
 
1400
 
 
1401
 
 
1402
        const bool b_full = isFull;
 
1403
                if (!octant->mNodes.empty ())
 
1404
                {
 
1405
                        NodeList::iterator it = octant->mNodes.begin();
 
1406
                        while (it != octant->mNodes.end())
 
1407
                        {
 
1408
                                PagingLandScapeOctreeNode * const on = (*it);
 
1409
                                if (on != exclude)
 
1410
                                {
 
1411
                                        if (b_full)
 
1412
                                        {
 
1413
                                                list.push_back(on);
 
1414
                                        }
 
1415
                                        else
 
1416
                                        {
 
1417
                                                const Intersection nsect = intersect(t, on->_getWorldAABB());
 
1418
                                                if (nsect != OUTSIDE)
 
1419
                                                        list.push_back(on);
 
1420
                                        }
 
1421
                                }
 
1422
                                ++it;
 
1423
                        }
 
1424
                }
 
1425
                if (octant->hasChildren ())
 
1426
                {
 
1427
                        if (octant->mChildren[ 0 ][ 0 ][ 0 ] != 0)
 
1428
                                _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 0 ][ 0 ]);
 
1429
 
 
1430
                        if (octant->mChildren[ 1 ][ 0 ][ 0 ] != 0)
 
1431
                                _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 0 ][ 0 ]);
 
1432
 
 
1433
                        if (octant->mChildren[ 0 ][ 1 ][ 0 ] != 0)
 
1434
                                _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 1 ][ 0 ]);
 
1435
 
 
1436
                        if (octant->mChildren[ 1 ][ 1 ][ 0 ] != 0)
 
1437
                                _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 1 ][ 0 ]);
 
1438
 
 
1439
                        if (octant->mChildren[ 0 ][ 0 ][ 1 ] != 0)
 
1440
                                _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 0 ][ 1 ]);
 
1441
 
 
1442
                        if (octant->mChildren[ 1 ][ 0 ][ 1 ] != 0)
 
1443
                                _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 0 ][ 1 ]);
 
1444
 
 
1445
                        if (octant->mChildren[ 0 ][ 1 ][ 1 ] != 0)
 
1446
                                _findNodes(t, list, exclude, b_full, octant->mChildren[ 0 ][ 1 ][ 1 ]);
 
1447
 
 
1448
                        if (octant->mChildren[ 1 ][ 1 ][ 1 ] != 0)
 
1449
                                _findNodes(t, list, exclude, b_full, octant->mChildren[ 1 ][ 1 ][ 1 ]);
 
1450
                }
 
1451
    }
 
1452
    //---------------------------------------------------------------------
 
1453
    void PagingLandScapeOctreeSceneManager::findNodesIn(const AxisAlignedBox &box, std::list < SceneNode * > &list, const SceneNode* const exclude)
 
1454
    {
 
1455
        _findNodes(box, list, exclude, false, mPagingLandScapeOctree);
 
1456
    }
 
1457
    //---------------------------------------------------------------------
 
1458
    void PagingLandScapeOctreeSceneManager::findNodesIn(const Sphere &sphere, std::list < SceneNode * > &list, const SceneNode* const exclude)
 
1459
    {
 
1460
        _findNodes(sphere, list, exclude, false, mPagingLandScapeOctree);
 
1461
    }
 
1462
    //---------------------------------------------------------------------
 
1463
    void PagingLandScapeOctreeSceneManager::findNodesIn(const PlaneBoundedVolume &volume, std::list < SceneNode * > &list, const SceneNode* const exclude)
 
1464
    {
 
1465
        _findNodes(volume, list, exclude, false, mPagingLandScapeOctree);
 
1466
    }
 
1467
    //---------------------------------------------------------------------
 
1468
    void PagingLandScapeOctreeSceneManager::findNodesIn(const Ray &r, std::list < SceneNode * > &list, const SceneNode* const exclude)
 
1469
    {
 
1470
        _findNodes(r, list, exclude, false, mPagingLandScapeOctree);
 
1471
    }
 
1472
    //---------------------------------------------------------------------
 
1473
    void PagingLandScapeOctreeSceneManager::resize(const AxisAlignedBox &box, const int depth)
 
1474
    {
 
1475
        mMaxDepth = depth;
 
1476
        resize(box);
 
1477
    }
 
1478
    //---------------------------------------------------------------------
 
1479
    void PagingLandScapeOctreeSceneManager::resize(const AxisAlignedBox &box)
 
1480
    {
 
1481
        std::list < SceneNode * > nodes;
 
1482
 
 
1483
        _findNodes(mPagingLandScapeOctree->getBoundingBox (), nodes, 0, true, mPagingLandScapeOctree);
 
1484
 
 
1485
        if (mPagingLandScapeOctree)
 
1486
            deleteOctree (mPagingLandScapeOctree);
 
1487
 
 
1488
        mBox = box;
 
1489
        mPagingLandScapeOctree = mOctreeSet.getPoolable();
 
1490
        assert (mPagingLandScapeOctree);       
 
1491
        mPagingLandScapeOctree->setSceneManager (this);
 
1492
        mPagingLandScapeOctree ->setBoundingBox (box.getMinimum(), box.getMaximum());       
 
1493
                registeredNodeInCamera (mPagingLandScapeOctree); 
 
1494
        
 
1495
        if (!nodes.empty())
 
1496
        {
 
1497
            std::list < SceneNode * > ::iterator it;
 
1498
            it = nodes.begin();
 
1499
 
 
1500
            while (it != nodes.end())
 
1501
            {
 
1502
                PagingLandScapeOctreeNode * const on = static_cast < PagingLandScapeOctreeNode * > (*it);
 
1503
                on->setOctant(0);
 
1504
                _updatePagingLandScapeOctreeNode(on);
 
1505
                ++it;
 
1506
            } // while (it != nodes.end())
 
1507
        }  
 
1508
    }
 
1509
    //---------------------------------------------------------------------
 
1510
    bool PagingLandScapeOctreeSceneManager::setOption(const String & key, const void * val)
 
1511
    {
 
1512
        if (key == "Size")
 
1513
        {
 
1514
            resize(* static_cast < const AxisAlignedBox * > (val));
 
1515
            return true;
 
1516
        }
 
1517
 
 
1518
        else if (key == "Depth")
 
1519
        {
 
1520
            assert (mPagingLandScapeOctree);
 
1521
                        mMaxDepth = * static_cast < const int * > (val);
 
1522
                        // copy the box since resize will delete mOctree and reference won't work
 
1523
                        AxisAlignedBox box = mPagingLandScapeOctree->getBoundingBox();
 
1524
            resize(box);
 
1525
            return true;
 
1526
        }
 
1527
        else if (key == "NextCullMode")
 
1528
        {
 
1529
            if (val)
 
1530
            {
 
1531
                CameraList::iterator it = mCameras.find (static_cast < const PagingLandScapeOctreeCamera * > (val)->getName());
 
1532
                if (it != mCameras.end())
 
1533
                                {
 
1534
                    static_cast < PagingLandScapeOctreeCamera * > (it->second)->setNextOcclusionMode();
 
1535
                    return true;
 
1536
                }
 
1537
            }
 
1538
            return false;
 
1539
                }
 
1540
                else if (key == "setNumberOfConservativeFrames")
 
1541
                {
 
1542
                        mOcclusion.setNumberOfConservativeFrames(*(static_cast < const unsigned int * > (val)));
 
1543
                }
 
1544
                else if (key == "CurrentOptionCamera")
 
1545
                { 
 
1546
                        if (val)
 
1547
                        {
 
1548
                                CameraList::iterator it = mCameras.find (static_cast < const PagingLandScapeOctreeCamera * > (val)->getName());
 
1549
                                if (it != mCameras.end())
 
1550
                                {
 
1551
                                        mCurrentOptionCamera = static_cast < PagingLandScapeOctreeCamera * > (it->second);
 
1552
                                }
 
1553
                                return true;
 
1554
                        }       
 
1555
                }
 
1556
                else if (key == "setCullingMode")
 
1557
                {
 
1558
                        assert (mCurrentOptionCamera);
 
1559
                        mCurrentOptionCamera->setOcclusionModeAsString(* static_cast < const String * > (val));                 
 
1560
                        return true;            
 
1561
                }
 
1562
        #ifdef _VISIBILITYDEBUG
 
1563
            else if (key == "ShowPagingLandScapeOctree")
 
1564
            {   
 
1565
                    mShowBoxes = * static_cast < const bool * > (val);
 
1566
                return true;
 
1567
            }
 
1568
            else if (key == "CullDebug")
 
1569
            {
 
1570
                mCullDebug = * static_cast < const bool * > (val);
 
1571
                return true;
 
1572
            }
 
1573
            else if (key == "CullCamera")
 
1574
            {
 
1575
                mCullCamera = * static_cast < const bool * > (val);
 
1576
                return true;
 
1577
            }
 
1578
        #endif //_VISIBILITYDEBUG    
 
1579
        return SceneManager::setOption(key, val);
 
1580
 
 
1581
 
 
1582
    }
 
1583
    //---------------------------------------------------------------------
 
1584
    bool PagingLandScapeOctreeSceneManager::getOption(const String & key, void *val)
 
1585
    {
 
1586
        if (key == "Size")
 
1587
        {
 
1588
            AxisAlignedBox * b = static_cast < AxisAlignedBox * > (val);
 
1589
            b->setExtents(mPagingLandScapeOctree->getBoundingBox ().getMinimum(), mPagingLandScapeOctree->getBoundingBox().getMaximum());
 
1590
            return true;
 
1591
        }
 
1592
 
 
1593
        else if (key == "Depth")
 
1594
        {
 
1595
            * static_cast < int * > (val) = mMaxDepth;
 
1596
            return true;
 
1597
                }
 
1598
                else if (key == "setNumberOfConservativeFrames")
 
1599
                {
 
1600
                        * static_cast < unsigned int * > (val) = mOcclusion.getNumberOfConservativeFrames();
 
1601
                        return true;
 
1602
                }  
 
1603
                else if (key == "CurrentOptionCamera")
 
1604
                {
 
1605
                        *static_cast < String * > (val) = mCurrentOptionCamera->getName(); 
 
1606
                        return true;    
 
1607
                }
 
1608
                else if (key == "getCullingMode")
 
1609
                {
 
1610
                        assert (mCurrentOptionCamera);
 
1611
                        *static_cast < String * > (val) = mCurrentOptionCamera->getOcclusionModeAsString();
 
1612
                        return true;            
 
1613
                }
 
1614
                
 
1615
        #ifdef _VISIBILITYDEBUG
 
1616
            else if (key == "ShowPagingLandScapeOctree")
 
1617
            {
 
1618
 
 
1619
                * static_cast < bool * > (val) = mShowBoxes;
 
1620
                return true;
 
1621
            }
 
1622
            else if (key == "CullCamera")
 
1623
            {
 
1624
                * static_cast < bool * > (val) = mCullCamera;
 
1625
                return true;
 
1626
            } 
 
1627
            else if (key == "CullDebug")
 
1628
            {
 
1629
                * static_cast < bool * > (val) = mCullDebug;
 
1630
                return true;
 
1631
                        }
 
1632
                        else if (key == "DebugText")
 
1633
                        {
 
1634
                                * static_cast < String * > (val) = mDebugText;
 
1635
                                return true;
 
1636
                        }
 
1637
        #endif //_VISIBILITYDEBUG
 
1638
    
 
1639
        return SceneManager::getOption(key, val);
 
1640
    }
 
1641
    //---------------------------------------------------------------------
 
1642
    void PagingLandScapeOctreeSceneManager::clearScene(void)
 
1643
    {
 
1644
        SceneManager::clearScene();
 
1645
 
 
1646
         // reset cameras
 
1647
        //CameraList::iterator iCam = mCameras.begin();
 
1648
        //for (; iCam != mCameras.end(); ++iCam)
 
1649
        //{
 
1650
        //    PagingLandScapeOctreeCamera *cam = static_cast <PagingLandScapeOctreeCamera *> (iCam->second);
 
1651
        //    if (cam->isRegisteredInOcclusionSystem ())
 
1652
        //    {
 
1653
        //        mPagingLandScapeOctree->traversal (UnregisterCameraTraversal(cam));                   
 
1654
        //        cam->setRegisteredInOcclusionSystem (false);
 
1655
       //     } 
 
1656
        //}            
 
1657
 
 
1658
        init(mBox, mMaxDepth);
 
1659
 
 
1660
    }
 
1661
    //---------------------------------------------------------------------
 
1662
    AxisAlignedBoxSceneQuery*
 
1663
    PagingLandScapeOctreeSceneManager::createAABBQuery(const AxisAlignedBox& box, unsigned long mask)
 
1664
    {
 
1665
        PagingLandScapeOctreeAxisAlignedBoxSceneQuery* q = new PagingLandScapeOctreeAxisAlignedBoxSceneQuery(this);
 
1666
        q->setBox(box);
 
1667
        q->setQueryMask(mask);
 
1668
        return q;
 
1669
    }
 
1670
    //---------------------------------------------------------------------
 
1671
    SphereSceneQuery*
 
1672
    PagingLandScapeOctreeSceneManager::createSphereQuery(const Sphere& sphere, unsigned long mask)
 
1673
    {
 
1674
        PagingLandScapeOctreeSphereSceneQuery* q = new PagingLandScapeOctreeSphereSceneQuery(this);
 
1675
        q->setSphere(sphere);
 
1676
        q->setQueryMask(mask);
 
1677
        return q;
 
1678
    }
 
1679
    //---------------------------------------------------------------------
 
1680
    PlaneBoundedVolumeListSceneQuery*
 
1681
    PagingLandScapeOctreeSceneManager::createPlaneBoundedVolumeQuery(const PlaneBoundedVolumeList& volumes,
 
1682
            unsigned long mask)
 
1683
    {
 
1684
        PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery* q = new PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery(this);
 
1685
        q->setVolumes(volumes);
 
1686
        q->setQueryMask(mask);
 
1687
        return q;
 
1688
    }
 
1689
 
 
1690
    //---------------------------------------------------------------------
 
1691
    RaySceneQuery*
 
1692
    PagingLandScapeOctreeSceneManager::createRayQuery(const Ray& ray, unsigned long mask)
 
1693
    {
 
1694
        PagingLandScapeOctreeRaySceneQuery* q = new PagingLandScapeOctreeRaySceneQuery(this);
 
1695
        q->setRay(ray);
 
1696
        q->setQueryMask(mask);
 
1697
        return q;
 
1698
    }
 
1699
    //---------------------------------------------------------------------
 
1700
    IntersectionSceneQuery*
 
1701
    PagingLandScapeOctreeSceneManager::createIntersectionQuery(unsigned long mask)
 
1702
   {
 
1703
 
 
1704
    // PagingLandScapeOctree implementation performs WORSE for < 500 objects
 
1705
    // TODO: optimize it so it's better in all cases
 
1706
    //PagingLandScapeOctreeIntersectionSceneQuery* q = new PagingLandScapeOctreeIntersectionSceneQuery(this);
 
1707
    DefaultIntersectionSceneQuery* q;
 
1708
    if (mPagingLandScapeOctree->numNodes () > 500)
 
1709
        q = new PagingLandScapeOctreeIntersectionSceneQuery(this);
 
1710
    else
 
1711
        q = new DefaultIntersectionSceneQuery(this);
 
1712
    q->setQueryMask(mask);
 
1713
    return q;
 
1714
   }
 
1715
}