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

Revision 2176, 36.5 KB checked in by mattausch, 17 years ago (diff)

removed using namespace std from .h

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