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-2013 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 PCZSceneManager.h - Portal Connected Zone Scene Manager 28 29 ----------------------------------------------------------------------------- 30 begin : Mon Feb 19 2007 31 author : Eric Cha 32 email : ericc@xenopi.com 33 Code Style Update : 34 ----------------------------------------------------------------------------- 35 */ 36 37 #ifndef PCZ_SCENEMANAGER_H 38 #define PCZ_SCENEMANAGER_H 39 40 #include <OgreSceneManager.h> 41 #include <OgreSphere.h> 42 43 #include "OgrePCZPrerequisites.h" 44 #include "OgrePCZSceneNode.h" 45 #include "OgrePCZone.h" 46 #include "OgrePCZoneFactory.h" 47 #include "OgrePortal.h" 48 #include "OgreAntiPortal.h" 49 50 namespace Ogre 51 { 52 53 class PCZone; 54 class PCZCamera; 55 class PCZIntersectionSceneQuery; 56 class PCZRaySceneQuery; 57 class PCZSphereSceneQuery; 58 class PCZAxisAlignedBoxSceneQuery; 59 class PCZPlaneBoundedVolumeListSceneQuery; 60 61 typedef vector<SceneNode*>::type NodeList; 62 typedef list<WireBoundingBox*>::type BoxList; 63 64 /** Specialized SceneManager that uses Portal-Connected-Zones to divide the scene spatially. 65 */ 66 67 class _OgrePCZPluginExport PCZSceneManager : public SceneManager 68 { 69 friend class PCZIntersectionSceneQuery; 70 friend class PCZRaySceneQuery; 71 friend class PCZSphereSceneQuery; 72 friend class PCZAxisAlignedBoxSceneQuery; 73 friend class PCZPlaneBoundedVolumeListSceneQuery; 74 75 public: 76 /** Standard Constructor. */ 77 PCZSceneManager(const String& name); 78 /** Standard destructor */ 79 ~PCZSceneManager(); 80 81 /// @copydoc SceneManager::getTypeName 82 const String& getTypeName(void) const; 83 84 /** Initializes the manager 85 */ 86 void init(const String &defaultZoneTypeName, 87 const String &filename = "none"); 88 89 /** Create a new portal instance 90 */ 91 Portal* createPortal(const String& name, PortalBase::PORTAL_TYPE type = PortalBase::PORTAL_TYPE_QUAD); 92 93 /** Delete a portal instance by pointer 94 */ 95 void destroyPortal(Portal * p); 96 97 /** Delete a portal instance by name 98 */ 99 void destroyPortal(const String & portalName); 100 101 /** Create a new anti portal instance */ 102 AntiPortal* createAntiPortal(const String& name, PortalBase::PORTAL_TYPE type = PortalBase::PORTAL_TYPE_QUAD); 103 104 /** Delete a anti portal instance by pointer */ 105 void destroyAntiPortal(AntiPortal * p); 106 107 /** Delete a anti portal instance by name */ 108 void destroyAntiPortal(const String& portalName); 109 110 /** Create a zone from a file (type of file 111 * depends on the zone type 112 */ 113 PCZone * createZoneFromFile(const String &zoneTypeName, 114 const String &zoneName, 115 PCZSceneNode * parentNode, 116 const String & filename); 117 118 /** Set the "main" geometry of the zone */ 119 virtual void setZoneGeometry(const String & zoneName, 120 PCZSceneNode * parentNode, 121 const String &filename); 122 123 /// override this to ensure specialised PCZSceneNode is used. 124 virtual SceneNode* createSceneNodeImpl(void); 125 /// override this to ensure their specialised PCZSceneNode is used. 126 virtual SceneNode* createSceneNodeImpl(const String& name); 127 /** Creates a PCZSceneNode */ 128 virtual SceneNode * createSceneNode ( void ); 129 /** Creates a PCZSceneNode */ 130 virtual SceneNode * createSceneNode ( const String &name ); 131 /** Creates a specialized PCZCamera */ 132 virtual Camera * createCamera( const String &name ); 133 134 /** Deletes a scene node by name & corresponding PCZSceneNode */ 135 virtual void destroySceneNode( const String &name ); 136 137 /** Deletes a scene node & corresponding PCZSceneNode */ 138 virtual void destroySceneNode(SceneNode* sn); 139 140 /** Overridden to clean up zones 141 */ 142 virtual void clearScene(void); 143 144 /** Overridden from SceneManager */ 145 void setWorldGeometryRenderQueue(uint8 qid); 146 147 /// Overridden from basic scene manager 148 void _renderScene(Camera *cam, Viewport *vp, bool includeOverlays); 149 150 /** Enable/disable sky rendering */ 151 void enableSky(bool); 152 153 /** Set the zone which contains the sky node */ 154 void setSkyZone(PCZone * zone); 155 156 /** Update Scene Graph (does several things now) */ 157 virtual void _updateSceneGraph( Camera * cam ); 158 159 /** Recurses through the PCZTree determining which nodes are visible. */ 160 virtual void _findVisibleObjects ( Camera * cam, 161 VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters ); 162 163 /** Alerts each unculled object, notifying it that it will be drawn. 164 * Useful for doing calculations only on nodes that will be drawn, prior 165 * to drawing them... 166 */ 167 virtual void _alertVisibleObjects( void ); 168 169 /** Creates a light for use in the scene. 170 @remarks 171 Lights can either be in a fixed position and independent of the 172 scene graph, or they can be attached to SceneNodes so they derive 173 their position from the parent node. Either way, they are created 174 using this method so that the SceneManager manages their 175 existence. 176 @param 177 name The name of the new light, to identify it later. 178 */ 179 virtual Light* createLight(const String& name); 180 181 /** Returns a pointer to the named Light which has previously been added to the scene. 182 @note Throws an exception if the named instance does not exist 183 */ 184 virtual Light* getLight(const String& name) const; 185 186 /** Returns whether a light with the given name exists. 187 */ 188 virtual bool hasLight(const String& name) const; 189 190 /** Removes the named light from the scene and destroys it. 191 @remarks 192 Any pointers held to this light after calling this method will be invalid. 193 */ 194 virtual void destroyLight(const String& name); 195 196 /** Removes and destroys all lights in the scene. 197 */ 198 virtual void destroyAllLights(void); 199 200 /** Check/Update the zone data for every portal in the scene. 201 * Essentially, this routine checks each portal for intersections 202 * with other portals and updates if a crossing occurs 203 */ 204 void _updatePortalZoneData(void); 205 206 /** Mark nodes dirty for every zone with moving portal in the scene */ 207 void _dirtyNodeByMovingPortals(void); 208 209 /** Update the PCZSceneNodes 210 */ 211 void _updatePCZSceneNodes(void); 212 213 /** Calculate which zones are affected by each light 214 */ 215 void _calcZonesAffectedByLights(Camera * cam); 216 217 /* Attempt to automatically connect unconnected portals to proper target zones 218 * by looking for matching portals in other zones which are at the same location 219 */ 220 void connectPortalsToTargetZonesByLocation(void); 221 222 /** Checks the given SceneNode, and determines if it needs to be moved 223 * to a different PCZone or be added to the visitors list of other PCZone(s). 224 */ 225 void _updatePCZSceneNode( PCZSceneNode * ); 226 227 /** Removes the given PCZSceneNode */ 228 void removeSceneNode( SceneNode * ); 229 230 /** add a PCZSceneNode to the scene by putting it in a zone 231 * NOTE: This zone will be the scene node's home zone 232 */ 233 void addPCZSceneNode(PCZSceneNode * sn, PCZone * zone); 234 235 /** Create a zone with the given name */ 236 PCZone * createZone(const String& zoneType, const String& instanceName); 237 238 /** Destroy an existing zone within the scene */ 239 void destroyZone(PCZone* zone, bool destroySceneNodes); 240 241 /** Make sure the home zone for the PCZSceneNode is up-to-date 242 */ 243 void _updateHomeZone( PCZSceneNode *, bool ); 244 245 /// Find the smallest zone which contains the point 246 PCZone * findZoneForPoint(Vector3 & point); 247 248 /// Create any zone-specific data necessary for all zones for the given node 249 void createZoneSpecificNodeData(PCZSceneNode *); 250 251 /// Create any zone-specific data necessary for all nodes for the given zone 252 void createZoneSpecificNodeData(PCZone *); 253 254 /// Set the home zone for a scene node 255 void setNodeHomeZone(SceneNode *, PCZone *); 256 257 /** Recurses the scene, adding any nodes intersecting with the box into the given list. 258 It ignores the exclude scene node. 259 */ 260 void findNodesIn( const AxisAlignedBox &box, 261 PCZSceneNodeList &list, 262 PCZone * startZone, 263 PCZSceneNode *exclude = 0 ); 264 265 /** Recurses the scene, adding any nodes intersecting with the sphere into the given list. 266 It will start in the start SceneNode if given, otherwise, it will start at the root node. 267 */ 268 void findNodesIn( const Sphere &sphere, 269 PCZSceneNodeList &list, 270 PCZone * startZone, 271 PCZSceneNode *start = 0 ); 272 273 /** Recurses the PCZTree, adding any nodes intersecting with the volume into the given list. 274 It will start in the start SceneNode if given, otherwise, it will start at the root node. 275 */ 276 void findNodesIn( const PlaneBoundedVolume &volume, 277 PCZSceneNodeList &list, 278 PCZone * startZone, 279 PCZSceneNode *start=0 ); 280 281 /** Recurses the scene, starting in the given startZone, adding any nodes intersecting with 282 the ray into the given list. 283 It will start in the start SceneNode if given, otherwise, it will start at the root node. 284 */ 285 void findNodesIn( const Ray &ray, 286 PCZSceneNodeList &list, 287 PCZone * startZone, 288 PCZSceneNode *start=0 ); 289 290 /** Get the default zone */ getDefaultZone(void)291 PCZone * getDefaultZone(void) 292 { 293 return mDefaultZone; 294 } 295 296 /** Get a zone by name */ 297 PCZone * getZoneByName(const String & zoneName); 298 299 /** Sets the portal visibility flag */ setShowPortals(bool b)300 void setShowPortals( bool b ) 301 { 302 mShowPortals = b; 303 }; 304 305 /** Sets the given option for the SceneManager 306 @remarks 307 Options are: 308 "ShowPortals", bool *; 309 "ShowBoundingBoxes", bool *; 310 */ 311 virtual bool setOption( const String &, const void * ); 312 /** Gets the given option for the Scene Manager. 313 @remarks 314 See setOption 315 */ 316 virtual bool getOption( const String &, void * ); 317 318 bool getOptionValues( const String & key, StringVector &refValueList ); 319 bool getOptionKeys( StringVector &refKeys ); 320 321 /** Overridden from SceneManager */ 322 AxisAlignedBoxSceneQuery* createAABBQuery(const AxisAlignedBox& box, uint32 mask = 0xFFFFFFFF); 323 SphereSceneQuery* createSphereQuery(const Sphere& sphere, uint32 mask = 0xFFFFFFFF); 324 PlaneBoundedVolumeListSceneQuery* createPlaneBoundedVolumeQuery(const PlaneBoundedVolumeList& volumes, uint32 mask = 0xFFFFFFFF); 325 RaySceneQuery* createRayQuery(const Ray& ray, uint32 mask = 0xFFFFFFFF); 326 IntersectionSceneQuery* createIntersectionQuery(uint32 mask = 0xFFFFFFFF); 327 328 /// ZoneMap iterator for read-only access to the zonemap 329 typedef MapIterator<ZoneMap> ZoneIterator; getZoneIterator(void)330 ZoneIterator getZoneIterator(void) {return ZoneIterator(mZones.begin(), mZones.end());} 331 332 /// Clear portal update flag from all zones 333 void _clearAllZonesPortalUpdateFlag(void); 334 335 /// @see SceneManager::prepareShadowTextures. 336 virtual void prepareShadowTextures(Camera* cam, Viewport* vp, const LightList* lightList = 0); 337 338 protected: 339 /// Type of default zone to be used 340 String mDefaultZoneTypeName; 341 342 /// Name of data file for default zone 343 String mDefaultZoneFileName; 344 345 /// List of visible nodes since last _findVisibleObjects() 346 NodeList mVisible; 347 348 /// Camera of last _findVisibleObjects() 349 Camera* mLastActiveCamera; 350 351 /// The root PCZone; 352 PCZone *mDefaultZone; 353 354 /// The list of all PCZones 355 ZoneMap mZones; 356 357 /// Master list of Portals in the world (includes all portals) 358 PortalList mPortals; 359 360 /// Master list of AntiPortals in the world. 361 AntiPortalList mAntiPortals; 362 363 /// Portals visibility flag 364 bool mShowPortals; 365 366 /// Frame counter used in visibility determination 367 unsigned long mFrameCount; 368 369 /// ZoneFactoryManager instance 370 PCZoneFactoryManager * mZoneFactoryManager; 371 372 /// The zone of the active camera (for shadow texture casting use); 373 PCZone* mActiveCameraZone; 374 375 /** Internal method for locating a list of lights which could be affecting the frustum. 376 @remarks 377 Custom scene managers are encouraged to override this method to make use of their 378 scene partitioning scheme to more efficiently locate lights, and to eliminate lights 379 which may be occluded by word geometry. 380 */ 381 virtual void findLightsAffectingFrustum(const Camera* camera); 382 /// Internal method for creating shadow textures (texture-based shadows) 383 virtual void ensureShadowTexturesCreated(); 384 /// Internal method for destroying shadow textures (texture-based shadows) 385 virtual void destroyShadowTextures(void); 386 /// Internal method for firing the pre caster texture shadows event 387 virtual void fireShadowTexturesPreCaster(Light* light, Camera* camera, size_t iteration); 388 }; 389 390 /// Factory for PCZSceneManager 391 class PCZSceneManagerFactory : public SceneManagerFactory 392 { 393 protected: 394 void initMetaData(void) const; 395 public: PCZSceneManagerFactory()396 PCZSceneManagerFactory() {} ~PCZSceneManagerFactory()397 ~PCZSceneManagerFactory() {} 398 /// Factory type name 399 static const String FACTORY_TYPE_NAME; 400 SceneManager* createInstance(const String& instanceName); 401 void destroyInstance(SceneManager* instance); 402 }; 403 404 405 406 } 407 408 #endif 409 410 411