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

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