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

Revision 2695, 34.8 KB checked in by mattausch, 16 years ago (diff)

debug version: problematic view points for vienna detected

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#ifdef USE_PERFTIMER 
150                mObjectTimer.Exit();
151#endif
152        }
153        // finished paring, create view cells manager
154        else if (element == "VisibilitySolution")
155        {
156                CreateViewCellsManager();
157
158#ifdef USE_PERFTIMER 
159                Debug << "pvs time: " << mPvsTimer.TotalTime() << endl;
160                Debug << "object time: " << mObjectTimer.TotalTime() << endl;
161                Debug << "box time: " << mBoxTimer.TotalTime() << endl;
162#endif
163        }
164        else if (element == "Interior")
165        {
166                switch (mCurrentState)
167                {
168                case PARSE_VIEWCELLS:
169                        EndViewCellInterior();
170                        break;
171                case PARSE_OBJECTSPACE_HIERARCHY:
172                        EndObjectSpaceHierarchyInterior();
173                        break;
174                case PARSE_VIEWSPACE_HIERARCHY:
175                        EndViewSpaceHierarchyInterior();
176                        break;
177                default:
178                        break;
179                }
180        }
181}
182
183
184void ViewCellsParseHandlers::EndObjectSpaceHierarchy()
185{
186        if (mObjectSpaceHierarchyType == OSP)
187        {
188                // for a spatial subdivision, it is not necessary to store
189                // the objects with the leaves, they can be classified geometrically
190                mHierarchyManager->mOspTree->
191                        InsertObjects(mHierarchyManager->mOspTree->mRoot, mPvsObjects);
192        }
193}
194
195
196void ViewCellsParseHandlers::EndViewSpaceHierarchyInterior()
197{
198        switch (mViewSpaceHierarchyType)
199        {
200        case BSP:
201                EndBspInterior();
202                break;
203        case VSP:
204                EndVspInterior();
205                break; 
206        default:
207                Debug << "not implemented view space hierarchy type " << mViewSpaceHierarchyType << endl;
208                break;
209        }
210}
211
212
213void ViewCellsParseHandlers::EndObjectSpaceHierarchyInterior()
214{
215        switch (mObjectSpaceHierarchyType)
216        {
217        case OSP:
218                EndOspInterior();
219                break;
220        case BVH:
221                EndBvhInterior();
222                break; 
223        default:
224                Debug << "not implemented object space hierarchy type " << mViewSpaceHierarchyType << endl;
225                break;
226        }
227}
228
229
230void ViewCellsParseHandlers::EndBspInterior()
231{
232        // go one up in the tree
233        if (mCurrentBspNode->GetParent())
234        {       //cout << "]";
235                mCurrentBspNode = mCurrentBspNode->GetParent();
236        }
237}
238
239
240void ViewCellsParseHandlers::EndBvhInterior()
241{
242        // go one up in the tree
243        if (mCurrentBvhNode->GetParent())
244        {       //cout << "]";
245                mCurrentBvhNode = mCurrentBvhNode->GetParent();
246        }
247}
248
249
250void ViewCellsParseHandlers::EndOspInterior()
251{
252        // go one up in the tree
253        if (mCurrentOspNode->mParent)
254        {       
255                //cout << "]";
256                mCurrentOspNode = mCurrentOspNode->mParent;
257        }
258}
259
260
261void ViewCellsParseHandlers::EndVspInterior()
262{
263        // go one up in the tree
264        if (mCurrentVspNode->GetParent())
265        {       
266                //cout << "]";
267                mCurrentVspNode = mCurrentVspNode->GetParent();
268        }
269}
270
271
272void ViewCellsParseHandlers::EndViewCellInterior()
273{
274        // go one up in the tree
275        if (mCurrentViewCell->GetParent())
276        {       
277                //cout << "]";
278                mCurrentViewCell = mCurrentViewCell->GetParent();
279        }
280}
281
282
283inline static bool vlt(ViewCell *v1, ViewCell *v2)
284{
285        return v1->mId < v2->mId;
286}
287
288
289void ViewCellsParseHandlers::EndViewCells()
290{
291        // sort view cells to help associating view cells according to their id
292        sort(mViewCells.begin(), mViewCells.end(), vlt);
293
294        // not parsing view cells anymore
295        mCurrentState = PARSE_OPTIONS;
296}
297
298
299void ViewCellsParseHandlers::EndBoundingBoxes()
300{
301        const long startTime = GetTime();
302       
303#ifdef USE_PERFTIMER 
304        mBoxTimer.Entry();
305#endif
306        if (mBoundingBoxConverter)
307        {
308                // all bounding boxes gathered in this step =>
309                // associate object ids with bounding boxes
310                mBoundingBoxConverter->IdentifyObjects(mIBoundingBoxes, mPvsObjects);
311        }
312
313        if (USE_HASH_COMPARE)
314        {
315                CreateHashVector();
316        }
317        else
318        {
319                // sort objects by id
320                sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
321        }
322
323        Debug << "\nconverted bounding boxes to objects in "
324                  << TimeDiff(startTime, GetTime()) * 1e-6 << " secs" << endl;
325
326#ifdef USE_PERFTIMER 
327        mBoxTimer.Exit();
328#endif
329}
330
331
332void ViewCellsParseHandlers::StartBspElement(string element,
333                                                                                         AttributeList& attributes)
334{
335        if (element == "Interior")
336        {
337                //cout << "[";
338                StartBspInterior(attributes);
339        }
340
341        if (element == "Leaf")
342        {
343                //cout << "l";
344                StartBspLeaf(attributes);
345        }
346}
347
348
349void ViewCellsParseHandlers::StartVspElement(string element,
350                                                                                         AttributeList& attributes)
351{
352        if (element == "Interior")
353        {
354                //cout << "[";
355                StartVspInterior(attributes);
356        }
357        if (element == "Leaf")
358        {
359                //cout << "l";
360                StartVspLeaf(attributes);
361        }
362}
363
364
365void ViewCellsParseHandlers::StartOspElement(string element,
366                                                                                         AttributeList& attributes)
367{
368        if (element == "Interior")
369        {
370                //cout << "[";
371                StartOspInterior(attributes);
372        }
373
374        if (element == "Leaf")
375        {
376                //cout << "l";
377                StartOspLeaf(attributes);
378        }
379}
380
381
382void ViewCellsParseHandlers::StartBvhElement(string element,
383                                                                                         AttributeList& attributes)
384{
385        if (element == "Interior")
386        {
387                //cout << "[";
388                StartBvhInterior(attributes);
389        }
390
391        if (element == "Leaf")
392        {
393                //cout << "l";
394                StartBvhLeaf(attributes);
395        }
396}
397
398
399void ViewCellsParseHandlers::StartViewSpaceHierarchyElement(const std::string &element,
400                                                                                                                        AttributeList& attributes)
401{
402        //-- use cell type according to the chosen method
403        switch (mViewSpaceHierarchyType)
404        {
405        case BSP:
406                StartBspElement(element, attributes);
407                break;
408        case VSP:
409                StartVspElement(element, attributes);
410                break;
411        default:
412                Debug << "not implemented" << endl;
413                break;
414        }
415}
416
417
418void ViewCellsParseHandlers::StartObjectSpaceHierarchyElement(const std::string &element,
419                                                                                                                          AttributeList& attributes)
420{
421        //-- use cell type according to the chosen method
422        switch (mObjectSpaceHierarchyType)
423        {
424                case OSP:
425                        StartOspElement(element, attributes);
426                        break;
427                case BVH:
428                        StartBvhElement(element, attributes);
429                        break;
430                default:
431                        Debug << "not implemented" << endl;
432                        break;
433        }
434}
435
436
437void ViewCellsParseHandlers::StartViewCellHierarchyElement(const std::string &element,
438                                                                                                                   AttributeList& attributes)
439{
440        // interiors + leaves interpreted view cells else
441        if (element == "Interior")
442        {
443                StartViewCell(attributes, false);
444                return;
445        }
446
447        if (element == "Leaf")
448        {
449                StartViewCell(attributes, true);
450                return;
451        }
452
453        Debug << "StartViewCellHierarchyElement: should not come here: " << element << endl;
454}
455
456
457void ViewCellsParseHandlers::startElement(const XMLCh* const name,
458                                                                                  AttributeList& attributes)
459{
460        StrX lname(name);
461        string element(lname.LocalForm());
462
463        if (element == "ViewCells")
464        {
465                cout << "\nparsing view cells" << endl;
466                Debug << "\nparsing view cells" << endl;
467               
468                mCurrentState = PARSE_VIEWCELLS;
469
470                // create new view cells hierarchy
471                mViewCellsTree = new ViewCellsTree();
472        }
473        // decides about the view cell hierarchy
474        else if (element == "ViewSpaceHierarchy")
475        {               
476                Debug << "\nparsing view space hierarchy" << endl;
477                cout  << "\nparsing view space hierarchy" << endl;
478
479                mCurrentState = PARSE_VIEWSPACE_HIERARCHY;
480                StartViewSpaceHierarchy(attributes);
481        }
482        // decides about the view cell hierarchy
483        else if (element == "ObjectSpaceHierarchy")
484        {
485                cout  << "\nparsing object space hierarchy" << endl;
486                Debug << "\nparsing object space hierarchy" << endl;
487
488                mCurrentState = PARSE_OBJECTSPACE_HIERARCHY;
489#ifdef USE_PERFTIMER 
490                mObjectTimer.Entry();
491#endif
492                StartObjectSpaceHierarchy(attributes);
493        }
494        // decides the used view cell hierarchy
495        else if (element == "BoundingBox")
496        {
497                StartBoundingBox(attributes);
498        }
499        else
500        {
501                const int n = 1000;
502                // parse view space hierarchy
503                switch (mCurrentState)
504                {
505                case PARSE_VIEWSPACE_HIERARCHY:
506                        if ((++ nViewCells % n) == 0)
507                        {
508                                cout << "\r" << nViewCells << " view cells parsed\r";
509                                Debug << nViewCells << " view cells parsed" << endl;
510                        }
511                        StartViewSpaceHierarchyElement(element, attributes);
512                        break;
513                case PARSE_OBJECTSPACE_HIERARCHY:
514                        if ((++ nObjects % n) == 0)
515                                cout <<"\r" << nObjects << " objects parsed\r";
516               
517                        StartObjectSpaceHierarchyElement(element, attributes);
518                        break;
519                case PARSE_VIEWCELLS:
520                        StartViewCellHierarchyElement(element, attributes);
521                        break;
522                default:
523                        break;
524                }
525        }
526       
527        ++ mElementCount;
528        mAttrCount += attributes.getLength();
529}
530
531
532void ViewCellsParseHandlers::StartViewCellPvs(ObjectPvs &pvs, const char *ptr)
533{
534        // handle object indices
535        vector<int> objIndices;
536        char *endptr;
537                       
538        while (1)
539        {       
540                // read object ids
541                const int index = strtol(ptr, &endptr, 10);
542               
543                if (ptr == endptr)
544                        break;
545               
546                objIndices.push_back(index);
547                ptr = endptr;
548        }
549
550#ifdef USE_PERFTIMER 
551        mPvsTimer.Entry();
552#endif
553        Intersectable::NewMail();
554
555        // TODO:
556        // 1) find objects and add them to pvs
557        // 2) get view cell with specified id
558        MeshInstance dummyInst(NULL);
559        pair<ObjectContainer::const_iterator, ObjectContainer::const_iterator> result;
560
561        vector<int>::const_iterator it, it_end = objIndices.end();
562       
563        for (it = objIndices.begin(); it != it_end; ++ it)
564        {
565                const int objId = *it; 
566       
567#if USE_HASH_COMPARE
568                pvs_hash::iterator oit = mHashPvs.find(objId);
569
570                if ((oit != mHashPvs.end()) && ((*oit).second->GetId() == objId))
571                {
572                        pvs.AddSample((*oit).second, 1.0f);
573                }
574#else
575        #if 0
576                dummyInst.SetId(objId);
577
578                ObjectContainer::iterator oit =
579                                                        lower_bound(mPvsObjects.begin(),
580                                                                                mPvsObjects.end(),
581                                                                                (Intersectable *)&dummyInst,
582                                                                                ilt);   
583
584                if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
585                {
586                        pvs.AddSample(*oit, 1.0f);
587                }
588        #else
589                pvs.AddSample(mPvsObjects[objId], 1.0f);
590        #endif
591#endif
592        }
593       
594#ifdef USE_PERFTIMER 
595        mPvsTimer.Exit();
596#endif
597}
598
599
600void ViewCellsParseHandlers::StartViewSpaceHierarchy(AttributeList& attributes)
601{
602        int len = attributes.getLength();
603
604        Vector3 bmin, bmax;
605
606        for (int i = 0; i < len; ++ i)
607        {
608                string attrName(StrX(attributes.getName(i)).LocalForm());
609                StrX attrValue(attributes.getValue(i));
610                const char *ptr = attrValue.LocalForm();
611
612                // hierarchy type
613                if (attrName == "type")
614                {
615                        if (strcmp(ptr, "bsp") == 0)
616                        {
617                                Debug << "\nview space hierarchy: Bsp" << endl;
618                                mViewSpaceHierarchyType = BSP;
619                        }
620                        else if (strcmp(ptr, "vsp") == 0)
621                        {
622                                Debug << "\nview space hierarchy: Vsp" << endl;
623                                mViewSpaceHierarchyType = VSP;
624                        }
625                }
626                else if (attrName == "min") // the view space extent
627                {
628                        sscanf(ptr, "%f %f %f",
629                                   &bmin.x, &bmin.y, &bmin.z);
630                }
631                else if (attrName == "max")
632                {
633                        sscanf(ptr, "%f %f %f",
634                                   &bmax.x, &bmax.y, &bmax.z);
635                }
636        }
637
638        mViewSpaceBox = AxisAlignedBox3(bmin, bmax);
639
640        // hack for submission: enlarge by some margin
641        mViewSpaceBox.SetMax(1, mViewSpaceBox.Max().y + 40.0f);
642        // create the hierarchy based on this information
643        CreateViewSpaceHierarchy();
644}
645
646
647void ViewCellsParseHandlers::StartObjectSpaceHierarchy(AttributeList& attributes)
648{
649        const int len = attributes.getLength();
650        Vector3 bmin, bmax;
651
652        for (int i = 0; i < len; ++ i)
653        {
654                string attrName(StrX(attributes.getName(i)).LocalForm());
655                StrX attrValue(attributes.getValue(i));
656                const char *ptr = attrValue.LocalForm();
657
658                // hierarchy type
659                if (attrName == "type")
660                {
661                        if (strcmp(ptr, "osp") == 0)
662                        {
663                                Debug << "\nobject space hierarchy: Osp" << endl;
664
665                                mHierarchyManager =
666                                        new HierarchyManager(HierarchyManager::KD_BASED_OBJ_SUBDIV);
667
668                                DEL_PTR(mHierarchyManager->mVspTree);
669                                mHierarchyManager->mVspTree = mVspTree;
670
671                                mObjectSpaceHierarchyType = OSP;
672
673                                //std::stable_sort(objects.begin(), objects.end(), ilt);
674                                mHierarchyManager->mOspTree->mBoundingBox.Initialize();
675                                ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
676                               
677                                //-- compute bounding box
678                                for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
679                                {
680                                        Intersectable *obj = *oit;
681                                        // compute bounding box of view space
682                                        mHierarchyManager->mOspTree->mBoundingBox.Include(obj->GetBox());
683                                }
684                        }
685                        else if (strcmp(ptr, "bvh") == 0)
686                        {
687                                Debug << "\nobject space hierarchy: Bvh" << endl;
688
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
713                const char *ptr = attrValue.LocalForm();
714
715                if (attrName == "id")
716                {
717                        sscanf(ptr, "%d", &id);
718                }
719                if (attrName == "min")
720                {
721                        sscanf(ptr, "%f %f %f", &bmin.x, &bmin.y, &bmin.z);
722                }
723                else if (attrName == "max")
724                {
725                        sscanf(ptr, "%f %f %f", &bmax.x, &bmax.y, &bmax.z);
726                }
727        }
728
729        AxisAlignedBox3 box(bmin, bmax);
730        mIBoundingBoxes.push_back(IndexedBoundingBox(id, box));
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{cout<<"x";
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                        //(*vit).second = vspVc;
1008                        (*vit) = vspVc;
1009                }
1010
1011                if (mHierarchyManager)
1012                {
1013                        // do this only if object hierarchy was already constructed
1014                        mHierarchyManager->mVspTree = mVspTree;
1015                        mVspTree->mHierarchyManager = mHierarchyManager;
1016                }
1017        }
1018}
1019
1020
1021void ViewCellsParseHandlers::CreateViewCellsManager()
1022{
1023        if (mViewSpaceHierarchyType == BSP)
1024        {
1025                Debug << "\ncreating view cells manager: VspBsp" << endl;
1026                mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
1027        }
1028        else if (mViewSpaceHierarchyType == VSP)
1029        {
1030                Debug << "\ncreating view cells manager: VspOsp" << endl;
1031                mViewCellsManager = new VspOspViewCellsManager(mViewCellsTree, mHierarchyManager);
1032        }
1033
1034        mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
1035}
1036
1037
1038void ViewCellsParseHandlers::characters(const XMLCh* const chars,
1039                                                                                const unsigned int length)
1040{
1041        mCharacterCount += length;
1042}
1043
1044
1045void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
1046                                                                                                 const unsigned int length)
1047{
1048        mSpaceCount += length;
1049}
1050
1051
1052void ViewCellsParseHandlers::resetDocument()
1053{
1054        mAttrCount = 0;
1055        mCharacterCount = 0;
1056        mElementCount = 0;
1057        mSpaceCount = 0;
1058}
1059
1060
1061void ViewCellsParseHandlers::StartVspLeaf(AttributeList& attributes)
1062{
1063        VspLeaf * leaf;
1064               
1065        if (mCurrentVspNode) // replace front or (if not NULL) back child
1066        {
1067                VspInterior *interior = static_cast<VspInterior *>(mCurrentVspNode);
1068                leaf = new VspLeaf(interior);
1069                interior->ReplaceChildLink(NULL, leaf);
1070        }
1071        else
1072        {
1073                leaf = new VspLeaf();
1074                mVspTree->mRoot = leaf;
1075        }
1076
1077        /////////////
1078        //-- find view cell associated with the id
1079
1080        int viewCellId;
1081        const int len = attributes.getLength();
1082         
1083        for (int i = 0; i < len; ++ i)
1084        {
1085                string attrName(StrX(attributes.getName(i)).LocalForm());
1086                StrX attrValue(attributes.getValue(i));
1087
1088                const char *ptr = attrValue.LocalForm();
1089                char *endptr = NULL;
1090
1091                if (attrName == "viewCellId")
1092                {
1093                        viewCellId = strtol(ptr, &endptr, 10);
1094                }
1095        }
1096       
1097        if (viewCellId >= 0) // valid view cell found
1098        {
1099                // TODO: get view cell with specified id
1100                ViewCellInterior dummyVc;
1101                dummyVc.SetId(viewCellId);
1102
1103                ViewCellContainer::iterator vit =
1104                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
1105               
1106                //ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
1107                if (vit == mViewCells.end())
1108                        Debug << "error: view cell " << viewCellId << " not found" << endl;
1109       
1110                //VspViewCell *viewCell = static_cast<VspViewCell *>((*vit).second);
1111                VspViewCell *viewCell = static_cast<VspViewCell *>(*vit);
1112               
1113                if (viewCell->GetId() == viewCellId)
1114                {
1115                        leaf->SetViewCell(viewCell);
1116                        viewCell->mLeaves.push_back(leaf);
1117                }
1118                else
1119                {
1120                        Debug << "error: view cell does not exist" << endl;
1121                }
1122        }
1123        else
1124        {       
1125                // add to invalid view space
1126                leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
1127                leaf->SetTreeValid(false);
1128                mVspTree->PropagateUpValidity(leaf);
1129        }
1130}
1131
1132
1133void ViewCellsParseHandlers::StartVspInterior(AttributeList& attributes)
1134{
1135        AxisAlignedPlane plane;
1136        const int len = attributes.getLength();
1137
1138        for (int i = 0; i < len; ++ i)
1139        {
1140                string attrName(StrX(attributes.getName(i)).LocalForm());
1141                StrX attrValue(attributes.getValue(i));
1142                const char *ptr = attrValue.LocalForm();
1143
1144                if (attrName == "plane")
1145                {
1146                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1147                }
1148        }
1149
1150        VspInterior* interior = new VspInterior(plane);
1151       
1152        if (mCurrentVspNode) // replace NULL child of parent with current node
1153        {
1154                VspInterior *parent = static_cast<VspInterior *>(mCurrentVspNode);
1155
1156                parent->ReplaceChildLink(NULL, interior);
1157                interior->SetParent(parent);
1158               
1159                AxisAlignedBox3 frontBox, backBox;
1160
1161                parent->GetBoundingBox().Split(
1162                        parent->GetPlane().mAxis,
1163                        parent->GetPlane().mPosition,
1164                        frontBox,
1165                        backBox);
1166
1167                if (parent->GetFront() == interior)
1168                        interior->SetBoundingBox(frontBox);
1169                else
1170                        interior->SetBoundingBox(backBox);
1171        }
1172        else
1173        {
1174                mVspTree->mRoot = interior;
1175                interior->SetBoundingBox(mVspTree->GetBoundingBox());
1176        }
1177
1178        mCurrentVspNode = interior;
1179}
1180
1181
1182void ViewCellsParseHandlers::StartOspInterior(AttributeList& attributes)
1183{
1184        AxisAlignedPlane plane;
1185        int len = attributes.getLength();
1186
1187        for (int i = 0; i < len; ++ i)
1188        {
1189                string attrName(StrX(attributes.getName(i)).LocalForm());
1190                StrX attrValue(attributes.getValue(i));
1191                const char *ptr = attrValue.LocalForm();
1192
1193                if (attrName == "plane")
1194                {
1195                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1196                }
1197        }
1198
1199        KdInterior* interior = new KdInterior(NULL);
1200       
1201        interior->mAxis = plane.mAxis;
1202        interior->mPosition = plane.mPosition;
1203
1204        if (mCurrentOspNode) // replace NULL child of parent with current node
1205        {
1206                KdInterior *parent = static_cast<KdInterior *>(mCurrentOspNode);
1207                parent->ReplaceChildLink(NULL, interior);
1208                interior->mParent = parent;
1209
1210                AxisAlignedBox3 frontBox, backBox;
1211
1212                parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
1213
1214                if (parent->mFront == interior)
1215                        interior->mBox = frontBox;
1216                else
1217                        interior->mBox = backBox;
1218        }
1219        else
1220        {
1221                mHierarchyManager->mOspTree->mRoot = interior;
1222                interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
1223        }
1224
1225        mCurrentOspNode = interior;
1226}
1227
1228
1229void ViewCellsParseHandlers::StartOspLeaf(AttributeList& attributes)
1230{
1231        KdLeaf * leaf = new KdLeaf(static_cast<KdInterior *>(mCurrentOspNode), NULL);
1232
1233        if (mCurrentOspNode)
1234        {
1235                 // replace front or (if not NULL) back child
1236                static_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
1237        }
1238        else
1239        {
1240                mHierarchyManager->mOspTree->mRoot = leaf;
1241        }
1242}
1243
1244
1245void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
1246{
1247        const int len = attributes.getLength();
1248        Vector3 minBox, maxBox;
1249
1250        ObjectContainer objects;
1251
1252        for (int i = 0; i < len; ++ i)
1253        {
1254                string attrName(StrX(attributes.getName(i)).LocalForm());
1255                StrX attrValue(attributes.getValue(i));
1256                const char *ptr = attrValue.LocalForm();
1257
1258                if (attrName == "min")
1259                {
1260                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1261                }
1262                if (attrName == "max")
1263                {
1264                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1265                }
1266                if (attrName == "objects")
1267                {
1268                        if (!mPreprocessorObjects.empty())
1269                                StartBvhLeafObjects(objects, ptr);
1270                }
1271        }
1272
1273        AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox);
1274
1275        BvhLeaf *leaf;
1276
1277        if (mCurrentBvhNode) // replace front or (if not NULL) back child
1278        {
1279                BvhInterior *interior = static_cast<BvhInterior *>(mCurrentBvhNode);
1280
1281                leaf = new BvhLeaf(box, interior, (int)objects.size());
1282                interior->ReplaceChildLink(NULL, leaf);
1283        }
1284        else
1285        {
1286                leaf = new BvhLeaf(box, NULL, (int)objects.size());
1287                mHierarchyManager->mBvHierarchy->mRoot = leaf;
1288        }
1289
1290        leaf->mObjects = objects;
1291        BvHierarchy::AssociateObjectsWithLeaf(leaf);
1292}
1293
1294
1295void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects,
1296                                                                                                 const char *ptr)
1297{
1298        vector<int> objIndices;
1299        char *endptr;
1300                       
1301        while (1)
1302        {
1303                const int index = strtol(ptr, &endptr, 10);
1304                if (ptr == endptr) break;
1305
1306                objIndices.push_back(index);
1307                ptr = endptr;
1308        }
1309
1310        MeshInstance dummyInst(NULL);
1311        vector<int>::const_iterator it, it_end = objIndices.end();
1312
1313        for (it = objIndices.begin(); it != it_end; ++ it)
1314        {
1315                const int objId = *it; 
1316                dummyInst.SetId(objId);
1317
1318                ObjectContainer::const_iterator oit =
1319                        lower_bound(mPreprocessorObjects.begin(),
1320                                                mPreprocessorObjects.end(),
1321                                                (Intersectable *)&dummyInst,
1322                                                ilt);   
1323                                                       
1324                if ((oit != mPreprocessorObjects.end()) && ((*oit)->GetId() == objId))
1325                {
1326                        objects.push_back(*oit);
1327                }
1328                else
1329                {
1330                        //cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
1331                }
1332        }
1333}
1334
1335
1336void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
1337{
1338        const int len = attributes.getLength();
1339        Vector3 minBox, maxBox;
1340
1341        for (int i = 0; i < len; ++ i)
1342        {
1343                string attrName(StrX(attributes.getName(i)).LocalForm());
1344                StrX attrValue(attributes.getValue(i));
1345                const char *ptr = attrValue.LocalForm();
1346
1347                if (attrName == "min")
1348                {
1349                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1350                }
1351                if (attrName == "max")
1352                {
1353                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1354                }
1355        }
1356
1357        BvhInterior* interior = new BvhInterior(AxisAlignedBox3(minBox, maxBox));
1358
1359        if (mCurrentBvhNode) // replace NULL child of parent with current node
1360        {
1361                BvhInterior *parent = static_cast<BvhInterior *>(mCurrentBvhNode);
1362                parent->ReplaceChildLink(NULL, interior);
1363                interior->SetParent(parent);
1364        }
1365        else
1366        {
1367                mHierarchyManager->mBvHierarchy->mRoot = interior;
1368        }
1369
1370        mCurrentBvhNode = interior;
1371}
1372
1373
1374// ---------------------------------------------------------------------------
1375//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
1376// ---------------------------------------------------------------------------
1377
1378
1379void
1380ViewCellsParseHandlers::error(const SAXParseException& e)
1381{
1382  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
1383                            << ", line " << e.getLineNumber()
1384                            << ", char " << e.getColumnNumber()
1385                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1386}
1387
1388void
1389ViewCellsParseHandlers::fatalError(const SAXParseException& e)
1390{
1391  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
1392                            << ", line " << e.getLineNumber()
1393                            << ", char " << e.getColumnNumber()
1394                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1395}
1396
1397void
1398ViewCellsParseHandlers::warning(const SAXParseException& e)
1399{
1400  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
1401                            << ", line " << e.getLineNumber()
1402                            << ", char " << e.getColumnNumber()
1403                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1404}
1405
1406
1407bool ViewCellsParser::ParseViewCellsFile(const string &filename,
1408                                                                                 ViewCellsManager **viewCells,
1409                                                                                 ObjectContainer &pvsObjects,
1410                                                                                 ObjectContainer &preprocessorObjects,
1411                                                                                 BoundingBoxConverter *bconverter)
1412{
1413        // Initialize the XML4C system
1414        try {
1415                XMLPlatformUtils::Initialize();
1416        }
1417
1418        catch (const XMLException& toCatch)
1419        {
1420                XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
1421                        << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
1422                return false;
1423        }
1424
1425        //  cout<<"parsing started"<<endl<<flush;
1426
1427        //
1428        //  Create a SAX parser object. Then, according to what we were told on
1429        //  the command line, set the options.
1430        //
1431        SAXParser* parser = new SAXParser;
1432        parser->setValidationScheme(valScheme);
1433        parser->setDoNamespaces(doNamespaces);
1434        parser->setDoSchema(doSchema);
1435        parser->setValidationSchemaFullChecking(schemaFullChecking);
1436
1437
1438        //
1439        //  Create our SAX handler object and install it on the parser, as the
1440        //  document and error handler. We are responsible for cleaning them
1441        //  up, but since its just stack based here, there's nothing special
1442        //  to do.
1443        //
1444        ViewCellsParseHandlers handler(pvsObjects, preprocessorObjects, bconverter);
1445        parser->setDocumentHandler(&handler);
1446        parser->setErrorHandler(&handler);
1447
1448        unsigned long duration;
1449        int errorCount = 0;
1450        // create a faux scope so that 'src' destructor is called before
1451        // XMLPlatformUtils::Terminate
1452        {
1453                //
1454                //  Kick off the parse and catch any exceptions. Create a standard
1455                //  input input source and tell the parser to parse from that.
1456                //
1457                //    StdInInputSource src;
1458                try
1459                {
1460                        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
1461
1462#if USE_GZLIB
1463                        XMLCh *myFilePath = XMLString::transcode(filename.c_str());
1464
1465                        GzFileInputSource isource(myFilePath);
1466                        parser->parse(isource);
1467#else
1468                        parser->parse(filename.c_str());
1469
1470#endif
1471
1472                        //if (mCreatePvsObjects)
1473                        //      handler.ReplacePvs();
1474
1475                        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1476                        duration = endMillis - startMillis;
1477                        errorCount = parser->getErrorCount();
1478                }
1479                catch (const OutOfMemoryException&)
1480                {
1481                        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1482                        errorCount = 2;
1483                        return false;
1484                }
1485                catch (const XMLException& e)
1486                {
1487                        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
1488                                << StrX(e.getMessage())
1489                                << "\n" << XERCES_STD_QUALIFIER endl;
1490                        errorCount = 1;
1491                        return false;
1492                }
1493
1494
1495                // Print out the stats that we collected and time taken
1496                if (!errorCount)
1497                {
1498                        XERCES_STD_QUALIFIER cerr << filename << ": " << duration << " ms ("
1499                                << handler.GetElementCount() << " elems, "
1500                                << handler.GetAttrCount() << " attrs, "
1501                                << handler.GetSpaceCount() << " spaces, "
1502                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1503                }
1504        }
1505
1506        //
1507        //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1508        //
1509        delete parser;
1510
1511        XMLPlatformUtils::Terminate();
1512
1513        //-- assign new view cells manager
1514        *viewCells = handler.mViewCellsManager;
1515
1516        if (errorCount > 0)
1517                return false;
1518        else
1519                return true;
1520}
1521
1522}
Note: See TracBrowser for help on using the repository browser.