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

Revision 1809, 25.3 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://www.ogre3d.org/
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 __SceneQuery_H__
26#define __SceneQuery_H__
27
28#include "OgrePrerequisites.h"
29#include "OgreAxisAlignedBox.h"
30#include "OgreSphere.h"
31#include "OgreRay.h"
32#include "OgreRenderOperation.h"
33#include "OgrePlaneBoundedVolume.h"
34
35namespace Ogre {
36
37    // forward declaration
38    class SceneQueryListener;
39    /** A class for performing queries on a scene.
40    @remarks
41        This is an abstract class for performing a query on a scene, i.e. to retrieve
42        a list of objects and/or world geometry sections which are potentially intersecting a
43        given region. Note the use of the word 'potentially': the results of a scene query
44        are generated based on bounding volumes, and as such are not correct at a triangle
45        level; the user of the SceneQuery is expected to filter the results further if
46        greater accuracy is required.
47    @par
48        Different SceneManagers will implement these queries in different ways to
49        exploit their particular scene organisation, and thus will provide their own
50        concrete subclasses. In fact, these subclasses will be derived from subclasses
51        of this class rather than directly because there will be region-type classes
52        in between.
53    @par
54        These queries could have just been implemented as methods on the SceneManager,
55        however, they are wrapped up as objects to allow 'compilation' of queries
56        if deemed appropriate by the implementation; i.e. each concrete subclass may
57        precalculate information (such as fixed scene partitions involved in the query)
58        to speed up the repeated use of the query.
59    @par
60        You should never try to create a SceneQuery object yourself, they should be created
61        using the SceneManager interfaces for the type of query required, e.g.
62        SceneManager::createSphereSceneQuery.
63    */
64    class _OgreExport SceneQuery
65    {
66    public:
67        /** This type can be used by collaborating applications & SceneManagers to
68            agree on the type of world geometry to be returned from queries. Not all
69            these types will be supported by all SceneManagers; once the application
70            has decided which SceneManager specialisation to use, it is expected that
71            it will know which type of world geometry abstraction is available to it.
72        */
73        enum WorldFragmentType {
74            /// Return no world geometry hits at all
75            WFT_NONE,
76            /// Return pointers to convex plane-bounded regions
77            WFT_PLANE_BOUNDED_REGION,
78            /// Return a single intersection point (typically RaySceneQuery only)
79            WFT_SINGLE_INTERSECTION,
80            /// Custom geometry as defined by the SceneManager
81            WFT_CUSTOM_GEOMETRY,
82            /// General RenderOperation structure
83            WFT_RENDER_OPERATION
84        };
85
86        /** Represents part of the world geometry that is a result of a SceneQuery.
87        @remarks
88            Since world geometry is normally vast and sprawling, we need a way of
89            retrieving parts of it based on a query. That is what this struct is for;
90            note there are potentially as many data structures for world geometry as there
91            are SceneManagers, however this structure includes a few common abstractions as
92            well as a more general format.
93        @par
94            The type of world fragment that is returned from a query depends on the
95            SceneManager, and the option set using SceneQuery::setWorldFragmentType.
96            You can see what fragment types are supported on the query in question by
97            calling SceneQuery::getSupportedWorldFragmentTypes().
98        */
99        struct WorldFragment {
100            /// The type of this world fragment
101            WorldFragmentType fragmentType;
102            /// Single intersection point, only applicable for WFT_SINGLE_INTERSECTION
103            Vector3 singleIntersection;
104            /// Planes bounding a convex region, only applicable for WFT_PLANE_BOUNDED_REGION
105            std::list<Plane>* planes;
106            /// Custom geometry block, only applicable for WFT_CUSTOM_GEOMETRY
107            void* geometry;
108            /// General render operation structure, fallback if nothing else is available
109            RenderOperation* renderOp;
110           
111        };
112    protected:
113        SceneManager* mParentSceneMgr;
114        uint32 mQueryMask;
115                uint32 mQueryTypeMask;
116        std::set<WorldFragmentType> mSupportedWorldFragments;
117        WorldFragmentType mWorldFragmentType;
118   
119    public:
120        /** Standard constructor, should be called by SceneManager. */
121        SceneQuery(SceneManager* mgr);
122        virtual ~SceneQuery();
123
124        /** Sets the mask for results of this query.
125        @remarks
126            This method allows you to set a 'mask' to limit the results of this
127            query to certain types of result. The actual meaning of this value is
128            up to the application; basically MovableObject instances will only be returned
129            from this query if a bitwise AND operation between this mask value and the
130            MovableObject::getQueryFlags value is non-zero. The application will
131            have to decide what each of the bits means.
132        */
133        virtual void setQueryMask(uint32 mask);
134        /** Returns the current mask for this query. */
135        virtual uint32 getQueryMask(void) const;
136
137        /** Sets the type mask for results of this query.
138        @remarks
139            This method allows you to set a 'type mask' to limit the results of this
140            query to certain types of objects. Whilst setQueryMask deals with flags
141                        set per instance of object, this method deals with setting a mask on
142                        flags set per type of object. Both may exclude an object from query
143                        results.
144        */
145        virtual void setQueryTypeMask(uint32 mask);
146        /** Returns the current mask for this query. */
147        virtual uint32 getQueryTypeMask(void) const;
148
149                /** Tells the query what kind of world geometry to return from queries;
150            often the full renderable geometry is not what is needed.
151        @remarks
152            The application receiving the world geometry is expected to know
153            what to do with it; inevitably this means that the application must
154            have knowledge of at least some of the structures
155            used by the custom SceneManager.
156        @par
157            The default setting is WFT_NONE.
158        */
159        virtual void setWorldFragmentType(enum WorldFragmentType wft);
160
161        /** Gets the current world fragment types to be returned from the query. */
162        virtual WorldFragmentType getWorldFragmentType(void) const;
163
164        /** Returns the types of world fragments this query supports. */
165        virtual const std::set<WorldFragmentType>* getSupportedWorldFragmentTypes(void) const
166            {return &mSupportedWorldFragments;}
167
168       
169    };
170
171    /** This optional class allows you to receive per-result callbacks from
172        SceneQuery executions instead of a single set of consolidated results.
173    @remarks
174        You should override this with your own subclass. Note that certain query
175        classes may refine this listener interface.
176    */
177    class _OgreExport SceneQueryListener
178    {
179    public:
180        virtual ~SceneQueryListener() { }
181        /** Called when a MovableObject is returned by a query.
182        @remarks
183            The implementor should return 'true' to continue returning objects,
184            or 'false' to abandon any further results from this query.
185        */
186        virtual bool queryResult(MovableObject* object) = 0;
187        /** Called when a WorldFragment is returned by a query.
188        @remarks
189            The implementor should return 'true' to continue returning objects,
190            or 'false' to abandon any further results from this query.
191        */
192        virtual bool queryResult(SceneQuery::WorldFragment* fragment) = 0;
193
194    };
195
196    typedef std::list<MovableObject*> SceneQueryResultMovableList;
197    typedef std::list<SceneQuery::WorldFragment*> SceneQueryResultWorldFragmentList;
198    /** Holds the results of a scene query. */
199    struct _OgreExport SceneQueryResult
200    {
201        /// List of movable objects in the query (entities, particle systems etc)
202        SceneQueryResultMovableList movables;
203        /// List of world fragments
204                SceneQueryResultWorldFragmentList worldFragments;
205    };
206
207    /** Abstract class defining a query which returns single results from a region.
208    @remarks
209        This class is simply a generalisation of the subtypes of query that return
210        a set of individual results in a region. See the SceneQuery class for abstract
211        information, and subclasses for the detail of each query type.
212    */
213    class _OgreExport RegionSceneQuery
214        : public SceneQuery, public SceneQueryListener
215    {
216    protected:
217        SceneQueryResult* mLastResult;
218    public:
219        /** Standard constructor, should be called by SceneManager. */
220        RegionSceneQuery(SceneManager* mgr);
221        virtual ~RegionSceneQuery();
222        /** Executes the query, returning the results back in one list.
223        @remarks
224            This method executes the scene query as configured, gathers the results
225            into one structure and returns a reference to that structure. These
226            results will also persist in this query object until the next query is
227            executed, or clearResults() is called. An more lightweight version of
228            this method that returns results through a listener is also available.
229        */
230        virtual SceneQueryResult& execute(void);
231
232        /** Executes the query and returns each match through a listener interface.
233        @remarks
234            Note that this method does not store the results of the query internally
235            so does not update the 'last result' value. This means that this version of
236            execute is more lightweight and therefore more efficient than the version
237            which returns the results as a collection.
238        */
239        virtual void execute(SceneQueryListener* listener) = 0;
240       
241        /** Gets the results of the last query that was run using this object, provided
242            the query was executed using the collection-returning version of execute.
243        */
244        virtual SceneQueryResult& getLastResults(void) const;
245        /** Clears the results of the last query execution.
246        @remarks
247            You only need to call this if you specifically want to free up the memory
248            used by this object to hold the last query results. This object clears the
249            results itself when executing and when destroying itself.
250        */
251        virtual void clearResults(void);
252
253        /** Self-callback in order to deal with execute which returns collection. */
254        bool queryResult(MovableObject* first);
255        /** Self-callback in order to deal with execute which returns collection. */
256        bool queryResult(SceneQuery::WorldFragment* fragment);
257    };
258
259    /** Specialises the SceneQuery class for querying within an axis aligned box. */
260    class _OgreExport AxisAlignedBoxSceneQuery : public RegionSceneQuery
261    {
262    protected:
263        AxisAlignedBox mAABB;
264    public:
265        AxisAlignedBoxSceneQuery(SceneManager* mgr);
266        virtual ~AxisAlignedBoxSceneQuery();
267
268        /** Sets the size of the box you wish to query. */
269        void setBox(const AxisAlignedBox& box);
270
271        /** Gets the box which is being used for this query. */
272        const AxisAlignedBox& getBox(void) const;
273
274    };
275
276    /** Specialises the SceneQuery class for querying within a sphere. */
277    class _OgreExport SphereSceneQuery : public RegionSceneQuery
278    {
279    protected:
280        Sphere mSphere;
281    public:
282        SphereSceneQuery(SceneManager* mgr);
283        virtual ~SphereSceneQuery();
284        /** Sets the sphere which is to be used for this query. */
285        void setSphere(const Sphere& sphere);
286
287        /** Gets the sphere which is being used for this query. */
288        const Sphere& getSphere() const;
289
290    };
291
292    /** Specialises the SceneQuery class for querying within a plane-bounded volume.
293    */
294    class _OgreExport PlaneBoundedVolumeListSceneQuery : public RegionSceneQuery
295    {
296    protected:
297        PlaneBoundedVolumeList mVolumes;
298    public:
299        PlaneBoundedVolumeListSceneQuery(SceneManager* mgr);
300        virtual ~PlaneBoundedVolumeListSceneQuery();
301        /** Sets the volume which is to be used for this query. */
302        void setVolumes(const PlaneBoundedVolumeList& volumes);
303
304        /** Gets the volume which is being used for this query. */
305        const PlaneBoundedVolumeList& getVolumes() const;
306
307    };
308
309
310    /*
311    /// Specialises the SceneQuery class for querying within a pyramid.
312    class _OgreExport PyramidSceneQuery : public RegionSceneQuery
313    {
314    public:
315        PyramidSceneQuery(SceneManager* mgr);
316        virtual ~PyramidSceneQuery();
317    };
318    */
319
320    /** Alternative listener class for dealing with RaySceneQuery.
321    @remarks
322        Because the RaySceneQuery returns results in an extra bit of information, namely
323        distance, the listener interface must be customised from the standard SceneQueryListener.
324    */
325    class _OgreExport RaySceneQueryListener
326    {
327    public:
328        virtual ~RaySceneQueryListener() { }
329        /** Called when a movable objects intersects the ray.
330        @remarks
331            As with SceneQueryListener, the implementor of this method should return 'true'
332            if further results are required, or 'false' to abandon any further results from
333            the current query.
334        */
335        virtual bool queryResult(MovableObject* obj, Real distance) = 0;
336
337        /** Called when a world fragment is intersected by the ray.
338        @remarks
339            As with SceneQueryListener, the implementor of this method should return 'true'
340            if further results are required, or 'false' to abandon any further results from
341            the current query.
342        */
343        virtual bool queryResult(SceneQuery::WorldFragment* fragment, Real distance) = 0;
344
345    };
346     
347    /** This struct allows a single comparison of result data no matter what the type */
348    struct _OgreExport RaySceneQueryResultEntry
349    {
350        /// Distance along the ray
351        Real distance;
352        /// The movable, or NULL if this is not a movable result
353        MovableObject* movable;
354        /// The world fragment, or NULL if this is not a fragment result
355        SceneQuery::WorldFragment* worldFragment;
356        /// Comparison operator for sorting
357        bool operator < (const RaySceneQueryResultEntry& rhs) const
358        {
359            return this->distance < rhs.distance;
360        }
361
362    };
363    typedef std::vector<RaySceneQueryResultEntry> RaySceneQueryResult;
364
365    /** Specialises the SceneQuery class for querying along a ray. */
366    class _OgreExport RaySceneQuery : public SceneQuery, public RaySceneQueryListener
367    {
368    protected:
369        Ray mRay;
370        bool mSortByDistance;
371        ushort mMaxResults;
372        RaySceneQueryResult mResult;
373
374    public:
375        RaySceneQuery(SceneManager* mgr);
376        virtual ~RaySceneQuery();
377        /** Sets the ray which is to be used for this query. */
378        virtual void setRay(const Ray& ray);
379        /** Gets the ray which is to be used for this query. */
380        virtual const Ray& getRay(void) const;
381        /** Sets whether the results of this query will be sorted by distance along the ray.
382        @remarks
383            Often you want to know what was the first object a ray intersected with, and this
384            method allows you to ask the query to sort the results so that the nearest results
385            are listed first.
386        @par
387            Note that because the query returns results based on bounding volumes, the ray may not
388            actually intersect the detail of the objects returned from the query, just their
389            bounding volumes. For this reason the caller is advised to use more detailed
390            intersection tests on the results if a more accurate result is required; OGRE uses
391            bounds checking in order to give the most speedy results since not all applications
392            need extreme accuracy.
393        @param sort If true, results will be sorted.
394        @param maxresults If sorting is enabled, this value can be used to constrain the maximum number
395            of results that are returned. Please note (as above) that the use of bounding volumes mean that
396            accuracy is not guaranteed; if in doubt, allow more results and filter them in more detail.
397            0 means unlimited results.
398        */
399        virtual void setSortByDistance(bool sort, ushort maxresults = 0);
400        /** Gets whether the results are sorted by distance. */
401        virtual bool getSortByDistance(void) const;
402        /** Gets the maximum number of results returned from the query (only relevant if
403        results are being sorted) */
404        virtual ushort getMaxResults(void) const;
405        /** Executes the query, returning the results back in one list.
406        @remarks
407            This method executes the scene query as configured, gathers the results
408            into one structure and returns a reference to that structure. These
409            results will also persist in this query object until the next query is
410            executed, or clearResults() is called. An more lightweight version of
411            this method that returns results through a listener is also available.
412        */
413        virtual RaySceneQueryResult& execute(void);
414
415        /** Executes the query and returns each match through a listener interface.
416        @remarks
417            Note that this method does not store the results of the query internally
418            so does not update the 'last result' value. This means that this version of
419            execute is more lightweight and therefore more efficient than the version
420            which returns the results as a collection.
421        */
422        virtual void execute(RaySceneQueryListener* listener) = 0;
423
424        /** Gets the results of the last query that was run using this object, provided
425            the query was executed using the collection-returning version of execute.
426        */
427        virtual RaySceneQueryResult& getLastResults(void);
428        /** Clears the results of the last query execution.
429        @remarks
430            You only need to call this if you specifically want to free up the memory
431            used by this object to hold the last query results. This object clears the
432            results itself when executing and when destroying itself.
433        */
434        virtual void clearResults(void);
435
436        /** Self-callback in order to deal with execute which returns collection. */
437        bool queryResult(MovableObject* obj, Real distance);
438        /** Self-callback in order to deal with execute which returns collection. */
439        bool queryResult(SceneQuery::WorldFragment* fragment, Real distance);
440
441
442
443
444    };
445
446    /** Alternative listener class for dealing with IntersectionSceneQuery.
447    @remarks
448        Because the IntersectionSceneQuery returns results in pairs, rather than singularly,
449        the listener interface must be customised from the standard SceneQueryListener.
450    */
451    class _OgreExport IntersectionSceneQueryListener
452    {
453    public:
454        virtual ~IntersectionSceneQueryListener() { }
455        /** Called when 2 movable objects intersect one another.
456        @remarks
457            As with SceneQueryListener, the implementor of this method should return 'true'
458            if further results are required, or 'false' to abandon any further results from
459            the current query.
460        */
461        virtual bool queryResult(MovableObject* first, MovableObject* second) = 0;
462
463        /** Called when a movable intersects a world fragment.
464        @remarks
465            As with SceneQueryListener, the implementor of this method should return 'true'
466            if further results are required, or 'false' to abandon any further results from
467            the current query.
468        */
469        virtual bool queryResult(MovableObject* movable, SceneQuery::WorldFragment* fragment) = 0;
470
471        /* NB there are no results for world fragments intersecting other world fragments;
472           it is assumed that world geometry is either static or at least that self-intersections
473           are irrelevant or dealt with elsewhere (such as the custom scene manager) */
474       
475   
476    };
477       
478    typedef std::pair<MovableObject*, MovableObject*> SceneQueryMovableObjectPair;
479    typedef std::pair<MovableObject*, SceneQuery::WorldFragment*> SceneQueryMovableObjectWorldFragmentPair;
480    typedef std::list<SceneQueryMovableObjectPair> SceneQueryMovableIntersectionList;
481    typedef std::list<SceneQueryMovableObjectWorldFragmentPair> SceneQueryMovableWorldFragmentIntersectionList;
482    /** Holds the results of an intersection scene query (pair values). */
483    struct _OgreExport IntersectionSceneQueryResult
484    {
485        /// List of movable / movable intersections (entities, particle systems etc)
486        SceneQueryMovableIntersectionList movables2movables;
487        /// List of movable / world intersections
488        SceneQueryMovableWorldFragmentIntersectionList movables2world;
489       
490       
491
492    };
493
494    /** Separate SceneQuery class to query for pairs of objects which are
495        possibly intersecting one another.
496    @remarks
497        This SceneQuery subclass considers the whole world and returns pairs of objects
498        which are close enough to each other that they may be intersecting. Because of
499        this slightly different focus, the return types and listener interface are
500        different for this class.
501    */
502    class _OgreExport IntersectionSceneQuery
503        : public SceneQuery, public IntersectionSceneQueryListener
504    {
505    protected:
506        IntersectionSceneQueryResult* mLastResult;
507    public:
508        IntersectionSceneQuery(SceneManager* mgr);
509        virtual ~IntersectionSceneQuery();
510
511        /** Executes the query, returning the results back in one list.
512        @remarks
513            This method executes the scene query as configured, gathers the results
514            into one structure and returns a reference to that structure. These
515            results will also persist in this query object until the next query is
516            executed, or clearResults() is called. An more lightweight version of
517            this method that returns results through a listener is also available.
518        */
519        virtual IntersectionSceneQueryResult& execute(void);
520
521        /** Executes the query and returns each match through a listener interface.
522        @remarks
523            Note that this method does not store the results of the query internally
524            so does not update the 'last result' value. This means that this version of
525            execute is more lightweight and therefore more efficient than the version
526            which returns the results as a collection.
527        */
528        virtual void execute(IntersectionSceneQueryListener* listener) = 0;
529
530        /** Gets the results of the last query that was run using this object, provided
531            the query was executed using the collection-returning version of execute.
532        */
533        virtual IntersectionSceneQueryResult& getLastResults(void) const;
534        /** Clears the results of the last query execution.
535        @remarks
536            You only need to call this if you specifically want to free up the memory
537            used by this object to hold the last query results. This object clears the
538            results itself when executing and when destroying itself.
539        */
540        virtual void clearResults(void);
541
542        /** Self-callback in order to deal with execute which returns collection. */
543        bool queryResult(MovableObject* first, MovableObject* second);
544        /** Self-callback in order to deal with execute which returns collection. */
545        bool queryResult(MovableObject* movable, SceneQuery::WorldFragment* fragment);
546    };
547   
548
549}
550   
551
552
553#endif
Note: See TracBrowser for help on using the repository browser.