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

Revision 2123, 36.5 KB checked in by mattausch, 18 years ago (diff)

worded on obj loading in Ogre

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