SpriteBatchItem.cc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  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 _SPRITE_BATCH_ITEM_H_
  23. #include "2d/core/SpriteBatchItem.h"
  24. #endif
  25. #ifndef _SPRITE_BATCH_H_
  26. #include "2d/core/SpriteBatch.h"
  27. #endif
  28. #ifndef _SCENE_OBJECT_H_
  29. #include "2d/sceneobject/SceneObject.h"
  30. #endif
  31. //-----------------------------------------------------------------------------
  32. StringTableEntry spritesItemTypeName = StringTable->insert( "Sprite" );
  33. static StringTableEntry spriteNameName = StringTable->insert("Name");
  34. static StringTableEntry spriteLogicalPositionName = StringTable->insert("LogicalPosition");
  35. static StringTableEntry spriteVisibleName = StringTable->insert("Visible");
  36. static StringTableEntry spriteLocalPositionName = StringTable->insert("Position");
  37. static StringTableEntry spriteLocalAngleName = StringTable->insert("Angle");
  38. static StringTableEntry spriteSizeName = StringTable->insert("Size");
  39. static StringTableEntry spriteDepthName = StringTable->insert("Depth");
  40. static StringTableEntry spriteFlipXName = StringTable->insert("FlipX");
  41. static StringTableEntry spriteFlipYName = StringTable->insert("FlipY");
  42. static StringTableEntry spriteSortPointName = StringTable->insert("SortPoint");
  43. static StringTableEntry spriteRenderGroupName = StringTable->insert("RenderGroup");
  44. static StringTableEntry spriteBlendModeName = StringTable->insert("BlendMode");
  45. static StringTableEntry spriteSrcBlendFactorName = StringTable->insert("SrcBlendFactor");
  46. static StringTableEntry spriteDstBlendFactorName = StringTable->insert("DstBlendFactor");
  47. static StringTableEntry spriteBlendColorName = StringTable->insert("BlendColor");
  48. static StringTableEntry spriteAlphaTestName = StringTable->insert("AlphaTest");
  49. static StringTableEntry spriteImageName = StringTable->insert("Image");
  50. static StringTableEntry spriteImageFrameName = StringTable->insert("Frame");
  51. static StringTableEntry spriteAnimationName = StringTable->insert("Animation");
  52. static StringTableEntry spriteDataObjectName = StringTable->insert("DataObject");
  53. //------------------------------------------------------------------------------
  54. SpriteBatchItem::SpriteBatchItem() : mProxyId( SpriteBatch::INVALID_SPRITE_PROXY )
  55. {
  56. resetState();
  57. }
  58. //------------------------------------------------------------------------------
  59. SpriteBatchItem::~SpriteBatchItem()
  60. {
  61. resetState();
  62. }
  63. //------------------------------------------------------------------------------
  64. void SpriteBatchItem::resetState( void )
  65. {
  66. // Call parent.
  67. Parent::resetState();
  68. // Do we have a proxy.
  69. if ( mProxyId != SpriteBatch::INVALID_SPRITE_PROXY )
  70. {
  71. // Sanity!
  72. AssertFatal( mSpriteBatch != NULL, "Cannot remove proxy with NULL sprite batch." );
  73. // Destroy proxy.
  74. mSpriteBatch->destroyQueryProxy( this );
  75. }
  76. mSpriteBatch = NULL;
  77. mBatchId = 0;
  78. mName = StringTable->EmptyString;
  79. mLogicalPosition.resetState();
  80. mVisible = true;
  81. mLocalPosition.SetZero();
  82. mDepth = 0.0f;
  83. mLocalAngle = 0.0f;
  84. setSize( Vector2( 1.0f, 1.0f ) );
  85. mFlipX = false;
  86. mFlipY = false;
  87. mSortPoint.SetZero();
  88. mRenderGroup = StringTable->EmptyString;
  89. mBlendMode = true;
  90. mSrcBlendFactor = GL_SRC_ALPHA;
  91. mDstBlendFactor = GL_ONE_MINUS_SRC_ALPHA;
  92. mBlendColor = ColorF(1.0f,1.0f,1.0f,1.0f);
  93. mAlphaTest = -1.0f;
  94. mDataObject = NULL;
  95. mLocalTransformDirty = true;
  96. mLocalAABB.lowerBound.Set( -0.5f, -0.5f );
  97. mLocalAABB.upperBound.Set( 0.5f, 0.5f );
  98. mRenderAABB.lowerBound.Set( -0.5f, -0.5f );
  99. mRenderAABB.upperBound.Set( 0.5f, 0.5f );
  100. mRenderPosition.setZero();
  101. mLastBatchTransformId = 0;
  102. mSpriteBatchQueryKey = 0;
  103. mUserData = NULL;
  104. // Require self ticking.
  105. mSelfTick = true;
  106. }
  107. //------------------------------------------------------------------------------
  108. void SpriteBatchItem::setBatchParent( SpriteBatch* pSpriteBatch, const U32 batchId )
  109. {
  110. // Sanity!
  111. AssertFatal( pSpriteBatch != NULL, "Cannot assign a NULL batch parent." );
  112. AssertFatal( mSpriteBatch == NULL, "Cannot assign batch parent as one is already assigned." );
  113. AssertFatal( batchId != 0, "Cannot assign a zero batch Id." );
  114. // Assign.
  115. mSpriteBatch = pSpriteBatch;
  116. mBatchId = batchId;
  117. // Create proxy.
  118. mSpriteBatch->createQueryProxy( this );
  119. }
  120. //------------------------------------------------------------------------------
  121. void SpriteBatchItem::copyTo( SpriteBatchItem* pSpriteBatchItem ) const
  122. {
  123. // Call parent.
  124. Parent::copyTo( pSpriteBatchItem );
  125. // Set sprite batch item.
  126. pSpriteBatchItem->setLogicalPosition( getLogicalPosition() );
  127. pSpriteBatchItem->setName( getName() );
  128. pSpriteBatchItem->setVisible( getVisible() );
  129. pSpriteBatchItem->setLocalPosition( getLocalPosition() );
  130. pSpriteBatchItem->setDepth( getDepth() );
  131. pSpriteBatchItem->setLocalAngle( getLocalAngle() );
  132. pSpriteBatchItem->setSize( getSize() );
  133. pSpriteBatchItem->setFlipX( getFlipX() );
  134. pSpriteBatchItem->setFlipY( getFlipY() );
  135. pSpriteBatchItem->setSortPoint( getSortPoint() );
  136. pSpriteBatchItem->setRenderGroup( getRenderGroup() );
  137. pSpriteBatchItem->setBlendMode( getBlendMode() );
  138. pSpriteBatchItem->setSrcBlendFactor( getSrcBlendFactor() );
  139. pSpriteBatchItem->setDstBlendFactor( getDstBlendFactor() );
  140. pSpriteBatchItem->setBlendColor( getBlendColor() );
  141. pSpriteBatchItem->setAlphaTest( getAlphaTest() );
  142. }
  143. //------------------------------------------------------------------------------
  144. void SpriteBatchItem::prepareRender( SceneRenderRequest* pSceneRenderRequest, const U32 batchTransformId )
  145. {
  146. // Debug Profiling.
  147. PROFILE_SCOPE(SpriteBatchItem_PrepareRender);
  148. // Sanity!
  149. AssertFatal( pSceneRenderRequest != NULL, "Cannot prepare a sprite batch with a NULL scene render request." );
  150. // Update the world transform.
  151. updateWorldTransform( batchTransformId );
  152. pSceneRenderRequest->mWorldPosition = mRenderPosition;
  153. pSceneRenderRequest->mDepth = getDepth();
  154. pSceneRenderRequest->mSortPoint = getSortPoint();
  155. pSceneRenderRequest->mSerialId = getBatchId();
  156. pSceneRenderRequest->mRenderGroup = getRenderGroup();
  157. pSceneRenderRequest->mBlendMode = getBlendMode();
  158. pSceneRenderRequest->mSrcBlendFactor = getSrcBlendFactor();
  159. pSceneRenderRequest->mDstBlendFactor = getDstBlendFactor();
  160. pSceneRenderRequest->mBlendColor = getBlendColor();
  161. pSceneRenderRequest->mAlphaTest = getAlphaTest();
  162. }
  163. //------------------------------------------------------------------------------
  164. void SpriteBatchItem::render( BatchRender* pBatchRenderer, const SceneRenderRequest* pSceneRenderRequest, const U32 batchTransformId )
  165. {
  166. // Debug Profiling.
  167. PROFILE_SCOPE(SpriteBatchItem_Render);
  168. // Update the world transform.
  169. updateWorldTransform( batchTransformId );
  170. // Set the blend mode.
  171. pBatchRenderer->setBlendMode( pSceneRenderRequest );
  172. // Set the alpha test mode.
  173. pBatchRenderer->setAlphaTestMode( pSceneRenderRequest );
  174. // Render.
  175. Parent::render( mFlipX, mFlipY,
  176. mRenderOOBB[0],
  177. mRenderOOBB[1],
  178. mRenderOOBB[2],
  179. mRenderOOBB[3],
  180. pBatchRenderer );
  181. }
  182. //------------------------------------------------------------------------------
  183. void SpriteBatchItem::updateLocalTransform( void )
  184. {
  185. // Debug Profiling.
  186. PROFILE_SCOPE(SpriteBatchItem_UpdateLocalTransform);
  187. // Sanity!
  188. AssertFatal( mSpriteBatch != NULL, "SpriteBatchItem::updateLocalTransform() - Cannot update local transform with a NULL sprite batch." );
  189. // Finish if local transform is not dirty.
  190. if ( !mLocalTransformDirty )
  191. return;
  192. // Set local transform.
  193. b2Transform localTransform;
  194. localTransform.p = mLocalPosition;
  195. localTransform.q.Set( mLocalAngle );
  196. // Calculate half size.
  197. const F32 halfWidth = mSize.x * 0.5f;
  198. const F32 halfHeight = mSize.y * 0.5f;
  199. // Set local size vertices.
  200. mLocalOOBB[0].Set( -halfWidth, -halfHeight );
  201. mLocalOOBB[1].Set( +halfWidth, -halfHeight );
  202. mLocalOOBB[2].Set( +halfWidth, +halfHeight );
  203. mLocalOOBB[3].Set( -halfWidth, +halfHeight );
  204. // Calculate local OOBB.
  205. CoreMath::mCalculateOOBB( mLocalOOBB, localTransform, mLocalOOBB );
  206. // Calculate local AABB.
  207. CoreMath::mOOBBtoAABB( mLocalOOBB, mLocalAABB );
  208. // Move query proxy.
  209. mSpriteBatch->moveQueryProxy( this, mLocalAABB );
  210. // Flag local transform as NOT dirty.
  211. mLocalTransformDirty = false;
  212. }
  213. //------------------------------------------------------------------------------
  214. void SpriteBatchItem::updateWorldTransform( const U32 batchTransformId )
  215. {
  216. // Debug Profiling.
  217. PROFILE_SCOPE(SpriteBatchItem_UpdateWorldTransform);
  218. // Sanity!
  219. AssertFatal( mSpriteBatch != NULL, "SpriteBatchItem::updateWorldTransform() - Cannot update transform with a NULL sprite batch." );
  220. // Update the local transform if needed.
  221. if ( mLocalTransformDirty )
  222. {
  223. updateLocalTransform();
  224. }
  225. // Finish if the batch transform is up-to-date.
  226. else if ( batchTransformId == mLastBatchTransformId )
  227. return;
  228. // Fetch world transform.
  229. const b2Transform& worldTransform = mSpriteBatch->getBatchTransform();
  230. // Calculate world OOBB.
  231. CoreMath::mCalculateOOBB( mLocalOOBB, worldTransform, mRenderOOBB );
  232. // Calculate render AABB.
  233. CoreMath::mOOBBtoAABB( mRenderOOBB, mRenderAABB );
  234. // Calculate the render position.
  235. mRenderPosition = mRenderAABB.GetCenter();
  236. // Note the last batch transform Id.
  237. mLastBatchTransformId = batchTransformId;
  238. }
  239. //------------------------------------------------------------------------------
  240. void SpriteBatchItem::onTamlCustomWrite( TamlCustomNode* pParentNode )
  241. {
  242. // Add sprite node.
  243. TamlCustomNode* pSpriteNode = pParentNode->addNode( spritesItemTypeName );
  244. // Write name.
  245. if ( getName() != StringTable->EmptyString )
  246. pSpriteNode->addField( spriteNameName, getName() );
  247. // Static frame provider?
  248. if ( isStaticFrameProvider() )
  249. {
  250. // Fetch image asset Id.
  251. StringTableEntry assetId = getImage();
  252. // Do we have an image?
  253. if ( assetId != StringTable->EmptyString )
  254. {
  255. // Yes, so write image asset Id.
  256. pSpriteNode->addField( spriteImageName, assetId );
  257. // Write image frame.
  258. pSpriteNode->addField( spriteImageFrameName, getImageFrame() );
  259. }
  260. }
  261. else
  262. {
  263. // Fetch animation asset Id.
  264. StringTableEntry assetId = getAnimation();
  265. // Do we have an animation?
  266. if ( assetId != StringTable->EmptyString )
  267. {
  268. // Yes, so write animation asset Id.
  269. pSpriteNode->addField( spriteAnimationName, assetId );
  270. }
  271. }
  272. // Write visible.
  273. if ( !mVisible )
  274. pSpriteNode->addField( spriteVisibleName, mVisible );
  275. // Write local position.
  276. pSpriteNode->addField( spriteLocalPositionName, mLocalPosition );
  277. // Write local angle.
  278. if ( mNotZero(mLocalAngle) )
  279. pSpriteNode->addField( spriteLocalAngleName, mRadToDeg(mLocalAngle) );
  280. // Write size.
  281. pSpriteNode->addField( spriteSizeName, mSize );
  282. // Write depth.
  283. if ( mNotZero(mDepth) )
  284. pSpriteNode->addField( spriteDepthName, mDepth );
  285. // Write flipX
  286. if ( mFlipX )
  287. pSpriteNode->addField( spriteFlipXName, mFlipX );
  288. // Write flipY
  289. if ( mFlipY )
  290. pSpriteNode->addField( spriteFlipYName, mFlipY );
  291. // Write sort point.
  292. if ( mSortPoint.notZero() )
  293. pSpriteNode->addField( spriteSortPointName, mSortPoint );
  294. // Write render group.
  295. if ( mRenderGroup != StringTable->EmptyString )
  296. pSpriteNode->addField( spriteRenderGroupName, mRenderGroup );
  297. // Write blend mode.
  298. if ( !mBlendMode )
  299. pSpriteNode->addField( spriteBlendModeName, mBlendMode );
  300. // Write source blend factor.
  301. if ( mBlendMode && mSrcBlendFactor != GL_SRC_ALPHA )
  302. pSpriteNode->addField( spriteSrcBlendFactorName, SceneObject::getSrcBlendFactorDescription(mSrcBlendFactor) );
  303. // Write destination blend factor.
  304. if ( mBlendMode && mDstBlendFactor != GL_ONE_MINUS_SRC_ALPHA )
  305. pSpriteNode->addField( spriteDstBlendFactorName, SceneObject::getDstBlendFactorDescription(mDstBlendFactor) );
  306. // Write blend color.
  307. if ( mBlendMode && mBlendColor != ColorF(1.0f, 1.0f, 1.0f, 1.0f) )
  308. pSpriteNode->addField( spriteBlendColorName, mBlendColor );
  309. // Write alpha test.
  310. if ( mBlendMode && mAlphaTest >= 0.0f )
  311. pSpriteNode->addField( spriteAlphaTestName, mAlphaTest );
  312. // Write logical position.
  313. if ( getLogicalPosition().isValid() )
  314. pSpriteNode->addField( spriteLogicalPositionName, getLogicalPosition().getString() );
  315. // Write data object.
  316. if ( getDataObject() != NULL )
  317. pSpriteNode->addNode( getDataObject() );
  318. }
  319. //------------------------------------------------------------------------------
  320. void SpriteBatchItem::onTamlCustomRead( const TamlCustomNode* pSpriteNode )
  321. {
  322. // Sanity!
  323. AssertFatal( mSpriteBatch != NULL, "SpriteBatchItem::onTamlCustomRead() - Cannot read sprite batch item with sprite batch." );
  324. // Fetch sprite fields.
  325. const TamlCustomFieldVector& spriteField = pSpriteNode->getFields();
  326. // Iterate property fields.
  327. for ( TamlCustomFieldVector::const_iterator fieldItr = spriteField.begin(); fieldItr != spriteField.end(); ++fieldItr )
  328. {
  329. // Fetch sprite field.
  330. TamlCustomField* pSpriteField = *fieldItr;
  331. // Fetch sprite field name.
  332. StringTableEntry fieldName = pSpriteField->getFieldName();
  333. // Reset image frame.
  334. S32 imageFrame = -1;
  335. if ( fieldName == spriteNameName )
  336. {
  337. setName( pSpriteField->getFieldValue() );
  338. }
  339. else if ( fieldName == spriteImageName )
  340. {
  341. setImage( pSpriteField->getFieldValue() );
  342. // Set image frame if it's available.
  343. if ( imageFrame != -1 )
  344. setImageFrame( imageFrame );
  345. }
  346. else if ( fieldName == spriteImageFrameName )
  347. {
  348. pSpriteField->getFieldValue( imageFrame );
  349. // Set image frame if image is available.
  350. if ( getImage() != StringTable->EmptyString )
  351. setImageFrame( imageFrame );
  352. }
  353. else if ( fieldName == spriteAnimationName )
  354. {
  355. setAnimation( pSpriteField->getFieldValue() );
  356. }
  357. else if ( fieldName == spriteVisibleName )
  358. {
  359. bool visible;
  360. pSpriteField->getFieldValue( visible );
  361. setVisible( visible );
  362. }
  363. else if ( fieldName == spriteLocalPositionName )
  364. {
  365. Vector2 localPosition;
  366. pSpriteField->getFieldValue( localPosition );
  367. setLocalPosition( localPosition );
  368. }
  369. else if ( fieldName == spriteLocalAngleName )
  370. {
  371. F32 localAngle;
  372. pSpriteField->getFieldValue( localAngle );
  373. setLocalAngle( mDegToRad( localAngle ) );
  374. }
  375. else if ( fieldName == spriteSizeName )
  376. {
  377. Vector2 size;
  378. pSpriteField->getFieldValue( size );
  379. setSize( size );
  380. }
  381. else if ( fieldName == spriteDepthName )
  382. {
  383. F32 depth;
  384. pSpriteField->getFieldValue( depth );
  385. setDepth( depth );
  386. }
  387. else if ( fieldName == spriteFlipXName )
  388. {
  389. bool flipX;
  390. pSpriteField->getFieldValue( flipX );
  391. setFlipX( flipX );
  392. }
  393. else if ( fieldName == spriteFlipYName )
  394. {
  395. bool flipY;
  396. pSpriteField->getFieldValue( flipY );
  397. setFlipY( flipY );
  398. }
  399. else if ( fieldName == spriteSortPointName )
  400. {
  401. Vector2 sortPoint;
  402. pSpriteField->getFieldValue( sortPoint );
  403. setSortPoint( sortPoint );
  404. }
  405. else if ( fieldName == spriteRenderGroupName )
  406. {
  407. setRenderGroup( pSpriteField->getFieldValue() );
  408. }
  409. else if ( fieldName == spriteBlendModeName )
  410. {
  411. bool blendMode;
  412. pSpriteField->getFieldValue( blendMode );
  413. setBlendMode( blendMode );
  414. }
  415. else if ( fieldName == spriteSrcBlendFactorName )
  416. {
  417. setSrcBlendFactor( (GLenum)SceneObject::getSrcBlendFactorEnum( pSpriteField->getFieldValue() ) );
  418. }
  419. else if ( fieldName == spriteDstBlendFactorName )
  420. {
  421. setDstBlendFactor( (GLenum)SceneObject::getDstBlendFactorEnum( pSpriteField->getFieldValue() ) );
  422. }
  423. else if ( fieldName == spriteBlendColorName )
  424. {
  425. ColorF blendColor;
  426. pSpriteField->getFieldValue( blendColor );
  427. setBlendColor( blendColor );
  428. }
  429. else if ( fieldName == spriteAlphaTestName )
  430. {
  431. F32 alphaTest;
  432. pSpriteField->getFieldValue( alphaTest );
  433. setAlphaTest( alphaTest );
  434. }
  435. // Logical position.
  436. else if ( fieldName == spriteLogicalPositionName )
  437. {
  438. // Fetch logical position.
  439. const char* pLogicalPositionArgs = pSpriteField->getFieldValue();
  440. // Is there any data?
  441. if ( dStrlen( pLogicalPositionArgs ) == 0 )
  442. {
  443. // No, so warn.
  444. Con::warnf( "SpriteBatchItem::onTamlCustomRead() - Encountered an empty sprite key. This sprite will no longer be addressable by logical position." );
  445. continue;
  446. }
  447. // Set logical position.
  448. setLogicalPosition( LogicalPosition( pLogicalPositionArgs ) );
  449. }
  450. }
  451. // Fetch sprite children.
  452. const TamlCustomNodeVector& spriteChildren = pSpriteNode->getChildren();
  453. // Set the data object if a single child exists.
  454. if ( spriteChildren.size() == 1 )
  455. setDataObject( spriteChildren[0]->getProxyObject<SimObject>(true) );
  456. }
  457. //------------------------------------------------------------------------------
  458. void SpriteBatchItem::WriteCustomTamlSchema( const AbstractClassRep* pClassRep, TiXmlElement* pParentElement )
  459. {
  460. // Sanity!
  461. AssertFatal( pClassRep != NULL, "SpriteBatchItem::WriteCustomTamlSchema() - ClassRep cannot be NULL." );
  462. AssertFatal( pParentElement != NULL, "SpriteBatchItem::WriteCustomTamlSchema() - Parent Element cannot be NULL." );
  463. // Create batch item element.
  464. TiXmlElement* pBatchItemElement = new TiXmlElement( "xs:element" );
  465. pBatchItemElement->SetAttribute( "name", spritesItemTypeName );
  466. pBatchItemElement->SetAttribute( "minOccurs", 0 );
  467. pBatchItemElement->SetAttribute( "maxOccurs", 1 );
  468. pParentElement->LinkEndChild( pBatchItemElement );
  469. // Create complex type Element.
  470. TiXmlElement* pBatchItemComplexTypeElement = new TiXmlElement( "xs:complexType" );
  471. pBatchItemElement->LinkEndChild( pBatchItemComplexTypeElement );
  472. // Create "Name" attribute.
  473. TiXmlElement* pBatchItemName = new TiXmlElement( "xs:attribute" );
  474. pBatchItemName->SetAttribute( "name", spriteNameName );
  475. pBatchItemName->SetAttribute( "type", "xs:string" );
  476. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemName );
  477. // "Create "Image" attribute.
  478. TiXmlElement* pBatchItemImage = new TiXmlElement( "xs:attribute" );
  479. pBatchItemImage->SetAttribute( "name", spriteImageName );
  480. pBatchItemImage->SetAttribute( "type", "AssetId_ConsoleType" );
  481. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemImage );
  482. // "Create "Image Frame" attribute.
  483. TiXmlElement* pBatchItemImageFrame = new TiXmlElement( "xs:attribute" );
  484. pBatchItemImageFrame->SetAttribute( "name", spriteImageFrameName );
  485. pBatchItemImageFrame->SetAttribute( "type", "xs:positiveInteger" );
  486. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemImageFrame );
  487. // "Create "Animation" attribute.
  488. TiXmlElement* pBatchItemAnimation = new TiXmlElement( "xs:attribute" );
  489. pBatchItemAnimation->SetAttribute( "name", spriteAnimationName );
  490. pBatchItemAnimation->SetAttribute( "type", "AssetId_ConsoleType" );
  491. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemAnimation );
  492. // Create "Visible" attribute.
  493. TiXmlElement* pBatchItemVisible = new TiXmlElement( "xs:attribute" );
  494. pBatchItemVisible->SetAttribute( "name", spriteVisibleName );
  495. pBatchItemVisible->SetAttribute( "type", "xs:boolean" );
  496. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemVisible );
  497. // Create "Local Position" attribute.
  498. TiXmlElement* pBatchItemPosition = new TiXmlElement( "xs:attribute" );
  499. pBatchItemPosition->SetAttribute( "name", spriteLocalPositionName );
  500. pBatchItemPosition->SetAttribute( "type", "Vector2_ConsoleType" );
  501. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemPosition );
  502. // Create "Size" attribute.
  503. TiXmlElement* pBatchItemSize = new TiXmlElement( "xs:attribute" );
  504. pBatchItemSize->SetAttribute( "name", spriteSizeName );
  505. pBatchItemSize->SetAttribute( "type", "Vector2_ConsoleType" );
  506. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemSize );
  507. // Create "Local Angle" attribute.
  508. TiXmlElement* pBatchItemAngle = new TiXmlElement( "xs:attribute" );
  509. pBatchItemAngle->SetAttribute( "name", spriteLocalAngleName );
  510. pBatchItemAngle->SetAttribute( "type", "xs:float" );
  511. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemAngle );
  512. // Create "Depth" attribute.
  513. TiXmlElement* pBatchItemDepth = new TiXmlElement( "xs:attribute" );
  514. pBatchItemDepth->SetAttribute( "name", spriteDepthName );
  515. pBatchItemDepth->SetAttribute( "type", "xs:float" );
  516. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemDepth );
  517. // Create "FlipX" attribute.
  518. TiXmlElement* pBatchItemFlipX = new TiXmlElement( "xs:attribute" );
  519. pBatchItemFlipX->SetAttribute( "name", spriteFlipXName );
  520. pBatchItemFlipX->SetAttribute( "type", "xs:boolean" );
  521. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemFlipX );
  522. // Create "FlipY" attribute.
  523. TiXmlElement* pBatchItemFlipY = new TiXmlElement( "xs:attribute" );
  524. pBatchItemFlipY->SetAttribute( "name", spriteFlipYName );
  525. pBatchItemFlipY->SetAttribute( "type", "xs:boolean" );
  526. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemFlipY );
  527. // Create "Sort Point" attribute.
  528. TiXmlElement* pBatchItemSortPoint = new TiXmlElement( "xs:attribute" );
  529. pBatchItemSortPoint->SetAttribute( "name", spriteSortPointName );
  530. pBatchItemSortPoint->SetAttribute( "type", "Vector2_ConsoleType" );
  531. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemSortPoint );
  532. // Create "Render Group" attribute.
  533. TiXmlElement* pBatchItemRenderGroup = new TiXmlElement( "xs:attribute" );
  534. pBatchItemRenderGroup->SetAttribute( "name", spriteRenderGroupName );
  535. pBatchItemRenderGroup->SetAttribute( "type", "xs:string" );
  536. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemRenderGroup );
  537. // Create "Blend Mode" attribute.
  538. TiXmlElement* pBatchItemBlendMode = new TiXmlElement( "xs:attribute" );
  539. pBatchItemBlendMode->SetAttribute( "name", spriteBlendModeName );
  540. pBatchItemBlendMode->SetAttribute( "type", "xs:boolean" );
  541. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemBlendMode );
  542. // Create "Source Blend Factor" attribute.
  543. TiXmlElement* pBatchItemSrcBlendFactor = new TiXmlElement( "xs:attribute" );
  544. pBatchItemSrcBlendFactor->SetAttribute( "name", spriteSrcBlendFactorName );
  545. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemSrcBlendFactor );
  546. TiXmlElement* pBatchItemSrcBlendFactorType = new TiXmlElement( "xs:simpleType" );
  547. pBatchItemSrcBlendFactor->LinkEndChild( pBatchItemSrcBlendFactorType );
  548. TiXmlElement* pBatchItemSrcBlendFactorTypeRestriction = new TiXmlElement( "xs:restriction" );
  549. pBatchItemSrcBlendFactorTypeRestriction->SetAttribute( "base", "xs:string" );
  550. pBatchItemSrcBlendFactorType->LinkEndChild( pBatchItemSrcBlendFactorTypeRestriction );
  551. const S32 srcBlendFactorEnumsCount = srcBlendFactorTable.size;
  552. for( S32 index = 0; index < srcBlendFactorEnumsCount; ++index )
  553. {
  554. // Add enumeration element.
  555. TiXmlElement* pSrcBlendFactorEnumeration = new TiXmlElement( "xs:enumeration" );
  556. pSrcBlendFactorEnumeration->SetAttribute( "value", srcBlendFactorTable.table[index].label );
  557. pBatchItemSrcBlendFactorTypeRestriction->LinkEndChild( pSrcBlendFactorEnumeration );
  558. }
  559. // Create "Destination Blend Factor" attribute.
  560. TiXmlElement* pBatchItemDstBlendFactor = new TiXmlElement( "xs:attribute" );
  561. pBatchItemDstBlendFactor->SetAttribute( "name", spriteDstBlendFactorName );
  562. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemDstBlendFactor );
  563. TiXmlElement* pBatchItemDstBlendFactorType = new TiXmlElement( "xs:simpleType" );
  564. pBatchItemDstBlendFactor->LinkEndChild( pBatchItemDstBlendFactorType );
  565. TiXmlElement* pBatchItemDstBlendFactorTypeRestriction = new TiXmlElement( "xs:restriction" );
  566. pBatchItemDstBlendFactorTypeRestriction->SetAttribute( "base", "xs:string" );
  567. pBatchItemDstBlendFactorType->LinkEndChild( pBatchItemDstBlendFactorTypeRestriction );
  568. const S32 dstBlendFactorEnumsCount = dstBlendFactorTable.size;
  569. for( S32 index = 0; index < dstBlendFactorEnumsCount; ++index )
  570. {
  571. // Add enumeration element.
  572. TiXmlElement* pDstBlendFactorEnumeration = new TiXmlElement( "xs:enumeration" );
  573. pDstBlendFactorEnumeration->SetAttribute( "value", dstBlendFactorTable.table[index].label );
  574. pBatchItemDstBlendFactorTypeRestriction->LinkEndChild( pDstBlendFactorEnumeration );
  575. }
  576. // Create "Blend Color" attribute.
  577. TiXmlElement* pBatchItemBlendColor = new TiXmlElement( "xs:attribute" );
  578. pBatchItemBlendColor->SetAttribute( "name", spriteBlendColorName );
  579. pBatchItemBlendColor->SetAttribute( "type", "Color_Enums" );
  580. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemBlendColor );
  581. // Create "Alpha Test" attribute.
  582. TiXmlElement* pBatchItemAlphaTest = new TiXmlElement( "xs:attribute" );
  583. pBatchItemAlphaTest->SetAttribute( "name", spriteAlphaTestName );
  584. pBatchItemAlphaTest->SetAttribute( "type", "xs:float" );
  585. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemAlphaTest );
  586. // Create "Logical Position" attribute.
  587. TiXmlElement* pBatchItemLogicalPosition = new TiXmlElement( "xs:attribute" );
  588. pBatchItemLogicalPosition->SetAttribute( "name", spriteLogicalPositionName );
  589. pBatchItemLogicalPosition->SetAttribute( "type", "xs:string" );
  590. pBatchItemComplexTypeElement->LinkEndChild( pBatchItemLogicalPosition );
  591. }