source: GTP/trunk/Lib/Geom/OgreStuff/include/opt/OgreBspSceneManager.h @ 1809

Revision 1809, 11.9 KB checked in by gumbau, 18 years ago (diff)
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://ogre.sourceforge.net/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#ifndef __BspSceneManager_H__
26#define __BspSceneManager_H__
27
28
29#include "OgreBspPrerequisites.h"
30#include "OgreSceneManager.h"
31#include "OgreStaticFaceGroup.h"
32#include "OgreRenderOperation.h"
33#include "OgreBspLevel.h"
34#include <set>
35
36
37namespace Ogre {
38
39
40    /** Specialisation of the SceneManager class to deal with indoor scenes
41        based on a BSP tree.
42        This class refines the behaviour of the default SceneManager to manage
43        a scene whose bulk of geometry is made up of an indoor environment which
44        is organised by a Binary Space Partition (BSP) tree. </p>
45        A BSP tree progressively subdivides the space using planes which are the nodes of the tree.
46        At some point we stop subdividing and everything in the remaining space is part of a 'leaf' which
47        contains a number of polygons. Typically we traverse the tree to locate the leaf in which a
48        point in space is (say the camera origin) and work from there. A second structure, the
49        Potentially Visible Set, tells us which other leaves can been seen from this
50        leaf, and we test their bounding boxes against the camera frustum to see which
51        we need to draw. Leaves are also a good place to start for collision detection since
52        they divide the level into discrete areas for testing.</p>
53        This BSP and PVS technique has been made famous by engines such as Quake and Unreal. Ogre
54        provides support for loading Quake3 level files to populate your world through this class,
55        by calling the BspSceneManager::setWorldGeometry. Note that this interface is made
56        available at the top level of the SceneManager class so you don't have to write your code
57        specifically for this class - just call Root::getSceneManager passing a SceneType of ST_INTERIOR
58        and in the current implementation you will get a BspSceneManager silently disguised as a
59        standard SceneManager.
60    */
61    class BspSceneManager : public SceneManager
62    {
63    protected:
64
65        // World geometry
66        BspLevelPtr mLevel;
67
68        // State variables for rendering WIP
69        // Set of face groups (by index) already included
70        typedef std::set<int> FaceGroupSet;
71        FaceGroupSet mFaceGroupSet;
72        // Material -> face group hashmap
73        typedef std::map<Material*, std::vector<StaticFaceGroup*>, materialLess > MaterialFaceGroupMap;
74        MaterialFaceGroupMap mMatFaceGroupMap;
75
76        RenderOperation mRenderOp;
77
78        // Debugging features
79        bool mShowNodeAABs;
80        RenderOperation mAABGeometry;
81
82        /** Walks the BSP tree looking for the node which the camera
83            is in, and tags any geometry which is in a visible leaf for
84            later processing.
85            @param camera Pointer to the viewpoint.
86            @returns The BSP node the camera was found in, for info.
87        */
88        BspNode* walkTree(Camera* camera, bool onlyShadowCasters);
89        /** Tags geometry in the leaf specified for later rendering. */
90        void processVisibleLeaf(BspNode* leaf, Camera* cam, bool onlyShadowCasters);
91
92        /** Caches a face group for imminent rendering. */
93        unsigned int cacheGeometry(unsigned int* pIndexes, const StaticFaceGroup* faceGroup);
94
95        /** Frees up allocated memory for geometry caches. */
96        void freeMemory(void);
97
98        /** Adds a bounding box to draw if turned on. */
99        void addBoundingBox(const AxisAlignedBox& aab, bool visible);
100
101        /** Renders the static level geometry tagged in walkTree. */
102        void renderStaticGeometry(void);
103
104                /** @copydoc SceneManager::clearScene */
105                void clearScene(void);
106
107
108        typedef std::set<const MovableObject*> MovablesForRendering;
109        MovablesForRendering mMovablesForRendering;
110
111    public:
112        BspSceneManager(const String& name);
113        ~BspSceneManager();
114
115
116                /// @copydoc SceneManager::getTypeName
117                const String& getTypeName(void) const;
118
119        /** Specialised from SceneManager to support Quake3 bsp files. */
120        void setWorldGeometry(const String& filename);
121
122        /** Specialised from SceneManager to support Quake3 bsp files. */
123        size_t estimateWorldGeometry(const String& filename);
124       
125        /** Specialised from SceneManager to support Quake3 bsp files. */
126        void setWorldGeometry(DataStreamPtr& stream,
127                        const String& typeName = StringUtil::BLANK);
128
129        /** Specialised from SceneManager to support Quake3 bsp files. */
130        size_t estimateWorldGeometry(DataStreamPtr& stream,
131                        const String& typeName = StringUtil::BLANK);
132
133                /** Tells the manager whether to draw the axis-aligned boxes that surround
134            nodes in the Bsp tree. For debugging purposes.
135        */
136        void showNodeBoxes(bool show);
137
138        /** Specialised to suggest viewpoints. */
139        ViewPoint getSuggestedViewpoint(bool random = false);
140
141        const BspLevelPtr& getLevel(void) {return mLevel; }
142
143        /** Overriden from SceneManager. */
144        void _findVisibleObjects(Camera* cam, bool onlyShadowCasters);
145
146        /** Overriden from SceneManager. */
147        void _renderVisibleObjects(void);
148
149        /** Creates a specialized BspSceneNode */
150        SceneNode * createSceneNode ( void );
151        /** Creates a specialized BspSceneNode */
152        SceneNode * createSceneNode ( const String &name );
153
154        /** Internal method for tagging BspNodes with objects which intersect them. */
155        void _notifyObjectMoved(const MovableObject* mov, const Vector3& pos);
156                /** Internal method for notifying the level that an object has been detached from a node */
157                void _notifyObjectDetached(const MovableObject* mov);
158
159        /** Creates an AxisAlignedBoxSceneQuery for this scene manager.
160        @remarks
161            This method creates a new instance of a query object for this scene manager,
162            for an axis aligned box region. See SceneQuery and AxisAlignedBoxSceneQuery
163            for full details.
164        @par
165            The instance returned from this method must be destroyed by calling
166            SceneManager::destroyQuery when it is no longer required.
167        @param box Details of the box which describes the region for this query.
168        @param mask The query mask to apply to this query; can be used to filter out
169            certain objects; see SceneQuery for details.
170        */
171        /*
172        virtual AxisAlignedBoxSceneQuery*
173            createAABBQuery(const AxisAlignedBox& box, unsigned long mask = 0xFFFFFFFF);
174        */
175        /** Creates a SphereSceneQuery for this scene manager.
176        @remarks
177            This method creates a new instance of a query object for this scene manager,
178            for a spherical region. See SceneQuery and SphereSceneQuery
179            for full details.
180        @par
181            The instance returned from this method must be destroyed by calling
182            SceneManager::destroyQuery when it is no longer required.
183        @param sphere Details of the sphere which describes the region for this query.
184        @param mask The query mask to apply to this query; can be used to filter out
185            certain objects; see SceneQuery for details.
186        */
187        /*
188        virtual SphereSceneQuery*
189            createSphereQuery(const Sphere& sphere, unsigned long mask = 0xFFFFFFFF);
190        */
191        /** Creates a RaySceneQuery for this scene manager.
192        @remarks
193            This method creates a new instance of a query object for this scene manager,
194            looking for objects which fall along a ray. See SceneQuery and RaySceneQuery
195            for full details.
196        @par
197            The instance returned from this method must be destroyed by calling
198            SceneManager::destroyQuery when it is no longer required.
199        @param ray Details of the ray which describes the region for this query.
200        @param mask The query mask to apply to this query; can be used to filter out
201            certain objects; see SceneQuery for details.
202        */
203        virtual RaySceneQuery*
204            createRayQuery(const Ray& ray, unsigned long mask = 0xFFFFFFFF);
205        /** Creates an IntersectionSceneQuery for this scene manager.
206        @remarks
207            This method creates a new instance of a query object for locating
208            intersecting objects. See SceneQuery and IntersectionSceneQuery
209            for full details.
210        @par
211            The instance returned from this method must be destroyed by calling
212            SceneManager::destroyQuery when it is no longer required.
213        @param mask The query mask to apply to this query; can be used to filter out
214            certain objects; see SceneQuery for details.
215        */
216        virtual IntersectionSceneQuery*
217            createIntersectionQuery(unsigned long mask = 0xFFFFFFFF);
218
219    };
220
221    /** BSP specialisation of IntersectionSceneQuery */
222    class BspIntersectionSceneQuery : public DefaultIntersectionSceneQuery
223    {
224    public:
225        BspIntersectionSceneQuery(SceneManager* creator);
226
227        /** See IntersectionSceneQuery. */
228        void execute(IntersectionSceneQueryListener* listener);
229
230    };
231
232    /** BSP specialisation of RaySceneQuery */
233    class BspRaySceneQuery : public DefaultRaySceneQuery
234    {
235    public:
236        BspRaySceneQuery(SceneManager* creator);
237        ~BspRaySceneQuery();
238
239        /** See RaySceneQuery. */
240        void execute(RaySceneQueryListener* listener);
241    protected:
242        /// Set for eliminating duplicates since objects can be in > 1 node
243        std::set<MovableObject*> mObjsThisQuery;
244        /// list of the last single intersection world fragments (derived)
245        std::vector<SceneQuery::WorldFragment*> mSingleIntersections;
246
247        void clearTemporaries(void);
248        /** Internal processing of a single node.
249        @returns true if we should continue tracing, false otherwise
250        */
251        bool processNode(const BspNode* node, const Ray& tracingRay, RaySceneQueryListener* listener,
252            Real maxDistance = Math::POS_INFINITY, Real traceDistance = 0.0f);
253        /** Internal processing of a single leaf.
254        @returns true if we should continue tracing, false otherwise
255        */
256        bool processLeaf(const BspNode* node, const Ray& tracingRay, RaySceneQueryListener* listener,
257            Real maxDistance = Math::POS_INFINITY, Real traceDistance = 0.0f);
258
259    };
260
261        /// Factory for BspSceneManager
262        class BspSceneManagerFactory : public SceneManagerFactory
263        {
264        protected:
265                void initMetaData(void) const;
266        public:
267                BspSceneManagerFactory() {}
268                ~BspSceneManagerFactory() {}
269                /// Factory type name
270                static const String FACTORY_TYPE_NAME;
271                SceneManager* createInstance(const String& instanceName);
272                void destroyInstance(SceneManager* instance);
273        };
274}
275
276#endif
Note: See TracBrowser for help on using the repository browser.