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

Revision 2097, 36.6 KB checked in by mattausch, 17 years ago (diff)

revived ogre engine pvs

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