/src/ogre/PlugIns/BSPSceneManager/include/OgreBspSceneManager.h
Line | Count | Source |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #ifndef __BspSceneManager_H__ |
29 | | #define __BspSceneManager_H__ |
30 | | |
31 | | |
32 | | #include "OgreBspPrerequisites.h" |
33 | | #include "OgreSceneManager.h" |
34 | | #include "OgreStaticFaceGroup.h" |
35 | | #include "OgreRenderOperation.h" |
36 | | #include "OgreBspLevel.h" |
37 | | #include <set> |
38 | | |
39 | | |
40 | | namespace Ogre { |
41 | | /** \addtogroup Plugins |
42 | | * @{ |
43 | | */ |
44 | | /** \addtogroup BSPSceneManager |
45 | | * @{ |
46 | | */ |
47 | | |
48 | | /** Specialisation of the SceneManager class to deal with indoor scenes |
49 | | based on a BSP tree. |
50 | | This class refines the behaviour of the default SceneManager to manage |
51 | | a scene whose bulk of geometry is made up of an indoor environment which |
52 | | is organised by a Binary Space Partition (BSP) tree. |
53 | | A BSP tree progressively subdivides the space using planes which are the nodes of the tree. |
54 | | At some point we stop subdividing and everything in the remaining space is part of a 'leaf' which |
55 | | contains a number of polygons. Typically we traverse the tree to locate the leaf in which a |
56 | | point in space is (say the camera origin) and work from there. A second structure, the |
57 | | Potentially Visible Set, tells us which other leaves can been seen from this |
58 | | leaf, and we test their bounding boxes against the camera frustum to see which |
59 | | we need to draw. Leaves are also a good place to start for collision detection since |
60 | | they divide the level into discrete areas for testing. |
61 | | This BSP and PVS technique has been made famous by engines such as Quake and Unreal. Ogre |
62 | | provides support for loading Quake3 level files to populate your world through this class, |
63 | | by calling the BspSceneManager::setWorldGeometry. Note that this interface is made |
64 | | available at the top level of the SceneManager class so you don't have to write your code |
65 | | specifically for this class - just call Root::getSceneManager passing a SceneType of ST_INTERIOR |
66 | | and in the current implementation you will get a BspSceneManager silently disguised as a |
67 | | standard SceneManager. |
68 | | */ |
69 | | class BspSceneManager : public SceneManager |
70 | | { |
71 | | /** Comparator for material map, for sorting materials into render order (e.g. transparent last). |
72 | | */ |
73 | | struct materialLess |
74 | | { |
75 | | bool operator()(const Material* x, const Material* y) const |
76 | 0 | { |
77 | | // If x transparent and y not, x > y (since x has to overlap y) |
78 | 0 | if (x->isTransparent() && !y->isTransparent()) |
79 | 0 | { |
80 | 0 | return false; |
81 | 0 | } |
82 | | // If y is transparent and x not, x < y |
83 | 0 | else if (!x->isTransparent() && y->isTransparent()) |
84 | 0 | { |
85 | 0 | return true; |
86 | 0 | } |
87 | 0 | else |
88 | 0 | { |
89 | | // Otherwise don't care (both transparent or both solid) |
90 | | // Just arbitrarily use pointer |
91 | 0 | return x < y; |
92 | 0 | } |
93 | 0 | } |
94 | | }; |
95 | | |
96 | | /// World geometry |
97 | | BspLevelPtr mLevel; |
98 | | |
99 | | // State variables for rendering WIP |
100 | | // Set of face groups (by index) already included |
101 | | typedef std::set<int> FaceGroupSet; |
102 | | FaceGroupSet mFaceGroupSet; |
103 | | // Material -> face group hashmap |
104 | | typedef std::map<Material*, std::vector<StaticFaceGroup*>, materialLess > MaterialFaceGroupMap; |
105 | | MaterialFaceGroupMap mMatFaceGroupMap; |
106 | | |
107 | | // Debugging features |
108 | | bool mShowNodeAABs; |
109 | | RenderOperation mAABGeometry; |
110 | | |
111 | | /** Walks the BSP tree looking for the node which the camera |
112 | | is in, and tags any geometry which is in a visible leaf for |
113 | | later processing. |
114 | | @param camera Pointer to the viewpoint. |
115 | | @return The BSP node the camera was found in, for info. |
116 | | */ |
117 | | BspNode* walkTree(Camera* camera, VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters); |
118 | | /** Tags geometry in the leaf specified for later rendering. */ |
119 | | void processVisibleLeaf(BspNode* leaf, Camera* cam, |
120 | | VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters); |
121 | | |
122 | | /** Adds a bounding box to draw if turned on. */ |
123 | | void addBoundingBox(const AxisAlignedBox& aab, bool visible); |
124 | | |
125 | | /** Renders the static level geometry tagged in walkTree. */ |
126 | | void renderStaticGeometry(void); |
127 | | |
128 | | /** @copydoc SceneManager::clearScene */ |
129 | | void clearScene(void) override; |
130 | | |
131 | | // Overridden so we can manually render world geometry |
132 | | bool fireRenderQueueEnded(uint8 id, const String& invocation) override; |
133 | | |
134 | | typedef std::set<const MovableObject*> MovablesForRendering; |
135 | | MovablesForRendering mMovablesForRendering; |
136 | | |
137 | | public: |
138 | | BspSceneManager(const String& name); |
139 | | ~BspSceneManager(); |
140 | | |
141 | | |
142 | | /// @copydoc SceneManager::getTypeName |
143 | | const String& getTypeName(void) const override; |
144 | | |
145 | | /** Specialised from SceneManager to support Quake3 bsp files. */ |
146 | | void setWorldGeometry(const String& filename) override; |
147 | | |
148 | | /** Specialised from SceneManager to support Quake3 bsp files. */ |
149 | | size_t estimateWorldGeometry(const String& filename) override; |
150 | | |
151 | | /** Specialised from SceneManager to support Quake3 bsp files. */ |
152 | | void setWorldGeometry(DataStreamPtr& stream, |
153 | | const String& typeName = BLANKSTRING) override; |
154 | | |
155 | | /** Specialised from SceneManager to support Quake3 bsp files. */ |
156 | | size_t estimateWorldGeometry(DataStreamPtr& stream, |
157 | | const String& typeName = BLANKSTRING) override; |
158 | | |
159 | | /** Tells the manager whether to draw the axis-aligned boxes that surround |
160 | | nodes in the Bsp tree. For debugging purposes. |
161 | | */ |
162 | | void showNodeBoxes(bool show); |
163 | | |
164 | | /** Specialised to suggest viewpoints. */ |
165 | | ViewPoint getSuggestedViewpoint(bool random = false) override; |
166 | | |
167 | 0 | const BspLevelPtr& getLevel(void) {return mLevel; } |
168 | | |
169 | | void setLevel(const BspLevelPtr& level); |
170 | | |
171 | | /** Overridden from SceneManager. */ |
172 | | void _findVisibleObjects(Camera* cam, VisibleObjectsBoundsInfo* visibleBounds, |
173 | | bool onlyShadowCasters) override; |
174 | | |
175 | | /** Creates a specialized BspSceneNode */ |
176 | | SceneNode * createSceneNodeImpl ( void ) override; |
177 | | /** Creates a specialized BspSceneNode */ |
178 | | SceneNode * createSceneNodeImpl ( const String &name ) override; |
179 | | |
180 | | /** Internal method for tagging BspNodes with objects which intersect them. */ |
181 | | void _notifyObjectMoved(const MovableObject* mov, const Vector3& pos); |
182 | | /** Internal method for notifying the level that an object has been detached from a node */ |
183 | | void _notifyObjectDetached(const MovableObject* mov); |
184 | | |
185 | | /* Creates an AxisAlignedBoxSceneQuery for this scene manager. |
186 | | |
187 | | This method creates a new instance of a query object for this scene manager, |
188 | | for an axis aligned box region. See SceneQuery and AxisAlignedBoxSceneQuery |
189 | | for full details. |
190 | | @par |
191 | | The instance returned from this method must be destroyed by calling |
192 | | SceneManager::destroyQuery when it is no longer required. |
193 | | @param box Details of the box which describes the region for this query. |
194 | | @param mask The query mask to apply to this query; can be used to filter out |
195 | | certain objects; see SceneQuery for details. |
196 | | */ |
197 | | /* |
198 | | virtual AxisAlignedBoxSceneQuery* |
199 | | createAABBQuery(const AxisAlignedBox& box, uint32 mask = 0xFFFFFFFF); |
200 | | */ |
201 | | /* Creates a SphereSceneQuery for this scene manager. |
202 | | |
203 | | This method creates a new instance of a query object for this scene manager, |
204 | | for a spherical region. See SceneQuery and SphereSceneQuery |
205 | | for full details. |
206 | | @par |
207 | | The instance returned from this method must be destroyed by calling |
208 | | SceneManager::destroyQuery when it is no longer required. |
209 | | @param sphere Details of the sphere which describes the region for this query. |
210 | | @param mask The query mask to apply to this query; can be used to filter out |
211 | | certain objects; see SceneQuery for details. |
212 | | */ |
213 | | /* |
214 | | virtual SphereSceneQuery* |
215 | | createSphereQuery(const Sphere& sphere, uint32 mask = 0xFFFFFFFF); |
216 | | */ |
217 | | /** Creates a RaySceneQuery for this scene manager. |
218 | | |
219 | | This method creates a new instance of a query object for this scene manager, |
220 | | looking for objects which fall along a ray. See SceneQuery and RaySceneQuery |
221 | | for full details. |
222 | | @par |
223 | | The instance returned from this method must be destroyed by calling |
224 | | SceneManager::destroyQuery when it is no longer required. |
225 | | @param ray Details of the ray which describes the region for this query. |
226 | | @param mask The query mask to apply to this query; can be used to filter out |
227 | | certain objects; see SceneQuery for details. |
228 | | */ |
229 | | RaySceneQuery* |
230 | | createRayQuery(const Ray& ray, uint32 mask = 0xFFFFFFFF) override; |
231 | | /** Creates an IntersectionSceneQuery for this scene manager. |
232 | | |
233 | | This method creates a new instance of a query object for locating |
234 | | intersecting objects. See SceneQuery and IntersectionSceneQuery |
235 | | for full details. |
236 | | @par |
237 | | The instance returned from this method must be destroyed by calling |
238 | | SceneManager::destroyQuery when it is no longer required. |
239 | | @param mask The query mask to apply to this query; can be used to filter out |
240 | | certain objects; see SceneQuery for details. |
241 | | */ |
242 | | IntersectionSceneQuery* |
243 | | createIntersectionQuery(uint32 mask = 0xFFFFFFFF) override; |
244 | | |
245 | | }; |
246 | | |
247 | | /** BSP specialisation of IntersectionSceneQuery */ |
248 | | class BspIntersectionSceneQuery : public DefaultIntersectionSceneQuery |
249 | | { |
250 | | std::set<WorldFragmentType> mSupportedWorldFragments; |
251 | | WorldFragmentType mWorldFragmentType; |
252 | | public: |
253 | | BspIntersectionSceneQuery(SceneManager* creator); |
254 | | |
255 | | /** See IntersectionSceneQuery. */ |
256 | | void execute(IntersectionSceneQueryListener* listener) override; |
257 | | |
258 | | /** Tells the query what kind of world geometry to return from queries; |
259 | | often the full renderable geometry is not what is needed. |
260 | | |
261 | | The application receiving the world geometry is expected to know |
262 | | what to do with it; inevitably this means that the application must |
263 | | have knowledge of at least some of the structures |
264 | | used by the custom SceneManager. |
265 | | @par |
266 | | The default setting is WFT_NONE. |
267 | | */ |
268 | | void setWorldFragmentType(enum WorldFragmentType wft) |
269 | 0 | { |
270 | 0 | // Check supported |
271 | 0 | OgreAssert(mSupportedWorldFragments.find(wft) != mSupportedWorldFragments.end(), |
272 | 0 | "This world fragment type is not supported."); |
273 | 0 | mWorldFragmentType = wft; |
274 | 0 | } |
275 | | |
276 | | /** Gets the current world fragment types to be returned from the query. */ |
277 | 0 | WorldFragmentType getWorldFragmentType(void) const { return mWorldFragmentType; } |
278 | | |
279 | | /** Returns the types of world fragments this query supports. */ |
280 | 0 | const std::set<WorldFragmentType>* getSupportedWorldFragmentTypes() const { return &mSupportedWorldFragments; } |
281 | | }; |
282 | | |
283 | | /** BSP specialisation of RaySceneQuery */ |
284 | | class BspRaySceneQuery : public DefaultRaySceneQuery |
285 | | { |
286 | | std::set<WorldFragmentType> mSupportedWorldFragments; |
287 | | WorldFragmentType mWorldFragmentType; |
288 | | public: |
289 | | BspRaySceneQuery(SceneManager* creator); |
290 | | ~BspRaySceneQuery(); |
291 | | |
292 | | /// @copydoc BspIntersectionSceneQuery::setWorldFragmentType |
293 | | void setWorldFragmentType(enum WorldFragmentType wft) |
294 | 0 | { |
295 | 0 | // Check supported |
296 | 0 | OgreAssert(mSupportedWorldFragments.find(wft) != mSupportedWorldFragments.end(), |
297 | 0 | "This world fragment type is not supported."); |
298 | 0 | mWorldFragmentType = wft; |
299 | 0 | } |
300 | | |
301 | | /// @copydoc BspIntersectionSceneQuery::getWorldFragmentType |
302 | 0 | WorldFragmentType getWorldFragmentType(void) const { return mWorldFragmentType; } |
303 | | |
304 | | /// @copydoc BspIntersectionSceneQuery::getSupportedWorldFragmentTypes |
305 | 0 | const std::set<WorldFragmentType>* getSupportedWorldFragmentTypes() const { return &mSupportedWorldFragments; } |
306 | | |
307 | | /** See RaySceneQuery. */ |
308 | | void execute(RaySceneQueryListener* listener) override; |
309 | | protected: |
310 | | /// Set for eliminating duplicates since objects can be in > 1 node |
311 | | std::set<MovableObject*> mObjsThisQuery; |
312 | | /// list of the last single intersection world fragments (derived) |
313 | | std::vector<SceneQuery::WorldFragment*> mSingleIntersections; |
314 | | |
315 | | void clearTemporaries(void); |
316 | | /** Internal processing of a single node. |
317 | | @return true if we should continue tracing, false otherwise |
318 | | */ |
319 | | bool processNode(const BspNode* node, const Ray& tracingRay, RaySceneQueryListener* listener, |
320 | | Real maxDistance = Math::POS_INFINITY, Real traceDistance = 0.0f); |
321 | | /** Internal processing of a single leaf. |
322 | | @return true if we should continue tracing, false otherwise |
323 | | */ |
324 | | bool processLeaf(const BspNode* node, const Ray& tracingRay, RaySceneQueryListener* listener, |
325 | | Real maxDistance = Math::POS_INFINITY, Real traceDistance = 0.0f); |
326 | | |
327 | | }; |
328 | | |
329 | | /// Factory for BspSceneManager |
330 | | class BspSceneManagerFactory : public SceneManagerFactory |
331 | | { |
332 | | public: |
333 | | /// Factory type name |
334 | | static const String FACTORY_TYPE_NAME; |
335 | | SceneManager* createInstance(const String& instanceName) override; |
336 | 0 | const String& getTypeName(void) const override { return FACTORY_TYPE_NAME; } |
337 | | }; |
338 | | /** @} */ |
339 | | /** @} */ |
340 | | } |
341 | | |
342 | | #endif |