interiorRes.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "interior/interiorRes.h"
  24. #include "console/console.h"
  25. #include "core/stream/fileStream.h"
  26. #include "interior/interior.h"
  27. #include "interior/interiorResObjects.h"
  28. #include "gfx/bitmap/gBitmap.h"
  29. #include "interior/forceField.h"
  30. const U32 InteriorResource::smFileVersion = 44;
  31. //--------------------------------------------------------------------------
  32. InteriorResource::InteriorResource()
  33. {
  34. VECTOR_SET_ASSOCIATION(mDetailLevels);
  35. VECTOR_SET_ASSOCIATION(mSubObjects);
  36. VECTOR_SET_ASSOCIATION(mTriggers);
  37. //VECTOR_SET_ASSOCIATION(mPaths);
  38. VECTOR_SET_ASSOCIATION(mInteriorPathFollowers);
  39. VECTOR_SET_ASSOCIATION(mForceFields);
  40. VECTOR_SET_ASSOCIATION(mAISpecialNodes);
  41. mPreviewBitmap = NULL;
  42. }
  43. InteriorResource::~InteriorResource()
  44. {
  45. U32 i;
  46. for (i = 0; i < mDetailLevels.size(); i++)
  47. delete mDetailLevels[i];
  48. for (i = 0; i < mSubObjects.size(); i++)
  49. delete mSubObjects[i];
  50. for (i = 0; i < mTriggers.size(); i++)
  51. delete mTriggers[i];
  52. for (i = 0; i < mInteriorPathFollowers.size(); i++)
  53. delete mInteriorPathFollowers[i];
  54. for (i = 0; i < mForceFields.size(); i++)
  55. delete mForceFields[i];
  56. for (i = 0; i < mAISpecialNodes.size(); i++)
  57. delete mAISpecialNodes[i];
  58. for (i = 0; i < mGameEntities.size(); i++)
  59. delete mGameEntities[i];
  60. delete mPreviewBitmap;
  61. mPreviewBitmap = NULL;
  62. }
  63. bool InteriorResource::read(Stream& stream)
  64. {
  65. AssertFatal(stream.hasCapability(Stream::StreamRead), "Interior::read: non-read capable stream passed");
  66. AssertFatal(stream.getStatus() == Stream::Ok, "Interior::read: Error, stream in inconsistent state");
  67. U32 i;
  68. // Version this stream
  69. U32 fileVersion;
  70. stream.read(&fileVersion);
  71. if (fileVersion != smFileVersion) {
  72. Con::errorf(ConsoleLogEntry::General, "InteriorResource::read: incompatible file version found.");
  73. return false;
  74. }
  75. // Handle preview
  76. bool previewIncluded = false;
  77. stream.read(&previewIncluded);
  78. if (previewIncluded) {
  79. GBitmap bmp;
  80. bmp.readBitmap("png",stream);
  81. }
  82. // Details
  83. U32 numDetailLevels;
  84. stream.read(&numDetailLevels);
  85. mDetailLevels.setSize(numDetailLevels);
  86. for (i = 0; i < mDetailLevels.size(); i++)
  87. mDetailLevels[i] = NULL;
  88. for (i = 0; i < mDetailLevels.size(); i++) {
  89. mDetailLevels[i] = new Interior;
  90. if (mDetailLevels[i]->read(stream) == false) {
  91. Con::errorf(ConsoleLogEntry::General, "Unable to read detail level %d in interior resource", i);
  92. return false;
  93. }
  94. }
  95. // Subobjects: mirrors, translucencies
  96. U32 numSubObjects;
  97. stream.read(&numSubObjects);
  98. mSubObjects.setSize(numSubObjects);
  99. for (i = 0; i < mSubObjects.size(); i++)
  100. mSubObjects[i] = NULL;
  101. for (i = 0; i < mSubObjects.size(); i++) {
  102. mSubObjects[i] = new Interior;
  103. if (mSubObjects[i]->read(stream) == false) {
  104. AssertISV(false, avar("Unable to read subobject %d in interior resource", i));
  105. return false;
  106. }
  107. }
  108. // Triggers
  109. U32 numTriggers;
  110. stream.read(&numTriggers);
  111. mTriggers.setSize(numTriggers);
  112. for (i = 0; i < mTriggers.size(); i++)
  113. mTriggers[i] = NULL;
  114. for (i = 0; i < mTriggers.size(); i++) {
  115. mTriggers[i] = new InteriorResTrigger;
  116. if (mTriggers[i]->read(stream) == false) {
  117. AssertISV(false, avar("Unable to read trigger %d in interior resource", i));
  118. return false;
  119. }
  120. }
  121. U32 numChildren;
  122. stream.read(&numChildren);
  123. mInteriorPathFollowers.setSize(numChildren);
  124. for (i = 0; i < mInteriorPathFollowers.size(); i++)
  125. mInteriorPathFollowers[i] = NULL;
  126. for (i = 0; i < mInteriorPathFollowers.size(); i++) {
  127. mInteriorPathFollowers[i] = new InteriorPathFollower;
  128. if (mInteriorPathFollowers[i]->read(stream) == false) {
  129. AssertISV(false, avar("Unable to read child %d in interior resource", i));
  130. return false;
  131. }
  132. }
  133. U32 numFields;
  134. stream.read(&numFields);
  135. mForceFields.setSize(numFields);
  136. for (i = 0; i < mForceFields.size(); i++)
  137. mForceFields[i] = NULL;
  138. for (i = 0; i < mForceFields.size(); i++) {
  139. mForceFields[i] = new ForceField;
  140. if (mForceFields[i]->read(stream) == false) {
  141. AssertISV(false, avar("Unable to read field %d in interior resource", i));
  142. return false;
  143. }
  144. }
  145. U32 numSpecNodes;
  146. stream.read(&numSpecNodes);
  147. mAISpecialNodes.setSize(numSpecNodes);
  148. for (i = 0; i < mAISpecialNodes.size(); i++)
  149. mAISpecialNodes[i] = NULL;
  150. for (i = 0; i < mAISpecialNodes.size(); i++) {
  151. mAISpecialNodes[i] = new AISpecialNode;
  152. if (mAISpecialNodes[i]->read(stream) == false) {
  153. AssertISV(false, avar("Unable to read SpecNode %d in interior resource", i));
  154. return false;
  155. }
  156. }
  157. U32 dummyInt;
  158. stream.read(&dummyInt);
  159. if (dummyInt == 1)
  160. {
  161. if (mDetailLevels.size() != 0)
  162. getDetailLevel(0)->readVehicleCollision(stream);
  163. }
  164. // For expansion purposes
  165. stream.read(&dummyInt);
  166. if(dummyInt == 2)
  167. {
  168. U32 numGameEnts;
  169. stream.read(&numGameEnts);
  170. mGameEntities.setSize(numGameEnts);
  171. for (i = 0; i < numGameEnts; i++)
  172. mGameEntities[i] = new ItrGameEntity;
  173. for (i = 0; i < numGameEnts; i++) {
  174. if (mGameEntities[i]->read(stream) == false) {
  175. AssertISV(false, avar("Unable to read SpecNode %d in interior resource", i));
  176. return false;
  177. }
  178. }
  179. stream.read(&dummyInt);
  180. }
  181. return (stream.getStatus() == Stream::Ok);
  182. }
  183. bool InteriorResource::write(Stream& stream) const
  184. {
  185. AssertFatal(stream.hasCapability(Stream::StreamWrite), "Interior::write: non-write capable stream passed");
  186. AssertFatal(stream.getStatus() == Stream::Ok, "Interior::write: Error, stream in inconsistent state");
  187. // Version the stream
  188. stream.write(smFileVersion);
  189. // Handle preview
  190. //
  191. if (mPreviewBitmap != NULL) {
  192. stream.write(bool(true));
  193. mPreviewBitmap->writeBitmap("png",stream);
  194. } else {
  195. stream.write(bool(false));
  196. }
  197. // Write out the interiors
  198. stream.write(mDetailLevels.size());
  199. U32 i;
  200. for (i = 0; i < mDetailLevels.size(); i++) {
  201. if (mDetailLevels[i]->write(stream) == false) {
  202. AssertISV(false, "Unable to write detail level to stream");
  203. return false;
  204. }
  205. }
  206. stream.write(mSubObjects.size());
  207. for (i = 0; i < mSubObjects.size(); i++) {
  208. if (mSubObjects[i]->write(stream) == false) {
  209. AssertISV(false, "Unable to write subobject to stream");
  210. return false;
  211. }
  212. }
  213. stream.write(mTriggers.size());
  214. for (i = 0; i < mTriggers.size(); i++) {
  215. if (mTriggers[i]->write(stream) == false) {
  216. AssertISV(false, "Unable to write trigger to stream");
  217. return false;
  218. }
  219. }
  220. stream.write(mInteriorPathFollowers.size());
  221. for (i = 0; i < mInteriorPathFollowers.size(); i++) {
  222. if (mInteriorPathFollowers[i]->write(stream) == false) {
  223. AssertISV(false, avar("Unable to write child %d in interior resource", i));
  224. return false;
  225. }
  226. }
  227. stream.write(mForceFields.size());
  228. for (i = 0; i < mForceFields.size(); i++) {
  229. if (mForceFields[i]->write(stream) == false) {
  230. AssertISV(false, avar("Unable to write field %d in interior resource", i));
  231. return false;
  232. }
  233. }
  234. stream.write(mAISpecialNodes.size());
  235. for (i = 0; i < mAISpecialNodes.size(); i++) {
  236. if (mAISpecialNodes[i]->write(stream) == false) {
  237. AssertISV(false, avar("Unable to write SpecNode %d in interior resource", i));
  238. return false;
  239. }
  240. }
  241. stream.write(U32(1));
  242. if (mDetailLevels.size() != 0)
  243. const_cast<Interior*>(mDetailLevels[0])->writeVehicleCollision(stream);
  244. // For expansion purposes
  245. if (mGameEntities.size())
  246. {
  247. stream.write(U32(2));
  248. stream.write(mGameEntities.size());
  249. for(i = 0; i < mGameEntities.size(); i++)
  250. {
  251. if (mGameEntities[i]->write(stream) == false) {
  252. AssertISV(false, avar("Unable to write GameEnt %d in interior resource", i));
  253. return false;
  254. }
  255. }
  256. }
  257. stream.write(U32(0));
  258. return (stream.getStatus() == Stream::Ok);
  259. }
  260. GBitmap* InteriorResource::extractPreview(Stream& stream)
  261. {
  262. AssertFatal(stream.hasCapability(Stream::StreamRead), "Interior::read: non-read capable stream passed");
  263. AssertFatal(stream.getStatus() == Stream::Ok, "Interior::read: Error, stream in inconsistent state");
  264. // Version this stream
  265. U32 fileVersion;
  266. stream.read(&fileVersion);
  267. if (fileVersion != smFileVersion) {
  268. Con::errorf(ConsoleLogEntry::General, "InteriorResource::read: incompatible file version found.");
  269. return NULL;
  270. }
  271. // Handle preview
  272. bool previewIncluded = false;
  273. stream.read(&previewIncluded);
  274. if (previewIncluded) {
  275. GBitmap* pBmp = new GBitmap;
  276. if (pBmp->readBitmap("png",stream) == true)
  277. return pBmp;
  278. delete pBmp;
  279. }
  280. return NULL;
  281. }
  282. //------------------------------------------------------------------------------
  283. //-------------------------------------- Interior Resource constructor
  284. template<> void *Resource<InteriorResource>::create(const Torque::Path &path)
  285. {
  286. FileStream stream;
  287. stream.open( path.getFullPath(), Torque::FS::File::Read );
  288. if ( stream.getStatus() != Stream::Ok )
  289. return NULL;
  290. InteriorResource* pResource = new InteriorResource;
  291. if (pResource->read(stream) == true)
  292. return pResource;
  293. else
  294. {
  295. delete pResource;
  296. return NULL;
  297. }
  298. }
  299. template<> ResourceBase::Signature Resource<InteriorResource>::signature()
  300. {
  301. return MakeFourCC('t','d','i','f');
  302. }