Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreSceneQuery.h @ 1

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