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

Revision 1297, 33.3 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 =
623                                        new HierarchyManager(mVspTree, HierarchyManager::KD_BASED_OBJ_SUBDIV);
[1286]624
625                                mObjectSpaceHierarchyType = OSP;
626
627                                //std::stable_sort(objects.begin(), objects.end(), ilt);
628                                mHierarchyManager->mOspTree->mBoundingBox.Initialize();
629                                ObjectContainer::const_iterator oit, oit_end = mObjects->end();
630                               
631                                //-- compute bounding box
632                                for (oit = mObjects->begin(); oit != oit_end; ++ oit)
633                                {
634                                        Intersectable *obj = *oit;
635                                        // compute bounding box of view space
636                                        mHierarchyManager->mOspTree->mBoundingBox.Include(obj->GetBox());
637                                }
[1264]638                        }
[1278]639                        else if (strcmp(ptr, "bvh") == 0)
[1264]640                        {
[1284]641                                cout << "\nobject space hierarchy: Bvh" << endl;
[1286]642                                mObjectSpaceHierarchyType = BVH;
[1284]643                                mHierarchyManager =
644                                        new HierarchyManager(mVspTree, HierarchyManager::BV_BASED_OBJ_SUBDIV);
[1264]645                        }
646                }
647        }
648}
649
650
[931]651void ViewCellsParseHandlers::StartBoundingBox(AttributeList& attributes)
652{
653        int len = attributes.getLength();
654
655        Vector3 bmin, bmax;
656        int id;
657
658        for (int i = 0; i < len; ++ i)
659        {
660                string attrName(StrX(attributes.getName(i)).LocalForm());
661                StrX attrValue(attributes.getValue(i));
662                const char *ptr = attrValue.LocalForm();
663
664                if (attrName == "id")
665                {
666                        sscanf(ptr, "%d", &id);
667                }
668                if (attrName == "min")
669                {
[1264]670                        sscanf(ptr, "%f %f %f", &bmin.x, &bmin.y, &bmin.z);
[931]671                }
672                else if (attrName == "max")
673                {
[1264]674                        sscanf(ptr, "%f %f %f", &bmax.x, &bmax.y, &bmax.z);
[931]675                }
676        }
677
678        AxisAlignedBox3 box(bmin, bmax);
679        mIBoundingBoxes.push_back(IndexedBoundingBox(id, box));
[1264]680        //cout << "bbox: " << box << endl;
[931]681}
682
683
[575]684void ViewCellsParseHandlers::StartBspLeaf(AttributeList& attributes)
[508]685{
[1287]686        BspLeaf * leaf;
[508]687
[590]688        if (mCurrentBspNode) // replace front or (if not NULL) back child
[508]689        {
[1287]690                BspInterior *interior = dynamic_cast<BspInterior *>(mCurrentBspNode);
691
692                leaf = new BspLeaf(interior);
693                interior->ReplaceChildLink(NULL, leaf);
[508]694        }
695        else
696        {
[1287]697                leaf = new BspLeaf();
[1264]698                mVspBspTree->mRoot = leaf;
[508]699        }
700
701        //-- find associated view cell
[1264]702
[508]703        int viewCellId;
704       
705        int len = attributes.getLength();
706         
707        for (int i = 0; i < len; ++ i)
708        {
709                string attrName(StrX(attributes.getName(i)).LocalForm());
710                StrX attrValue(attributes.getValue(i));
711
712                const char *ptr = attrValue.LocalForm();
713                char *endptr = NULL;
714
715                if (attrName == "viewCellId")
716                {
717                        viewCellId = strtol(ptr, &endptr, 10);
718                }
719        }
[590]720       
[1264]721        if (viewCellId >= 0) // valid view cell found
[508]722        {
723                // TODO: get view cell with specified id
[590]724                ViewCellInterior dummyVc;
[508]725                dummyVc.SetId(viewCellId);
726
727                ViewCellContainer::iterator vit =
728                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
729                       
[651]730                BspViewCell *viewCell = dynamic_cast<BspViewCell *>(*vit);
[654]731       
[508]732                if (viewCell->GetId() == viewCellId)
733                {
[1284]734                        // create new view cell for bsp nodes
[651]735                        leaf->SetViewCell(viewCell);
736                        viewCell->mLeaf = leaf;
[508]737                }
738                else
739                {
[1284]740                        cout << "error: view cell does not exist" << endl;
[508]741                }
742        }
743        else
744        {
[863]745                // add to invalid view space
[1286]746                leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
747                leaf->SetTreeValid(false);
748                mVspBspTree->PropagateUpValidity(leaf);
[654]749        }
[508]750}
751
752
[575]753void ViewCellsParseHandlers::StartBspInterior(AttributeList& attributes)
[508]754{
755        Plane3 plane;
756        int len = attributes.getLength();
757
758        for (int i = 0; i < len; ++ i)
759        {
760                string attrName(StrX(attributes.getName(i)).LocalForm());
761                StrX attrValue(attributes.getValue(i));
762                const char *ptr = attrValue.LocalForm();
763
764                if (attrName == "plane")
765                {
766                        sscanf(ptr, "%f %f %f %f",
767                                   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
768                }
769        }
770
771        BspInterior* interior = new BspInterior(plane);
772       
[590]773        if (mCurrentBspNode) // replace NULL child of parent with current node
[508]774        {
[1287]775                BspInterior *parent = dynamic_cast<BspInterior *>(mCurrentBspNode);
[508]776
[1287]777                parent->ReplaceChildLink(NULL, interior);
778                interior->SetParent(parent);
[508]779        }
780        else
781        {
[1264]782                mVspBspTree->mRoot = interior;
[508]783        }
784
[590]785        mCurrentBspNode = interior;
[508]786}
787
788
[651]789void ViewCellsParseHandlers::StartViewCellLeaf(AttributeList& attributes)
790{
[1284]791        ViewCellLeaf *viewCell = new ViewCellLeaf();
[575]792
[651]793        if (mCurrentViewCell) // replace front or (if not NULL) back child
794        {
[1284]795                ViewCellInterior *interior =
796                        dynamic_cast<ViewCellInterior *>(mCurrentViewCell);
[651]797                interior->SetupChildLink(viewCell);
798        }
799        else // root
800        {
801                mViewCellsTree->SetRoot(viewCell);
802        }
803
[1286]804        StartViewCellPvs(viewCell, attributes);
[651]805
806        // collect leaves
807        mViewCells.push_back(viewCell);
808}
809
810
811void ViewCellsParseHandlers::StartViewCellInterior(AttributeList& attributes)
812{
813        ViewCellInterior* interior = new ViewCellInterior();
[1286]814       
[651]815        if (mCurrentViewCell) // replace NULL child of parent with current node
816        {
817                ViewCellInterior *current = dynamic_cast<ViewCellInterior *>(mCurrentViewCell);
818
819                current->SetupChildLink(interior);
820        }
821        else
822        {
823                mViewCellsTree->SetRoot(interior);
824        }
825
826        mCurrentViewCell = interior;
827
[1286]828        StartViewCellPvs(interior, attributes);
[651]829}
830
831
[1264]832void ViewCellsParseHandlers::CreateViewSpaceHierarchy()
[575]833{
[1264]834        if (mViewSpaceHierarchyType == BSP)
[575]835        {
[1264]836                cout << "hierarchy type: Bsp" << endl;
[575]837
[1264]838                mVspBspTree = new VspBspTree();
[575]839
[1264]840                // set view space box
841                mVspBspTree->mBox = mViewSpaceBox;
[1284]842
843                ViewCellContainer::iterator vit, vit_end = mViewCells.end();
844
845                // reset view cells using the current node type
846                for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
847                {
848                        ViewCell *vc = *vit;
849
850                        BspViewCell *bspVc = new BspViewCell();
851                        bspVc->SetPvs(vc->GetPvs());
852                        bspVc->SetId(vc->GetId());
853
854                        if (vc->IsRoot())
855                        {
856                                mViewCellsTree->mRoot = bspVc;
857                        }
858                        else
859                        {
[1286]860                vc->GetParent()->ReplaceChildLink(vc, bspVc);
[1284]861                        }
862
863                        DEL_PTR(vc);
864                        (*vit) = bspVc;
865                }
[1264]866        }
867        else if (mViewSpaceHierarchyType == VSP)
[975]868        {
[1264]869                cout << "hierarchy type: Vsp" << endl;
[577]870
[1264]871                mVspTree = new VspTree();
[1278]872
[1264]873                // set view space box
874                mVspTree->mBoundingBox = mViewSpaceBox;
[1278]875
[1284]876                ViewCellContainer::iterator vit, vit_end = mViewCells.end();
877
878                // reset view cells using the current node type
879                for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
880                {
881                        ViewCell *vc = *vit;
882
883                        VspViewCell *vspVc = new VspViewCell();
884                        vspVc->SetPvs(vc->GetPvs());
885                        vspVc->SetId(vc->GetId());
886
887                        if (vc->IsRoot())
888                        {
889                                mViewCellsTree->mRoot = vspVc;
890                        }
891                        else
892                        {
[1286]893                                vc->GetParent()->ReplaceChildLink(vc, vspVc);
[1284]894                        }
895                       
896                        DEL_PTR(vc);
897                        (*vit) = vspVc;
898                }
899
900                // if object space hierarchy already constructed
[1278]901                if (mHierarchyManager)
902                {
903                        mHierarchyManager->mVspTree = mVspTree;
904                        mVspTree->mHierarchyManager = mHierarchyManager;
905                }
[1264]906        }
[1287]907        //cout << "\nview space box: " << mViewSpaceBox << endl;
[1264]908}
[577]909
[1264]910
911void ViewCellsParseHandlers::CreateViewCellsManager(/*const char *name*/)
912{
[1286]913        if (mViewSpaceHierarchyType == BSP)
[1264]914        {
915                Debug << "creating view cells manager: VspBsp" << endl;
[1022]916
[1264]917                mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
[1022]918        }
[1264]919        else if (mViewSpaceHierarchyType == VSP)
920        {
[1278]921                Debug << "creating view cells manager: VspOsp" << endl;
[1022]922
[1264]923                // hack
[1278]924                mViewCellsManager = new VspOspViewCellsManager(mViewCellsTree, mHierarchyManager);
[1264]925        }
[1263]926
[577]927        mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
[575]928}
929
930
[508]931void ViewCellsParseHandlers::characters(const XMLCh* const chars,
932                                                                                const unsigned int length)
933{
934        mCharacterCount += length;
935}
936
937
938void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
939                                                                                                 const unsigned int length)
940{
941        mSpaceCount += length;
942}
943
944
945void ViewCellsParseHandlers::resetDocument()
946{
947        mAttrCount = 0;
948        mCharacterCount = 0;
949        mElementCount = 0;
950        mSpaceCount = 0;
951}
952
953
[1201]954void ViewCellsParseHandlers::StartVspLeaf(AttributeList& attributes)
955{
[1287]956        VspLeaf * leaf;
957               
[1201]958        if (mCurrentVspNode) // replace front or (if not NULL) back child
959        {
[1287]960                VspInterior *interior = dynamic_cast<VspInterior *>(mCurrentVspNode);
961                leaf = new VspLeaf(interior);
962                interior->ReplaceChildLink(NULL, leaf);
[1201]963        }
964        else
965        {
[1287]966                leaf = new VspLeaf();
[1201]967                mVspTree->mRoot = leaf;
968        }
969
970        //-- find associated view cell
971        int viewCellId;
972       
973        int len = attributes.getLength();
974         
975        for (int i = 0; i < len; ++ i)
976        {
977                string attrName(StrX(attributes.getName(i)).LocalForm());
978                StrX attrValue(attributes.getValue(i));
979
980                const char *ptr = attrValue.LocalForm();
981                char *endptr = NULL;
982
983                if (attrName == "viewCellId")
984                {
985                        viewCellId = strtol(ptr, &endptr, 10);
986                }
987        }
988       
989        if (viewCellId >= 0) // valid view cell
990        {
991                // TODO: get view cell with specified id
992                ViewCellInterior dummyVc;
993                dummyVc.SetId(viewCellId);
994
[1287]995                //cout << "\nsearching view cell with id " << viewCellId << endl;
[1284]996
[1201]997                ViewCellContainer::iterator vit =
998                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
999                       
[1284]1000                if (vit == mViewCells.end())
1001                        cout << "error: view cell " << viewCellId << " not found" << endl;
[1286]1002       
[1201]1003                VspViewCell *viewCell = dynamic_cast<VspViewCell *>(*vit);
[1286]1004               
[1201]1005                if (viewCell->GetId() == viewCellId)
1006                {
1007                        leaf->SetViewCell(viewCell);
1008                        viewCell->mLeaf = leaf;
1009                }
1010                else
1011                {
[1284]1012                        cout << "error: view cell does not exist" << endl;
[1201]1013                }
1014        }
1015        else
[1286]1016        {       
[1201]1017                // add to invalid view space
1018                leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
1019                leaf->SetTreeValid(false);
1020                mVspTree->PropagateUpValidity(leaf);
1021        }
1022}
1023
1024
1025void ViewCellsParseHandlers::StartVspInterior(AttributeList& attributes)
1026{
1027        AxisAlignedPlane plane;
1028        int len = attributes.getLength();
1029
1030        for (int i = 0; i < len; ++ i)
1031        {
1032                string attrName(StrX(attributes.getName(i)).LocalForm());
1033                StrX attrValue(attributes.getValue(i));
1034                const char *ptr = attrValue.LocalForm();
1035
1036                if (attrName == "plane")
1037                {
[1286]1038                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
[1201]1039                }
1040        }
1041
1042        VspInterior* interior = new VspInterior(plane);
1043       
1044        if (mCurrentVspNode) // replace NULL child of parent with current node
1045        {
[1286]1046                VspInterior *parent = dynamic_cast<VspInterior *>(mCurrentVspNode);
[1201]1047
[1286]1048                parent->ReplaceChildLink(NULL, interior);
1049                interior->SetParent(parent);
1050               
1051                AxisAlignedBox3 frontBox, backBox;
1052
[1287]1053                parent->GetBoundingBox().Split(
1054                        parent->GetPlane().mAxis,
1055                        parent->GetPlane().mPosition,
1056                        frontBox,
1057                        backBox);
1058
[1286]1059                if (parent->GetFront() == interior)
1060                        interior->SetBoundingBox(frontBox);
1061                else
1062                        interior->SetBoundingBox(backBox);
[1201]1063        }
1064        else
1065        {
1066                mVspTree->mRoot = interior;
[1286]1067                interior->SetBoundingBox(mVspTree->GetBoundingBox());
[1201]1068        }
1069
1070        mCurrentVspNode = interior;
1071}
1072
1073
1074void ViewCellsParseHandlers::StartOspInterior(AttributeList& attributes)
1075{
1076        AxisAlignedPlane plane;
1077        int len = attributes.getLength();
1078
1079        for (int i = 0; i < len; ++ i)
1080        {
1081                string attrName(StrX(attributes.getName(i)).LocalForm());
1082                StrX attrValue(attributes.getValue(i));
1083                const char *ptr = attrValue.LocalForm();
1084
1085                if (attrName == "plane")
1086                {
[1286]1087                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
[1201]1088                }
1089        }
1090
1091        KdInterior* interior = new KdInterior(NULL);
1092       
1093        interior->mAxis = plane.mAxis;
1094        interior->mPosition = plane.mPosition;
1095
[1286]1096        if (mCurrentOspNode) // replace NULL child of parent with current node
[1201]1097        {
[1286]1098                KdInterior *parent = dynamic_cast<KdInterior *>(mCurrentOspNode);
[1201]1099                parent->ReplaceChildLink(NULL, interior);
1100                interior->mParent = parent;
[1286]1101
1102                AxisAlignedBox3 frontBox, backBox;
1103
1104                parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
[1287]1105
[1286]1106                if (parent->mFront == interior)
1107                        interior->mBox = frontBox;
1108                else
1109                        interior->mBox = backBox;
[1201]1110        }
1111        else
1112        {
[1278]1113                mHierarchyManager->mOspTree->mRoot = interior;
[1286]1114                interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
[1201]1115        }
1116
[1286]1117        mCurrentOspNode = interior;
[1201]1118}
1119
1120
1121void ViewCellsParseHandlers::StartOspLeaf(AttributeList& attributes)
1122{
1123        KdLeaf * leaf =
[1286]1124                new KdLeaf(dynamic_cast<KdInterior *>(mCurrentOspNode), NULL);
[1201]1125
[1286]1126        if (mCurrentOspNode) // replace front or (if not NULL) back child
[1201]1127        {
[1286]1128                dynamic_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
[1201]1129        }
1130        else
1131        {
[1278]1132                mHierarchyManager->mOspTree->mRoot = leaf;
[1201]1133        }
1134}
1135
1136
[1264]1137void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
[1286]1138{
1139        const int len = attributes.getLength();
1140        Vector3 minBox, maxBox;
[1201]1141
[1286]1142        ObjectContainer objects;
1143
1144        for (int i = 0; i < len; ++ i)
[1264]1145        {
[1286]1146                string attrName(StrX(attributes.getName(i)).LocalForm());
1147                StrX attrValue(attributes.getValue(i));
1148                const char *ptr = attrValue.LocalForm();
1149
1150                if (attrName == "min")
1151                {
[1287]1152                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
[1286]1153                }
1154                if (attrName == "max")
1155                {
[1287]1156                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
[1286]1157                }
1158                if (attrName == "objects")
1159                {
1160                        StartBvhLeafObjects(objects, ptr);
1161                }
[1264]1162        }
[1286]1163
[1287]1164        AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox);
[1286]1165
[1287]1166        BvhLeaf *leaf;
[1286]1167
1168        if (mCurrentBvhNode) // replace front or (if not NULL) back child
1169        {
[1287]1170                BvhInterior *interior = dynamic_cast<BvhInterior *>(mCurrentBvhNode);
1171                leaf = new BvhLeaf(box, interior, (int)objects.size());
1172                interior->ReplaceChildLink(NULL, leaf);
[1286]1173        }
[1264]1174        else
1175        {
[1287]1176                leaf = new BvhLeaf(box, NULL, (int)objects.size());
[1278]1177                mHierarchyManager->mBvHierarchy->mRoot = leaf;
[1286]1178        }
[1287]1179
1180        leaf->mObjects = objects;
[1264]1181}
[1201]1182
[1264]1183
[1286]1184void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects,
1185                                                                                                 const char *ptr)
1186{
1187        vector<int> objIndices;
1188
1189        char *endptr;
1190                       
1191        while (1)
1192        {
1193                const int index = strtol(ptr, &endptr, 10);
1194                if (ptr == endptr) break;
1195
1196                objIndices.push_back(index);
1197                ptr = endptr;
1198        }
1199
1200        //TODO: find objects and add them to pvs
1201        // TODO: get view cell with specified id
1202        MeshInstance dummyInst(NULL);
1203
1204        vector<int>::const_iterator it, it_end = objIndices.end();
1205
1206        for (it = objIndices.begin(); it != it_end; ++ it)
1207        {
1208                const int objId = *it; 
1209                dummyInst.SetId(objId);
1210
1211                ObjectContainer::iterator oit =
[1287]1212                        lower_bound(mObjects->begin(),
1213                                                mObjects->end(),
1214                                                (Intersectable *)&dummyInst,
1215                                                ilt);   
[1286]1216                                                       
1217                if ((oit != mObjects->end()) && ((*oit)->GetId() == objId))
1218                {
1219                        objects.push_back(*oit);       
1220                }
1221                else
1222                {
1223                        cout << "error: object with id " << objId << " does not exist" << endl;
1224                }
1225        }
1226}
1227
1228
[1264]1229void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
[1286]1230{
1231        const int len = attributes.getLength();
1232        Vector3 minBox, maxBox;
[1264]1233
1234        for (int i = 0; i < len; ++ i)
1235        {
1236                string attrName(StrX(attributes.getName(i)).LocalForm());
1237                StrX attrValue(attributes.getValue(i));
1238                const char *ptr = attrValue.LocalForm();
1239
[1286]1240                if (attrName == "min")
[1294]1241                {
[1287]1242                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
[1264]1243                }
[1286]1244                if (attrName == "max")
[1294]1245                {
[1287]1246                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
[1286]1247                }
[1264]1248        }
1249
[1286]1250        BvhInterior* interior = new BvhInterior(AxisAlignedBox3(minBox, maxBox));
[1264]1251
[1286]1252        if (mCurrentBvhNode) // replace NULL child of parent with current node
[1264]1253        {
[1286]1254                BvhInterior *parent = dynamic_cast<BvhInterior *>(mCurrentBvhNode);
[1264]1255                parent->ReplaceChildLink(NULL, interior);
[1286]1256                interior->SetParent(parent);
[1264]1257        }
1258        else
[1294]1259        {
[1287]1260                mHierarchyManager->mBvHierarchy->mRoot = interior;
[1264]1261        }
[1294]1262
[1286]1263        mCurrentBvhNode = interior;
[1264]1264}
1265
1266
[508]1267// ---------------------------------------------------------------------------
1268//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
1269// ---------------------------------------------------------------------------
[1201]1270
1271
[508]1272void
1273ViewCellsParseHandlers::error(const SAXParseException& e)
1274{
1275  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
1276                            << ", line " << e.getLineNumber()
1277                            << ", char " << e.getColumnNumber()
1278                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1279}
1280
1281void
1282ViewCellsParseHandlers::fatalError(const SAXParseException& e)
1283{
1284  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
1285                            << ", line " << e.getLineNumber()
1286                            << ", char " << e.getColumnNumber()
1287                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1288}
1289
1290void
1291ViewCellsParseHandlers::warning(const SAXParseException& e)
1292{
1293  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
1294                            << ", line " << e.getLineNumber()
1295                            << ", char " << e.getColumnNumber()
1296                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1297}
1298
1299
[1221]1300bool ViewCellsParser::ParseViewCellsFile(const string filename,
1301                                                                                 ViewCellsManager **viewCells,
1302                                                                                 ObjectContainer *objects,
1303                                                                                 BoundingBoxConverter *bconverter)
[508]1304{
1305  // Initialize the XML4C system
1306  try {
1307    XMLPlatformUtils::Initialize();
1308  }
1309 
1310  catch (const XMLException& toCatch)
1311    {
1312      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
1313                                << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
1314      return false;
1315    }
1316 
1317  //
1318  //  Create a SAX parser object. Then, according to what we were told on
1319  //  the command line, set the options.
1320  //
1321  SAXParser* parser = new SAXParser;
1322  parser->setValidationScheme(valScheme);
1323  parser->setDoNamespaces(doNamespaces);
1324  parser->setDoSchema(doSchema);
1325  parser->setValidationSchemaFullChecking(schemaFullChecking);
1326 
1327
1328  //
1329  //  Create our SAX handler object and install it on the parser, as the
1330  //  document and error handler. We are responsible for cleaning them
1331  //  up, but since its just stack based here, there's nothing special
1332  //  to do.
1333  //
[1004]1334  ViewCellsParseHandlers handler(objects, bconverter);
[508]1335  parser->setDocumentHandler(&handler);
1336  parser->setErrorHandler(&handler);
1337 
1338  unsigned long duration;
1339  int errorCount = 0;
1340  // create a faux scope so that 'src' destructor is called before
1341  // XMLPlatformUtils::Terminate
1342  {
1343    //
1344    //  Kick off the parse and catch any exceptions. Create a standard
1345    //  input input source and tell the parser to parse from that.
1346    //
1347    //    StdInInputSource src;
1348    try
[1264]1349        {
[508]1350        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
[1264]1351
[1201]1352#if USE_GZLIB
[971]1353        XMLCh *myFilePath = XMLString::transcode(filename.c_str());
1354       
1355        GzFileInputSource isource(myFilePath);
1356        parser->parse(isource);
1357#else
[508]1358        parser->parse(filename.c_str());
[971]1359#endif
1360
[508]1361        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1362        duration = endMillis - startMillis;
1363        errorCount = parser->getErrorCount();
1364      }
1365    catch (const OutOfMemoryException&)
1366      {
1367        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1368        errorCount = 2;
1369        return false;
1370      }
1371    catch (const XMLException& e)
1372      {
[870]1373                        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
[508]1374                                  << StrX(e.getMessage())
1375                                  << "\n" << XERCES_STD_QUALIFIER endl;
[870]1376                        errorCount = 1;
1377                        return false;
[508]1378      }
1379
1380   
1381    // Print out the stats that we collected and time taken
1382    if (!errorCount) {
[870]1383                XERCES_STD_QUALIFIER cerr << filename << ": " << duration << " ms ("
[508]1384                                << handler.GetElementCount() << " elems, "
1385                                << handler.GetAttrCount() << " attrs, "
1386                                << handler.GetSpaceCount() << " spaces, "
1387                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1388    }
1389  }
1390 
1391  //
1392  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1393  //
1394  delete parser;
1395 
1396  XMLPlatformUtils::Terminate();
1397 
[931]1398  //-- assign new view cells manager
[577]1399  *viewCells = handler.mViewCellsManager;
[651]1400 
[508]1401  if (errorCount > 0)
1402    return false;
1403  else
1404    return true;
[556]1405}
[860]1406
1407}
Note: See TracBrowser for help on using the repository browser.