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

Revision 1421, 33.4 KB checked in by mattausch, 18 years ago (diff)
Line 
1// ---------------------------------------------------------------------------
2//  Includes for all the program files to see
3// ---------------------------------------------------------------------------
4#include <string.h>
5#include <stdlib.h>
6#include <iostream>
7using namespace std;
8#include <xercesc/util/PlatformUtils.hpp>
9
10// ---------------------------------------------------------------------------
11//  Includes
12// ---------------------------------------------------------------------------
13#include <xercesc/framework/StdInInputSource.hpp>
14#include <xercesc/parsers/SAXParser.hpp>
15#include <xercesc/util/OutOfMemoryException.hpp>
16
17// ---------------------------------------------------------------------------
18//  Includes
19// ---------------------------------------------------------------------------
20#include <xercesc/sax/AttributeList.hpp>
21#include <xercesc/sax/SAXParseException.hpp>
22#include <xercesc/sax/SAXException.hpp>
23
24#include "ViewCellsParser.h"
25
26#include "ViewCellsParserXerces.h"
27#include "Mesh.h"
28#include "VspBspTree.h"
29#include "ViewCellBsp.h"
30#include "ViewCellsManager.h"
31#include "GzFileInputSource.h"
32#include "OspTree.h"
33#include "VspTree.h"
34#include "KdTree.h"
35#include "BvHierarchy.h"
36#include "HierarchyManager.h"
37
38
39namespace GtpVisibilityPreprocessor {
40
41
42// ---------------------------------------------------------------------------
43//  Local data
44//
45//  doNamespaces
46//      Indicates whether namespace processing should be enabled or not.
47//      The default is no, but -n overrides that.
48//
49//  doSchema
50//      Indicates whether schema processing should be enabled or not.
51//      The default is no, but -s overrides that.
52//
53//  schemaFullChecking
54//      Indicates whether full schema constraint checking should be enabled or not.
55//      The default is no, but -s overrides that.
56//
57//  valScheme
58//      Indicates what validation scheme to use. It defaults to 'auto', but
59//      can be set via the -v= command.
60// ---------------------------------------------------------------------------
61static bool     doNamespaces       = false;
62static bool     doSchema           = false;
63static bool     schemaFullChecking = false;
64static SAXParser::ValSchemes    valScheme       = SAXParser::Val_Auto;
65
66
67
68inline static bool ilt(Intersectable *obj1, Intersectable *obj2)
69{
70        return obj1->mId < obj2->mId;
71}
72
73
74// ---------------------------------------------------------------------------
75//  StdInParseHandlers: Constructors and Destructor
76// ---------------------------------------------------------------------------
77ViewCellsParseHandlers::ViewCellsParseHandlers(ObjectContainer *objects,
78                                                                                           BoundingBoxConverter *bconverter):
79  mElementCount(0)
80  , mAttrCount(0)
81  , mCharacterCount(0)
82  , mSpaceCount(0)
83  , mViewCellsManager(NULL)
84  , mVspBspTree(NULL)
85  , mBspTree(NULL)
86  , mViewCellsTree(NULL)
87  , mCurrentState(PARSE_OPTIONS)
88  , mCurrentViewCell(NULL)
89  , mCurrentBspNode(NULL)
90  , mCurrentVspNode(NULL)
91  , mCurrentOspNode(NULL)
92  , mCurrentBvhNode(NULL)
93  , mObjects(objects)
94  , mBoundingBoxConverter(bconverter)
95  , mHierarchyManager(NULL)
96{
97        std::stable_sort(mObjects->begin(), mObjects->end(), ilt);
98}
99
100
101ViewCellsParseHandlers::~ViewCellsParseHandlers()
102{
103}
104
105
106// ---------------------------------------------------------------------------
107//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
108// ---------------------------------------------------------------------------
109
110
111void ViewCellsParseHandlers::endElement(const XMLCh* const name)
112{
113        StrX lname(name);
114        string element(lname.LocalForm());
115
116        if (element == "BoundingBoxes")
117        {
118                EndBoundingBoxes();
119        }
120
121        if (element == "ViewCells")
122        {       
123                EndViewCells();
124        }
125
126        if (element == "ObjectSpaceHierarchy")
127        {
128                EndObjectSpaceHierarchy();
129        }
130
131        // finished, create view cells manager
132        if (element == "VisibilitySolution")
133        {
134                CreateViewCellsManager();
135        }
136
137        if (element == "Interior")
138        {
139                switch (mCurrentState)
140                {
141                case PARSE_VIEWCELLS:
142                        EndViewCellInterior();
143                        break;
144                case PARSE_OBJECTSPACE_HIERARCHY:
145                        EndObjectSpaceHierarchyInterior();
146                        break;
147                case PARSE_VIEWSPACE_HIERARCHY:
148                        EndViewSpaceHierarchyInterior();
149                        break;
150                default:
151                        break;
152                }
153        }
154}
155
156
157void ViewCellsParseHandlers::EndObjectSpaceHierarchy()
158{
159        if (mObjectSpaceHierarchyType == OSP)
160        {
161                // 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
922                mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
923        }
924        else if (mViewSpaceHierarchyType == VSP)
925        {
926                Debug << "creating view cells manager: VspOsp" << endl;
927                // hack
928                mViewCellsManager = new VspOspViewCellsManager(mViewCellsTree, mHierarchyManager);
929        }
930
931        mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
932}
933
934
935void ViewCellsParseHandlers::characters(const XMLCh* const chars,
936                                                                                const unsigned int length)
937{
938        mCharacterCount += length;
939}
940
941
942void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
943                                                                                                 const unsigned int length)
944{
945        mSpaceCount += length;
946}
947
948
949void ViewCellsParseHandlers::resetDocument()
950{
951        mAttrCount = 0;
952        mCharacterCount = 0;
953        mElementCount = 0;
954        mSpaceCount = 0;
955}
956
957
958void ViewCellsParseHandlers::StartVspLeaf(AttributeList& attributes)
959{
960        VspLeaf * leaf;
961               
962        if (mCurrentVspNode) // replace front or (if not NULL) back child
963        {
964                VspInterior *interior = dynamic_cast<VspInterior *>(mCurrentVspNode);
965                leaf = new VspLeaf(interior);
966                interior->ReplaceChildLink(NULL, leaf);
967        }
968        else
969        {
970                leaf = new VspLeaf();
971                mVspTree->mRoot = leaf;
972        }
973
974        //-- find associated view cell
975        int viewCellId;
976       
977        int len = attributes.getLength();
978         
979        for (int i = 0; i < len; ++ i)
980        {
981                string attrName(StrX(attributes.getName(i)).LocalForm());
982                StrX attrValue(attributes.getValue(i));
983
984                const char *ptr = attrValue.LocalForm();
985                char *endptr = NULL;
986
987                if (attrName == "viewCellId")
988                {
989                        viewCellId = strtol(ptr, &endptr, 10);
990                }
991        }
992       
993        if (viewCellId >= 0) // valid view cell
994        {
995                // TODO: get view cell with specified id
996                ViewCellInterior dummyVc;
997                dummyVc.SetId(viewCellId);
998
999                //cout << "\nsearching view cell with id " << viewCellId << endl;
1000
1001                ViewCellContainer::iterator vit =
1002                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
1003                       
1004                if (vit == mViewCells.end())
1005                        cout << "error: view cell " << viewCellId << " not found" << endl;
1006       
1007                VspViewCell *viewCell = dynamic_cast<VspViewCell *>(*vit);
1008               
1009                if (viewCell->GetId() == viewCellId)
1010                {
1011                        leaf->SetViewCell(viewCell);
1012                        viewCell->mLeaf = leaf;
1013                }
1014                else
1015                {
1016                        cout << "error: view cell does not exist" << endl;
1017                }
1018        }
1019        else
1020        {       
1021                // add to invalid view space
1022                leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
1023                leaf->SetTreeValid(false);
1024                mVspTree->PropagateUpValidity(leaf);
1025        }
1026}
1027
1028
1029void ViewCellsParseHandlers::StartVspInterior(AttributeList& attributes)
1030{
1031        AxisAlignedPlane plane;
1032        int len = attributes.getLength();
1033
1034        for (int i = 0; i < len; ++ i)
1035        {
1036                string attrName(StrX(attributes.getName(i)).LocalForm());
1037                StrX attrValue(attributes.getValue(i));
1038                const char *ptr = attrValue.LocalForm();
1039
1040                if (attrName == "plane")
1041                {
1042                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1043                }
1044        }
1045
1046        VspInterior* interior = new VspInterior(plane);
1047       
1048        if (mCurrentVspNode) // replace NULL child of parent with current node
1049        {
1050                VspInterior *parent = dynamic_cast<VspInterior *>(mCurrentVspNode);
1051
1052                parent->ReplaceChildLink(NULL, interior);
1053                interior->SetParent(parent);
1054               
1055                AxisAlignedBox3 frontBox, backBox;
1056
1057                parent->GetBoundingBox().Split(
1058                        parent->GetPlane().mAxis,
1059                        parent->GetPlane().mPosition,
1060                        frontBox,
1061                        backBox);
1062
1063                if (parent->GetFront() == interior)
1064                        interior->SetBoundingBox(frontBox);
1065                else
1066                        interior->SetBoundingBox(backBox);
1067        }
1068        else
1069        {
1070                mVspTree->mRoot = interior;
1071                interior->SetBoundingBox(mVspTree->GetBoundingBox());
1072        }
1073
1074        mCurrentVspNode = interior;
1075}
1076
1077
1078void ViewCellsParseHandlers::StartOspInterior(AttributeList& attributes)
1079{
1080        AxisAlignedPlane plane;
1081        int len = attributes.getLength();
1082
1083        for (int i = 0; i < len; ++ i)
1084        {
1085                string attrName(StrX(attributes.getName(i)).LocalForm());
1086                StrX attrValue(attributes.getValue(i));
1087                const char *ptr = attrValue.LocalForm();
1088
1089                if (attrName == "plane")
1090                {
1091                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1092                }
1093        }
1094
1095        KdInterior* interior = new KdInterior(NULL);
1096       
1097        interior->mAxis = plane.mAxis;
1098        interior->mPosition = plane.mPosition;
1099
1100        if (mCurrentOspNode) // replace NULL child of parent with current node
1101        {
1102                KdInterior *parent = dynamic_cast<KdInterior *>(mCurrentOspNode);
1103                parent->ReplaceChildLink(NULL, interior);
1104                interior->mParent = parent;
1105
1106                AxisAlignedBox3 frontBox, backBox;
1107
1108                parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
1109
1110                if (parent->mFront == interior)
1111                        interior->mBox = frontBox;
1112                else
1113                        interior->mBox = backBox;
1114        }
1115        else
1116        {
1117                mHierarchyManager->mOspTree->mRoot = interior;
1118                interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
1119        }
1120
1121        mCurrentOspNode = interior;
1122}
1123
1124
1125void ViewCellsParseHandlers::StartOspLeaf(AttributeList& attributes)
1126{
1127        KdLeaf * leaf =
1128                new KdLeaf(dynamic_cast<KdInterior *>(mCurrentOspNode), NULL);
1129
1130        if (mCurrentOspNode) // replace front or (if not NULL) back child
1131        {
1132                dynamic_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
1133        }
1134        else
1135        {
1136                mHierarchyManager->mOspTree->mRoot = leaf;
1137        }
1138}
1139
1140
1141void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
1142{
1143        const int len = attributes.getLength();
1144        Vector3 minBox, maxBox;
1145
1146        ObjectContainer objects;
1147
1148        for (int i = 0; i < len; ++ i)
1149        {
1150                string attrName(StrX(attributes.getName(i)).LocalForm());
1151                StrX attrValue(attributes.getValue(i));
1152                const char *ptr = attrValue.LocalForm();
1153
1154                if (attrName == "min")
1155                {
1156                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1157                }
1158                if (attrName == "max")
1159                {
1160                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1161                }
1162                if (attrName == "objects")
1163                {
1164                        StartBvhLeafObjects(objects, ptr);
1165                }
1166        }
1167
1168        AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox);
1169
1170        BvhLeaf *leaf;
1171
1172        if (mCurrentBvhNode) // replace front or (if not NULL) back child
1173        {
1174                BvhInterior *interior = dynamic_cast<BvhInterior *>(mCurrentBvhNode);
1175                leaf = new BvhLeaf(box, interior, (int)objects.size());
1176                interior->ReplaceChildLink(NULL, leaf);
1177        }
1178        else
1179        {
1180                leaf = new BvhLeaf(box, NULL, (int)objects.size());
1181                mHierarchyManager->mBvHierarchy->mRoot = leaf;
1182        }
1183
1184        leaf->mObjects = objects;
1185}
1186
1187
1188void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects,
1189                                                                                                 const char *ptr)
1190{
1191        vector<int> objIndices;
1192
1193        char *endptr;
1194                       
1195        while (1)
1196        {
1197                const int index = strtol(ptr, &endptr, 10);
1198                if (ptr == endptr) break;
1199
1200                objIndices.push_back(index);
1201                ptr = endptr;
1202        }
1203
1204        //TODO: find objects and add them to pvs
1205        // TODO: get view cell with specified id
1206        MeshInstance dummyInst(NULL);
1207
1208        vector<int>::const_iterator it, it_end = objIndices.end();
1209
1210        for (it = objIndices.begin(); it != it_end; ++ it)
1211        {
1212                const int objId = *it; 
1213                dummyInst.SetId(objId);
1214
1215                ObjectContainer::iterator oit =
1216                        lower_bound(mObjects->begin(),
1217                                                mObjects->end(),
1218                                                (Intersectable *)&dummyInst,
1219                                                ilt);   
1220                                                       
1221                if ((oit != mObjects->end()) && ((*oit)->GetId() == objId))
1222                {
1223                        objects.push_back(*oit);       
1224                }
1225                else
1226                {
1227                        cout << "error: object with id " << objId << " does not exist" << endl;
1228                }
1229        }
1230}
1231
1232
1233void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
1234{
1235        const int len = attributes.getLength();
1236        Vector3 minBox, maxBox;
1237
1238        for (int i = 0; i < len; ++ i)
1239        {
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                {
1246                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1247                }
1248                if (attrName == "max")
1249                {
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                BvhInterior *parent = dynamic_cast<BvhInterior *>(mCurrentBvhNode);
1259                parent->ReplaceChildLink(NULL, interior);
1260                interior->SetParent(parent);
1261        }
1262        else
1263        {
1264                mHierarchyManager->mBvHierarchy->mRoot = interior;
1265        }
1266
1267        mCurrentBvhNode = interior;
1268}
1269
1270
1271// ---------------------------------------------------------------------------
1272//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
1273// ---------------------------------------------------------------------------
1274
1275
1276void
1277ViewCellsParseHandlers::error(const SAXParseException& e)
1278{
1279  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
1280                            << ", line " << e.getLineNumber()
1281                            << ", char " << e.getColumnNumber()
1282                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1283}
1284
1285void
1286ViewCellsParseHandlers::fatalError(const SAXParseException& e)
1287{
1288  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
1289                            << ", line " << e.getLineNumber()
1290                            << ", char " << e.getColumnNumber()
1291                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1292}
1293
1294void
1295ViewCellsParseHandlers::warning(const SAXParseException& e)
1296{
1297  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
1298                            << ", line " << e.getLineNumber()
1299                            << ", char " << e.getColumnNumber()
1300                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1301}
1302
1303
1304bool ViewCellsParser::ParseViewCellsFile(const string filename,
1305                                                                                 ViewCellsManager **viewCells,
1306                                                                                 ObjectContainer *objects,
1307                                                                                 BoundingBoxConverter *bconverter)
1308{
1309  // Initialize the XML4C system
1310  try {
1311    XMLPlatformUtils::Initialize();
1312  }
1313 
1314  catch (const XMLException& toCatch)
1315    {
1316      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
1317                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
1318      return false;
1319    }
1320 
1321  //
1322  //  Create a SAX parser object. Then, according to what we were told on
1323  //  the command line, set the options.
1324  //
1325  SAXParser* parser = new SAXParser;
1326  parser->setValidationScheme(valScheme);
1327  parser->setDoNamespaces(doNamespaces);
1328  parser->setDoSchema(doSchema);
1329  parser->setValidationSchemaFullChecking(schemaFullChecking);
1330 
1331
1332  //
1333  //  Create our SAX handler object and install it on the parser, as the
1334  //  document and error handler. We are responsible for cleaning them
1335  //  up, but since its just stack based here, there's nothing special
1336  //  to do.
1337  //
1338  ViewCellsParseHandlers handler(objects, bconverter);
1339  parser->setDocumentHandler(&handler);
1340  parser->setErrorHandler(&handler);
1341 
1342  unsigned long duration;
1343  int errorCount = 0;
1344  // create a faux scope so that 'src' destructor is called before
1345  // XMLPlatformUtils::Terminate
1346  {
1347    //
1348    //  Kick off the parse and catch any exceptions. Create a standard
1349    //  input input source and tell the parser to parse from that.
1350    //
1351    //    StdInInputSource src;
1352    try
1353        {
1354        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
1355
1356#if USE_GZLIB
1357        XMLCh *myFilePath = XMLString::transcode(filename.c_str());
1358       
1359        GzFileInputSource isource(myFilePath);
1360        parser->parse(isource);
1361#else
1362        parser->parse(filename.c_str());
1363#endif
1364
1365        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1366        duration = endMillis - startMillis;
1367        errorCount = parser->getErrorCount();
1368      }
1369    catch (const OutOfMemoryException&)
1370      {
1371        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1372        errorCount = 2;
1373        return false;
1374      }
1375    catch (const XMLException& e)
1376      {
1377                        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
1378                                  << StrX(e.getMessage())
1379                                  << "\n" << XERCES_STD_QUALIFIER endl;
1380                        errorCount = 1;
1381                        return false;
1382      }
1383
1384   
1385    // Print out the stats that we collected and time taken
1386    if (!errorCount) {
1387                XERCES_STD_QUALIFIER cerr << filename << ": " << duration << " ms ("
1388                                << handler.GetElementCount() << " elems, "
1389                                << handler.GetAttrCount() << " attrs, "
1390                                << handler.GetSpaceCount() << " spaces, "
1391                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1392    }
1393  }
1394 
1395  //
1396  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1397  //
1398  delete parser;
1399 
1400  XMLPlatformUtils::Terminate();
1401 
1402  //-- assign new view cells manager
1403  *viewCells = handler.mViewCellsManager;
1404 
1405  if (errorCount > 0)
1406    return false;
1407  else
1408    return true;
1409}
1410
1411}
Note: See TracBrowser for help on using the repository browser.