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

Revision 2115, 8.9 KB checked in by mattausch, 17 years ago (diff)

changed pvs loading: loading objects in a first pass

RevLine 
[2069]1#ifndef _PlatformBoundingBoxConverter_H__
2#define _PlatformBoundingBoxConverter_H__
[933]3 
4#include "OgreAxisAlignedBox.h"
5#include "AxisAlignedBox3.h"
6#include "Vector3.h"
7#include "BoundingBoxConverter.h"
8#include "Containers.h"
[1616]9#include "IntersectableWrapper.h"
[933]10
[1616]11
[933]12namespace Ogre {
13
[1616]14#define USE_KD_PVS 1
[2111]15
[933]16class Entity;
17class OctreeSceneManager;
[1296]18class KdTreeSceneManager;
[1595]19class BvHierarchySceneManager;
[933]20
[1616]21typedef vector<Entity *> EntityContainer;
[1595]22
[2066]23class EngineIntersectable: public GtpVisibilityPreprocessor::IntersectableWrapper<EntityContainer *>
[1616]24{
25public:
[2066]26        EngineIntersectable(EntityContainer *item):
[1616]27        GtpVisibilityPreprocessor::IntersectableWrapper<EntityContainer *>(item) {}
28
29        // hack
[2066]30        EngineIntersectable::~EngineIntersectable()
[1616]31        {
32                delete mItem;
33        }
34
35        int Type() const
36        {
[2066]37                return Intersectable::ENGINE_INTERSECTABLE;
[1616]38        }
39};
40
[2115]41
[933]42/**     Class which converts preprocessor types to OGRE types
43*/
[1595]44template<typename T>
45class __declspec(dllexport) PlatFormBoundingBoxConverter: public GtpVisibilityPreprocessor::BoundingBoxConverter
[933]46{
47public:
[1595]48        PlatFormBoundingBoxConverter(T *sm);
49       
[933]50        bool IdentifyObjects(const GtpVisibilityPreprocessor::IndexedBoundingBoxContainer &iboxes,
51                                                 GtpVisibilityPreprocessor::ObjectContainer &objects) const;
52
53
54protected:
55
[1595]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();
[933]64
[1595]65                return AxisAlignedBox(min - veps, max + veps);
66        }
67       
[1623]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        }
[1616]83        /** find object which fits best to this bounding box
84        */
[1595]85        Entity *FindBestFittingObject(const AxisAlignedBox &box) const;
[1616]86       
87        /** find objects which are intersected by this box
88        */
89        void FindIntersectingObjects(const AxisAlignedBox &box,
90                                                                 vector<Entity *> &objects) const;
[1595]91
[2066]92        /// this can be any scene manager
[1595]93        T *mSceneMgr;
[933]94};
95
[1595]96//-------------------------------------------------------------------------
97template<typename T>
98PlatFormBoundingBoxConverter<T>::PlatFormBoundingBoxConverter(T *sm):
99mSceneMgr(sm)
100{
101}
102//-----------------------------------------------------------------------
103template<typename T>
104Entity *PlatFormBoundingBoxConverter<T>::FindBestFittingObject(const AxisAlignedBox &box) const
105{
106        list<SceneNode *> sceneNodeList;
[1623]107        AxisAlignedBox3 enlargedBox =
[1595]108        AxisAlignedBox mybox = EnlargeBox(box);
109               
110        // get intersecting scene nodes
[2066]111        // note: this function must be provided by scene manager
[1595]112        mSceneMgr->findNodesIn(mybox, sceneNodeList, NULL);
113               
114        // minimal overlap
115        float overlap = 0;//1e-6;
116
117        Entity *bestFittingObj = NULL;
118        float bestFit = overlap;
119
120        // perfect fit threshold
121        const float thresh = 1.0 - GtpVisibilityPreprocessor::Limits::Small;
122
123        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
[2115]124
[1595]125        // find the bbox which is closest to the current bbox
[2113]126        for (sit = sceneNodeList.begin(); sit != sit_end; ++ sit)
[1595]127        {
128                SceneNode *sn = *sit;
129                SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator();
130
131        while (oit.hasMoreElements())
132                {
133                        MovableObject *mo = oit.getNext();
134
135                        // we are only interested in scene entities
136                        if (mo->getMovableType() != "Entity")
137                        {
138                                continue;
139                        }
[1676]140                         
[1595]141                        const AxisAlignedBox bbox = EnlargeBox(mo->getWorldBoundingBox());
142                                       
143                        // compute measure how much aabbs overlap
144                        overlap = RatioOfOverlap(OgreTypeConverter::ConvertFromOgre(mybox),
145                                                                         OgreTypeConverter::ConvertFromOgre(bbox));
146       
147                         if (overlap > bestFit)
148                         {
149                                 bestFit = overlap;
150                                 bestFittingObj = static_cast<Entity *>(mo);
151
152                                 // perfect fit => object found, early exit
153                                 if (overlap >= thresh)
154                                 {
155                                         return bestFittingObj;
156                                 }
157                         }
158                }
159        }
160
161        if (0)
162        {
163                std::stringstream d;
164                if (bestFittingObj)
165                        d << "best fit: " << bestFit;     
166                else
167                        d << "warning, no best fitting object\n" << box;
168       
169                Ogre::LogManager::getSingleton().logMessage(d.str());
170        }
171
172        return bestFittingObj;
173}
[2066]174
175
176#define ENLARGE_OBJECT_BBOX 0
[2069]177#define ENLRAGE_NODE_BBOX 0
178
[2066]179template<typename T>
[1623]180void PlatFormBoundingBoxConverter<T>::FindIntersectingObjects(const AxisAlignedBox &box,
181                                                                                                                          EntityContainer &objects) const
[2066]182{
[1623]183        list<SceneNode *> sceneNodeList;
[2097]184
[2066]185        // find intersecting scene nodes to get candidates for intersection
186    // note: this function has to be provided by scene manager
[2097]187
[2066]188#if ENLARGE_NODE_BBOX
189        // make search radius larger
[2097]190        AxisAlignedBox largebox = EnlargeBox(box);
191        mSceneMgr->findNodesIn(largebox, sceneNodeList, NULL);
[1623]192
193        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
194
[2066]195        GtpVisibilityPreprocessor::AxisAlignedBox3 nodeBox =
[2097]196                OgreTypeConverter::ConvertFromOgre(largebox);
[2066]197#else
[1623]198
[1616]199        mSceneMgr->findNodesIn(box, sceneNodeList, NULL);
200
[2069]201        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
202
[2066]203        GtpVisibilityPreprocessor::AxisAlignedBox3 nodeBox =
204                OgreTypeConverter::ConvertFromOgre(box);
205#endif
[2097]206
[2066]207        // loop through the intersected scene nodes
[1616]208        for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(); ++ sit)
209        {
210                SceneNode *sn = *sit;
211                SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator();
212
[2066]213                // find the objects that intersect the box
[1616]214        while (oit.hasMoreElements())
215                {
216                        MovableObject *mo = oit.getNext();
217
218                        // we are only interested in scene entities
219                        if (mo->getMovableType() != "Entity")
220                                continue;
[2066]221                       
222                        // get the bounding box of the objects
[2069]223#if ENLARGE_OBJECT_BBOX
[2066]224                        // compare with enlarged entitiy box
225                        const AxisAlignedBox bbox = EnlargeBox(mo->getWorldBoundingBox());
226#else
[1616]227                        const AxisAlignedBox bbox = mo->getWorldBoundingBox();
[2066]228#endif
[1616]229
[2066]230                        // test for intersection (note: function provided of preprocessor)
231                        if (Overlap(nodeBox, OgreTypeConverter::ConvertFromOgre(bbox)))
232                        {
233                                objects.push_back(static_cast<Entity *>(mo));
234                        }
[1616]235                }
236        }
237}
[2097]238
[1616]239#if USE_KD_PVS
[1595]240//-------------------------------------------------------------------------
241template<typename T>
242bool PlatFormBoundingBoxConverter<T>::IdentifyObjects(
243        const GtpVisibilityPreprocessor::IndexedBoundingBoxContainer &iboxes,
244        GtpVisibilityPreprocessor::ObjectContainer &objects) const
245{
246        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer::
247                const_iterator iit, iit_end = iboxes.end();
248 
[2066]249        for (iit = iboxes.begin(); iit != iit_end; ++ iit)
[1616]250        {
[2115]251                const GtpVisibilityPreprocessor::AxisAlignedBox3 pbox = (*iit).second;
252                const int id = (*iit).first;
253
[2066]254                const AxisAlignedBox box =
[2115]255                        OgreTypeConverter::ConvertToOgre(pbox);
[1616]256               
[2115]257                EntityContainer entryObjects;
[1616]258
259                // find all objects that intersect the bounding box
[2115]260                FindIntersectingObjects(box, entryObjects);
[1616]261
[2115]262                // TODO: can actually just put single objects into pvs with same id,
263                // this can be sorted out later!!
264#if 1
265                EntityContainer::const_iterator eit, eit_end = entryObjects.end();
266
267                for (eit = entryObjects.begin(); eit != eit_end; ++ eit)
268                {
269                        Entity *ent = *eit;
270
271            // warning: multiple ids possible
272                        OgreMeshInstance *omi = new OgreMeshInstance(ent);
273                        omi->SetId(id);
274                        objects.push_back(omi);
275                }
276#else
[2066]277                EngineIntersectable *entry =
278                        new EngineIntersectable(entryObjects);
[2097]279
[2115]280                entry->SetId(id);
[1616]281                objects.push_back(entry);
[2115]282#endif
[1616]283        }
284
285        return true;
286}
[2115]287
[1616]288#else
[2115]289
[1616]290//-------------------------------------------------------------------------
291template<typename T>
292bool PlatFormBoundingBoxConverter<T>::IdentifyObjects(
293        const GtpVisibilityPreprocessor::IndexedBoundingBoxContainer &iboxes,
294        GtpVisibilityPreprocessor::ObjectContainer &objects) const
295{
296        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer::
297                const_iterator iit, iit_end = iboxes.end();
298 
[1595]299        for (iit = iboxes.begin(); iit != iit_end; ++ iit)
300        {
301                const GtpVisibilityPreprocessor::AxisAlignedBox3 box = (*iit).second;
302                const AxisAlignedBox currentBox = OgreTypeConverter::ConvertToOgre(box);
303   
304                Entity *ent = FindBestFittingObject(currentBox);
[2066]305                if (!ent) continue;
306               
307                // create new mesh instance
308                OgreMeshInstance *omi = new OgreMeshInstance(ent);
309                omi->SetId((*iit).first);
310                objects.push_back(omi);
[1595]311        }
312
313        return true;
314}
[1616]315#endif
[1595]316
317typedef PlatFormBoundingBoxConverter<OctreeSceneManager> OctreeBoundingBoxConverter;
318typedef PlatFormBoundingBoxConverter<BvHierarchySceneManager> BvhBoundingBoxConverter;
319typedef PlatFormBoundingBoxConverter<KdTreeSceneManager> KdTreeBoundingBoxConverter;
320
[933]321} // namespace Ogre
322
[1595]323#endif // PlatFormBoundingBoxConverter
Note: See TracBrowser for help on using the repository browser.