Coverage Report

Created: 2025-10-10 06:46

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