1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../Graphics/Drawable.h"
26 #include "../Math/BoundingBox.h"
27 #include "../Math/Frustum.h"
28 #include "../Math/Ray.h"
29 #include "../Math/Sphere.h"
30 
31 namespace Urho3D
32 {
33 
34 class Drawable;
35 class Node;
36 
37 /// Base class for octree queries.
38 class URHO3D_API OctreeQuery
39 {
40 public:
41     /// Construct with query parameters.
OctreeQuery(PODVector<Drawable * > & result,unsigned char drawableFlags,unsigned viewMask)42     OctreeQuery(PODVector<Drawable*>& result, unsigned char drawableFlags, unsigned viewMask) :
43         result_(result),
44         drawableFlags_(drawableFlags),
45         viewMask_(viewMask)
46     {
47     }
48 
49     /// Destruct.
~OctreeQuery()50     virtual ~OctreeQuery()
51     {
52     }
53 
54     /// Intersection test for an octant.
55     virtual Intersection TestOctant(const BoundingBox& box, bool inside) = 0;
56     /// Intersection test for drawables.
57     virtual void TestDrawables(Drawable** start, Drawable** end, bool inside) = 0;
58 
59     /// Result vector reference.
60     PODVector<Drawable*>& result_;
61     /// Drawable flags to include.
62     unsigned char drawableFlags_;
63     /// Drawable layers to include.
64     unsigned viewMask_;
65 
66 private:
67     /// Prevent copy construction.
68     OctreeQuery(const OctreeQuery& rhs);
69     /// Prevent assignment.
70     OctreeQuery& operator =(const OctreeQuery& rhs);
71 };
72 
73 /// Point octree query.
74 class URHO3D_API PointOctreeQuery : public OctreeQuery
75 {
76 public:
77     /// Construct with point and query parameters.
78     PointOctreeQuery(PODVector<Drawable*>& result, const Vector3& point, unsigned char drawableFlags = DRAWABLE_ANY,
79         unsigned viewMask = DEFAULT_VIEWMASK) :
OctreeQuery(result,drawableFlags,viewMask)80         OctreeQuery(result, drawableFlags, viewMask),
81         point_(point)
82     {
83     }
84 
85     /// Intersection test for an octant.
86     virtual Intersection TestOctant(const BoundingBox& box, bool inside);
87     /// Intersection test for drawables.
88     virtual void TestDrawables(Drawable** start, Drawable** end, bool inside);
89 
90     /// Point.
91     Vector3 point_;
92 };
93 
94 /// %Sphere octree query.
95 class URHO3D_API SphereOctreeQuery : public OctreeQuery
96 {
97 public:
98     /// Construct with sphere and query parameters.
99     SphereOctreeQuery(PODVector<Drawable*>& result, const Sphere& sphere, unsigned char drawableFlags = DRAWABLE_ANY,
100         unsigned viewMask = DEFAULT_VIEWMASK) :
OctreeQuery(result,drawableFlags,viewMask)101         OctreeQuery(result, drawableFlags, viewMask),
102         sphere_(sphere)
103     {
104     }
105 
106     /// Intersection test for an octant.
107     virtual Intersection TestOctant(const BoundingBox& box, bool inside);
108     /// Intersection test for drawables.
109     virtual void TestDrawables(Drawable** start, Drawable** end, bool inside);
110 
111     /// Sphere.
112     Sphere sphere_;
113 };
114 
115 /// Bounding box octree query.
116 class URHO3D_API BoxOctreeQuery : public OctreeQuery
117 {
118 public:
119     /// Construct with bounding box and query parameters.
120     BoxOctreeQuery(PODVector<Drawable*>& result, const BoundingBox& box, unsigned char drawableFlags = DRAWABLE_ANY,
121         unsigned viewMask = DEFAULT_VIEWMASK) :
OctreeQuery(result,drawableFlags,viewMask)122         OctreeQuery(result, drawableFlags, viewMask),
123         box_(box)
124     {
125     }
126 
127     /// Intersection test for an octant.
128     virtual Intersection TestOctant(const BoundingBox& box, bool inside);
129     /// Intersection test for drawables.
130     virtual void TestDrawables(Drawable** start, Drawable** end, bool inside);
131 
132     /// Bounding box.
133     BoundingBox box_;
134 };
135 
136 /// %Frustum octree query.
137 class URHO3D_API FrustumOctreeQuery : public OctreeQuery
138 {
139 public:
140     /// Construct with frustum and query parameters.
141     FrustumOctreeQuery(PODVector<Drawable*>& result, const Frustum& frustum, unsigned char drawableFlags = DRAWABLE_ANY,
142         unsigned viewMask = DEFAULT_VIEWMASK) :
OctreeQuery(result,drawableFlags,viewMask)143         OctreeQuery(result, drawableFlags, viewMask),
144         frustum_(frustum)
145     {
146     }
147 
148     /// Intersection test for an octant.
149     virtual Intersection TestOctant(const BoundingBox& box, bool inside);
150     /// Intersection test for drawables.
151     virtual void TestDrawables(Drawable** start, Drawable** end, bool inside);
152 
153     /// Frustum.
154     Frustum frustum_;
155 };
156 
157 /// General octree query result. Used for Lua bindings only.
158 struct URHO3D_API OctreeQueryResult
159 {
160     /// Construct with defaults.
OctreeQueryResultOctreeQueryResult161     OctreeQueryResult() :
162         drawable_(0),
163         node_(0)
164     {
165     }
166 
167     /// Test for inequality, added to prevent GCC from complaining.
168     bool operator !=(const OctreeQueryResult& rhs) const { return drawable_ != rhs.drawable_ || node_ != rhs.node_; }
169 
170     /// Drawable.
171     Drawable* drawable_;
172     /// Scene node.
173     Node* node_;
174 };
175 
176 /// Graphics raycast detail level.
177 enum RayQueryLevel
178 {
179     RAY_AABB = 0,
180     RAY_OBB,
181     RAY_TRIANGLE,
182     RAY_TRIANGLE_UV
183 };
184 
185 /// Raycast result.
186 struct URHO3D_API RayQueryResult
187 {
188     /// Construct with defaults.
RayQueryResultRayQueryResult189     RayQueryResult() :
190         drawable_(0),
191         node_(0)
192     {
193     }
194 
195     /// Test for inequality, added to prevent GCC from complaining.
196     bool operator !=(const RayQueryResult& rhs) const
197     {
198         return position_ != rhs.position_ ||
199                normal_ != rhs.normal_ ||
200                textureUV_ != rhs.textureUV_ ||
201                distance_ != rhs.distance_ ||
202                drawable_ != rhs.drawable_ ||
203                node_ != rhs.node_ ||
204                subObject_ != rhs.subObject_;
205     }
206 
207     /// Hit position in world space.
208     Vector3 position_;
209     /// Hit normal in world space. Negation of ray direction if per-triangle data not available.
210     Vector3 normal_;
211     /// Hit texture position
212     Vector2 textureUV_;
213     /// Distance from ray origin.
214     float distance_;
215     /// Drawable.
216     Drawable* drawable_;
217     /// Scene node.
218     Node* node_;
219     /// Drawable specific subobject if applicable.
220     unsigned subObject_;
221 };
222 
223 /// Raycast octree query.
224 class URHO3D_API RayOctreeQuery
225 {
226 public:
227     /// Construct with ray and query parameters.
228     RayOctreeQuery(PODVector<RayQueryResult>& result, const Ray& ray, RayQueryLevel level = RAY_TRIANGLE,
229         float maxDistance = M_INFINITY, unsigned char drawableFlags = DRAWABLE_ANY, unsigned viewMask = DEFAULT_VIEWMASK) :
result_(result)230         result_(result),
231         ray_(ray),
232         drawableFlags_(drawableFlags),
233         viewMask_(viewMask),
234         maxDistance_(maxDistance),
235         level_(level)
236     {
237     }
238 
239     /// Result vector reference.
240     PODVector<RayQueryResult>& result_;
241     /// Ray.
242     Ray ray_;
243     /// Drawable flags to include.
244     unsigned char drawableFlags_;
245     /// Drawable layers to include.
246     unsigned viewMask_;
247     /// Maximum ray distance.
248     float maxDistance_;
249     /// Raycast detail level.
250     RayQueryLevel level_;
251 
252 private:
253     /// Prevent copy construction.
254     RayOctreeQuery(const RayOctreeQuery& rhs);
255     /// Prevent assignment.
256     RayOctreeQuery& operator =(const RayOctreeQuery& rhs);
257 };
258 
259 class URHO3D_API AllContentOctreeQuery : public OctreeQuery
260 {
261 public:
262     /// Construct.
AllContentOctreeQuery(PODVector<Drawable * > & result,unsigned char drawableFlags,unsigned viewMask)263     AllContentOctreeQuery(PODVector<Drawable*>& result, unsigned char drawableFlags, unsigned viewMask) :
264         OctreeQuery(result, drawableFlags, viewMask)
265     {
266     }
267 
268     /// Intersection test for an octant.
269     virtual Intersection TestOctant(const BoundingBox& box, bool inside);
270     /// Intersection test for drawables.
271     virtual void TestDrawables(Drawable** start, Drawable** end, bool inside);
272 };
273 
274 }
275