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

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