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

Revision 2115, 36.1 KB checked in by mattausch, 17 years ago (diff)

changed pvs loading: loading objects in a first pass

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