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

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