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

Revision 1621, 8.5 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        /** find object which fits best to this bounding box
69        */
70        Entity *FindBestFittingObject(const AxisAlignedBox &box) const;
71       
72        /** find objects which are intersected by this box
73        */
74        void FindIntersectingObjects(const AxisAlignedBox &box,
75                                                                 vector<Entity *> &objects) const;
76
77        T *mSceneMgr;
78};
79
80//-------------------------------------------------------------------------
81template<typename T>
82PlatFormBoundingBoxConverter<T>::PlatFormBoundingBoxConverter(T *sm):
83mSceneMgr(sm)
84{
85}
86//-----------------------------------------------------------------------
87template<typename T>
88Entity *PlatFormBoundingBoxConverter<T>::FindBestFittingObject(const AxisAlignedBox &box) const
89{
90        list<SceneNode *> sceneNodeList;
91        AxisAlignedBox mybox = EnlargeBox(box);
92               
93        // get intersecting scene nodes
94        mSceneMgr->findNodesIn(mybox, sceneNodeList, NULL);
95               
96        // minimal overlap
97        float overlap = 0;//1e-6;
98
99        Entity *bestFittingObj = NULL;
100        float bestFit = overlap;
101
102        // perfect fit threshold
103        const float thresh = 1.0 - GtpVisibilityPreprocessor::Limits::Small;
104
105        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
106        // find the bbox which is closest to the current bbox
107        for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(); ++ sit)
108        {
109                SceneNode *sn = *sit;
110                SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator();
111
112        while (oit.hasMoreElements())
113                {
114                        MovableObject *mo = oit.getNext();
115
116                        // we are only interested in scene entities
117                        if (mo->getMovableType() != "Entity")
118                        {
119                                continue;
120                        }
121                         mo->
122                        const AxisAlignedBox bbox = EnlargeBox(mo->getWorldBoundingBox());
123                                       
124                        // compute measure how much aabbs overlap
125                        overlap = RatioOfOverlap(OgreTypeConverter::ConvertFromOgre(mybox),
126                                                                         OgreTypeConverter::ConvertFromOgre(bbox));
127       
128                         if (overlap > bestFit)
129                         {
130                                 bestFit = overlap;
131                                 bestFittingObj = static_cast<Entity *>(mo);
132
133                                 // perfect fit => object found, early exit
134                                 if (overlap >= thresh)
135                                 {
136                                         return bestFittingObj;
137                                 }
138                         }
139                }
140        }
141
142        if (0)
143        {
144                std::stringstream d;
145                if (bestFittingObj)
146                        d << "best fit: " << bestFit;     
147                else
148                        d << "warning, no best fitting object\n" << box;
149       
150                Ogre::LogManager::getSingleton().logMessage(d.str());
151        }
152
153        return bestFittingObj;
154}
155//-----------------------------------------------------------------------
156template<typename T>
157void PlatFormBoundingBoxConverter<T>::FindIntersectingObjects(const AxisAlignedBox &box,
158                                                                                                                          EntityContainer &objects) const
159{//return;
160        list<SceneNode *> sceneNodeList;
161                       
162        // get intersecting scene nodes (= candidates)
163        //AxisAlignedBox mybox = EnlargeBox(box);
164        //mSceneMgr->findNodesIn(mybox, sceneNodeList, NULL);
165        mSceneMgr->findNodesIn(box, sceneNodeList, NULL);
166
167        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
168
169        //GtpVisibilityPreprocessor::AxisAlignedBox nodeBox = OgreTypeConverter::ConvertFromOgre(mybox);
170        GtpVisibilityPreprocessor::AxisAlignedBox3 nodeBox = OgreTypeConverter::ConvertFromOgre(box);
171
172        // find really intersecting objects
173        for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(); ++ sit)
174        {
175                SceneNode *sn = *sit;
176                SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator();
177
178        while (oit.hasMoreElements())
179                {
180                        MovableObject *mo = oit.getNext();
181
182                        // we are only interested in scene entities
183                        if (mo->getMovableType() != "Entity")
184                        {
185                                continue;
186                        }
187                         
188                        //const AxisAlignedBox bbox = EnlargeBox(mo->getWorldBoundingBox());
189                        const AxisAlignedBox bbox = mo->getWorldBoundingBox();
190
191                        const bool overlaps = Overlap(nodeBox,
192                                                                                  OgreTypeConverter::ConvertFromOgre(bbox)
193                                                                                  );
194                                                                                  //,0.00001);
195       
196                         if (overlaps)
197                         {
198                                 objects.push_back(static_cast<Entity *>(mo));
199                         }
200                }
201        }
202}
203
204#if USE_KD_PVS
205//-------------------------------------------------------------------------
206template<typename T>
207bool PlatFormBoundingBoxConverter<T>::IdentifyObjects(
208        const GtpVisibilityPreprocessor::IndexedBoundingBoxContainer &iboxes,
209        GtpVisibilityPreprocessor::ObjectContainer &objects) const
210{
211        //Ogre::LogManager().logMessage("pvs: intersecting objects");
212        const long startTime = GtpVisibilityPreprocessor::GetTime();
213
214        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer::
215                const_iterator iit, iit_end = iboxes.end();
216 
217        int i = 0;
218
219        for (iit = iboxes.begin(); iit != iit_end; ++ iit, ++ i)
220        {
221                if (0 && ((i % 1000) == 0))
222                {
223                        std::stringstream d; d << "found " << i << " objects";
224                        Ogre::LogManager().getSingleton().logMessage(d.str());
225                }
226
227                const AxisAlignedBox box = OgreTypeConverter::ConvertToOgre((*iit).second);
228               
229                //GtpVisibilityPreprocessor::ObjectContainer *entryObjects = new EntityContainer();
230                EntityContainer *entryObjects = new EntityContainer();
231
232                // find all objects that intersect the bounding box
233                FindIntersectingObjects(box, *entryObjects);
234
235                /*vector<Entity *>::const_iterator mit, mit_end = sceneObjects.end();
236               
237                for (mit = sceneObjects.begin(); mit != mit_end; ++ mit)
238                {
239                        Entity *ent = *mit;
240                        // create new mesh instance
241                        OgreMeshInstance *omi = new OgreGetOrCreateOgreMeshInstance(ent);
242                        //omi->SetId((*iit).first);
243                        entryObjects->push_back(omi);
244                }*/
245
246                ObjectsIntersectable *entry =
247                        new ObjectsIntersectable(entryObjects);
248                entry->SetId((*iit).first);
249                //kdObj->mBbox = (*iit).second;
250                objects.push_back(entry);
251        }
252
253        //std::stringstream d; d << "finished object intersection in " << GtpVisibilityPreprocessor::TimeDiff(startTime, GtpVisibilityPreprocessor::GetTime()) * 1e-3 << "secs";
254        //Ogre::LogManager().logMessage(d.str());
255
256        return true;
257}
258#else
259//-------------------------------------------------------------------------
260template<typename T>
261bool PlatFormBoundingBoxConverter<T>::IdentifyObjects(
262        const GtpVisibilityPreprocessor::IndexedBoundingBoxContainer &iboxes,
263        GtpVisibilityPreprocessor::ObjectContainer &objects) const
264{
265        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer::
266                const_iterator iit, iit_end = iboxes.end();
267 
268        for (iit = iboxes.begin(); iit != iit_end; ++ iit)
269        {
270                const GtpVisibilityPreprocessor::AxisAlignedBox3 box = (*iit).second;
271                const AxisAlignedBox currentBox = OgreTypeConverter::ConvertToOgre(box);
272   
273                Entity *ent = FindBestFittingObject(currentBox);
274
275                if (ent)
276                {
277                        // create new mesh instance
278                        OgreMeshInstance *omi = new OgreMeshInstance(ent);
279                        omi->SetId((*iit).first);
280                        objects.push_back(omi);
281                }
282        }
283
284        return true;
285}
286#endif
287
288typedef PlatFormBoundingBoxConverter<OctreeSceneManager> OctreeBoundingBoxConverter;
289typedef PlatFormBoundingBoxConverter<BvHierarchySceneManager> BvhBoundingBoxConverter;
290typedef PlatFormBoundingBoxConverter<KdTreeSceneManager> KdTreeBoundingBoxConverter;
291
292} // namespace Ogre
293
294#endif // PlatFormBoundingBoxConverter
Note: See TracBrowser for help on using the repository browser.