[692] | 1 | /*
|
---|
| 2 | -----------------------------------------------------------------------------
|
---|
| 3 | This source file is part of OGRE
|
---|
| 4 | (Object-oriented Graphics Rendering Engine)
|
---|
| 5 | For the latest info, see http://ogre.sourceforge.net/
|
---|
| 6 |
|
---|
| 7 | Copyright (c) 2000-2005 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 | #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 |
|
---|
| 37 | namespace 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
|
---|