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

Revision 1551, 33.6 KB checked in by mattausch, 18 years ago (diff)

updated view cells loading. probably no optimal for performance

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                StartViewCell(attributes, false);
396        }
397
398        if (element == "Leaf")
399        {
400                cout << "l";
401                StartViewCell(attributes, true);
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(ObjectPvs &pvs, const char *ptr)
467{
468        // handle obect indices
469        vector<int> objIndices;
470        char *endptr;
471                       
472        while (1)
473        {       // read object ids
474                const int index = strtol(ptr, &endptr, 10);
475                if (ptr == endptr)
476                        break;
477                objIndices.push_back(index);
478                ptr = endptr;
479        }
480
481        // TODO:
482        // 1) find objects and add them to pvs
483        // 2) get view cell with specified id
484        MeshInstance dummyInst(NULL);
485
486        vector<int>::const_iterator it, it_end = objIndices.end();
487        for (it = objIndices.begin(); it != it_end; ++ it)
488        {
489                const int objId = *it; 
490                dummyInst.SetId(objId);
491
492                ObjectContainer::iterator oit =
493                        lower_bound(mObjects->begin(),
494                        mObjects->end(),
495                        (Intersectable *)&dummyInst, ilt);     
496
497                if ((oit != mObjects->end()) && ((*oit)->GetId() == objId))
498                {
499                        // $$JB we should store a float a per object which corresponds
500                        // to sumof pdfs, i.e. its relative visibility
501                        // temporarily set to 1.0f
502                        pvs.AddSample(*oit, 1.0f);                             
503                }
504                else
505                {
506                        cout << "error: object with id " << objId << " does not exist" << endl;
507                }
508        }
509}
510
511
512void ViewCellsParseHandlers::StartViewSpaceHierarchy(AttributeList& attributes)
513{
514        int len = attributes.getLength();
515
516        Vector3 bmin, bmax;
517
518        for (int i = 0; i < len; ++ i)
519        {
520                string attrName(StrX(attributes.getName(i)).LocalForm());
521                StrX attrValue(attributes.getValue(i));
522                const char *ptr = attrValue.LocalForm();
523
524                // hierarchy type
525                if (attrName == "type")
526                {
527                        if (strcmp(ptr, "bsp") == 0)
528                        {
529                                cout << "\nview space hierarchy: Bsp" << endl;
530                                mViewSpaceHierarchyType = BSP;
531                        }
532                        else if (strcmp(ptr, "vsp") == 0)
533                        {
534                                cout << "\nview space hierarchy: Vsp" << endl;
535                                mViewSpaceHierarchyType = VSP;
536                        }
537                }
538                else if (attrName == "min") // the view space extent
539                {
540                        sscanf(ptr, "%f %f %f",
541                                   &bmin.x, &bmin.y, &bmin.z);
542                }
543                else if (attrName == "max")
544                {
545                        sscanf(ptr, "%f %f %f",
546                                   &bmax.x, &bmax.y, &bmax.z);
547                }
548        }
549
550        mViewSpaceBox = AxisAlignedBox3(bmin, bmax);
551
552        // create the hierarchy based on this information
553        CreateViewSpaceHierarchy();
554}
555
556
557void ViewCellsParseHandlers::StartObjectSpaceHierarchy(AttributeList& attributes)
558{
559        const int len = attributes.getLength();
560        Vector3 bmin, bmax;
561
562        for (int i = 0; i < len; ++ i)
563        {
564                string attrName(StrX(attributes.getName(i)).LocalForm());
565                StrX attrValue(attributes.getValue(i));
566                const char *ptr = attrValue.LocalForm();
567
568                // hierarchy type
569                if (attrName == "type")
570                {
571                        if (strcmp(ptr, "osp") == 0)
572                        {
573                                cout << "\nobject space hierarchy: Osp" << endl;
574
575                                mHierarchyManager =
576                                        new HierarchyManager(HierarchyManager::KD_BASED_OBJ_SUBDIV);
577
578                                DEL_PTR(mHierarchyManager->mVspTree);
579                                mHierarchyManager->mVspTree = mVspTree;
580
581                                mObjectSpaceHierarchyType = OSP;
582
583                                //std::stable_sort(objects.begin(), objects.end(), ilt);
584                                mHierarchyManager->mOspTree->mBoundingBox.Initialize();
585                                ObjectContainer::const_iterator oit, oit_end = mObjects->end();
586                               
587                                //-- compute bounding box
588                                for (oit = mObjects->begin(); oit != oit_end; ++ oit)
589                                {
590                                        Intersectable *obj = *oit;
591                                        // compute bounding box of view space
592                                        mHierarchyManager->mOspTree->mBoundingBox.Include(obj->GetBox());
593                                }
594                        }
595                        else if (strcmp(ptr, "bvh") == 0)
596                        {
597                                cout << "\nobject space hierarchy: Bvh" << endl;
598                                mObjectSpaceHierarchyType = BVH;
599                                mHierarchyManager =
600                                        new HierarchyManager(HierarchyManager::BV_BASED_OBJ_SUBDIV);
601
602                                DEL_PTR(mHierarchyManager->mVspTree);
603                                mHierarchyManager->mVspTree = mVspTree;
604                        }
605                }
606        }
607}
608
609
610void ViewCellsParseHandlers::StartBoundingBox(AttributeList& attributes)
611{
612        int len = attributes.getLength();
613
614        Vector3 bmin, bmax;
615        int id;
616
617        for (int i = 0; i < len; ++ i)
618        {
619                string attrName(StrX(attributes.getName(i)).LocalForm());
620                StrX attrValue(attributes.getValue(i));
621                const char *ptr = attrValue.LocalForm();
622
623                if (attrName == "id")
624                {
625                        sscanf(ptr, "%d", &id);
626                }
627                if (attrName == "min")
628                {
629                        sscanf(ptr, "%f %f %f", &bmin.x, &bmin.y, &bmin.z);
630                }
631                else if (attrName == "max")
632                {
633                        sscanf(ptr, "%f %f %f", &bmax.x, &bmax.y, &bmax.z);
634                }
635        }
636
637        AxisAlignedBox3 box(bmin, bmax);
638        mIBoundingBoxes.push_back(IndexedBoundingBox(id, box));
639        //cout << "bbox: " << box << endl;
640}
641
642
643void ViewCellsParseHandlers::StartBspLeaf(AttributeList& attributes)
644{
645        BspLeaf * leaf;
646
647        if (mCurrentBspNode) // replace front or (if not NULL) back child
648        {
649                BspInterior *interior = dynamic_cast<BspInterior *>(mCurrentBspNode);
650
651                leaf = new BspLeaf(interior);
652                interior->ReplaceChildLink(NULL, leaf);
653        }
654        else
655        {
656                leaf = new BspLeaf();
657                mVspBspTree->mRoot = leaf;
658        }
659
660        ///////////
661        //-- find associated view cell
662
663        int viewCellId;
664       
665        int len = attributes.getLength();
666         
667        for (int i = 0; i < len; ++ i)
668        {
669                string attrName(StrX(attributes.getName(i)).LocalForm());
670                StrX attrValue(attributes.getValue(i));
671
672                const char *ptr = attrValue.LocalForm();
673                char *endptr = NULL;
674
675                if (attrName == "viewCellId")
676                {
677                        viewCellId = strtol(ptr, &endptr, 10);
678                }
679        }
680       
681        if (viewCellId >= 0) // valid view cell found
682        {
683                // TODO: get view cell with specified id
684                ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
685                BspViewCell *viewCell = dynamic_cast<BspViewCell *>((*vit).second);
686       
687                if (viewCell->GetId() == viewCellId)
688                {
689                        // create new view cell for bsp nodes
690                        leaf->SetViewCell(viewCell);
691                        viewCell->mLeaves.push_back(leaf);
692                }
693                else
694                {
695                        cout << "error: view cell does not exist" << endl;
696                }
697        }
698        else
699        {
700                // add to invalid view space
701                leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
702                leaf->SetTreeValid(false);
703                mVspBspTree->PropagateUpValidity(leaf);
704        }
705}
706
707
708void ViewCellsParseHandlers::StartBspInterior(AttributeList& attributes)
709{
710        Plane3 plane;
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                const char *ptr = attrValue.LocalForm();
718
719                if (attrName == "plane")
720                {
721                        sscanf(ptr, "%f %f %f %f",
722                                   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
723                }
724        }
725
726        BspInterior* interior = new BspInterior(plane);
727       
728        if (mCurrentBspNode) // replace NULL child of parent with current node
729        {
730                BspInterior *parent = dynamic_cast<BspInterior *>(mCurrentBspNode);
731
732                parent->ReplaceChildLink(NULL, interior);
733                interior->SetParent(parent);
734        }
735        else
736        {
737                mVspBspTree->mRoot = interior;
738        }
739
740        mCurrentBspNode = interior;
741}
742
743
744ViewCell *ViewCellsParseHandlers::GetOrCreateViewCell(const int id, const bool isLeaf)
745{
746        ViewCellsMap::iterator vit = mViewCells.find(id);
747
748        if (vit != mViewCells.end())
749        {
750                return (*vit).second;
751        }
752        else
753        {
754                ViewCell *vc;
755                if (isLeaf)
756                {
757                        vc = new ViewCellLeaf();
758                }
759                else
760                {
761                        vc = new ViewCellInterior();
762                }
763
764                vc->SetId(id);
765                mViewCells[id] = vc;
766                return vc;
767        }
768}
769
770
771void ViewCellsParseHandlers::StartViewCell(AttributeList& attributes, const bool isLeaf)
772{
773        ViewCell *viewCell = NULL;
774       
775        const int len = attributes.getLength();
776        float mergeCost;
777        ObjectPvs pvs;
778
779        for (int i = 0; i < len; ++ i)
780        {
781                const string attrName(StrX(attributes.getName(i)).LocalForm());
782       
783                if (attrName == "id")
784                {
785                        const StrX attrValue(attributes.getValue(i));
786                        const char *ptr = attrValue.LocalForm();
787                        char *endptr = NULL;
788                        const int id = strtol(ptr, &endptr, 10);
789
790                        // create new view cell, otherwise use reference.
791                        viewCell = GetOrCreateViewCell(id, isLeaf);
792                       
793                        if (mCurrentViewCell) // replace front or (if not NULL) back child
794                        {       
795                                ViewCellInterior *interior =
796                                        dynamic_cast<ViewCellInterior *>(mCurrentViewCell);
797                                interior->SetupChildLink(viewCell);
798                        }
799                        else
800                        {       // set the new root
801                                mViewCellsTree->SetRoot(viewCell);
802                        }
803                       
804                        if (!isLeaf)
805                        {
806                                mCurrentViewCell = viewCell;
807                        }
808                }
809                if (attrName == "pvs")
810                {
811                        StrX attrValue(attributes.getValue(i));
812                        const char *ptr = attrValue.LocalForm();
813
814                        // note: id must come before pvs!
815                        // otherwise view cell is undefined
816                        StartViewCellPvs(pvs, ptr);
817                }
818                else if (attrName == "active")
819                {
820                        StrX attrValue(attributes.getValue(i));
821                        const char *ptr = attrValue.LocalForm();
822                        char *endptr = NULL;
823                        const bool isActive = (bool)strtol(ptr, &endptr, 10);
824
825                        if (isActive)
826                        {
827                                // TODO
828                        }
829                }
830                else if (attrName == "mergecost")
831                {
832                        StrX attrValue(attributes.getValue(i));
833                       
834                        const char *ptr = attrValue.LocalForm();
835                        char *endptr = NULL;
836                        mergeCost = (float)strtod(ptr, &endptr);
837                }
838        }
839
840        viewCell->SetMergeCost(mergeCost);
841        viewCell->SetPvs(pvs);
842}
843
844
845void ViewCellsParseHandlers::CreateViewSpaceHierarchy()
846{
847        if (mViewSpaceHierarchyType == BSP)
848        {
849                cout << "hierarchy type: Bsp" << endl;
850                mVspBspTree = new VspBspTree();
851
852                // set view space box
853                mVspBspTree->mBox = mViewSpaceBox;
854
855                ViewCellsMap::iterator vit, vit_end = mViewCells.end();
856
857                // remove view cells and exchange them with the
858                // view cells specialized for the current hierarchy node type
859                for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
860                {
861                        ViewCell *vc = (*vit).second;
862                        if (!vc->IsLeaf()) // exchange only leaves
863                                continue;
864                        BspViewCell *bspVc = new BspViewCell();
865                        bspVc->SetId(vc->GetId());
866                        bspVc->SetPvs(vc->GetPvs());
867
868                        if (vc->IsRoot())
869                        {
870                                mViewCellsTree->mRoot = bspVc;
871                        }
872                        else
873                        {
874                vc->GetParent()->ReplaceChildLink(vc, bspVc);
875                        }
876
877                        DEL_PTR(vc);
878                        (*vit).second = bspVc;
879                }
880        }
881        else if (mViewSpaceHierarchyType == VSP)
882        {
883                cout << "hierarchy type: Vsp" << endl;
884                mVspTree = new VspTree();
885
886                // set view space box
887                mVspTree->mBoundingBox = mViewSpaceBox;
888
889                ViewCellsMap::iterator vit, vit_end = mViewCells.end();
890
891                // reset view cells using the current node type
892                for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
893                {
894                        ViewCell *vc = (*vit).second;
895
896                        VspViewCell *vspVc = new VspViewCell();
897                        vspVc->SetPvs(vc->GetPvs());
898                        vspVc->SetId(vc->GetId());
899
900                        if (!vc->IsLeaf()) // exchange only leaves
901                                continue;
902
903                        if (vc->IsRoot())
904                        {
905                                mViewCellsTree->mRoot = vspVc;
906                        }
907                        else
908                        {
909                                vc->GetParent()->ReplaceChildLink(vc, vspVc);
910                        }
911                       
912                        DEL_PTR(vc);
913                        (*vit).second = vspVc;
914                }
915
916                // if object space hierarchy already constructed
917                if (mHierarchyManager)
918                {
919                        mHierarchyManager->mVspTree = mVspTree;
920                        mVspTree->mHierarchyManager = mHierarchyManager;
921                }
922        }
923}
924
925
926void ViewCellsParseHandlers::CreateViewCellsManager()
927{
928        if (mViewSpaceHierarchyType == BSP)
929        {
930                Debug << "creating view cells manager: VspBsp" << endl;
931                mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
932        }
933        else if (mViewSpaceHierarchyType == VSP)
934        {
935                Debug << "creating view cells manager: VspOsp" << endl;
936                mViewCellsManager = new VspOspViewCellsManager(mViewCellsTree, mHierarchyManager);
937        }
938
939        mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
940}
941
942
943void ViewCellsParseHandlers::characters(const XMLCh* const chars,
944                                                                                const unsigned int length)
945{
946        mCharacterCount += length;
947}
948
949
950void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
951                                                                                                 const unsigned int length)
952{
953        mSpaceCount += length;
954}
955
956
957void ViewCellsParseHandlers::resetDocument()
958{
959        mAttrCount = 0;
960        mCharacterCount = 0;
961        mElementCount = 0;
962        mSpaceCount = 0;
963}
964
965
966void ViewCellsParseHandlers::StartVspLeaf(AttributeList& attributes)
967{
968        VspLeaf * leaf;
969               
970        if (mCurrentVspNode) // replace front or (if not NULL) back child
971        {
972                VspInterior *interior = dynamic_cast<VspInterior *>(mCurrentVspNode);
973                leaf = new VspLeaf(interior);
974                interior->ReplaceChildLink(NULL, leaf);
975        }
976        else
977        {
978                leaf = new VspLeaf();
979                mVspTree->mRoot = leaf;
980        }
981
982        /////////////
983        //-- find view cell associated with the id
984
985        int viewCellId;
986       
987        int len = attributes.getLength();
988         
989        for (int i = 0; i < len; ++ i)
990        {
991                string attrName(StrX(attributes.getName(i)).LocalForm());
992                StrX attrValue(attributes.getValue(i));
993
994                const char *ptr = attrValue.LocalForm();
995                char *endptr = NULL;
996
997                if (attrName == "viewCellId")
998                {
999                        viewCellId = strtol(ptr, &endptr, 10);
1000                }
1001        }
1002       
1003        if (viewCellId >= 0) // valid view cell found
1004        {
1005                // TODO: get view cell with specified id
1006                /*ViewCellInterior dummyVc;
1007                dummyVc.SetId(viewCellId);
1008
1009                ViewCellContainer::iterator vit =
1010                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
1011                */
1012                ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
1013                if (vit == mViewCells.end())
1014                        cout << "error: view cell " << viewCellId << " not found" << endl;
1015       
1016                VspViewCell *viewCell = dynamic_cast<VspViewCell *>((*vit).second);
1017               
1018                if (viewCell->GetId() == viewCellId)
1019                {
1020                        leaf->SetViewCell(viewCell);
1021                        viewCell->mLeaves.push_back(leaf);
1022                }
1023                else
1024                {
1025                        cout << "error: view cell does not exist" << endl;
1026                }
1027        }
1028        else
1029        {       
1030                // add to invalid view space
1031                leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
1032                leaf->SetTreeValid(false);
1033                mVspTree->PropagateUpValidity(leaf);
1034        }
1035}
1036
1037
1038void ViewCellsParseHandlers::StartVspInterior(AttributeList& attributes)
1039{
1040        AxisAlignedPlane plane;
1041        int len = attributes.getLength();
1042
1043        for (int i = 0; i < len; ++ i)
1044        {
1045                string attrName(StrX(attributes.getName(i)).LocalForm());
1046                StrX attrValue(attributes.getValue(i));
1047                const char *ptr = attrValue.LocalForm();
1048
1049                if (attrName == "plane")
1050                {
1051                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1052                }
1053        }
1054
1055        VspInterior* interior = new VspInterior(plane);
1056       
1057        if (mCurrentVspNode) // replace NULL child of parent with current node
1058        {
1059                VspInterior *parent = dynamic_cast<VspInterior *>(mCurrentVspNode);
1060
1061                parent->ReplaceChildLink(NULL, interior);
1062                interior->SetParent(parent);
1063               
1064                AxisAlignedBox3 frontBox, backBox;
1065
1066                parent->GetBoundingBox().Split(
1067                        parent->GetPlane().mAxis,
1068                        parent->GetPlane().mPosition,
1069                        frontBox,
1070                        backBox);
1071
1072                if (parent->GetFront() == interior)
1073                        interior->SetBoundingBox(frontBox);
1074                else
1075                        interior->SetBoundingBox(backBox);
1076        }
1077        else
1078        {
1079                mVspTree->mRoot = interior;
1080                interior->SetBoundingBox(mVspTree->GetBoundingBox());
1081        }
1082
1083        mCurrentVspNode = interior;
1084}
1085
1086
1087void ViewCellsParseHandlers::StartOspInterior(AttributeList& attributes)
1088{
1089        AxisAlignedPlane plane;
1090        int len = attributes.getLength();
1091
1092        for (int i = 0; i < len; ++ i)
1093        {
1094                string attrName(StrX(attributes.getName(i)).LocalForm());
1095                StrX attrValue(attributes.getValue(i));
1096                const char *ptr = attrValue.LocalForm();
1097
1098                if (attrName == "plane")
1099                {
1100                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1101                }
1102        }
1103
1104        KdInterior* interior = new KdInterior(NULL);
1105       
1106        interior->mAxis = plane.mAxis;
1107        interior->mPosition = plane.mPosition;
1108
1109        if (mCurrentOspNode) // replace NULL child of parent with current node
1110        {
1111                KdInterior *parent = dynamic_cast<KdInterior *>(mCurrentOspNode);
1112                parent->ReplaceChildLink(NULL, interior);
1113                interior->mParent = parent;
1114
1115                AxisAlignedBox3 frontBox, backBox;
1116
1117                parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
1118
1119                if (parent->mFront == interior)
1120                        interior->mBox = frontBox;
1121                else
1122                        interior->mBox = backBox;
1123        }
1124        else
1125        {
1126                mHierarchyManager->mOspTree->mRoot = interior;
1127                interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
1128        }
1129
1130        mCurrentOspNode = interior;
1131}
1132
1133
1134void ViewCellsParseHandlers::StartOspLeaf(AttributeList& attributes)
1135{
1136        KdLeaf * leaf =
1137                new KdLeaf(dynamic_cast<KdInterior *>(mCurrentOspNode), NULL);
1138
1139        if (mCurrentOspNode) // replace front or (if not NULL) back child
1140        {
1141                dynamic_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
1142        }
1143        else
1144        {
1145                mHierarchyManager->mOspTree->mRoot = leaf;
1146        }
1147}
1148
1149
1150void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
1151{
1152        const int len = attributes.getLength();
1153        Vector3 minBox, maxBox;
1154
1155        ObjectContainer objects;
1156
1157        for (int i = 0; i < len; ++ i)
1158        {
1159                string attrName(StrX(attributes.getName(i)).LocalForm());
1160                StrX attrValue(attributes.getValue(i));
1161                const char *ptr = attrValue.LocalForm();
1162
1163                if (attrName == "min")
1164                {
1165                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1166                }
1167                if (attrName == "max")
1168                {
1169                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1170                }
1171                if (attrName == "objects")
1172                {
1173                        StartBvhLeafObjects(objects, ptr);
1174                }
1175        }
1176
1177        AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox);
1178
1179        BvhLeaf *leaf;
1180
1181        if (mCurrentBvhNode) // replace front or (if not NULL) back child
1182        {
1183                BvhInterior *interior = dynamic_cast<BvhInterior *>(mCurrentBvhNode);
1184                leaf = new BvhLeaf(box, interior, (int)objects.size());
1185                interior->ReplaceChildLink(NULL, leaf);
1186        }
1187        else
1188        {
1189                leaf = new BvhLeaf(box, NULL, (int)objects.size());
1190                mHierarchyManager->mBvHierarchy->mRoot = leaf;
1191        }
1192
1193        leaf->mObjects = objects;
1194        BvHierarchy::AssociateObjectsWithLeaf(leaf);   
1195}
1196
1197
1198void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects,
1199                                                                                                 const char *ptr)
1200{
1201        vector<int> objIndices;
1202        char *endptr;
1203                       
1204        while (1)
1205        {
1206                const int index = strtol(ptr, &endptr, 10);
1207                if (ptr == endptr) break;
1208
1209                objIndices.push_back(index);
1210                ptr = endptr;
1211        }
1212
1213        //TODO: find objects and add them to pvs
1214        // TODO: get view cell with specified id
1215        MeshInstance dummyInst(NULL);
1216
1217        vector<int>::const_iterator it, it_end = objIndices.end();
1218
1219        for (it = objIndices.begin(); it != it_end; ++ it)
1220        {
1221                const int objId = *it; 
1222                dummyInst.SetId(objId);
1223
1224                ObjectContainer::iterator oit =
1225                        lower_bound(mObjects->begin(),
1226                                                mObjects->end(),
1227                                                (Intersectable *)&dummyInst,
1228                                                ilt);   
1229                                                       
1230                if ((oit != mObjects->end()) && ((*oit)->GetId() == objId))
1231                {
1232                        objects.push_back(*oit);
1233                }
1234                else
1235                {
1236                        cout << "error: object with id " << objId << " does not exist" << endl;
1237                }
1238        }
1239}
1240
1241
1242void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
1243{
1244        const int len = attributes.getLength();
1245        Vector3 minBox, maxBox;
1246
1247        for (int i = 0; i < len; ++ i)
1248        {
1249                string attrName(StrX(attributes.getName(i)).LocalForm());
1250                StrX attrValue(attributes.getValue(i));
1251                const char *ptr = attrValue.LocalForm();
1252
1253                if (attrName == "min")
1254                {
1255                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1256                }
1257                if (attrName == "max")
1258                {
1259                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1260                }
1261        }
1262
1263        BvhInterior* interior = new BvhInterior(AxisAlignedBox3(minBox, maxBox));
1264
1265        if (mCurrentBvhNode) // replace NULL child of parent with current node
1266        {
1267                BvhInterior *parent = dynamic_cast<BvhInterior *>(mCurrentBvhNode);
1268                parent->ReplaceChildLink(NULL, interior);
1269                interior->SetParent(parent);
1270        }
1271        else
1272        {
1273                mHierarchyManager->mBvHierarchy->mRoot = interior;
1274        }
1275
1276        mCurrentBvhNode = interior;
1277}
1278
1279
1280// ---------------------------------------------------------------------------
1281//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
1282// ---------------------------------------------------------------------------
1283
1284
1285void
1286ViewCellsParseHandlers::error(const SAXParseException& e)
1287{
1288  XERCES_STD_QUALIFIER cerr << "\nError 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::fatalError(const SAXParseException& e)
1296{
1297  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
1298                            << ", line " << e.getLineNumber()
1299                            << ", char " << e.getColumnNumber()
1300                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1301}
1302
1303void
1304ViewCellsParseHandlers::warning(const SAXParseException& e)
1305{
1306  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
1307                            << ", line " << e.getLineNumber()
1308                            << ", char " << e.getColumnNumber()
1309                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1310}
1311
1312
1313bool ViewCellsParser::ParseViewCellsFile(const string filename,
1314                                                                                 ViewCellsManager **viewCells,
1315                                                                                 ObjectContainer *objects,
1316                                                                                 BoundingBoxConverter *bconverter)
1317{
1318  // Initialize the XML4C system
1319  try {
1320    XMLPlatformUtils::Initialize();
1321  }
1322 
1323  catch (const XMLException& toCatch)
1324    {
1325      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
1326                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
1327      return false;
1328    }
1329 
1330  //
1331  //  Create a SAX parser object. Then, according to what we were told on
1332  //  the command line, set the options.
1333  //
1334  SAXParser* parser = new SAXParser;
1335  parser->setValidationScheme(valScheme);
1336  parser->setDoNamespaces(doNamespaces);
1337  parser->setDoSchema(doSchema);
1338  parser->setValidationSchemaFullChecking(schemaFullChecking);
1339 
1340
1341  //
1342  //  Create our SAX handler object and install it on the parser, as the
1343  //  document and error handler. We are responsible for cleaning them
1344  //  up, but since its just stack based here, there's nothing special
1345  //  to do.
1346  //
1347  ViewCellsParseHandlers handler(objects, bconverter);
1348  parser->setDocumentHandler(&handler);
1349  parser->setErrorHandler(&handler);
1350 
1351  unsigned long duration;
1352  int errorCount = 0;
1353  // create a faux scope so that 'src' destructor is called before
1354  // XMLPlatformUtils::Terminate
1355  {
1356    //
1357    //  Kick off the parse and catch any exceptions. Create a standard
1358    //  input input source and tell the parser to parse from that.
1359    //
1360    //    StdInInputSource src;
1361    try
1362        {
1363        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
1364
1365#if USE_GZLIB
1366        XMLCh *myFilePath = XMLString::transcode(filename.c_str());
1367       
1368        GzFileInputSource isource(myFilePath);
1369        parser->parse(isource);
1370#else
1371        parser->parse(filename.c_str());
1372#endif
1373
1374        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1375        duration = endMillis - startMillis;
1376        errorCount = parser->getErrorCount();
1377      }
1378    catch (const OutOfMemoryException&)
1379      {
1380        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1381        errorCount = 2;
1382        return false;
1383      }
1384    catch (const XMLException& e)
1385      {
1386                        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
1387                                  << StrX(e.getMessage())
1388                                  << "\n" << XERCES_STD_QUALIFIER endl;
1389                        errorCount = 1;
1390                        return false;
1391      }
1392
1393   
1394    // Print out the stats that we collected and time taken
1395    if (!errorCount) {
1396                XERCES_STD_QUALIFIER cerr << filename << ": " << duration << " ms ("
1397                                << handler.GetElementCount() << " elems, "
1398                                << handler.GetAttrCount() << " attrs, "
1399                                << handler.GetSpaceCount() << " spaces, "
1400                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1401    }
1402  }
1403 
1404  //
1405  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1406  //
1407  delete parser;
1408 
1409  XMLPlatformUtils::Terminate();
1410 
1411  //-- assign new view cells manager
1412  *viewCells = handler.mViewCellsManager;
1413 
1414  if (errorCount > 0)
1415    return false;
1416  else
1417    return true;
1418}
1419
1420}
Note: See TracBrowser for help on using the repository browser.