source: GTP/trunk/App/Demos/Geom/OgreStuff/include/OgreSceneQuery.h @ 1030

Revision 1030, 24.8 KB checked in by gumbau, 18 years ago (diff)

Ogre Stuff initial import

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        unsigned long mQueryMask;
115        std::set<WorldFragmentType> mSupportedWorldFragments;
116        WorldFragmentType mWorldFragmentType;
117   
118    public:
119        /** Standard constructor, should be called by SceneManager. */
120        SceneQuery(SceneManager* mgr);
121        virtual ~SceneQuery();
122
123        /** Sets the mask for results of this query.
124        @remarks
125            This method allows you to set a 'mask' to limit the results of this
126            query to certain types of result. The actual meaning of this value is
127            up to the application; basically MovableObject instances will only be returned
128            from this query if a bitwise AND operation between this mask value and the
129            MovableObject::getQueryFlags value is non-zero. The application will
130            have to decide what each of the bits means.
131        */
132        virtual void setQueryMask(unsigned long mask);
133        /** Returns the current mask for this query. */
134        virtual unsigned long getQueryMask(void) const;
135
136        /** Tells the query what kind of world geometry to return from queries;
137            often the full renderable geometry is not what is needed.
138        @remarks
139            The application receiving the world geometry is expected to know
140            what to do with it; inevitably this means that the application must
141            have knowledge of at least some of the structures
142            used by the custom SceneManager.
143        @par
144            The default setting is WFT_NONE.
145        */
146        virtual void setWorldFragmentType(enum WorldFragmentType wft);
147
148        /** Gets the current world fragment types to be returned from the query. */
149        virtual WorldFragmentType getWorldFragmentType(void) const;
150
151        /** Returns the types of world fragments this query supports. */
152        virtual const std::set<WorldFragmentType>* getSupportedWorldFragmentTypes(void) const
153            {return &mSupportedWorldFragments;}
154
155       
156    };
157
158    /** This optional class allows you to receive per-result callbacks from
159        SceneQuery executions instead of a single set of consolidated results.
160    @remarks
161        You should override this with your own subclass. Note that certain query
162        classes may refine this listener interface.
163    */
164    class _OgreExport SceneQueryListener
165    {
166    public:
167        virtual ~SceneQueryListener() { }
168        /** Called when a MovableObject is returned by a query.
169        @remarks
170            The implementor should return 'true' to continue returning objects,
171            or 'false' to abandon any further results from this query.
172        */
173        virtual bool queryResult(MovableObject* object) = 0;
174        /** Called when a WorldFragment is returned by a query.
175        @remarks
176            The implementor should return 'true' to continue returning objects,
177            or 'false' to abandon any further results from this query.
178        */
179        virtual bool queryResult(SceneQuery::WorldFragment* fragment) = 0;
180
181    };
182
183    typedef std::list<MovableObject*> SceneQueryResultMovableList;
184    typedef std::list<SceneQuery::WorldFragment*> SceneQueryResultWorldFragmentList;
185    /** Holds the results of a scene query. */
186    struct _OgreExport SceneQueryResult
187    {
188        /// List of movable objects in the query (entities, particle systems etc)
189        SceneQueryResultMovableList movables;
190        /// List of world fragments
191                SceneQueryResultWorldFragmentList worldFragments;
192    };
193
194    /** Abstract class defining a query which returns single results from a region.
195    @remarks
196        This class is simply a generalisation of the subtypes of query that return
197        a set of individual results in a region. See the SceneQuery class for abstract
198        information, and subclasses for the detail of each query type.
199    */
200    class _OgreExport RegionSceneQuery
201        : public SceneQuery, public SceneQueryListener
202    {
203    protected:
204        SceneQueryResult* mLastResult;
205    public:
206        /** Standard constructor, should be called by SceneManager. */
207        RegionSceneQuery(SceneManager* mgr);
208        virtual ~RegionSceneQuery();
209        /** Executes the query, returning the results back in one list.
210        @remarks
211            This method executes the scene query as configured, gathers the results
212            into one structure and returns a reference to that structure. These
213            results will also persist in this query object until the next query is
214            executed, or clearResults() is called. An more lightweight version of
215            this method that returns results through a listener is also available.
216        */
217        virtual SceneQueryResult& execute(void);
218
219        /** Executes the query and returns each match through a listener interface.
220        @remarks
221            Note that this method does not store the results of the query internally
222            so does not update the 'last result' value. This means that this version of
223            execute is more lightweight and therefore more efficient than the version
224            which returns the results as a collection.
225        */
226        virtual void execute(SceneQueryListener* listener) = 0;
227       
228        /** Gets the results of the last query that was run using this object, provided
229            the query was executed using the collection-returning version of execute.
230        */
231        virtual SceneQueryResult& getLastResults(void) const;
232        /** Clears the results of the last query execution.
233        @remarks
234            You only need to call this if you specifically want to free up the memory
235            used by this object to hold the last query results. This object clears the
236            results itself when executing and when destroying itself.
237        */
238        virtual void clearResults(void);
239
240        /** Self-callback in order to deal with execute which returns collection. */
241        bool queryResult(MovableObject* first);
242        /** Self-callback in order to deal with execute which returns collection. */
243        bool queryResult(SceneQuery::WorldFragment* fragment);
244    };
245
246    /** Specialises the SceneQuery class for querying within an axis aligned box. */
247    class _OgreExport AxisAlignedBoxSceneQuery : public RegionSceneQuery
248    {
249    protected:
250        AxisAlignedBox mAABB;
251    public:
252        AxisAlignedBoxSceneQuery(SceneManager* mgr);
253        virtual ~AxisAlignedBoxSceneQuery();
254
255        /** Sets the size of the box you wish to query. */
256        void setBox(const AxisAlignedBox& box);
257
258        /** Gets the box which is being used for this query. */
259        const AxisAlignedBox& getBox(void) const;
260
261    };
262
263    /** Specialises the SceneQuery class for querying within a sphere. */
264    class _OgreExport SphereSceneQuery : public RegionSceneQuery
265    {
266    protected:
267        Sphere mSphere;
268    public:
269        SphereSceneQuery(SceneManager* mgr);
270        virtual ~SphereSceneQuery();
271        /** Sets the sphere which is to be used for this query. */
272        void setSphere(const Sphere& sphere);
273
274        /** Gets the sphere which is being used for this query. */
275        const Sphere& getSphere() const;
276
277    };
278
279    /** Specialises the SceneQuery class for querying within a plane-bounded volume.
280    */
281    class _OgreExport PlaneBoundedVolumeListSceneQuery : public RegionSceneQuery
282    {
283    protected:
284        PlaneBoundedVolumeList mVolumes;
285    public:
286        PlaneBoundedVolumeListSceneQuery(SceneManager* mgr);
287        virtual ~PlaneBoundedVolumeListSceneQuery();
288        /** Sets the volume which is to be used for this query. */
289        void setVolumes(const PlaneBoundedVolumeList& volumes);
290
291        /** Gets the volume which is being used for this query. */
292        const PlaneBoundedVolumeList& getVolumes() const;
293
294    };
295
296
297    /*
298    /// Specialises the SceneQuery class for querying within a pyramid.
299    class _OgreExport PyramidSceneQuery : public RegionSceneQuery
300    {
301    public:
302        PyramidSceneQuery(SceneManager* mgr);
303        virtual ~PyramidSceneQuery();
304    };
305    */
306
307    /** Alternative listener class for dealing with RaySceneQuery.
308    @remarks
309        Because the RaySceneQuery returns results in an extra bit of information, namely
310        distance, the listener interface must be customised from the standard SceneQueryListener.
311    */
312    class _OgreExport RaySceneQueryListener
313    {
314    public:
315        virtual ~RaySceneQueryListener() { }
316        /** Called when a movable objects intersects the ray.
317        @remarks
318            As with SceneQueryListener, the implementor of this method should return 'true'
319            if further results are required, or 'false' to abandon any further results from
320            the current query.
321        */
322        virtual bool queryResult(MovableObject* obj, Real distance) = 0;
323
324        /** Called when a world fragment is intersected by the ray.
325        @remarks
326            As with SceneQueryListener, the implementor of this method should return 'true'
327            if further results are required, or 'false' to abandon any further results from
328            the current query.
329        */
330        virtual bool queryResult(SceneQuery::WorldFragment* fragment, Real distance) = 0;
331
332    };
333     
334    /** This struct allows a single comparison of result data no matter what the type */
335    struct _OgreExport RaySceneQueryResultEntry
336    {
337        /// Distance along the ray
338        Real distance;
339        /// The movable, or NULL if this is not a movable result
340        MovableObject* movable;
341        /// The world fragment, or NULL if this is not a fragment result
342        SceneQuery::WorldFragment* worldFragment;
343        /// Comparison operator for sorting
344        bool operator < (const RaySceneQueryResultEntry& rhs) const
345        {
346            return this->distance < rhs.distance;
347        }
348
349    };
350    typedef std::list<RaySceneQueryResultEntry> RaySceneQueryResult;
351
352    /** Specialises the SceneQuery class for querying along a ray. */
353    class _OgreExport RaySceneQuery : public SceneQuery, public RaySceneQueryListener
354    {
355    protected:
356        Ray mRay;
357        bool mSortByDistance;
358        ushort mMaxResults;
359        RaySceneQueryResult* mLastResult;
360
361    public:
362        RaySceneQuery(SceneManager* mgr);
363        virtual ~RaySceneQuery();
364        /** Sets the ray which is to be used for this query. */
365        virtual void setRay(const Ray& ray);
366        /** Gets the ray which is to be used for this query. */
367        virtual const Ray& getRay(void) const;
368        /** Sets whether the results of this query will be sorted by distance along the ray.
369        @remarks
370            Often you want to know what was the first object a ray intersected with, and this
371            method allows you to ask the query to sort the results so that the nearest results
372            are listed first.
373        @par
374            Note that because the query returns results based on bounding volumes, the ray may not
375            actually intersect the detail of the objects returned from the query, just their
376            bounding volumes. For this reason the caller is advised to use more detailed
377            intersection tests on the results if a more accurate result is required; OGRE uses
378            bounds checking in order to give the most speedy results since not all applications
379            need extreme accuracy.
380        @param sort If true, results will be sorted.
381        @param maxresults If sorting is enabled, this value can be used to constrain the maximum number
382            of results that are returned. Please note (as above) that the use of bounding volumes mean that
383            accuracy is not guaranteed; if in doubt, allow more results and filter them in more detail.
384            0 means unlimited results.
385        */
386        virtual void setSortByDistance(bool sort, ushort maxresults = 0);
387        /** Gets whether the results are sorted by distance. */
388        virtual bool getSortByDistance(void) const;
389        /** Gets the maximum number of results returned from the query (only relevant if
390        results are being sorted) */
391        virtual ushort getMaxResults(void) const;
392        /** Executes the query, returning the results back in one list.
393        @remarks
394            This method executes the scene query as configured, gathers the results
395            into one structure and returns a reference to that structure. These
396            results will also persist in this query object until the next query is
397            executed, or clearResults() is called. An more lightweight version of
398            this method that returns results through a listener is also available.
399        */
400        virtual RaySceneQueryResult& execute(void);
401
402        /** Executes the query and returns each match through a listener interface.
403        @remarks
404            Note that this method does not store the results of the query internally
405            so does not update the 'last result' value. This means that this version of
406            execute is more lightweight and therefore more efficient than the version
407            which returns the results as a collection.
408        */
409        virtual void execute(RaySceneQueryListener* listener) = 0;
410
411        /** Gets the results of the last query that was run using this object, provided
412            the query was executed using the collection-returning version of execute.
413        */
414        virtual RaySceneQueryResult& getLastResults(void) const;
415        /** Clears the results of the last query execution.
416        @remarks
417            You only need to call this if you specifically want to free up the memory
418            used by this object to hold the last query results. This object clears the
419            results itself when executing and when destroying itself.
420        */
421        virtual void clearResults(void);
422
423        /** Self-callback in order to deal with execute which returns collection. */
424        bool queryResult(MovableObject* obj, Real distance);
425        /** Self-callback in order to deal with execute which returns collection. */
426        bool queryResult(SceneQuery::WorldFragment* fragment, Real distance);
427
428
429
430
431    };
432
433    /** Alternative listener class for dealing with IntersectionSceneQuery.
434    @remarks
435        Because the IntersectionSceneQuery returns results in pairs, rather than singularly,
436        the listener interface must be customised from the standard SceneQueryListener.
437    */
438    class _OgreExport IntersectionSceneQueryListener
439    {
440    public:
441        virtual ~IntersectionSceneQueryListener() { }
442        /** Called when 2 movable objects intersect one another.
443        @remarks
444            As with SceneQueryListener, the implementor of this method should return 'true'
445            if further results are required, or 'false' to abandon any further results from
446            the current query.
447        */
448        virtual bool queryResult(MovableObject* first, MovableObject* second) = 0;
449
450        /** Called when a movable intersects a world fragment.
451        @remarks
452            As with SceneQueryListener, the implementor of this method should return 'true'
453            if further results are required, or 'false' to abandon any further results from
454            the current query.
455        */
456        virtual bool queryResult(MovableObject* movable, SceneQuery::WorldFragment* fragment) = 0;
457
458        /* NB there are no results for world fragments intersecting other world fragments;
459           it is assumed that world geometry is either static or at least that self-intersections
460           are irrelevant or dealt with elsewhere (such as the custom scene manager) */
461       
462   
463    };
464       
465    typedef std::pair<MovableObject*, MovableObject*> SceneQueryMovableObjectPair;
466    typedef std::pair<MovableObject*, SceneQuery::WorldFragment*> SceneQueryMovableObjectWorldFragmentPair;
467    typedef std::list<SceneQueryMovableObjectPair> SceneQueryMovableIntersectionList;
468    typedef std::list<SceneQueryMovableObjectWorldFragmentPair> SceneQueryMovableWorldFragmentIntersectionList;
469    /** Holds the results of an intersection scene query (pair values). */
470    struct _OgreExport IntersectionSceneQueryResult
471    {
472        /// List of movable / movable intersections (entities, particle systems etc)
473        SceneQueryMovableIntersectionList movables2movables;
474        /// List of movable / world intersections
475        SceneQueryMovableWorldFragmentIntersectionList movables2world;
476       
477       
478
479    };
480
481    /** Separate SceneQuery class to query for pairs of objects which are
482        possibly intersecting one another.
483    @remarks
484        This SceneQuery subclass considers the whole world and returns pairs of objects
485        which are close enough to each other that they may be intersecting. Because of
486        this slightly different focus, the return types and listener interface are
487        different for this class.
488    */
489    class _OgreExport IntersectionSceneQuery
490        : public SceneQuery, public IntersectionSceneQueryListener
491    {
492    protected:
493        IntersectionSceneQueryResult* mLastResult;
494    public:
495        IntersectionSceneQuery(SceneManager* mgr);
496        virtual ~IntersectionSceneQuery();
497
498        /** Executes the query, returning the results back in one list.
499        @remarks
500            This method executes the scene query as configured, gathers the results
501            into one structure and returns a reference to that structure. These
502            results will also persist in this query object until the next query is
503            executed, or clearResults() is called. An more lightweight version of
504            this method that returns results through a listener is also available.
505        */
506        virtual IntersectionSceneQueryResult& execute(void);
507
508        /** Executes the query and returns each match through a listener interface.
509        @remarks
510            Note that this method does not store the results of the query internally
511            so does not update the 'last result' value. This means that this version of
512            execute is more lightweight and therefore more efficient than the version
513            which returns the results as a collection.
514        */
515        virtual void execute(IntersectionSceneQueryListener* listener) = 0;
516
517        /** Gets the results of the last query that was run using this object, provided
518            the query was executed using the collection-returning version of execute.
519        */
520        virtual IntersectionSceneQueryResult& getLastResults(void) const;
521        /** Clears the results of the last query execution.
522        @remarks
523            You only need to call this if you specifically want to free up the memory
524            used by this object to hold the last query results. This object clears the
525            results itself when executing and when destroying itself.
526        */
527        virtual void clearResults(void);
528
529        /** Self-callback in order to deal with execute which returns collection. */
530        bool queryResult(MovableObject* first, MovableObject* second);
531        /** Self-callback in order to deal with execute which returns collection. */
532        bool queryResult(MovableObject* movable, SceneQuery::WorldFragment* fragment);
533    };
534   
535
536}
537   
538
539
540#endif
Note: See TracBrowser for help on using the repository browser.