source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp @ 2672

Revision 2672, 34.7 KB checked in by mattausch, 16 years ago (diff)

added obj version of full city

Line 
1// ---------------------------------------------------------------------------
2//  Includes for all the program files to see
3// ---------------------------------------------------------------------------
4#include <string.h>
5#include <stdlib.h>
6#include <iostream>
7#include <xercesc/util/PlatformUtils.hpp>
8
9// ---------------------------------------------------------------------------
10//  Includes
11// ---------------------------------------------------------------------------
12#include <xercesc/framework/StdInInputSource.hpp>
13#include <xercesc/parsers/SAXParser.hpp>
14#include <xercesc/util/OutOfMemoryException.hpp>
15
16// ---------------------------------------------------------------------------
17//  Includes
18// ---------------------------------------------------------------------------
19#include <xercesc/sax/AttributeList.hpp>
20#include <xercesc/sax/SAXParseException.hpp>
21#include <xercesc/sax/SAXException.hpp>
22
23#include "ViewCellsParser.h"
24
25#include "ViewCellsParserXerces.h"
26#include "Mesh.h"
27#include "VspBspTree.h"
28#include "ViewCellBsp.h"
29#include "ViewCellsManager.h"
30#include "GzFileInputSource.h"
31#include "OspTree.h"
32#include "VspTree.h"
33#include "KdTree.h"
34#include "BvHierarchy.h"
35#include "HierarchyManager.h"
36
37
38using namespace std;
39
40namespace GtpVisibilityPreprocessor {
41
42
43// ---------------------------------------------------------------------------
44//  Local data
45//
46//  doNamespaces
47//      Indicates whether namespace processing should be enabled or not.
48//      The default is no, but -n overrides that.
49//
50//  doSchema
51//      Indicates whether schema processing should be enabled or not.
52//      The default is no, but -s overrides that.
53//
54//  schemaFullChecking
55//      Indicates whether full schema constraint checking should be enabled or not.
56//      The default is no, but -s overrides that.
57//
58//  valScheme
59//      Indicates what validation scheme to use. It defaults to 'auto', but
60//      can be set via the -v= command.
61// ---------------------------------------------------------------------------
62static bool doNamespaces = false;
63static bool doSchema = false;
64static bool schemaFullChecking = false;
65static SAXParser::ValSchemes valScheme = SAXParser::Val_Auto;
66
67// hack for loading bvh nodes
68#define PVS_HACK 0
69#define USE_HASH_COMPARE 1
70
71
72inline static bool ilt(Intersectable *obj1, Intersectable *obj2)
73{
74        return obj1->mId < obj2->mId;
75}
76
77
78// ---------------------------------------------------------------------------
79//  StdInParseHandlers: Constructors and Destructor
80// ---------------------------------------------------------------------------
81ViewCellsParseHandlers::ViewCellsParseHandlers(ObjectContainer &pvsObjects,
82                                                                                           ObjectContainer &preprocessorObjects,
83                                                                                           BoundingBoxConverter *bconverter
84                                                                                           ):
85  mElementCount(0)
86  , mAttrCount(0)
87  , mCharacterCount(0)
88  , mSpaceCount(0)
89  , mViewCellsManager(NULL)
90  , mVspBspTree(NULL)
91  , mBspTree(NULL)
92  , mViewCellsTree(NULL)
93  , mCurrentState(PARSE_OPTIONS)
94  , mCurrentViewCell(NULL)
95  , mCurrentBspNode(NULL)
96  , mCurrentVspNode(NULL)
97  , mCurrentOspNode(NULL)
98  , mCurrentBvhNode(NULL)
99  , mPvsObjects(pvsObjects)
100  , mPreprocessorObjects(preprocessorObjects)
101  , mBoundingBoxConverter(bconverter)
102  , mHierarchyManager(NULL)
103  , nViewCells(0)
104  , nObjects(0)
105{
106}
107
108
109ViewCellsParseHandlers::~ViewCellsParseHandlers()
110{
111}
112
113
114void ViewCellsParseHandlers::CreateHashVector()
115{
116        ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
117
118        for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
119        {
120                mHashPvs[(*oit)->GetId()] = (*oit);
121        }
122        //Debug<<"\nhsize: " << mHashPvs.size() << endl;
123}
124
125
126// ---------------------------------------------------------------------------
127//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
128// ---------------------------------------------------------------------------
129
130
131void ViewCellsParseHandlers::endElement(const XMLCh* const name)
132{
133        StrX lname(name);
134        string element(lname.LocalForm());
135
136        if (element == "BoundingBoxes")
137        {
138                EndBoundingBoxes();
139        }
140        else if (element == "ViewCells")
141        {       
142                EndViewCells();
143                Debug << "view cell hierarchy parsed" << endl;
144        }
145        else if (element == "ObjectSpaceHierarchy")
146        {
147                EndObjectSpaceHierarchy();
148                Debug << "object space hierarchy parsed" << endl;
149#ifdef USE_PERFTIMER 
150                mObjectTimer.Exit();
151#endif
152        }
153        // finished paring, create view cells manager
154        else if (element == "VisibilitySolution")
155        {
156                CreateViewCellsManager();
157
158#ifdef USE_PERFTIMER 
159                Debug << "pvs time: " << mPvsTimer.TotalTime() << endl;
160                Debug << "object time: " << mObjectTimer.TotalTime() << endl;
161                Debug << "box time: " << mBoxTimer.TotalTime() << endl;
162#endif
163        }
164        else if (element == "Interior")
165        {
166                switch (mCurrentState)
167                {
168                case PARSE_VIEWCELLS:
169                        EndViewCellInterior();
170                        break;
171                case PARSE_OBJECTSPACE_HIERARCHY:
172                        EndObjectSpaceHierarchyInterior();
173                        break;
174                case PARSE_VIEWSPACE_HIERARCHY:
175                        EndViewSpaceHierarchyInterior();
176                        break;
177                default:
178                        break;
179                }
180        }
181}
182
183
184void ViewCellsParseHandlers::EndObjectSpaceHierarchy()
185{
186        if (mObjectSpaceHierarchyType == OSP)
187        {
188                // for a spatial subdivision, it is not necessary to store
189                // the objects with the leaves, they can be classified geometrically
190                mHierarchyManager->mOspTree->
191                        InsertObjects(mHierarchyManager->mOspTree->mRoot, mPvsObjects);
192        }
193}
194
195
196void ViewCellsParseHandlers::EndViewSpaceHierarchyInterior()
197{
198        switch (mViewSpaceHierarchyType)
199        {
200        case BSP:
201                EndBspInterior();
202                break;
203        case VSP:
204                EndVspInterior();
205                break; 
206        default:
207                Debug << "not implemented view space hierarchy type " << mViewSpaceHierarchyType << endl;
208                break;
209        }
210}
211
212
213void ViewCellsParseHandlers::EndObjectSpaceHierarchyInterior()
214{
215        switch (mObjectSpaceHierarchyType)
216        {
217        case OSP:
218                EndOspInterior();
219                break;
220        case BVH:
221                EndBvhInterior();
222                break; 
223        default:
224                Debug << "not implemented object space hierarchy type " << mViewSpaceHierarchyType << endl;
225                break;
226        }
227}
228
229
230void ViewCellsParseHandlers::EndBspInterior()
231{
232        // go one up in the tree
233        if (mCurrentBspNode->GetParent())
234        {       //cout << "]";
235                mCurrentBspNode = mCurrentBspNode->GetParent();
236        }
237}
238
239
240void ViewCellsParseHandlers::EndBvhInterior()
241{
242        // go one up in the tree
243        if (mCurrentBvhNode->GetParent())
244        {       //cout << "]";
245                mCurrentBvhNode = mCurrentBvhNode->GetParent();
246        }
247}
248
249
250void ViewCellsParseHandlers::EndOspInterior()
251{
252        // go one up in the tree
253        if (mCurrentOspNode->mParent)
254        {       
255                //cout << "]";
256                mCurrentOspNode = mCurrentOspNode->mParent;
257        }
258}
259
260
261void ViewCellsParseHandlers::EndVspInterior()
262{
263        // go one up in the tree
264        if (mCurrentVspNode->GetParent())
265        {       
266                //cout << "]";
267                mCurrentVspNode = mCurrentVspNode->GetParent();
268        }
269}
270
271
272void ViewCellsParseHandlers::EndViewCellInterior()
273{
274        // go one up in the tree
275        if (mCurrentViewCell->GetParent())
276        {       
277                //cout << "]";
278                mCurrentViewCell = mCurrentViewCell->GetParent();
279        }
280}
281
282
283inline static bool vlt(ViewCell *v1, ViewCell *v2)
284{
285        return v1->mId < v2->mId;
286}
287
288
289void ViewCellsParseHandlers::EndViewCells()
290{
291        // sort view cells to help associating view cells according to their id
292        sort(mViewCells.begin(), mViewCells.end(), vlt);
293
294        // not parsing view cells anymore
295        mCurrentState = PARSE_OPTIONS;
296}
297
298
299void ViewCellsParseHandlers::EndBoundingBoxes()
300{
301        const long startTime = GetTime();
302       
303#ifdef USE_PERFTIMER 
304        mBoxTimer.Entry();
305#endif
306        if (mBoundingBoxConverter)
307        {
308                // all bounding boxes gathered in this step =>
309                // associate object ids with bounding boxes
310                mBoundingBoxConverter->IdentifyObjects(mIBoundingBoxes, mPvsObjects);
311        }
312
313        if (USE_HASH_COMPARE)
314        {
315                CreateHashVector();
316        }
317        else
318        {
319                // sort objects by id
320                sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
321        }
322
323        Debug << "\nconverted bounding boxes to objects in "
324                  << TimeDiff(startTime, GetTime()) * 1e-6 << " secs" << endl;
325
326#ifdef USE_PERFTIMER 
327        mBoxTimer.Exit();
328#endif
329}
330
331
332void ViewCellsParseHandlers::StartBspElement(string element,
333                                                                                         AttributeList& attributes)
334{
335        if (element == "Interior")
336        {
337                //cout << "[";
338                StartBspInterior(attributes);
339        }
340
341        if (element == "Leaf")
342        {
343                //cout << "l";
344                StartBspLeaf(attributes);
345        }
346}
347
348
349void ViewCellsParseHandlers::StartVspElement(string element,
350                                                                                         AttributeList& attributes)
351{
352        if (element == "Interior")
353        {
354                //cout << "[";
355                StartVspInterior(attributes);
356        }
357        if (element == "Leaf")
358        {
359                //cout << "l";
360                StartVspLeaf(attributes);
361        }
362}
363
364
365void ViewCellsParseHandlers::StartOspElement(string element,
366                                                                                         AttributeList& attributes)
367{
368        if (element == "Interior")
369        {
370                //cout << "[";
371                StartOspInterior(attributes);
372        }
373
374        if (element == "Leaf")
375        {
376                //cout << "l";
377                StartOspLeaf(attributes);
378        }
379}
380
381
382void ViewCellsParseHandlers::StartBvhElement(string element,
383                                                                                         AttributeList& attributes)
384{
385        if (element == "Interior")
386        {
387                //cout << "[";
388                StartBvhInterior(attributes);
389        }
390
391        if (element == "Leaf")
392        {
393                //cout << "l";
394                StartBvhLeaf(attributes);
395        }
396}
397
398
399void ViewCellsParseHandlers::StartViewSpaceHierarchyElement(const std::string &element,
400                                                                                                                        AttributeList& attributes)
401{
402        //-- use cell type according to the chosen method
403        switch (mViewSpaceHierarchyType)
404        {
405        case BSP:
406                StartBspElement(element, attributes);
407                break;
408        case VSP:
409                StartVspElement(element, attributes);
410                break;
411        default:
412                Debug << "not implemented" << endl;
413                break;
414        }
415}
416
417
418void ViewCellsParseHandlers::StartObjectSpaceHierarchyElement(const std::string &element,
419                                                                                                                          AttributeList& attributes)
420{
421        //-- use cell type according to the chosen method
422        switch (mObjectSpaceHierarchyType)
423        {
424                case OSP:
425                        StartOspElement(element, attributes);
426                        break;
427                case BVH:
428                        StartBvhElement(element, attributes);
429                        break;
430                default:
431                        Debug << "not implemented" << endl;
432                        break;
433        }
434}
435
436
437void ViewCellsParseHandlers::StartViewCellHierarchyElement(const std::string &element,
438                                                                                                                   AttributeList& attributes)
439{
440        // interiors + leaves interpreted view cells else
441        if (element == "Interior")
442        {
443                StartViewCell(attributes, false);
444                return;
445        }
446
447        if (element == "Leaf")
448        {
449                StartViewCell(attributes, true);
450                return;
451        }
452
453        Debug << "StartViewCellHierarchyElement: should not come here: " << element << endl;
454}
455
456
457void ViewCellsParseHandlers::startElement(const XMLCh* const name,
458                                                                                  AttributeList& attributes)
459{
460        StrX lname(name);
461        string element(lname.LocalForm());
462
463        if (element == "ViewCells")
464        {
465                cout << "\nparsing view cells" << endl;
466                Debug << "\nparsing view cells" << endl;
467               
468                mCurrentState = PARSE_VIEWCELLS;
469
470                // create new view cells hierarchy
471                mViewCellsTree = new ViewCellsTree();
472        }
473        // decides about the view cell hierarchy
474        else if (element == "ViewSpaceHierarchy")
475        {               
476                Debug << "\nparsing view space hierarchy" << endl;
477                cout  << "\nparsing view space hierarchy" << endl;
478
479                mCurrentState = PARSE_VIEWSPACE_HIERARCHY;
480                StartViewSpaceHierarchy(attributes);
481        }
482        // decides about the view cell hierarchy
483        else if (element == "ObjectSpaceHierarchy")
484        {
485                cout  << "\nparsing object space hierarchy" << endl;
486                Debug << "\nparsing object space hierarchy" << endl;
487
488                mCurrentState = PARSE_OBJECTSPACE_HIERARCHY;
489#ifdef USE_PERFTIMER 
490                mObjectTimer.Entry();
491#endif
492                StartObjectSpaceHierarchy(attributes);
493        }
494        // decides the used view cell hierarchy
495        else if (element == "BoundingBox")
496        {
497                StartBoundingBox(attributes);
498        }
499        else
500        {
501                const int n = 1000;
502                // parse view space hierarchy
503                switch (mCurrentState)
504                {
505                case PARSE_VIEWSPACE_HIERARCHY:
506                        if ((++ nViewCells % n) == 0)
507                        {
508                                cout << "\r" << nViewCells << " view cells parsed\r";
509                                Debug << nViewCells << " view cells parsed" << endl;
510                        }
511                        StartViewSpaceHierarchyElement(element, attributes);
512                        break;
513                case PARSE_OBJECTSPACE_HIERARCHY:
514                        if ((++ nObjects % n) == 0)
515                                cout <<"\r" << nObjects << " objects parsed\r";
516               
517                        StartObjectSpaceHierarchyElement(element, attributes);
518                        break;
519                case PARSE_VIEWCELLS:
520                        StartViewCellHierarchyElement(element, attributes);
521                        break;
522                default:
523                        break;
524                }
525        }
526       
527        ++ mElementCount;
528        mAttrCount += attributes.getLength();
529}
530
531
532void ViewCellsParseHandlers::StartViewCellPvs(ObjectPvs &pvs, const char *ptr)
533{
534        // handle object indices
535        vector<int> objIndices;
536        char *endptr;
537                       
538        while (1)
539        {       
540                // read object ids
541                const int index = strtol(ptr, &endptr, 10);
542               
543                if (ptr == endptr)
544                        break;
545               
546                objIndices.push_back(index);
547                ptr = endptr;
548        }
549
550#ifdef USE_PERFTIMER 
551        mPvsTimer.Entry();
552#endif
553        Intersectable::NewMail();
554
555        // TODO:
556        // 1) find objects and add them to pvs
557        // 2) get view cell with specified id
558        MeshInstance dummyInst(NULL);
559        pair<ObjectContainer::const_iterator, ObjectContainer::const_iterator> result;
560
561        vector<int>::const_iterator it, it_end = objIndices.end();
562       
563        for (it = objIndices.begin(); it != it_end; ++ it)
564        {
565                const int objId = *it; 
566       
567#if USE_HASH_COMPARE
568                pvs_hash::iterator oit = mHashPvs.find(objId);
569
570                if ((oit != mHashPvs.end()) && ((*oit).second->GetId() == objId))
571                {
572                        pvs.AddSample((*oit).second, 1.0f);
573                }
574#else
575        #if 0
576                dummyInst.SetId(objId);
577
578                ObjectContainer::iterator oit =
579                                                        lower_bound(mPvsObjects.begin(),
580                                                                                mPvsObjects.end(),
581                                                                                (Intersectable *)&dummyInst,
582                                                                                ilt);   
583
584                if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
585                {
586                        pvs.AddSample(*oit, 1.0f);
587                }
588        #else
589                pvs.AddSample(mPvsObjects[objId], 1.0f);
590        #endif
591#endif
592        }
593       
594#ifdef USE_PERFTIMER 
595        mPvsTimer.Exit();
596#endif
597}
598
599
600void ViewCellsParseHandlers::StartViewSpaceHierarchy(AttributeList& attributes)
601{
602        int len = attributes.getLength();
603
604        Vector3 bmin, bmax;
605
606        for (int i = 0; i < len; ++ i)
607        {
608                string attrName(StrX(attributes.getName(i)).LocalForm());
609                StrX attrValue(attributes.getValue(i));
610                const char *ptr = attrValue.LocalForm();
611
612                // hierarchy type
613                if (attrName == "type")
614                {
615                        if (strcmp(ptr, "bsp") == 0)
616                        {
617                                Debug << "\nview space hierarchy: Bsp" << endl;
618                                mViewSpaceHierarchyType = BSP;
619                        }
620                        else if (strcmp(ptr, "vsp") == 0)
621                        {
622                                Debug << "\nview space hierarchy: Vsp" << endl;
623                                mViewSpaceHierarchyType = VSP;
624                        }
625                }
626                else if (attrName == "min") // the view space extent
627                {
628                        sscanf(ptr, "%f %f %f",
629                                   &bmin.x, &bmin.y, &bmin.z);
630                }
631                else if (attrName == "max")
632                {
633                        sscanf(ptr, "%f %f %f",
634                                   &bmax.x, &bmax.y, &bmax.z);
635                }
636        }
637
638        mViewSpaceBox = AxisAlignedBox3(bmin, bmax);
639
640        // create the hierarchy based on this information
641        CreateViewSpaceHierarchy();
642}
643
644
645void ViewCellsParseHandlers::StartObjectSpaceHierarchy(AttributeList& attributes)
646{
647        const int len = attributes.getLength();
648        Vector3 bmin, bmax;
649
650        for (int i = 0; i < len; ++ i)
651        {
652                string attrName(StrX(attributes.getName(i)).LocalForm());
653                StrX attrValue(attributes.getValue(i));
654                const char *ptr = attrValue.LocalForm();
655
656                // hierarchy type
657                if (attrName == "type")
658                {
659                        if (strcmp(ptr, "osp") == 0)
660                        {
661                                Debug << "\nobject space hierarchy: Osp" << endl;
662
663                                mHierarchyManager =
664                                        new HierarchyManager(HierarchyManager::KD_BASED_OBJ_SUBDIV);
665
666                                DEL_PTR(mHierarchyManager->mVspTree);
667                                mHierarchyManager->mVspTree = mVspTree;
668
669                                mObjectSpaceHierarchyType = OSP;
670
671                                //std::stable_sort(objects.begin(), objects.end(), ilt);
672                                mHierarchyManager->mOspTree->mBoundingBox.Initialize();
673                                ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
674                               
675                                //-- compute bounding box
676                                for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
677                                {
678                                        Intersectable *obj = *oit;
679                                        // compute bounding box of view space
680                                        mHierarchyManager->mOspTree->mBoundingBox.Include(obj->GetBox());
681                                }
682                        }
683                        else if (strcmp(ptr, "bvh") == 0)
684                        {
685                                Debug << "\nobject space hierarchy: Bvh" << endl;
686
687                                mObjectSpaceHierarchyType = BVH;
688                                mHierarchyManager =
689                                        new HierarchyManager(HierarchyManager::BV_BASED_OBJ_SUBDIV);
690
691                                DEL_PTR(mHierarchyManager->mVspTree);
692                                mHierarchyManager->mVspTree = mVspTree;
693                        }
694                }
695        }
696}
697
698
699void ViewCellsParseHandlers::StartBoundingBox(AttributeList& attributes)
700{
701        int len = attributes.getLength();
702
703        Vector3 bmin, bmax;
704        int id;
705
706        for (int i = 0; i < len; ++ i)
707        {
708                string attrName(StrX(attributes.getName(i)).LocalForm());
709                StrX attrValue(attributes.getValue(i));
710
711                const char *ptr = attrValue.LocalForm();
712
713                if (attrName == "id")
714                {
715                        sscanf(ptr, "%d", &id);
716                }
717                if (attrName == "min")
718                {
719                        sscanf(ptr, "%f %f %f", &bmin.x, &bmin.y, &bmin.z);
720                }
721                else if (attrName == "max")
722                {
723                        sscanf(ptr, "%f %f %f", &bmax.x, &bmax.y, &bmax.z);
724                }
725        }
726
727        AxisAlignedBox3 box(bmin, bmax);
728        mIBoundingBoxes.push_back(IndexedBoundingBox(id, box));
729}
730
731
732void ViewCellsParseHandlers::StartBspLeaf(AttributeList& attributes)
733{
734        BspLeaf * leaf;
735
736        if (mCurrentBspNode) // replace front or (if not NULL) back child
737        {
738                BspInterior *interior = static_cast<BspInterior *>(mCurrentBspNode);
739
740                leaf = new BspLeaf(interior);
741                interior->ReplaceChildLink(NULL, leaf);
742        }
743        else
744        {
745                leaf = new BspLeaf();
746                mVspBspTree->mRoot = leaf;
747        }
748
749        ///////////
750        //-- find associated view cell
751
752        int viewCellId;
753        const int len = attributes.getLength();
754         
755        for (int i = 0; i < len; ++ i)
756        {
757                string attrName(StrX(attributes.getName(i)).LocalForm());
758                StrX attrValue(attributes.getValue(i));
759
760                const char *ptr = attrValue.LocalForm();
761                char *endptr = NULL;
762
763                if (attrName == "viewCellId")
764                {
765                        viewCellId = strtol(ptr, &endptr, 10);
766                }
767        }
768       
769        if (viewCellId >= 0) // valid view cell found
770        {
771                // TODO: get view cell with specified id
772                ViewCellInterior dummyVc;
773                dummyVc.SetId(viewCellId);
774
775                ViewCellContainer::iterator vit =
776                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
777               
778                //ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
779//              BspViewCell *viewCell = static_cast<BspViewCell *>((*vit).second);
780
781                BspViewCell *viewCell = static_cast<BspViewCell *>(*vit);
782                if (viewCell->GetId() == viewCellId)
783                {
784                        // create new view cell for bsp nodes
785                        leaf->SetViewCell(viewCell);
786                        viewCell->mLeaves.push_back(leaf);
787                }
788                else
789                {
790                        cerr << "error: view cell does not exist" << endl;
791                }
792        }
793        else
794        {
795                // add to invalid view space
796                leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
797                leaf->SetTreeValid(false);
798                mVspBspTree->PropagateUpValidity(leaf);
799        }
800}
801
802
803void ViewCellsParseHandlers::StartBspInterior(AttributeList& attributes)
804{cout<<"x";
805        Plane3 plane;
806        int len = attributes.getLength();
807
808        for (int i = 0; i < len; ++ i)
809        {
810                string attrName(StrX(attributes.getName(i)).LocalForm());
811                StrX attrValue(attributes.getValue(i));
812                const char *ptr = attrValue.LocalForm();
813
814                if (attrName == "plane")
815                {
816                        sscanf(ptr, "%f %f %f %f",
817                                   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
818                }
819        }
820
821        BspInterior* interior = new BspInterior(plane);
822       
823        if (mCurrentBspNode) // replace NULL child of parent with current node
824        {
825                BspInterior *parent = static_cast<BspInterior *>(mCurrentBspNode);
826
827                parent->ReplaceChildLink(NULL, interior);
828                interior->SetParent(parent);
829        }
830        else
831        {
832                mVspBspTree->mRoot = interior;
833        }
834
835        mCurrentBspNode = interior;
836}
837
838
839void ViewCellsParseHandlers::StartViewCell(AttributeList& attributes, const bool isLeaf)
840{
841        ViewCell *viewCell = NULL;
842        const int len = attributes.getLength();
843        float mergeCost;
844       
845        if (isLeaf)
846        {
847                viewCell = new ViewCellLeaf();
848        }
849        else
850        {
851                viewCell = new ViewCellInterior();
852        }
853
854        for (int i = 0; i < len; ++ i)
855        {
856                const string attrName(StrX(attributes.getName(i)).LocalForm());
857       
858                if (attrName == "id")
859                {
860                        const StrX attrValue(attributes.getValue(i));
861                        const char *ptr = attrValue.LocalForm();
862                        char *endptr = NULL;
863                        const int id = strtol(ptr, &endptr, 10);
864
865                        // create new view cell, otherwise use reference.
866                        viewCell->SetId(id);
867
868                        if (mCurrentViewCell)
869                        {       // replace front or (if not NULL) back child
870                                ViewCellInterior *interior =
871                                        static_cast<ViewCellInterior *>(mCurrentViewCell);
872                                interior->SetupChildLink(viewCell);
873                        }
874                        else
875                        {       // set the new root
876                                mViewCellsTree->SetRoot(viewCell);
877                        }
878                       
879                        if (!isLeaf)
880                        {
881                                mCurrentViewCell = viewCell;
882                        }
883                }
884                if (attrName == "pvs")
885                {
886                        StrX attrValue(attributes.getValue(i));
887                        const char *ptr = attrValue.LocalForm();
888
889                        // hack: assume that view cell id comes before pvs
890                        // otherwise view cell is undefined
891
892                        StartViewCellPvs(viewCell->GetPvs(), ptr);
893                        //StartViewCellPvs(pvs, ptr);
894                }
895                else if (attrName == "active")
896                {
897                        StrX attrValue(attributes.getValue(i));
898                        const char *ptr = attrValue.LocalForm();
899                        char *endptr = NULL;
900                        const bool isActive = (bool)strtol(ptr, &endptr, 10);
901
902                        if (isActive)
903                        {
904                                // TODO
905                        }
906                }
907                else if (attrName == "mergecost")
908                {
909                        StrX attrValue(attributes.getValue(i));
910                       
911                        const char *ptr = attrValue.LocalForm();
912                        char *endptr = NULL;
913                        mergeCost = (float)strtod(ptr, &endptr);
914                }
915        }
916
917        viewCell->SetMergeCost(mergeCost);
918        //viewCell->SetPvs(pvs);
919        mViewCells.push_back(viewCell);
920}
921
922
923void ViewCellsParseHandlers::CreateViewSpaceHierarchy()
924{cout<<"y";
925        if (mViewSpaceHierarchyType == BSP)
926        {
927                Debug << "hierarchy type: Bsp" << endl;
928                mVspBspTree = new VspBspTree();
929
930                // set view space box
931                mVspBspTree->mBoundingBox = mViewSpaceBox;
932
933                //ViewCellsMap::iterator vit, vit_end = mViewCells.end();
934                ViewCellContainer::iterator vit, vit_end = mViewCells.end();
935
936                int i = 0;
937                // remove view cells and exchange them with the
938                // view cells specialized for the current hierarchy node type
939                for (vit = mViewCells.begin(); vit != vit_end; ++ vit, ++ i)
940                {
941                        ViewCell *vc = (*vit);
942
943                        if (!vc->IsLeaf()) // exchange only leaves
944                                continue;
945               
946                        BspViewCell *bspVc = new BspViewCell();
947
948                        bspVc->SetId(vc->GetId());
949                        //bspVc->GetPvs().reserve(vc->GetPvs().size());
950                        bspVc->SetPvs(vc->GetPvs());
951
952                        if (vc->IsRoot())
953                        {
954                                mViewCellsTree->mRoot = bspVc;
955                        }
956                        else
957                        {
958                vc->GetParent()->ReplaceChildLink(vc, bspVc);
959                        }
960
961                        // delete old view cell
962                        DEL_PTR(vc);
963
964                        //(*vit).second = bspVc;
965                        (*vit) = bspVc;
966                }
967                cout << "finished creating view space hierarchy" << endl;
968        }
969        else if (mViewSpaceHierarchyType == VSP)
970        {
971                Debug << "hierarchy type: Vsp" << endl;
972                mVspTree = new VspTree();
973
974                // set view space box
975                mVspTree->mBoundingBox = mViewSpaceBox;
976
977                // ViewCellsMap::iterator vit, vit_end = mViewCells.end();
978                ViewCellContainer::iterator vit, vit_end = mViewCells.end();
979
980                // reset view cells using the current node type
981                for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
982                {
983                        //ViewCell *vc = (*vit).second;
984                        ViewCell *vc = (*vit);
985                       
986                        if (!vc->IsLeaf()) // exchange only leaves
987                                continue;
988
989                        VspViewCell *vspVc = new VspViewCell();
990
991                        vspVc->SetPvs(vc->GetPvs());
992                        vspVc->SetId(vc->GetId());
993
994                        if (vc->IsRoot())
995                        {
996                                mViewCellsTree->mRoot = vspVc;
997                        }
998                        else
999                        {
1000                                vc->GetParent()->ReplaceChildLink(vc, vspVc);
1001                        }
1002                       
1003                        // exchange view cell with new one
1004                        DEL_PTR(vc);
1005                        //(*vit).second = vspVc;
1006                        (*vit) = vspVc;
1007                }
1008
1009                if (mHierarchyManager)
1010                {
1011                        // do this only if object hierarchy was already constructed
1012                        mHierarchyManager->mVspTree = mVspTree;
1013                        mVspTree->mHierarchyManager = mHierarchyManager;
1014                }
1015        }
1016}
1017
1018
1019void ViewCellsParseHandlers::CreateViewCellsManager()
1020{
1021        if (mViewSpaceHierarchyType == BSP)
1022        {
1023                Debug << "\ncreating view cells manager: VspBsp" << endl;
1024                mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
1025        }
1026        else if (mViewSpaceHierarchyType == VSP)
1027        {
1028                Debug << "\ncreating view cells manager: VspOsp" << endl;
1029                mViewCellsManager = new VspOspViewCellsManager(mViewCellsTree, mHierarchyManager);
1030        }
1031
1032        mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
1033}
1034
1035
1036void ViewCellsParseHandlers::characters(const XMLCh* const chars,
1037                                                                                const unsigned int length)
1038{
1039        mCharacterCount += length;
1040}
1041
1042
1043void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
1044                                                                                                 const unsigned int length)
1045{
1046        mSpaceCount += length;
1047}
1048
1049
1050void ViewCellsParseHandlers::resetDocument()
1051{
1052        mAttrCount = 0;
1053        mCharacterCount = 0;
1054        mElementCount = 0;
1055        mSpaceCount = 0;
1056}
1057
1058
1059void ViewCellsParseHandlers::StartVspLeaf(AttributeList& attributes)
1060{
1061        VspLeaf * leaf;
1062               
1063        if (mCurrentVspNode) // replace front or (if not NULL) back child
1064        {
1065                VspInterior *interior = static_cast<VspInterior *>(mCurrentVspNode);
1066                leaf = new VspLeaf(interior);
1067                interior->ReplaceChildLink(NULL, leaf);
1068        }
1069        else
1070        {
1071                leaf = new VspLeaf();
1072                mVspTree->mRoot = leaf;
1073        }
1074
1075        /////////////
1076        //-- find view cell associated with the id
1077
1078        int viewCellId;
1079        const int len = attributes.getLength();
1080         
1081        for (int i = 0; i < len; ++ i)
1082        {
1083                string attrName(StrX(attributes.getName(i)).LocalForm());
1084                StrX attrValue(attributes.getValue(i));
1085
1086                const char *ptr = attrValue.LocalForm();
1087                char *endptr = NULL;
1088
1089                if (attrName == "viewCellId")
1090                {
1091                        viewCellId = strtol(ptr, &endptr, 10);
1092                }
1093        }
1094       
1095        if (viewCellId >= 0) // valid view cell found
1096        {
1097                // TODO: get view cell with specified id
1098                ViewCellInterior dummyVc;
1099                dummyVc.SetId(viewCellId);
1100
1101                ViewCellContainer::iterator vit =
1102                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
1103               
1104                //ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
1105                if (vit == mViewCells.end())
1106                        Debug << "error: view cell " << viewCellId << " not found" << endl;
1107       
1108                //VspViewCell *viewCell = static_cast<VspViewCell *>((*vit).second);
1109                VspViewCell *viewCell = static_cast<VspViewCell *>(*vit);
1110               
1111                if (viewCell->GetId() == viewCellId)
1112                {
1113                        leaf->SetViewCell(viewCell);
1114                        viewCell->mLeaves.push_back(leaf);
1115                }
1116                else
1117                {
1118                        Debug << "error: view cell does not exist" << endl;
1119                }
1120        }
1121        else
1122        {       
1123                // add to invalid view space
1124                leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
1125                leaf->SetTreeValid(false);
1126                mVspTree->PropagateUpValidity(leaf);
1127        }
1128}
1129
1130
1131void ViewCellsParseHandlers::StartVspInterior(AttributeList& attributes)
1132{
1133        AxisAlignedPlane plane;
1134        const int len = attributes.getLength();
1135
1136        for (int i = 0; i < len; ++ i)
1137        {
1138                string attrName(StrX(attributes.getName(i)).LocalForm());
1139                StrX attrValue(attributes.getValue(i));
1140                const char *ptr = attrValue.LocalForm();
1141
1142                if (attrName == "plane")
1143                {
1144                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1145                }
1146        }
1147
1148        VspInterior* interior = new VspInterior(plane);
1149       
1150        if (mCurrentVspNode) // replace NULL child of parent with current node
1151        {
1152                VspInterior *parent = static_cast<VspInterior *>(mCurrentVspNode);
1153
1154                parent->ReplaceChildLink(NULL, interior);
1155                interior->SetParent(parent);
1156               
1157                AxisAlignedBox3 frontBox, backBox;
1158
1159                parent->GetBoundingBox().Split(
1160                        parent->GetPlane().mAxis,
1161                        parent->GetPlane().mPosition,
1162                        frontBox,
1163                        backBox);
1164
1165                if (parent->GetFront() == interior)
1166                        interior->SetBoundingBox(frontBox);
1167                else
1168                        interior->SetBoundingBox(backBox);
1169        }
1170        else
1171        {
1172                mVspTree->mRoot = interior;
1173                interior->SetBoundingBox(mVspTree->GetBoundingBox());
1174        }
1175
1176        mCurrentVspNode = interior;
1177}
1178
1179
1180void ViewCellsParseHandlers::StartOspInterior(AttributeList& attributes)
1181{
1182        AxisAlignedPlane plane;
1183        int len = attributes.getLength();
1184
1185        for (int i = 0; i < len; ++ i)
1186        {
1187                string attrName(StrX(attributes.getName(i)).LocalForm());
1188                StrX attrValue(attributes.getValue(i));
1189                const char *ptr = attrValue.LocalForm();
1190
1191                if (attrName == "plane")
1192                {
1193                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1194                }
1195        }
1196
1197        KdInterior* interior = new KdInterior(NULL);
1198       
1199        interior->mAxis = plane.mAxis;
1200        interior->mPosition = plane.mPosition;
1201
1202        if (mCurrentOspNode) // replace NULL child of parent with current node
1203        {
1204                KdInterior *parent = static_cast<KdInterior *>(mCurrentOspNode);
1205                parent->ReplaceChildLink(NULL, interior);
1206                interior->mParent = parent;
1207
1208                AxisAlignedBox3 frontBox, backBox;
1209
1210                parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
1211
1212                if (parent->mFront == interior)
1213                        interior->mBox = frontBox;
1214                else
1215                        interior->mBox = backBox;
1216        }
1217        else
1218        {
1219                mHierarchyManager->mOspTree->mRoot = interior;
1220                interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
1221        }
1222
1223        mCurrentOspNode = interior;
1224}
1225
1226
1227void ViewCellsParseHandlers::StartOspLeaf(AttributeList& attributes)
1228{
1229        KdLeaf * leaf = new KdLeaf(static_cast<KdInterior *>(mCurrentOspNode), NULL);
1230
1231        if (mCurrentOspNode)
1232        {
1233                 // replace front or (if not NULL) back child
1234                static_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
1235        }
1236        else
1237        {
1238                mHierarchyManager->mOspTree->mRoot = leaf;
1239        }
1240}
1241
1242
1243void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
1244{
1245        const int len = attributes.getLength();
1246        Vector3 minBox, maxBox;
1247
1248        ObjectContainer objects;
1249
1250        for (int i = 0; i < len; ++ i)
1251        {
1252                string attrName(StrX(attributes.getName(i)).LocalForm());
1253                StrX attrValue(attributes.getValue(i));
1254                const char *ptr = attrValue.LocalForm();
1255
1256                if (attrName == "min")
1257                {
1258                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1259                }
1260                if (attrName == "max")
1261                {
1262                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1263                }
1264                if (attrName == "objects")
1265                {
1266                        if (!mPreprocessorObjects.empty())
1267                                StartBvhLeafObjects(objects, ptr);
1268                }
1269        }
1270
1271        AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox);
1272
1273        BvhLeaf *leaf;
1274
1275        if (mCurrentBvhNode) // replace front or (if not NULL) back child
1276        {
1277                BvhInterior *interior = static_cast<BvhInterior *>(mCurrentBvhNode);
1278
1279                leaf = new BvhLeaf(box, interior, (int)objects.size());
1280                interior->ReplaceChildLink(NULL, leaf);
1281        }
1282        else
1283        {
1284                leaf = new BvhLeaf(box, NULL, (int)objects.size());
1285                mHierarchyManager->mBvHierarchy->mRoot = leaf;
1286        }
1287
1288        leaf->mObjects = objects;
1289        BvHierarchy::AssociateObjectsWithLeaf(leaf);
1290}
1291
1292
1293void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects,
1294                                                                                                 const char *ptr)
1295{
1296        vector<int> objIndices;
1297        char *endptr;
1298                       
1299        while (1)
1300        {
1301                const int index = strtol(ptr, &endptr, 10);
1302                if (ptr == endptr) break;
1303
1304                objIndices.push_back(index);
1305                ptr = endptr;
1306        }
1307
1308        MeshInstance dummyInst(NULL);
1309        vector<int>::const_iterator it, it_end = objIndices.end();
1310
1311        for (it = objIndices.begin(); it != it_end; ++ it)
1312        {
1313                const int objId = *it; 
1314                dummyInst.SetId(objId);
1315
1316                ObjectContainer::const_iterator oit =
1317                        lower_bound(mPreprocessorObjects.begin(),
1318                                                mPreprocessorObjects.end(),
1319                                                (Intersectable *)&dummyInst,
1320                                                ilt);   
1321                                                       
1322                if ((oit != mPreprocessorObjects.end()) && ((*oit)->GetId() == objId))
1323                {
1324                        objects.push_back(*oit);
1325                }
1326                else
1327                {
1328                        //cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
1329                }
1330        }
1331}
1332
1333
1334void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
1335{
1336        const int len = attributes.getLength();
1337        Vector3 minBox, maxBox;
1338
1339        for (int i = 0; i < len; ++ i)
1340        {
1341                string attrName(StrX(attributes.getName(i)).LocalForm());
1342                StrX attrValue(attributes.getValue(i));
1343                const char *ptr = attrValue.LocalForm();
1344
1345                if (attrName == "min")
1346                {
1347                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1348                }
1349                if (attrName == "max")
1350                {
1351                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1352                }
1353        }
1354
1355        BvhInterior* interior = new BvhInterior(AxisAlignedBox3(minBox, maxBox));
1356
1357        if (mCurrentBvhNode) // replace NULL child of parent with current node
1358        {
1359                BvhInterior *parent = static_cast<BvhInterior *>(mCurrentBvhNode);
1360                parent->ReplaceChildLink(NULL, interior);
1361                interior->SetParent(parent);
1362        }
1363        else
1364        {
1365                mHierarchyManager->mBvHierarchy->mRoot = interior;
1366        }
1367
1368        mCurrentBvhNode = interior;
1369}
1370
1371
1372// ---------------------------------------------------------------------------
1373//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
1374// ---------------------------------------------------------------------------
1375
1376
1377void
1378ViewCellsParseHandlers::error(const SAXParseException& e)
1379{
1380  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
1381                            << ", line " << e.getLineNumber()
1382                            << ", char " << e.getColumnNumber()
1383                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1384}
1385
1386void
1387ViewCellsParseHandlers::fatalError(const SAXParseException& e)
1388{
1389  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
1390                            << ", line " << e.getLineNumber()
1391                            << ", char " << e.getColumnNumber()
1392                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1393}
1394
1395void
1396ViewCellsParseHandlers::warning(const SAXParseException& e)
1397{
1398  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
1399                            << ", line " << e.getLineNumber()
1400                            << ", char " << e.getColumnNumber()
1401                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1402}
1403
1404
1405bool ViewCellsParser::ParseViewCellsFile(const string &filename,
1406                                                                                 ViewCellsManager **viewCells,
1407                                                                                 ObjectContainer &pvsObjects,
1408                                                                                 ObjectContainer &preprocessorObjects,
1409                                                                                 BoundingBoxConverter *bconverter)
1410{
1411        // Initialize the XML4C system
1412        try {
1413                XMLPlatformUtils::Initialize();
1414        }
1415
1416        catch (const XMLException& toCatch)
1417        {
1418                XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
1419                        << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
1420                return false;
1421        }
1422
1423        //  cout<<"parsing started"<<endl<<flush;
1424
1425        //
1426        //  Create a SAX parser object. Then, according to what we were told on
1427        //  the command line, set the options.
1428        //
1429        SAXParser* parser = new SAXParser;
1430        parser->setValidationScheme(valScheme);
1431        parser->setDoNamespaces(doNamespaces);
1432        parser->setDoSchema(doSchema);
1433        parser->setValidationSchemaFullChecking(schemaFullChecking);
1434
1435
1436        //
1437        //  Create our SAX handler object and install it on the parser, as the
1438        //  document and error handler. We are responsible for cleaning them
1439        //  up, but since its just stack based here, there's nothing special
1440        //  to do.
1441        //
1442        ViewCellsParseHandlers handler(pvsObjects, preprocessorObjects, bconverter);
1443        parser->setDocumentHandler(&handler);
1444        parser->setErrorHandler(&handler);
1445
1446        unsigned long duration;
1447        int errorCount = 0;
1448        // create a faux scope so that 'src' destructor is called before
1449        // XMLPlatformUtils::Terminate
1450        {
1451                //
1452                //  Kick off the parse and catch any exceptions. Create a standard
1453                //  input input source and tell the parser to parse from that.
1454                //
1455                //    StdInInputSource src;
1456                try
1457                {
1458                        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
1459
1460#if USE_GZLIB
1461                        XMLCh *myFilePath = XMLString::transcode(filename.c_str());
1462
1463                        GzFileInputSource isource(myFilePath);
1464                        parser->parse(isource);
1465#else
1466                        parser->parse(filename.c_str());
1467
1468#endif
1469
1470                        //if (mCreatePvsObjects)
1471                        //      handler.ReplacePvs();
1472
1473                        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1474                        duration = endMillis - startMillis;
1475                        errorCount = parser->getErrorCount();
1476                }
1477                catch (const OutOfMemoryException&)
1478                {
1479                        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1480                        errorCount = 2;
1481                        return false;
1482                }
1483                catch (const XMLException& e)
1484                {
1485                        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
1486                                << StrX(e.getMessage())
1487                                << "\n" << XERCES_STD_QUALIFIER endl;
1488                        errorCount = 1;
1489                        return false;
1490                }
1491
1492
1493                // Print out the stats that we collected and time taken
1494                if (!errorCount)
1495                {
1496                        XERCES_STD_QUALIFIER cerr << filename << ": " << duration << " ms ("
1497                                << handler.GetElementCount() << " elems, "
1498                                << handler.GetAttrCount() << " attrs, "
1499                                << handler.GetSpaceCount() << " spaces, "
1500                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1501                }
1502        }
1503
1504        //
1505        //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1506        //
1507        delete parser;
1508
1509        XMLPlatformUtils::Terminate();
1510
1511        //-- assign new view cells manager
1512        *viewCells = handler.mViewCellsManager;
1513
1514        if (errorCount > 0)
1515                return false;
1516        else
1517                return true;
1518}
1519
1520}
Note: See TracBrowser for help on using the repository browser.