root/OpenSceneGraph/trunk/src/osgPlugins/txp/trpage_pparse.cpp @ 13041

Revision 13041, 13.9 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* ************************
2   Copyright Terrain Experts Inc.
3   Terrain Experts Inc (TERREX) reserves all rights to this source code
4   unless otherwise specified in writing by the President of TERREX.
5   This copyright may be updated in the future, in which case that version
6   supercedes this one.
7   -------------------
8   Terrex Experts Inc.
9   4400 East Broadway #314
10   Tucson, AZ  85711
11   info@terrex.com
12   Tel: (520) 323-7990
13   ************************
14   */
15
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19
20/* trpage_pparse.cpp
21    This file contains classes that can parse a TerraPage
22    archive for the purpose of printing it out.
23 */
24
25#include <trpage_print.h>
26#include <trpage_scene.h>
27#include <trpage_managers.h>
28
29namespace
30{
31   // This will recursivelly call itself up until
32   // all the tiule are done
33   void printBuf(int lod, int x, int y, trpgr_Archive *archive, trpgPrintGraphParser& parser, trpgMemReadBuffer &buf, trpgPrintBuffer &pBuf)
34   {
35      char ls[1024];
36       sprintf(ls,"Tile (lod) (x,y) = (%d) (%d,%d)", lod, x, y);
37       pBuf.prnLine(ls);
38      pBuf.IncreaseIndent();
39      parser.Reset();
40      parser.Parse(buf);
41      pBuf.DecreaseIndent();
42
43      // Save the list
44//      std::vector<const trpgChildRef> childRefList;
45// The const in the template parameter was removed because it causes GCC to
46// freak out.  I am of the opinion that const doesn't make sense in a template
47// parameter for std::vector anyway... const prevents you from changing the
48// value, so what exactly is the point?  How does one add entries to the vector
49// without giving them a value?  -ADS
50      std::vector<trpgChildRef> childRefList;
51      for(unsigned int idx =0; idx < parser.GetNbChildrenRef(); idx++)
52         childRefList.push_back(*parser.GetChildRef(idx));
53
54
55      for(unsigned int idx =0; idx < childRefList.size(); idx++)
56      {
57         const trpgChildRef& childRef = childRefList[idx];
58         trpgMemReadBuffer childBuf(archive->GetEndian());
59         trpgwAppAddress tileAddr;
60         int glod, gx, gy;
61
62         childRef.GetTileAddress(tileAddr);
63         childRef.GetTileLoc(gx,gy,glod);
64
65         trpgTileTable::TileMode mode;
66         archive->GetTileTable()->GetMode(mode);
67         bool status;
68         if(mode == trpgTileTable::Local)
69            status = archive->ReadTile(tileAddr, childBuf);
70         else
71            status = archive->ReadExternalTile(gx, gy, glod, childBuf);
72
73         if(status)
74            printBuf(glod, gx, gy, archive, parser, childBuf, pBuf);
75
76      }
77   }
78} // end namespace
79
80
81
82
83
84
85
86
87
88/* Set up the callbacks for the scene graph parser.
89    In our case this is just one read helper with
90    a switch statement.
91 */
92trpgPrintGraphParser::trpgPrintGraphParser(trpgr_Archive *inArch,trpgrImageHelper *inImg,trpgPrintBuffer *inBuf):printBuf(inBuf), archive(inArch), imageHelp(inImg), childRefCB(0)
93{
94    // Register the readers
95    AddCallback(TRPG_GEOMETRY,new ReadHelper(this,printBuf));
96    AddCallback(TRPG_GROUP,new ReadHelper(this,printBuf));
97    AddCallback(TRPG_ATTACH,new ReadHelper(this,printBuf));
98   AddCallback(TRPG_CHILDREF,new ReadHelper(this,printBuf));
99    AddCallback(TRPG_BILLBOARD,new ReadHelper(this,printBuf));
100    AddCallback(TRPG_LOD,new ReadHelper(this,printBuf));
101    AddCallback(TRPG_TRANSFORM,new ReadHelper(this,printBuf));
102    AddCallback(TRPG_MODELREF,new ReadHelper(this,printBuf));
103    AddCallback(TRPG_LAYER,new ReadHelper(this,printBuf));
104    AddCallback(TRPG_LIGHT,new ReadHelper(this,printBuf));
105    AddCallback(TRPG_LABEL,new ReadHelper(this,printBuf));
106    AddCallback(TRPGTILEHEADER,new ReadHelper(this,printBuf));
107
108   childRefCB = dynamic_cast<ReadHelper *>(GetCallback(TRPG_CHILDREF));
109}
110
111/* Start Children is called when the parser hits a Push
112    in the read buffer.  We just want to indent further when
113    that happens.
114 */
115bool trpgPrintGraphParser::StartChildren(void *)
116{
117    printBuf->IncreaseIndent();
118
119    return true;
120}
121
122
123/* End Children is called when the parser hits a Pop
124    in the read buffer.  We just want to reduce the indent
125    when that happens.
126 */
127bool trpgPrintGraphParser::EndChildren(void *)
128{
129    printBuf->DecreaseIndent();
130
131    return true;
132}
133
134unsigned int trpgPrintGraphParser::GetNbChildrenRef() const
135{
136   if(childRefCB)
137      return childRefCB->GetNbChildrenRef();
138   else
139      return 0;
140}
141
142const trpgChildRef* trpgPrintGraphParser::GetChildRef(unsigned int idx) const
143{
144   if(childRefCB)
145      return childRefCB->GetChildRef(idx);
146   else
147      return 0;
148
149}
150
151
152
153void trpgPrintGraphParser::Reset()
154{
155   if(childRefCB)
156      childRefCB->Reset();
157}
158
159void trpgPrintGraphParser::ReadHelper::Reset()
160{
161   childRefList.clear();
162}
163
164unsigned int trpgPrintGraphParser::ReadHelper::GetNbChildrenRef() const
165{
166   return childRefList.size();
167}
168const trpgChildRef* trpgPrintGraphParser::ReadHelper::GetChildRef(unsigned int idx) const
169{
170   if(idx >= childRefList.size())
171      return 0;
172   else
173      return &childRefList[idx];
174}
175
176/* Read Helper parse method sets up the correct class depending
177    on the token and asks it to read and print itself. It will save
178   any child ref node encountered that a user can access to continue
179   traversal.
180 */
181void *trpgPrintGraphParser::ReadHelper::Parse(trpgToken tok,trpgReadBuffer &buf)
182{
183   // This will celar any child ref list from a previous parse.
184    trpgReadWriteable *obj = NULL;
185    trpgTileHeader *tileHead = NULL;
186
187    switch (tok) {
188    case TRPG_GEOMETRY:
189        obj = new trpgGeometry();
190        break;
191    case TRPG_GROUP:
192        obj = new trpgGroup();
193        break;
194    case TRPG_ATTACH:
195        obj = new trpgAttach();
196        break;
197   case TRPG_CHILDREF:
198      childRefList.push_back(trpgChildRef());
199      obj = &childRefList.back();
200        break;
201    case TRPG_BILLBOARD:
202        obj = new trpgBillboard();
203        break;
204    case TRPG_LOD:
205        obj = new trpgLod();
206        break;
207    case TRPG_TRANSFORM:
208        obj = new trpgTransform();
209        break;
210    case TRPG_MODELREF:
211        obj = new trpgModelRef();
212        break;
213    case TRPG_LAYER:
214        obj = new trpgLayer();
215        break;
216    case TRPG_LIGHT:
217        obj = new trpgLight();
218        break;
219    case TRPG_LABEL:
220        obj = new trpgLabel();
221        break;
222
223    case TRPGTILEHEADER:
224        obj = tileHead = new trpgTileHeader();
225        break;
226    };
227
228    if (obj) {
229        if (obj->Read(buf))
230            obj->Print(*pBuf);
231        // For the tile header, do a little more work
232        if (tok == TRPGTILEHEADER) {
233            int numMat;
234            tileHead->GetNumLocalMaterial(numMat);
235            for (int i=0;i<numMat;i++) {
236                trpgLocalMaterial locMat;
237                tileHead->GetLocalMaterial(i,locMat);
238                const trpgMaterial *baseMat;
239                const trpgTexture *baseTex;
240                int totSize;
241                trpgrImageHelper *imageHelp = parse->GetImageHelp();
242                int numImages=1;
243                locMat.GetNumLocals(numImages);
244                for (int imgN=0;imgN<numImages;imgN++) {
245                    // read all the images for each local material
246                    imageHelp->GetNthImageInfoForLocalMat(&locMat,imgN,&baseMat,&baseTex,totSize);
247
248                    // Fetch the whole image
249                    {
250                        char *pixels = new char[totSize];
251                        bool failed = false;
252                        try {
253                            failed = !imageHelp->GetNthImageForLocalMat(&locMat,imgN,pixels,totSize);
254                        }
255                        catch (...) {
256                            failed = true;
257                        }
258                        if (failed) {
259                            fprintf(stderr,"Failed to read local image %d from local material %d.\n",imgN,i);
260                        } else
261                            fprintf(stderr,"Read local image %d from local material %d successfully.\n",imgN,i);
262                        delete [] pixels;
263                    }
264
265                    // Fetch the individual mipmap levels
266                    {
267
268                        bool hasMipmap = false;
269                        baseTex->GetIsMipmap(hasMipmap);
270                        int numMipmap = hasMipmap ? baseTex->CalcNumMipmaps() : 0;
271                        for (int j=1;j<numMipmap;j++) {
272                            //int mipOffset = (const_cast<trpgTexture *>(baseTex))->MipLevelOffset(j);
273                            int mipSize = (const_cast<trpgTexture *>(baseTex))->MipLevelSize(j);
274                            if (mipSize) {
275                                char *pixels = new char[mipSize];
276                                bool failed = false;
277                                try {
278                                    failed = !imageHelp->GetNthImageMipLevelForLocalMat(j,&locMat,imgN,pixels,mipSize);
279                                }
280                                catch (...) {
281                                    failed = true;
282                                }
283                                if (failed)
284                                    fprintf(stderr,"Failed to read mipmap level %d for local image %d from local material %d.\n",j,imgN,i);
285                                else
286                                    fprintf(stderr,"Read mipmap level %d for local image %d from local material %d.\n",j,imgN,i);
287                                delete [] pixels;
288                            }
289                        }
290                    }
291                }
292            }
293        }
294
295      // We delete all object except the child ref node
296      if(tok != TRPG_CHILDREF)
297           delete obj;
298    }
299
300    // Need to return non-zero.  Otherwise it's interpreted as an error
301    return (void *)1;
302}
303
304// The following routine is not compiled if there's no _splitpath
305#ifdef _splitpath
306/* This is a convenience function to print out the contents
307    of an entire TerraPage archive.
308
309   There are two versions of this function.  The first takes
310   a file name and the second an opened archive where the header
311   has already been read.
312 */
313bool trpgPrintArchive(char *filename,trpgPrintBuffer &pBuf,int flags)
314{
315    trpgr_Archive archive;
316
317    // Break path apart so we can find the directory
318    char drive[100],dir[1024],fname[1024],ext[1024];
319    _splitpath(filename,drive,dir,fname,ext);
320
321    char rname[1024],baseDir[1024];
322    sprintf(baseDir,"%s%s",drive,dir);
323    sprintf(rname,"%s%s",fname,ext);
324
325    if (!*baseDir) strcpy(baseDir,".");
326    archive.SetDirectory(baseDir);
327    if (!archive.OpenFile(rname)) {
328        fprintf(stdout,"Failed to open archive.\n");
329        return false;
330    }
331    if (!archive.ReadHeader()) {
332        fprintf(stdout,"Failed to read header.\n");
333        return false;
334    }
335
336    bool status = trpgPrintArchive(&archive,pBuff,flags);
337    return status;
338}
339#endif
340
341bool trpgPrintArchive(trpgr_Archive *archive,trpgPrintBuffer &pBuf,int flags)
342{
343    char ls[1024];
344
345    if (!archive->isValid())  return false;
346
347    pBuf.prnLine("====Header Structures====");
348
349    // Print out the header portion
350    archive->GetHeader()->Print(pBuf);
351    archive->GetMaterialTable()->Print(pBuf);
352    archive->GetTexTable()->Print(pBuf);
353    archive->GetModelTable()->Print(pBuf);
354    archive->GetTileTable()->Print(pBuf);
355    archive->GetLightTable()->Print(pBuf);
356    archive->GetRangeTable()->Print(pBuf);
357    archive->GetTextStyleTable()->Print(pBuf);
358    archive->GetSupportStyleTable()->Print(pBuf);
359    archive->GetLabelPropertyTable()->Print(pBuf);
360    pBuf.prnLine();
361
362    // Read the local images and do the math for the templates
363
364    // Now do the tiles
365    if (!archive->isValid())  return false;
366
367   int majorVersion, minorVersion;
368   archive->GetHeader()->GetVersion(majorVersion, minorVersion);
369
370    // Parser that prints out a tile scene graph
371    trpgrImageHelper* imageHelp=archive->GetNewRImageHelper(archive->GetEndian(),archive->getDir(),
372            *archive->GetMaterialTable(),*archive->GetTexTable());
373
374    trpgPrintGraphParser parser(archive,imageHelp,&pBuf);
375
376    pBuf.prnLine("====Tile Data====");
377    int nl,x,y;
378    trpgMemReadBuffer buf(archive->GetEndian());
379    // Iterate over the terrain lods
380    int numLod;
381    archive->GetHeader()->GetNumLods(numLod);
382    trpg2iPoint tileSize;
383   if(majorVersion == 2 && minorVersion >= 1)
384   {
385      // Version 2.1
386      // Because of variable lod support in version 2.1 and over, we can
387      // no longer suppose that all lod level are all populated with tiles
388      // in all of the gaming area. We have to parse the parent to know that.
389      // Also the tile table only contains lod 0 tiles so we can no longer access
390      // the tile directly from its grid location. So we have to traverse.
391      trpg2iPoint blockTileSize;
392      if(archive->GetHeader()->GetLodSize(0,blockTileSize)) {
393        for(x = 0; x < blockTileSize.x; x++)
394            for( y = 0; y < blockTileSize.y; y++)
395                if (archive->ReadTile(x,y,0,buf))
396                printBuf(0, x, y, archive, parser, buf, pBuf);
397
398      }
399
400   }
401   else
402   {
403       for (nl=0;nl<numLod;nl++) {
404           archive->GetHeader()->GetLodSize(nl,tileSize);
405           // Iterate over the tiles
406           for (x=tileSize.x-1;x>=0;x--)
407               for (y=0;y<tileSize.y;y++) {
408                   sprintf(ls,"Tile (lod) (x,y) = (%d) (%d,%d)",nl,x,y);
409                   pBuf.prnLine(ls);
410                   if (archive->ReadTile(x,y,nl,buf)) {
411                       if (flags & TRPGPRN_BODY) {
412                          pBuf.IncreaseIndent();
413                          // Parse it (also prints it
414                          if (!parser.Parse(buf))
415                          {
416                              char errString[80];
417                              sprintf(errString, "**** Warning: tile anomaly detected: (%d) (%d,%d) ****",nl,x,y);
418                              // send it both ways so it's easier to spot
419                              pBuf.prnLine(errString);
420                              fprintf(stderr,"%s\n",errString);
421                          }
422                          pBuf.DecreaseIndent();
423                       }
424                   } else
425                       pBuf.prnLine("  Couldn't read tile.");
426               }
427       }
428   }
429
430    return true;
431}
Note: See TracBrowser for help on using the browser.