2
0

SkeletonAsset.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 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. #ifndef _CONSOLE_H_
  23. #include "console/console.h"
  24. #endif
  25. #ifndef _CONSOLEINTERNAL_H_
  26. #include "console/consoleInternal.h"
  27. #endif
  28. #ifndef _GBITMAP_H_
  29. #include "graphics/gBitmap.h"
  30. #endif
  31. #ifndef _UTILITY_H_
  32. #include "2d/core/Utility.h"
  33. #endif
  34. #ifndef _SCENE_OBJECT_H_
  35. #include "2d/sceneobject/SceneObject.h"
  36. #endif
  37. #ifndef _SKELETON_ASSET_H_
  38. #include "2d/assets/SkeletonAsset.h"
  39. #endif
  40. // Script bindings.
  41. #include "SkeletonAsset_ScriptBinding.h"
  42. //------------------------------------------------------------------------------
  43. IMPLEMENT_CONOBJECT(SkeletonAsset);
  44. //------------------------------------------------------------------------------
  45. ConsoleType( skeletonAssetPtr, TypeSkeletonAssetPtr, sizeof(AssetPtr<SkeletonAsset>), ASSET_ID_FIELD_PREFIX )
  46. //-----------------------------------------------------------------------------
  47. ConsoleGetType( TypeSkeletonAssetPtr )
  48. {
  49. // Fetch asset Id.
  50. return (*((AssetPtr<SkeletonAsset>*)dptr)).getAssetId();
  51. }
  52. //-----------------------------------------------------------------------------
  53. ConsoleSetType( TypeSkeletonAssetPtr )
  54. {
  55. // Was a single argument specified?
  56. if( argc == 1 )
  57. {
  58. // Yes, so fetch field value.
  59. const char* pFieldValue = argv[0];
  60. // Fetch asset pointer.
  61. AssetPtr<SkeletonAsset>* pAssetPtr = dynamic_cast<AssetPtr<SkeletonAsset>*>((AssetPtrBase*)(dptr));
  62. // Is the asset pointer the correct type?
  63. if (pAssetPtr == NULL )
  64. {
  65. // No, so fail.
  66. Con::warnf( "(TypeSkeletonAssetPtr) - Failed to set asset Id '%d'.", pFieldValue );
  67. return;
  68. }
  69. // Set asset.
  70. pAssetPtr->setAssetId( pFieldValue );
  71. return;
  72. }
  73. // Warn.
  74. Con::warnf( "(TypeSkeletonAssetPtr) - Cannot set multiple args to a single asset." );
  75. }
  76. //------------------------------------------------------------------------------
  77. SkeletonAsset::SkeletonAsset() : mSkeletonFile(StringTable->EmptyString),
  78. mAtlasFile(StringTable->EmptyString),
  79. mAtlasDirty(true),
  80. mAtlas(NULL),
  81. mSkeletonData(NULL),
  82. mStateData(NULL)
  83. {
  84. }
  85. //------------------------------------------------------------------------------
  86. SkeletonAsset::~SkeletonAsset()
  87. {
  88. spAnimationStateData_dispose(mStateData);
  89. spSkeletonData_dispose(mSkeletonData);
  90. spAtlas_dispose(mAtlas);
  91. }
  92. //------------------------------------------------------------------------------
  93. void SkeletonAsset::initPersistFields()
  94. {
  95. // Call parent.
  96. Parent::initPersistFields();
  97. // Fields.
  98. addProtectedField("AtlasFile", TypeAssetLooseFilePath, Offset(mAtlasFile, SkeletonAsset), &setAtlasFile, &defaultProtectedGetFn, &writeAtlasFile, "The loose file pointing to the .atlas file used for skinning");
  99. addProtectedField("SkeletonFile", TypeAssetLooseFilePath, Offset(mSkeletonFile, SkeletonAsset), &setSkeletonFile, &defaultProtectedGetFn, &writeSkeletonFile, "The loose file produced by the editor, which is fed into this asset");
  100. }
  101. //------------------------------------------------------------------------------
  102. bool SkeletonAsset::onAdd()
  103. {
  104. // Call Parent.
  105. if (!Parent::onAdd())
  106. return false;
  107. return true;
  108. }
  109. //------------------------------------------------------------------------------
  110. void SkeletonAsset::onRemove()
  111. {
  112. // Call Parent.
  113. Parent::onRemove();
  114. }
  115. //------------------------------------------------------------------------------
  116. void SkeletonAsset::setSkeletonFile( const char* pSkeletonFile )
  117. {
  118. // Sanity!
  119. AssertFatal( pSkeletonFile != NULL, "Cannot use a NULL skeleton file." );
  120. // Fetch skeleton file.
  121. pSkeletonFile = StringTable->insert( pSkeletonFile );
  122. // Ignore no change.
  123. if (pSkeletonFile == mSkeletonFile )
  124. return;
  125. // Update.
  126. mSkeletonFile = getOwned() ? expandAssetFilePath( pSkeletonFile ) : StringTable->insert( pSkeletonFile );
  127. // Refresh the asset.
  128. refreshAsset();
  129. }
  130. //------------------------------------------------------------------------------
  131. void SkeletonAsset::setAtlasFile( const char* pAtlasFile )
  132. {
  133. // Sanity!
  134. AssertFatal( pAtlasFile != NULL, "Cannot use a NULL atlas file." );
  135. // Fetch atlas file.
  136. pAtlasFile = StringTable->insert( pAtlasFile );
  137. // Ignore no change.
  138. if (pAtlasFile == mAtlasFile )
  139. return;
  140. // Update.
  141. mAtlasFile = getOwned() ? expandAssetFilePath( pAtlasFile ) : StringTable->insert( pAtlasFile );
  142. mAtlasDirty = true;
  143. // Refresh the asset.
  144. refreshAsset();
  145. }
  146. //------------------------------------------------------------------------------
  147. void SkeletonAsset::copyTo(SimObject* object)
  148. {
  149. // Call to parent.
  150. Parent::copyTo(object);
  151. // Cast to asset.
  152. SkeletonAsset* pAsset = static_cast<SkeletonAsset*>(object);
  153. // Sanity!
  154. AssertFatal(pAsset != NULL, "SkeletonAsset::copyTo() - Object is not the correct type.");
  155. // Copy state.
  156. pAsset->setAtlasFile( getAtlasFile() );
  157. pAsset->setSkeletonFile( getSkeletonFile() );
  158. }
  159. //------------------------------------------------------------------------------
  160. void SkeletonAsset::initializeAsset( void )
  161. {
  162. // Call parent.
  163. Parent::initializeAsset();
  164. // Ensure the skeleton file is expanded.
  165. mSkeletonFile = expandAssetFilePath( mSkeletonFile );
  166. // Ensure the skeleton file is expanded.
  167. mAtlasFile = expandAssetFilePath( mAtlasFile );
  168. // Build the atlas data
  169. if (mAtlasDirty)
  170. buildAtlasData();
  171. // Build the skeleton data
  172. buildSkeletonData();
  173. }
  174. //------------------------------------------------------------------------------
  175. void SkeletonAsset::onAssetRefresh( void )
  176. {
  177. // Ignore if not yet added to the sim.
  178. if (!isProperlyAdded() )
  179. return;
  180. // Call parent.
  181. Parent::onAssetRefresh();
  182. // Reset any states or data
  183. if (mAtlasDirty)
  184. buildAtlasData();
  185. buildSkeletonData();
  186. }
  187. //-----------------------------------------------------------------------------
  188. void SkeletonAsset::buildAtlasData( void )
  189. {
  190. // If the atlas data was previously created, need to release it
  191. if (mAtlas)
  192. spAtlas_dispose(mAtlas);
  193. // If we are using a .atlas file
  194. if (mAtlasFile != StringTable->EmptyString)
  195. mAtlas = spAtlas_readAtlasFile(mAtlasFile);
  196. // Atlas load failure
  197. AssertFatal(mAtlas != NULL, "SkeletonAsset::buildAtlasData() - Atlas was not loaded.");
  198. spAtlasPage* currentPage = mAtlas->pages;
  199. while (currentPage != NULL)
  200. {
  201. // Allocate a new ImageAsset. If we have multiple atlases, we would loop this multiple times
  202. ImageAsset* pImageAsset = new ImageAsset();
  203. const char* imageFilePath = expandAssetFilePath(currentPage->name);
  204. // Point to the raw file (png or jpg)
  205. pImageAsset->setImageFile( imageFilePath);
  206. // Enable Explicit Mode so we can use region coordinates
  207. pImageAsset->setExplicitMode( true );
  208. spAtlasRegion* currentRegion = mAtlas->regions;
  209. // Add it to the AssetDatabase, making it accessible everywhere
  210. mImageAsset = AssetDatabase.addPrivateAsset( pImageAsset );
  211. // Loop through the Atlas information to create cell regions
  212. while (currentRegion != NULL)
  213. {
  214. pImageAsset->addExplicitCell( currentRegion->x, currentRegion->y, currentRegion->width, currentRegion->height, currentRegion->name );
  215. currentRegion = currentRegion->next;
  216. }
  217. mImageAsset->forceCalculation();
  218. currentPage = currentPage->next;
  219. }
  220. mAtlasDirty = false;
  221. }
  222. //-----------------------------------------------------------------------------
  223. void SkeletonAsset::buildSkeletonData( void )
  224. {
  225. // Atlas load failure
  226. AssertFatal(mAtlas != NULL, "SkeletonAsset::buildSkeletonData() - Atlas was not loaded.");
  227. // Clear state data
  228. if (mStateData)
  229. spAnimationStateData_dispose(mStateData);
  230. // Clear skeleton data
  231. if (mSkeletonData)
  232. spSkeletonData_dispose(mSkeletonData);
  233. spSkeletonJson* json = spSkeletonJson_create(mAtlas);
  234. mSkeletonData = spSkeletonJson_readSkeletonDataFile(json, mSkeletonFile);
  235. if (!mSkeletonData)
  236. {
  237. spAtlas_dispose(mAtlas);
  238. mAtlas = 0;
  239. // Report json->error message
  240. AssertFatal(mSkeletonData != NULL, "SkeletonAsset::buildSkeletonData() - Skeleton data was not valid.");
  241. }
  242. spSkeletonJson_dispose(json);
  243. mStateData = spAnimationStateData_create(mSkeletonData);
  244. }
  245. //-----------------------------------------------------------------------------
  246. bool SkeletonAsset::isAssetValid( void ) const
  247. {
  248. return ((mAtlas != NULL) && (mSkeletonData != NULL) && (mStateData != NULL) && mImageAsset.notNull());
  249. }
  250. //-----------------------------------------------------------------------------
  251. void SkeletonAsset::onTamlPreWrite( void )
  252. {
  253. // Call parent.
  254. Parent::onTamlPreWrite();
  255. // Ensure the skeleton file is collapsed.
  256. mSkeletonFile = collapseAssetFilePath( mSkeletonFile );
  257. // Ensure the atlas file is collapsed.
  258. mAtlasFile = collapseAssetFilePath( mAtlasFile );
  259. }
  260. //-----------------------------------------------------------------------------
  261. void SkeletonAsset::onTamlPostWrite( void )
  262. {
  263. // Call parent.
  264. Parent::onTamlPostWrite();
  265. // Ensure the skeleton file is expanded.
  266. mSkeletonFile = expandAssetFilePath( mSkeletonFile );
  267. // Ensure the atlas file is expanded.
  268. mAtlasFile = expandAssetFilePath( mAtlasFile );
  269. }
  270. //------------------------------------------------------------------------------
  271. void SkeletonAsset::onTamlCustomWrite( TamlCustomNodes& customNodes )
  272. {
  273. // Debug Profiling.
  274. PROFILE_SCOPE(SkeletonAsset_OnTamlCustomWrite);
  275. // Call parent.
  276. Parent::onTamlCustomWrite( customNodes );
  277. }
  278. //-----------------------------------------------------------------------------
  279. void SkeletonAsset::onTamlCustomRead( const TamlCustomNodes& customNodes )
  280. {
  281. // Debug Profiling.
  282. PROFILE_SCOPE(SkeletonAsset_OnTamlCustomRead);
  283. // Call parent.
  284. Parent::onTamlCustomRead( customNodes );
  285. }