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

Revision 2588, 34.7 KB checked in by bittner, 17 years ago (diff)

sceneBox bugfix

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