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

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