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

Revision 1558, 33.6 KB checked in by mattausch, 18 years ago (diff)

added the preprocessor front end

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