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

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