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

Revision 1287, 33.5 KB checked in by mattausch, 18 years ago (diff)

implemented bv hierarchy

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