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

Revision 2721, 34.9 KB checked in by mattausch, 17 years ago (diff)
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        // hack for submission: enlarge by some margin
641        if (0)
642        {
643                const float VIEWSPACE_OFFSET = 40.0f;
644                mViewSpaceBox.SetMax(1, mViewSpaceBox.Max().y + VIEWSPACE_OFFSET);
645        }
646
647        // create the hierarchy based on this information
648        CreateViewSpaceHierarchy();
649}
650
651
652void ViewCellsParseHandlers::StartObjectSpaceHierarchy(AttributeList& attributes)
653{
654        const int len = attributes.getLength();
655        Vector3 bmin, bmax;
656
657        for (int i = 0; i < len; ++ i)
658        {
659                string attrName(StrX(attributes.getName(i)).LocalForm());
660                StrX attrValue(attributes.getValue(i));
661                const char *ptr = attrValue.LocalForm();
662
663                // hierarchy type
664                if (attrName == "type")
665                {
666                        if (strcmp(ptr, "osp") == 0)
667                        {
668                                Debug << "\nobject space hierarchy: Osp" << endl;
669
670                                mHierarchyManager =
671                                        new HierarchyManager(HierarchyManager::KD_BASED_OBJ_SUBDIV);
672
673                                DEL_PTR(mHierarchyManager->mVspTree);
674                                mHierarchyManager->mVspTree = mVspTree;
675
676                                mObjectSpaceHierarchyType = OSP;
677
678                                //std::stable_sort(objects.begin(), objects.end(), ilt);
679                                mHierarchyManager->mOspTree->mBoundingBox.Initialize();
680                                ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
681                               
682                                //-- compute bounding box
683                                for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
684                                {
685                                        Intersectable *obj = *oit;
686                                        // compute bounding box of view space
687                                        mHierarchyManager->mOspTree->mBoundingBox.Include(obj->GetBox());
688                                }
689                        }
690                        else if (strcmp(ptr, "bvh") == 0)
691                        {
692                                Debug << "\nobject space hierarchy: Bvh" << endl;
693
694                                mObjectSpaceHierarchyType = BVH;
695                                mHierarchyManager =
696                                        new HierarchyManager(HierarchyManager::BV_BASED_OBJ_SUBDIV);
697
698                                DEL_PTR(mHierarchyManager->mVspTree);
699                                mHierarchyManager->mVspTree = mVspTree;
700                        }
701                }
702        }
703}
704
705
706void ViewCellsParseHandlers::StartBoundingBox(AttributeList& attributes)
707{
708        int len = attributes.getLength();
709
710        Vector3 bmin, bmax;
711        int id;
712
713        for (int i = 0; i < len; ++ i)
714        {
715                string attrName(StrX(attributes.getName(i)).LocalForm());
716                StrX attrValue(attributes.getValue(i));
717
718                const char *ptr = attrValue.LocalForm();
719
720                if (attrName == "id")
721                {
722                        sscanf(ptr, "%d", &id);
723                }
724                if (attrName == "min")
725                {
726                        sscanf(ptr, "%f %f %f", &bmin.x, &bmin.y, &bmin.z);
727                }
728                else if (attrName == "max")
729                {
730                        sscanf(ptr, "%f %f %f", &bmax.x, &bmax.y, &bmax.z);
731                }
732        }
733
734        AxisAlignedBox3 box(bmin, bmax);
735        mIBoundingBoxes.push_back(IndexedBoundingBox(id, box));
736}
737
738
739void ViewCellsParseHandlers::StartBspLeaf(AttributeList& attributes)
740{
741        BspLeaf * leaf;
742
743        if (mCurrentBspNode) // replace front or (if not NULL) back child
744        {
745                BspInterior *interior = static_cast<BspInterior *>(mCurrentBspNode);
746
747                leaf = new BspLeaf(interior);
748                interior->ReplaceChildLink(NULL, leaf);
749        }
750        else
751        {
752                leaf = new BspLeaf();
753                mVspBspTree->mRoot = leaf;
754        }
755
756        ///////////
757        //-- find associated view cell
758
759        int viewCellId;
760        const int len = attributes.getLength();
761         
762        for (int i = 0; i < len; ++ i)
763        {
764                string attrName(StrX(attributes.getName(i)).LocalForm());
765                StrX attrValue(attributes.getValue(i));
766
767                const char *ptr = attrValue.LocalForm();
768                char *endptr = NULL;
769
770                if (attrName == "viewCellId")
771                {
772                        viewCellId = strtol(ptr, &endptr, 10);
773                }
774        }
775       
776        if (viewCellId >= 0) // valid view cell found
777        {
778                // TODO: get view cell with specified id
779                ViewCellInterior dummyVc;
780                dummyVc.SetId(viewCellId);
781
782                ViewCellContainer::iterator vit =
783                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
784               
785                //ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
786//              BspViewCell *viewCell = static_cast<BspViewCell *>((*vit).second);
787
788                BspViewCell *viewCell = static_cast<BspViewCell *>(*vit);
789                if (viewCell->GetId() == viewCellId)
790                {
791                        // create new view cell for bsp nodes
792                        leaf->SetViewCell(viewCell);
793                        viewCell->mLeaves.push_back(leaf);
794                }
795                else
796                {
797                        cerr << "error: view cell does not exist" << endl;
798                }
799        }
800        else
801        {
802                // add to invalid view space
803                leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
804                leaf->SetTreeValid(false);
805                mVspBspTree->PropagateUpValidity(leaf);
806        }
807}
808
809
810void ViewCellsParseHandlers::StartBspInterior(AttributeList& attributes)
811{cout<<"x";
812        Plane3 plane;
813        int len = attributes.getLength();
814
815        for (int i = 0; i < len; ++ i)
816        {
817                string attrName(StrX(attributes.getName(i)).LocalForm());
818                StrX attrValue(attributes.getValue(i));
819                const char *ptr = attrValue.LocalForm();
820
821                if (attrName == "plane")
822                {
823                        sscanf(ptr, "%f %f %f %f",
824                                   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
825                }
826        }
827
828        BspInterior* interior = new BspInterior(plane);
829       
830        if (mCurrentBspNode) // replace NULL child of parent with current node
831        {
832                BspInterior *parent = static_cast<BspInterior *>(mCurrentBspNode);
833
834                parent->ReplaceChildLink(NULL, interior);
835                interior->SetParent(parent);
836        }
837        else
838        {
839                mVspBspTree->mRoot = interior;
840        }
841
842        mCurrentBspNode = interior;
843}
844
845
846void ViewCellsParseHandlers::StartViewCell(AttributeList& attributes, const bool isLeaf)
847{
848        ViewCell *viewCell = NULL;
849        const int len = attributes.getLength();
850        float mergeCost;
851       
852        if (isLeaf)
853        {
854                viewCell = new ViewCellLeaf();
855        }
856        else
857        {
858                viewCell = new ViewCellInterior();
859        }
860
861        for (int i = 0; i < len; ++ i)
862        {
863                const string attrName(StrX(attributes.getName(i)).LocalForm());
864       
865                if (attrName == "id")
866                {
867                        const StrX attrValue(attributes.getValue(i));
868                        const char *ptr = attrValue.LocalForm();
869                        char *endptr = NULL;
870                        const int id = strtol(ptr, &endptr, 10);
871
872                        // create new view cell, otherwise use reference.
873                        viewCell->SetId(id);
874
875                        if (mCurrentViewCell)
876                        {       // replace front or (if not NULL) back child
877                                ViewCellInterior *interior =
878                                        static_cast<ViewCellInterior *>(mCurrentViewCell);
879                                interior->SetupChildLink(viewCell);
880                        }
881                        else
882                        {       // set the new root
883                                mViewCellsTree->SetRoot(viewCell);
884                        }
885                       
886                        if (!isLeaf)
887                        {
888                                mCurrentViewCell = viewCell;
889                        }
890                }
891                if (attrName == "pvs")
892                {
893                        StrX attrValue(attributes.getValue(i));
894                        const char *ptr = attrValue.LocalForm();
895
896                        // hack: assume that view cell id comes before pvs
897                        // otherwise view cell is undefined
898
899                        StartViewCellPvs(viewCell->GetPvs(), ptr);
900                        //StartViewCellPvs(pvs, ptr);
901                }
902                else if (attrName == "active")
903                {
904                        StrX attrValue(attributes.getValue(i));
905                        const char *ptr = attrValue.LocalForm();
906                        char *endptr = NULL;
907                        const bool isActive = (bool)strtol(ptr, &endptr, 10);
908
909                        if (isActive)
910                        {
911                                // TODO
912                        }
913                }
914                else if (attrName == "mergecost")
915                {
916                        StrX attrValue(attributes.getValue(i));
917                       
918                        const char *ptr = attrValue.LocalForm();
919                        char *endptr = NULL;
920                        mergeCost = (float)strtod(ptr, &endptr);
921                }
922        }
923
924        viewCell->SetMergeCost(mergeCost);
925        //viewCell->SetPvs(pvs);
926        mViewCells.push_back(viewCell);
927}
928
929
930void ViewCellsParseHandlers::CreateViewSpaceHierarchy()
931{
932        if (mViewSpaceHierarchyType == BSP)
933        {
934                Debug << "hierarchy type: Bsp" << endl;
935                mVspBspTree = new VspBspTree();
936
937                // set view space box
938                mVspBspTree->mBoundingBox = mViewSpaceBox;
939
940                //ViewCellsMap::iterator vit, vit_end = mViewCells.end();
941                ViewCellContainer::iterator vit, vit_end = mViewCells.end();
942
943                int i = 0;
944                // remove view cells and exchange them with the
945                // view cells specialized for the current hierarchy node type
946                for (vit = mViewCells.begin(); vit != vit_end; ++ vit, ++ i)
947                {
948                        ViewCell *vc = (*vit);
949
950                        if (!vc->IsLeaf()) // exchange only leaves
951                                continue;
952               
953                        BspViewCell *bspVc = new BspViewCell();
954
955                        bspVc->SetId(vc->GetId());
956                        //bspVc->GetPvs().reserve(vc->GetPvs().size());
957                        bspVc->SetPvs(vc->GetPvs());
958
959                        if (vc->IsRoot())
960                        {
961                                mViewCellsTree->mRoot = bspVc;
962                        }
963                        else
964                        {
965                vc->GetParent()->ReplaceChildLink(vc, bspVc);
966                        }
967
968                        // delete old view cell
969                        DEL_PTR(vc);
970
971                        //(*vit).second = bspVc;
972                        (*vit) = bspVc;
973                }
974                cout << "finished creating view space hierarchy" << endl;
975        }
976        else if (mViewSpaceHierarchyType == VSP)
977        {
978                Debug << "hierarchy type: Vsp" << endl;
979                mVspTree = new VspTree();
980
981                // set view space box
982                mVspTree->mBoundingBox = mViewSpaceBox;
983
984                // ViewCellsMap::iterator vit, vit_end = mViewCells.end();
985                ViewCellContainer::iterator vit, vit_end = mViewCells.end();
986
987                // reset view cells using the current node type
988                for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
989                {
990                        //ViewCell *vc = (*vit).second;
991                        ViewCell *vc = (*vit);
992                       
993                        if (!vc->IsLeaf()) // exchange only leaves
994                                continue;
995
996                        VspViewCell *vspVc = new VspViewCell();
997
998                        vspVc->SetPvs(vc->GetPvs());
999                        vspVc->SetId(vc->GetId());
1000
1001                        if (vc->IsRoot())
1002                        {
1003                                mViewCellsTree->mRoot = vspVc;
1004                        }
1005                        else
1006                        {
1007                                vc->GetParent()->ReplaceChildLink(vc, vspVc);
1008                        }
1009                       
1010                        // exchange view cell with new one
1011                        DEL_PTR(vc);
1012                        //(*vit).second = vspVc;
1013                        (*vit) = vspVc;
1014                }
1015
1016                if (mHierarchyManager)
1017                {
1018                        // do this only if object hierarchy was already constructed
1019                        mHierarchyManager->mVspTree = mVspTree;
1020                        mVspTree->mHierarchyManager = mHierarchyManager;
1021                }
1022        }
1023}
1024
1025
1026void ViewCellsParseHandlers::CreateViewCellsManager()
1027{
1028        if (mViewSpaceHierarchyType == BSP)
1029        {
1030                Debug << "\ncreating view cells manager: VspBsp" << endl;
1031                mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
1032        }
1033        else if (mViewSpaceHierarchyType == VSP)
1034        {
1035                Debug << "\ncreating view cells manager: VspOsp" << endl;
1036                mViewCellsManager = new VspOspViewCellsManager(mViewCellsTree, mHierarchyManager);
1037        }
1038
1039        mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
1040}
1041
1042
1043void ViewCellsParseHandlers::characters(const XMLCh* const chars,
1044                                                                                const unsigned int length)
1045{
1046        mCharacterCount += length;
1047}
1048
1049
1050void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
1051                                                                                                 const unsigned int length)
1052{
1053        mSpaceCount += length;
1054}
1055
1056
1057void ViewCellsParseHandlers::resetDocument()
1058{
1059        mAttrCount = 0;
1060        mCharacterCount = 0;
1061        mElementCount = 0;
1062        mSpaceCount = 0;
1063}
1064
1065
1066void ViewCellsParseHandlers::StartVspLeaf(AttributeList& attributes)
1067{
1068        VspLeaf * leaf;
1069               
1070        if (mCurrentVspNode) // replace front or (if not NULL) back child
1071        {
1072                VspInterior *interior = static_cast<VspInterior *>(mCurrentVspNode);
1073                leaf = new VspLeaf(interior);
1074                interior->ReplaceChildLink(NULL, leaf);
1075        }
1076        else
1077        {
1078                leaf = new VspLeaf();
1079                mVspTree->mRoot = leaf;
1080        }
1081
1082        /////////////
1083        //-- find view cell associated with the id
1084
1085        int viewCellId;
1086        const int len = attributes.getLength();
1087         
1088        for (int i = 0; i < len; ++ i)
1089        {
1090                string attrName(StrX(attributes.getName(i)).LocalForm());
1091                StrX attrValue(attributes.getValue(i));
1092
1093                const char *ptr = attrValue.LocalForm();
1094                char *endptr = NULL;
1095
1096                if (attrName == "viewCellId")
1097                {
1098                        viewCellId = strtol(ptr, &endptr, 10);
1099                }
1100        }
1101       
1102        if (viewCellId >= 0) // valid view cell found
1103        {
1104                // TODO: get view cell with specified id
1105                ViewCellInterior dummyVc;
1106                dummyVc.SetId(viewCellId);
1107
1108                ViewCellContainer::iterator vit =
1109                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
1110               
1111                //ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
1112                if (vit == mViewCells.end())
1113                        Debug << "error: view cell " << viewCellId << " not found" << endl;
1114       
1115                //VspViewCell *viewCell = static_cast<VspViewCell *>((*vit).second);
1116                VspViewCell *viewCell = static_cast<VspViewCell *>(*vit);
1117               
1118                if (viewCell->GetId() == viewCellId)
1119                {
1120                        leaf->SetViewCell(viewCell);
1121                        viewCell->mLeaves.push_back(leaf);
1122                }
1123                else
1124                {
1125                        Debug << "error: view cell does not exist" << endl;
1126                }
1127        }
1128        else
1129        {       
1130                // add to invalid view space
1131                leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
1132                leaf->SetTreeValid(false);
1133                mVspTree->PropagateUpValidity(leaf);
1134        }
1135}
1136
1137
1138void ViewCellsParseHandlers::StartVspInterior(AttributeList& attributes)
1139{
1140        AxisAlignedPlane plane;
1141        const int len = attributes.getLength();
1142
1143        for (int i = 0; i < len; ++ i)
1144        {
1145                string attrName(StrX(attributes.getName(i)).LocalForm());
1146                StrX attrValue(attributes.getValue(i));
1147                const char *ptr = attrValue.LocalForm();
1148
1149                if (attrName == "plane")
1150                {
1151                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1152                }
1153        }
1154
1155        VspInterior* interior = new VspInterior(plane);
1156       
1157        if (mCurrentVspNode) // replace NULL child of parent with current node
1158        {
1159                VspInterior *parent = static_cast<VspInterior *>(mCurrentVspNode);
1160
1161                parent->ReplaceChildLink(NULL, interior);
1162                interior->SetParent(parent);
1163               
1164                AxisAlignedBox3 frontBox, backBox;
1165
1166                parent->GetBoundingBox().Split(
1167                        parent->GetPlane().mAxis,
1168                        parent->GetPlane().mPosition,
1169                        frontBox,
1170                        backBox);
1171
1172                if (parent->GetFront() == interior)
1173                        interior->SetBoundingBox(frontBox);
1174                else
1175                        interior->SetBoundingBox(backBox);
1176        }
1177        else
1178        {
1179                mVspTree->mRoot = interior;
1180                interior->SetBoundingBox(mVspTree->GetBoundingBox());
1181        }
1182
1183        mCurrentVspNode = interior;
1184}
1185
1186
1187void ViewCellsParseHandlers::StartOspInterior(AttributeList& attributes)
1188{
1189        AxisAlignedPlane plane;
1190        int len = attributes.getLength();
1191
1192        for (int i = 0; i < len; ++ i)
1193        {
1194                string attrName(StrX(attributes.getName(i)).LocalForm());
1195                StrX attrValue(attributes.getValue(i));
1196                const char *ptr = attrValue.LocalForm();
1197
1198                if (attrName == "plane")
1199                {
1200                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1201                }
1202        }
1203
1204        KdInterior* interior = new KdInterior(NULL);
1205       
1206        interior->mAxis = plane.mAxis;
1207        interior->mPosition = plane.mPosition;
1208
1209        if (mCurrentOspNode) // replace NULL child of parent with current node
1210        {
1211                KdInterior *parent = static_cast<KdInterior *>(mCurrentOspNode);
1212                parent->ReplaceChildLink(NULL, interior);
1213                interior->mParent = parent;
1214
1215                AxisAlignedBox3 frontBox, backBox;
1216
1217                parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
1218
1219                if (parent->mFront == interior)
1220                        interior->mBox = frontBox;
1221                else
1222                        interior->mBox = backBox;
1223        }
1224        else
1225        {
1226                mHierarchyManager->mOspTree->mRoot = interior;
1227                interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
1228        }
1229
1230        mCurrentOspNode = interior;
1231}
1232
1233
1234void ViewCellsParseHandlers::StartOspLeaf(AttributeList& attributes)
1235{
1236        KdLeaf * leaf = new KdLeaf(static_cast<KdInterior *>(mCurrentOspNode), NULL);
1237
1238        if (mCurrentOspNode)
1239        {
1240                 // replace front or (if not NULL) back child
1241                static_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
1242        }
1243        else
1244        {
1245                mHierarchyManager->mOspTree->mRoot = leaf;
1246        }
1247}
1248
1249
1250void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
1251{
1252        const int len = attributes.getLength();
1253        Vector3 minBox, maxBox;
1254
1255        ObjectContainer objects;
1256
1257        for (int i = 0; i < len; ++ i)
1258        {
1259                string attrName(StrX(attributes.getName(i)).LocalForm());
1260                StrX attrValue(attributes.getValue(i));
1261                const char *ptr = attrValue.LocalForm();
1262
1263                if (attrName == "min")
1264                {
1265                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1266                }
1267                if (attrName == "max")
1268                {
1269                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1270                }
1271                if (attrName == "objects")
1272                {
1273                        if (!mPreprocessorObjects.empty())
1274                                StartBvhLeafObjects(objects, ptr);
1275                }
1276        }
1277
1278        AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox);
1279
1280        BvhLeaf *leaf;
1281
1282        if (mCurrentBvhNode) // replace front or (if not NULL) back child
1283        {
1284                BvhInterior *interior = static_cast<BvhInterior *>(mCurrentBvhNode);
1285
1286                leaf = new BvhLeaf(box, interior, (int)objects.size());
1287                interior->ReplaceChildLink(NULL, leaf);
1288        }
1289        else
1290        {
1291                leaf = new BvhLeaf(box, NULL, (int)objects.size());
1292                mHierarchyManager->mBvHierarchy->mRoot = leaf;
1293        }
1294
1295        leaf->mObjects = objects;
1296        BvHierarchy::AssociateObjectsWithLeaf(leaf);
1297}
1298
1299
1300void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects,
1301                                                                                                 const char *ptr)
1302{
1303        vector<int> objIndices;
1304        char *endptr;
1305                       
1306        while (1)
1307        {
1308                const int index = strtol(ptr, &endptr, 10);
1309                if (ptr == endptr) break;
1310
1311                objIndices.push_back(index);
1312                ptr = endptr;
1313        }
1314
1315        MeshInstance dummyInst(NULL);
1316        vector<int>::const_iterator it, it_end = objIndices.end();
1317
1318        for (it = objIndices.begin(); it != it_end; ++ it)
1319        {
1320                const int objId = *it; 
1321                dummyInst.SetId(objId);
1322
1323                ObjectContainer::const_iterator oit =
1324                        lower_bound(mPreprocessorObjects.begin(),
1325                                                mPreprocessorObjects.end(),
1326                                                (Intersectable *)&dummyInst,
1327                                                ilt);   
1328                                                       
1329                if ((oit != mPreprocessorObjects.end()) && ((*oit)->GetId() == objId))
1330                {
1331                        objects.push_back(*oit);
1332                }
1333                else
1334                {
1335                        //cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
1336                }
1337        }
1338}
1339
1340
1341void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
1342{
1343        const int len = attributes.getLength();
1344        Vector3 minBox, maxBox;
1345
1346        for (int i = 0; i < len; ++ i)
1347        {
1348                string attrName(StrX(attributes.getName(i)).LocalForm());
1349                StrX attrValue(attributes.getValue(i));
1350                const char *ptr = attrValue.LocalForm();
1351
1352                if (attrName == "min")
1353                {
1354                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1355                }
1356                if (attrName == "max")
1357                {
1358                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1359                }
1360        }
1361
1362        BvhInterior* interior = new BvhInterior(AxisAlignedBox3(minBox, maxBox));
1363
1364        if (mCurrentBvhNode) // replace NULL child of parent with current node
1365        {
1366                BvhInterior *parent = static_cast<BvhInterior *>(mCurrentBvhNode);
1367                parent->ReplaceChildLink(NULL, interior);
1368                interior->SetParent(parent);
1369        }
1370        else
1371        {
1372                mHierarchyManager->mBvHierarchy->mRoot = interior;
1373        }
1374
1375        mCurrentBvhNode = interior;
1376}
1377
1378
1379// ---------------------------------------------------------------------------
1380//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
1381// ---------------------------------------------------------------------------
1382
1383
1384void
1385ViewCellsParseHandlers::error(const SAXParseException& e)
1386{
1387  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
1388                            << ", line " << e.getLineNumber()
1389                            << ", char " << e.getColumnNumber()
1390                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1391}
1392
1393void
1394ViewCellsParseHandlers::fatalError(const SAXParseException& e)
1395{
1396  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
1397                            << ", line " << e.getLineNumber()
1398                            << ", char " << e.getColumnNumber()
1399                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1400}
1401
1402void
1403ViewCellsParseHandlers::warning(const SAXParseException& e)
1404{
1405  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
1406                            << ", line " << e.getLineNumber()
1407                            << ", char " << e.getColumnNumber()
1408                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1409}
1410
1411
1412bool ViewCellsParser::ParseViewCellsFile(const string &filename,
1413                                                                                 ViewCellsManager **viewCells,
1414                                                                                 ObjectContainer &pvsObjects,
1415                                                                                 ObjectContainer &preprocessorObjects,
1416                                                                                 BoundingBoxConverter *bconverter)
1417{
1418        // Initialize the XML4C system
1419        try {
1420                XMLPlatformUtils::Initialize();
1421        }
1422
1423        catch (const XMLException& toCatch)
1424        {
1425                XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
1426                        << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
1427                return false;
1428        }
1429
1430        //  cout<<"parsing started"<<endl<<flush;
1431
1432        //
1433        //  Create a SAX parser object. Then, according to what we were told on
1434        //  the command line, set the options.
1435        //
1436        SAXParser* parser = new SAXParser;
1437        parser->setValidationScheme(valScheme);
1438        parser->setDoNamespaces(doNamespaces);
1439        parser->setDoSchema(doSchema);
1440        parser->setValidationSchemaFullChecking(schemaFullChecking);
1441
1442
1443        //
1444        //  Create our SAX handler object and install it on the parser, as the
1445        //  document and error handler. We are responsible for cleaning them
1446        //  up, but since its just stack based here, there's nothing special
1447        //  to do.
1448        //
1449        ViewCellsParseHandlers handler(pvsObjects, preprocessorObjects, bconverter);
1450        parser->setDocumentHandler(&handler);
1451        parser->setErrorHandler(&handler);
1452
1453        unsigned long duration;
1454        int errorCount = 0;
1455        // create a faux scope so that 'src' destructor is called before
1456        // XMLPlatformUtils::Terminate
1457        {
1458                //
1459                //  Kick off the parse and catch any exceptions. Create a standard
1460                //  input input source and tell the parser to parse from that.
1461                //
1462                //    StdInInputSource src;
1463                try
1464                {
1465                        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
1466
1467#if USE_GZLIB
1468                        XMLCh *myFilePath = XMLString::transcode(filename.c_str());
1469
1470                        GzFileInputSource isource(myFilePath);
1471                        parser->parse(isource);
1472#else
1473                        parser->parse(filename.c_str());
1474
1475#endif
1476
1477                        //if (mCreatePvsObjects)
1478                        //      handler.ReplacePvs();
1479
1480                        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1481                        duration = endMillis - startMillis;
1482                        errorCount = parser->getErrorCount();
1483                }
1484                catch (const OutOfMemoryException&)
1485                {
1486                        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1487                        errorCount = 2;
1488                        return false;
1489                }
1490                catch (const XMLException& e)
1491                {
1492                        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
1493                                << StrX(e.getMessage())
1494                                << "\n" << XERCES_STD_QUALIFIER endl;
1495                        errorCount = 1;
1496                        return false;
1497                }
1498
1499
1500                // Print out the stats that we collected and time taken
1501                if (!errorCount)
1502                {
1503                        XERCES_STD_QUALIFIER cerr << filename << ": " << duration << " ms ("
1504                                << handler.GetElementCount() << " elems, "
1505                                << handler.GetAttrCount() << " attrs, "
1506                                << handler.GetSpaceCount() << " spaces, "
1507                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1508                }
1509        }
1510
1511        //
1512        //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1513        //
1514        delete parser;
1515
1516        XMLPlatformUtils::Terminate();
1517
1518        //-- assign new view cells manager
1519        *viewCells = handler.mViewCellsManager;
1520
1521        if (errorCount > 0)
1522                return false;
1523        else
1524                return true;
1525}
1526
1527}
Note: See TracBrowser for help on using the repository browser.