source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreBoundingBoxConverter.h @ 1623

Revision 1623, 10.4 KB checked in by mattausch, 18 years ago (diff)
Line 
1#ifndef _PlatFormBoundingBoxConverter_H__
2#define _PlatFormBoundingBoxConverter_H__
3 
4#include "OgreAxisAlignedBox.h"
5#include "AxisAlignedBox3.h"
6#include "Vector3.h"
7#include "BoundingBoxConverter.h"
8#include "Containers.h"
9#include "IntersectableWrapper.h"
10//#include "KdTree.h"
11
12
13namespace Ogre {
14
15#define USE_KD_PVS 1
16class Entity;
17class OctreeSceneManager;
18class KdTreeSceneManager;
19class BvHierarchySceneManager;
20
21typedef vector<Entity *> EntityContainer;
22
23class ObjectsIntersectable: public GtpVisibilityPreprocessor::IntersectableWrapper<EntityContainer *>
24{
25public:
26        ObjectsIntersectable(EntityContainer *item):
27        GtpVisibilityPreprocessor::IntersectableWrapper<EntityContainer *>(item) {}
28
29        // hack
30        ObjectsIntersectable::~ObjectsIntersectable()
31        {
32                //CLEAR_CONTAINER(*mItem);
33                delete mItem;
34        }
35
36        int Type() const
37        {
38                return Intersectable::OBJECTS_INTERSECTABLE;
39        }
40};
41
42/**     Class which converts preprocessor types to OGRE types
43*/
44template<typename T>
45class __declspec(dllexport) PlatFormBoundingBoxConverter: public GtpVisibilityPreprocessor::BoundingBoxConverter
46{
47public:
48        PlatFormBoundingBoxConverter(T *sm);
49       
50        bool IdentifyObjects(const GtpVisibilityPreprocessor::IndexedBoundingBoxContainer &iboxes,
51                                                 GtpVisibilityPreprocessor::ObjectContainer &objects) const;
52
53
54protected:
55
56        //-------------------------------------------------------------------------
57        inline static AxisAlignedBox EnlargeBox(const AxisAlignedBox &box)
58        {
59                const float eps = 1e-3f;
60                const Vector3 veps(eps, eps, eps);
61               
62                Vector3 max = box.getMaximum();
63        Vector3 min = box.getMinimum();
64
65                return AxisAlignedBox(min - veps, max + veps);
66        }
67       
68        //-------------------------------------------------------------------------
69        inline static AxisAlignedBox ScaleBox(const AxisAlignedBox &box)
70        {
71                const float scale = 1.5f;
72        Vector3 max = box.getMaximum();
73        Vector3 min = box.getMinimum();
74                Vector3 size = max - min;
75                Vector3 newSize = size*(scale*0.5f);
76                Vector3 center = 0.5f * (min + max);
77
78                Vector3 min = center - newSize;
79                Vector3 max = center + newSize;
80
81                return AxisAlignedBox(min, max);
82        }
83        /** find object which fits best to this bounding box
84        */
85        Entity *FindBestFittingObject(const AxisAlignedBox &box) const;
86       
87        /** find objects which are intersected by this box
88        */
89        void FindIntersectingObjects(const AxisAlignedBox &box,
90                                                                 vector<Entity *> &objects) const;
91
92        T *mSceneMgr;
93};
94
95//-------------------------------------------------------------------------
96template<typename T>
97PlatFormBoundingBoxConverter<T>::PlatFormBoundingBoxConverter(T *sm):
98mSceneMgr(sm)
99{
100}
101//-----------------------------------------------------------------------
102template<typename T>
103Entity *PlatFormBoundingBoxConverter<T>::FindBestFittingObject(const AxisAlignedBox &box) const
104{
105        list<SceneNode *> sceneNodeList;
106        AxisAlignedBox3 enlargedBox =
107        AxisAlignedBox mybox = EnlargeBox(box);
108               
109        // get intersecting scene nodes
110        mSceneMgr->findNodesIn(mybox, sceneNodeList, NULL);
111               
112        // minimal overlap
113        float overlap = 0;//1e-6;
114
115        Entity *bestFittingObj = NULL;
116        float bestFit = overlap;
117
118        // perfect fit threshold
119        const float thresh = 1.0 - GtpVisibilityPreprocessor::Limits::Small;
120
121        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
122        // find the bbox which is closest to the current bbox
123        for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(); ++ sit)
124        {
125                SceneNode *sn = *sit;
126                SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator();
127
128        while (oit.hasMoreElements())
129                {
130                        MovableObject *mo = oit.getNext();
131
132                        // we are only interested in scene entities
133                        if (mo->getMovableType() != "Entity")
134                        {
135                                continue;
136                        }
137                         mo->
138                        const AxisAlignedBox bbox = EnlargeBox(mo->getWorldBoundingBox());
139                                       
140                        // compute measure how much aabbs overlap
141                        overlap = RatioOfOverlap(OgreTypeConverter::ConvertFromOgre(mybox),
142                                                                         OgreTypeConverter::ConvertFromOgre(bbox));
143       
144                         if (overlap > bestFit)
145                         {
146                                 bestFit = overlap;
147                                 bestFittingObj = static_cast<Entity *>(mo);
148
149                                 // perfect fit => object found, early exit
150                                 if (overlap >= thresh)
151                                 {
152                                         return bestFittingObj;
153                                 }
154                         }
155                }
156        }
157
158        if (0)
159        {
160                std::stringstream d;
161                if (bestFittingObj)
162                        d << "best fit: " << bestFit;     
163                else
164                        d << "warning, no best fitting object\n" << box;
165       
166                Ogre::LogManager::getSingleton().logMessage(d.str());
167        }
168
169        return bestFittingObj;
170}
171//-----------------------------------------------------------------------
172/*template<typename T>
173void PlatFormBoundingBoxConverter<T>::FindIntersectingObjects(const AxisAlignedBox &box,
174                                                                                                                          EntityContainer &objects) const
175{//return;
176        list<SceneNode *> sceneNodeList;
177                       
178        // get intersecting scene nodes (= candidates)
179        AxisAlignedBox mybox = EnlargeBox(box);
180        mSceneMgr->findNodesIn(mybox, sceneNodeList, NULL);
181        //mSceneMgr->findNodesIn(box, sceneNodeList, NULL);
182
183        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
184
185        GtpVisibilityPreprocessor::AxisAlignedBox3 nodeBox = OgreTypeConverter::ConvertFromOgre(mybox);
186        //GtpVisibilityPreprocessor::AxisAlignedBox3 nodeBox = OgreTypeConverter::ConvertFromOgre(box);
187
188        // find really intersecting objects
189        for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(); ++ sit)
190        {
191                SceneNode *sn = *sit;
192                SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator();
193
194        while (oit.hasMoreElements())
195                {
196                        MovableObject *mo = oit.getNext();
197
198                        // we are only interested in scene entities
199                        if (mo->getMovableType() != "Entity")
200                        {
201                                continue;
202                        }
203                         
204                        //const AxisAlignedBox bbox = EnlargeBox(mo->getWorldBoundingBox());
205                        const AxisAlignedBox bbox = mo->getWorldBoundingBox();
206
207                        const bool overlaps = Overlap(nodeBox,
208                                                                                  OgreTypeConverter::ConvertFromOgre(bbox)
209                                                                                  );
210                                                                                  //,0.00001);
211       
212                         if (overlaps)
213                         {
214                                 objects.push_back(static_cast<Entity *>(mo));
215                         }
216                }
217        }
218}
219*/
220template<typename T>
221void PlatFormBoundingBoxConverter<T>::FindIntersectingObjects(const AxisAlignedBox &box,
222                                                                                                                          EntityContainer &objects) const
223{//return;
224        list<SceneNode *> sceneNodeList;
225                       
226        // get intersecting scene nodes (= candidates)
227        AxisAlignedBox mybox = EnlargeBox(box);
228        //mSceneMgr->findNodesIn(mybox, sceneNodeList, NULL);
229        mSceneMgr->findNodesIn(box, sceneNodeList, NULL);
230
231        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
232
233        //GtpVisibilityPreprocessor::AxisAlignedBox3 nodeBox = OgreTypeConverter::ConvertFromOgre(mybox);
234        GtpVisibilityPreprocessor::AxisAlignedBox3 nodeBox = OgreTypeConverter::ConvertFromOgre(box);
235
236        // find really intersecting objects
237        for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(); ++ sit)
238        {
239                SceneNode *sn = *sit;
240                SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator();
241
242        while (oit.hasMoreElements())
243                {
244                        MovableObject *mo = oit.getNext();
245
246                        // we are only interested in scene entities
247                        if (mo->getMovableType() != "Entity")
248                        {
249                                continue;
250                        }
251                         
252                        //const AxisAlignedBox bbox = EnlargeBox(mo->getWorldBoundingBox());
253                        const AxisAlignedBox bbox = mo->getWorldBoundingBox();
254
255                        const bool overlaps = Overlap(nodeBox,
256                                                                                  OgreTypeConverter::ConvertFromOgre(bbox)
257                                                                                  );
258                                                                                  //,0.00001);
259       
260                         if (overlaps)
261                         {
262                                 objects.push_back(static_cast<Entity *>(mo));
263                         }
264                }
265        }
266}
267#if USE_KD_PVS
268//-------------------------------------------------------------------------
269template<typename T>
270bool PlatFormBoundingBoxConverter<T>::IdentifyObjects(
271        const GtpVisibilityPreprocessor::IndexedBoundingBoxContainer &iboxes,
272        GtpVisibilityPreprocessor::ObjectContainer &objects) const
273{
274        //Ogre::LogManager().logMessage("pvs: intersecting objects");
275        const long startTime = GtpVisibilityPreprocessor::GetTime();
276
277        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer::
278                const_iterator iit, iit_end = iboxes.end();
279 
280        int i = 0;
281
282        for (iit = iboxes.begin(); iit != iit_end; ++ iit, ++ i)
283        {
284                if (0 && ((i % 1000) == 0))
285                {
286                        std::stringstream d; d << "found " << i << " objects";
287                        Ogre::LogManager().getSingleton().logMessage(d.str());
288                }
289
290                const AxisAlignedBox box = OgreTypeConverter::ConvertToOgre((*iit).second);
291               
292                //GtpVisibilityPreprocessor::ObjectContainer *entryObjects = new EntityContainer();
293                EntityContainer *entryObjects = new EntityContainer();
294
295                // find all objects that intersect the bounding box
296                FindIntersectingObjects(box, *entryObjects);
297
298                /*vector<Entity *>::const_iterator mit, mit_end = sceneObjects.end();
299               
300                for (mit = sceneObjects.begin(); mit != mit_end; ++ mit)
301                {
302                        Entity *ent = *mit;
303                        // create new mesh instance
304                        OgreMeshInstance *omi = new OgreGetOrCreateOgreMeshInstance(ent);
305                        //omi->SetId((*iit).first);
306                        entryObjects->push_back(omi);
307                }*/
308
309                ObjectsIntersectable *entry =
310                        new ObjectsIntersectable(entryObjects);
311                entry->SetId((*iit).first);
312                //kdObj->mBbox = (*iit).second;
313                objects.push_back(entry);
314        }
315
316        //std::stringstream d; d << "finished object intersection in " << GtpVisibilityPreprocessor::TimeDiff(startTime, GtpVisibilityPreprocessor::GetTime()) * 1e-3 << "secs";
317        //Ogre::LogManager().logMessage(d.str());
318
319        return true;
320}
321#else
322//-------------------------------------------------------------------------
323template<typename T>
324bool PlatFormBoundingBoxConverter<T>::IdentifyObjects(
325        const GtpVisibilityPreprocessor::IndexedBoundingBoxContainer &iboxes,
326        GtpVisibilityPreprocessor::ObjectContainer &objects) const
327{
328        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer::
329                const_iterator iit, iit_end = iboxes.end();
330 
331        for (iit = iboxes.begin(); iit != iit_end; ++ iit)
332        {
333                const GtpVisibilityPreprocessor::AxisAlignedBox3 box = (*iit).second;
334                const AxisAlignedBox currentBox = OgreTypeConverter::ConvertToOgre(box);
335   
336                Entity *ent = FindBestFittingObject(currentBox);
337
338                if (ent)
339                {
340                        // create new mesh instance
341                        OgreMeshInstance *omi = new OgreMeshInstance(ent);
342                        omi->SetId((*iit).first);
343                        objects.push_back(omi);
344                }
345        }
346
347        return true;
348}
349#endif
350
351typedef PlatFormBoundingBoxConverter<OctreeSceneManager> OctreeBoundingBoxConverter;
352typedef PlatFormBoundingBoxConverter<BvHierarchySceneManager> BvhBoundingBoxConverter;
353typedef PlatFormBoundingBoxConverter<KdTreeSceneManager> KdTreeBoundingBoxConverter;
354
355} // namespace Ogre
356
357#endif // PlatFormBoundingBoxConverter
Note: See TracBrowser for help on using the repository browser.