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

Revision 1633, 34.9 KB checked in by mattausch, 18 years ago (diff)

worked on gradient method for vsposp

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