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-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software; you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | #include "OgreStableHeaders.h"
|
---|
26 | #include "OgreSceneManager.h"
|
---|
27 | #include "OgreEntity.h"
|
---|
28 | #include "OgreRoot.h"
|
---|
29 |
|
---|
30 | namespace Ogre {
|
---|
31 | //---------------------------------------------------------------------
|
---|
32 | DefaultIntersectionSceneQuery::DefaultIntersectionSceneQuery(SceneManager* creator)
|
---|
33 | : IntersectionSceneQuery(creator)
|
---|
34 | {
|
---|
35 | // No world geometry results supported
|
---|
36 | mSupportedWorldFragments.insert(SceneQuery::WFT_NONE);
|
---|
37 | }
|
---|
38 | //---------------------------------------------------------------------
|
---|
39 | DefaultIntersectionSceneQuery::~DefaultIntersectionSceneQuery()
|
---|
40 | {
|
---|
41 | }
|
---|
42 | //---------------------------------------------------------------------
|
---|
43 | void DefaultIntersectionSceneQuery::execute(IntersectionSceneQueryListener* listener)
|
---|
44 | {
|
---|
45 | // Iterate over all movable types
|
---|
46 | Root::MovableObjectFactoryIterator factIt =
|
---|
47 | Root::getSingleton().getMovableObjectFactoryIterator();
|
---|
48 | while(factIt.hasMoreElements())
|
---|
49 | {
|
---|
50 | SceneManager::MovableObjectIterator objItA =
|
---|
51 | mParentSceneMgr->getMovableObjectIterator(
|
---|
52 | factIt.getNext()->getType());
|
---|
53 | while (objItA.hasMoreElements())
|
---|
54 | {
|
---|
55 | MovableObject* a = objItA.getNext();
|
---|
56 | // skip entire section if type doesn't match
|
---|
57 | if (!(a->getTypeFlags() & mQueryTypeMask))
|
---|
58 | break;
|
---|
59 |
|
---|
60 | // Skip if a does not pass the mask
|
---|
61 | if (!(a->getQueryFlags() & mQueryMask) ||
|
---|
62 | !a->isInScene())
|
---|
63 | continue;
|
---|
64 |
|
---|
65 | // Check against later objects in the same group
|
---|
66 | SceneManager::MovableObjectIterator objItB = objItA;
|
---|
67 | while (objItB.hasMoreElements())
|
---|
68 | {
|
---|
69 | MovableObject* b = objItB.getNext();
|
---|
70 |
|
---|
71 | // Apply mask to b (both must pass)
|
---|
72 | if ((b->getQueryFlags() & mQueryMask) &&
|
---|
73 | b->isInScene())
|
---|
74 | {
|
---|
75 | const AxisAlignedBox& box1 = a->getWorldBoundingBox();
|
---|
76 | const AxisAlignedBox& box2 = b->getWorldBoundingBox();
|
---|
77 |
|
---|
78 | if (box1.intersects(box2))
|
---|
79 | {
|
---|
80 | if (!listener->queryResult(a, b)) return;
|
---|
81 | }
|
---|
82 | }
|
---|
83 | }
|
---|
84 | // Check against later groups
|
---|
85 | Root::MovableObjectFactoryIterator factItLater = factIt;
|
---|
86 | while (factItLater.hasMoreElements())
|
---|
87 | {
|
---|
88 | SceneManager::MovableObjectIterator objItC =
|
---|
89 | mParentSceneMgr->getMovableObjectIterator(
|
---|
90 | factIt.getNext()->getType());
|
---|
91 | while (objItC.hasMoreElements())
|
---|
92 | {
|
---|
93 | MovableObject* c = objItC.getNext();
|
---|
94 | // skip entire section if type doesn't match
|
---|
95 | if (!(c->getTypeFlags() & mQueryTypeMask))
|
---|
96 | break;
|
---|
97 |
|
---|
98 | // Apply mask to c (both must pass)
|
---|
99 | if ((c->getQueryFlags() & mQueryMask) &&
|
---|
100 | c->isInScene())
|
---|
101 | {
|
---|
102 | const AxisAlignedBox& box1 = a->getWorldBoundingBox();
|
---|
103 | const AxisAlignedBox& box2 = c->getWorldBoundingBox();
|
---|
104 |
|
---|
105 | if (box1.intersects(box2))
|
---|
106 | {
|
---|
107 | if (!listener->queryResult(a, c)) return;
|
---|
108 | }
|
---|
109 | }
|
---|
110 | }
|
---|
111 |
|
---|
112 | }
|
---|
113 |
|
---|
114 | }
|
---|
115 |
|
---|
116 |
|
---|
117 | }
|
---|
118 |
|
---|
119 | }
|
---|
120 | //---------------------------------------------------------------------
|
---|
121 | DefaultAxisAlignedBoxSceneQuery::
|
---|
122 | DefaultAxisAlignedBoxSceneQuery(SceneManager* creator)
|
---|
123 | : AxisAlignedBoxSceneQuery(creator)
|
---|
124 | {
|
---|
125 | // No world geometry results supported
|
---|
126 | mSupportedWorldFragments.insert(SceneQuery::WFT_NONE);
|
---|
127 | }
|
---|
128 | //---------------------------------------------------------------------
|
---|
129 | DefaultAxisAlignedBoxSceneQuery::~DefaultAxisAlignedBoxSceneQuery()
|
---|
130 | {
|
---|
131 | }
|
---|
132 | //---------------------------------------------------------------------
|
---|
133 | void DefaultAxisAlignedBoxSceneQuery::execute(SceneQueryListener* listener)
|
---|
134 | {
|
---|
135 | // Iterate over all movable types
|
---|
136 | Root::MovableObjectFactoryIterator factIt =
|
---|
137 | Root::getSingleton().getMovableObjectFactoryIterator();
|
---|
138 | while(factIt.hasMoreElements())
|
---|
139 | {
|
---|
140 | SceneManager::MovableObjectIterator objItA =
|
---|
141 | mParentSceneMgr->getMovableObjectIterator(
|
---|
142 | factIt.getNext()->getType());
|
---|
143 | while (objItA.hasMoreElements())
|
---|
144 | {
|
---|
145 | MovableObject* a = objItA.getNext();
|
---|
146 | // skip whole group if type doesn't match
|
---|
147 | if (!(a->getTypeFlags() & mQueryTypeMask))
|
---|
148 | break;
|
---|
149 |
|
---|
150 | if ((a->getQueryFlags() & mQueryMask) &&
|
---|
151 | a->isInScene() &&
|
---|
152 | mAABB.intersects(a->getWorldBoundingBox()))
|
---|
153 | {
|
---|
154 | if (!listener->queryResult(a)) return;
|
---|
155 | }
|
---|
156 | }
|
---|
157 | }
|
---|
158 | }
|
---|
159 | //---------------------------------------------------------------------
|
---|
160 | DefaultRaySceneQuery::
|
---|
161 | DefaultRaySceneQuery(SceneManager* creator) : RaySceneQuery(creator)
|
---|
162 | {
|
---|
163 | // No world geometry results supported
|
---|
164 | mSupportedWorldFragments.insert(SceneQuery::WFT_NONE);
|
---|
165 | }
|
---|
166 | //---------------------------------------------------------------------
|
---|
167 | DefaultRaySceneQuery::~DefaultRaySceneQuery()
|
---|
168 | {
|
---|
169 | }
|
---|
170 | //---------------------------------------------------------------------
|
---|
171 | void DefaultRaySceneQuery::execute(RaySceneQueryListener* listener)
|
---|
172 | {
|
---|
173 | // Note that becuase we have no scene partitioning, we actually
|
---|
174 | // perform a complete scene search even if restricted results are
|
---|
175 | // requested; smarter scene manager queries can utilise the paritioning
|
---|
176 | // of the scene in order to reduce the number of intersection tests
|
---|
177 | // required to fulfil the query
|
---|
178 |
|
---|
179 | // Iterate over all movable types
|
---|
180 | Root::MovableObjectFactoryIterator factIt =
|
---|
181 | Root::getSingleton().getMovableObjectFactoryIterator();
|
---|
182 | while(factIt.hasMoreElements())
|
---|
183 | {
|
---|
184 | SceneManager::MovableObjectIterator objItA =
|
---|
185 | mParentSceneMgr->getMovableObjectIterator(
|
---|
186 | factIt.getNext()->getType());
|
---|
187 | while (objItA.hasMoreElements())
|
---|
188 | {
|
---|
189 | MovableObject* a = objItA.getNext();
|
---|
190 | // skip whole group if type doesn't match
|
---|
191 | if (!(a->getTypeFlags() & mQueryTypeMask))
|
---|
192 | break;
|
---|
193 |
|
---|
194 | if( (a->getQueryFlags() & mQueryMask) &&
|
---|
195 | a->isInScene())
|
---|
196 | {
|
---|
197 | // Do ray / box test
|
---|
198 | std::pair<bool, Real> result =
|
---|
199 | mRay.intersects(a->getWorldBoundingBox());
|
---|
200 |
|
---|
201 | if (result.first)
|
---|
202 | {
|
---|
203 | if (!listener->queryResult(a, result.second)) return;
|
---|
204 | }
|
---|
205 | }
|
---|
206 | }
|
---|
207 | }
|
---|
208 |
|
---|
209 | }
|
---|
210 | //---------------------------------------------------------------------
|
---|
211 | DefaultSphereSceneQuery::
|
---|
212 | DefaultSphereSceneQuery(SceneManager* creator) : SphereSceneQuery(creator)
|
---|
213 | {
|
---|
214 | // No world geometry results supported
|
---|
215 | mSupportedWorldFragments.insert(SceneQuery::WFT_NONE);
|
---|
216 | }
|
---|
217 | //---------------------------------------------------------------------
|
---|
218 | DefaultSphereSceneQuery::~DefaultSphereSceneQuery()
|
---|
219 | {
|
---|
220 | }
|
---|
221 | //---------------------------------------------------------------------
|
---|
222 | void DefaultSphereSceneQuery::execute(SceneQueryListener* listener)
|
---|
223 | {
|
---|
224 | Sphere testSphere;
|
---|
225 |
|
---|
226 | // Iterate over all movable types
|
---|
227 | Root::MovableObjectFactoryIterator factIt =
|
---|
228 | Root::getSingleton().getMovableObjectFactoryIterator();
|
---|
229 | while(factIt.hasMoreElements())
|
---|
230 | {
|
---|
231 | SceneManager::MovableObjectIterator objItA =
|
---|
232 | mParentSceneMgr->getMovableObjectIterator(
|
---|
233 | factIt.getNext()->getType());
|
---|
234 | while (objItA.hasMoreElements())
|
---|
235 | {
|
---|
236 | MovableObject* a = objItA.getNext();
|
---|
237 | // skip whole group if type doesn't match
|
---|
238 | if (!(a->getTypeFlags() & mQueryTypeMask))
|
---|
239 | break;
|
---|
240 | // Skip unattached
|
---|
241 | if (!a->isInScene() ||
|
---|
242 | !(a->getQueryFlags() & mQueryMask))
|
---|
243 | continue;
|
---|
244 |
|
---|
245 | // Do sphere / sphere test
|
---|
246 | testSphere.setCenter(a->getParentNode()->_getDerivedPosition());
|
---|
247 | testSphere.setRadius(a->getBoundingRadius());
|
---|
248 | if (mSphere.intersects(testSphere))
|
---|
249 | {
|
---|
250 | if (!listener->queryResult(a)) return;
|
---|
251 | }
|
---|
252 | }
|
---|
253 | }
|
---|
254 | }
|
---|
255 | //---------------------------------------------------------------------
|
---|
256 | DefaultPlaneBoundedVolumeListSceneQuery::
|
---|
257 | DefaultPlaneBoundedVolumeListSceneQuery(SceneManager* creator)
|
---|
258 | : PlaneBoundedVolumeListSceneQuery(creator)
|
---|
259 | {
|
---|
260 | // No world geometry results supported
|
---|
261 | mSupportedWorldFragments.insert(SceneQuery::WFT_NONE);
|
---|
262 | }
|
---|
263 | //---------------------------------------------------------------------
|
---|
264 | DefaultPlaneBoundedVolumeListSceneQuery::~DefaultPlaneBoundedVolumeListSceneQuery()
|
---|
265 | {
|
---|
266 | }
|
---|
267 | //---------------------------------------------------------------------
|
---|
268 | void DefaultPlaneBoundedVolumeListSceneQuery::execute(SceneQueryListener* listener)
|
---|
269 | {
|
---|
270 | // Iterate over all movable types
|
---|
271 | Root::MovableObjectFactoryIterator factIt =
|
---|
272 | Root::getSingleton().getMovableObjectFactoryIterator();
|
---|
273 | while(factIt.hasMoreElements())
|
---|
274 | {
|
---|
275 | SceneManager::MovableObjectIterator objItA =
|
---|
276 | mParentSceneMgr->getMovableObjectIterator(
|
---|
277 | factIt.getNext()->getType());
|
---|
278 | while (objItA.hasMoreElements())
|
---|
279 | {
|
---|
280 | MovableObject* a = objItA.getNext();
|
---|
281 | // skip whole group if type doesn't match
|
---|
282 | if (!(a->getTypeFlags() & mQueryTypeMask))
|
---|
283 | break;
|
---|
284 |
|
---|
285 | PlaneBoundedVolumeList::iterator pi, piend;
|
---|
286 | piend = mVolumes.end();
|
---|
287 | for (pi = mVolumes.begin(); pi != piend; ++pi)
|
---|
288 | {
|
---|
289 | PlaneBoundedVolume& vol = *pi;
|
---|
290 | // Do AABB / plane volume test
|
---|
291 | if ((a->getQueryFlags() & mQueryMask) &&
|
---|
292 | a->isInScene() &&
|
---|
293 | vol.intersects(a->getWorldBoundingBox()))
|
---|
294 | {
|
---|
295 | if (!listener->queryResult(a)) return;
|
---|
296 | break;
|
---|
297 | }
|
---|
298 | }
|
---|
299 | }
|
---|
300 | }
|
---|
301 | }
|
---|
302 | }
|
---|