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

Revision 2539, 36.0 KB checked in by mattausch, 17 years ago (diff)

fixed obj loading error

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