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

Revision 2049, 37.0 KB checked in by bittner, 17 years ago (diff)

glrenderer updates

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