PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Semester 7/GameEngine/OpenSceneGraph-3.4.0/src/osgPlugins/txp/trpage_pparse.cpp

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