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

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