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

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