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

Revision 1486, 33.4 KB checked in by mattausch, 18 years ago (diff)

worked on guided visibility sampling

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