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