Sprite.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. #include "Base.h"
  2. #include "Sprite.h"
  3. #include "Scene.h"
  4. namespace gameplay
  5. {
  6. Sprite::Sprite() : Drawable(),
  7. _width(0), _height(0), _offset(OFFSET_BOTTOM_LEFT), _anchor(Vector2(0.5f, 0.5f)), _flipFlags(FLIP_NONE),
  8. _frames(NULL), _frameCount(1), _frameStride(0), _framePadding(1), _frameIndex(0),
  9. _opacity(1.0f), _color(Vector4::one()), _blendMode(BLEND_ALPHA), _batch(NULL)
  10. {
  11. }
  12. Sprite::~Sprite()
  13. {
  14. SAFE_DELETE_ARRAY(_frames);
  15. SAFE_DELETE(_batch);
  16. }
  17. Sprite& Sprite::operator=(const Sprite& sprite)
  18. {
  19. return *this;
  20. }
  21. Sprite* Sprite::create(const char* imagePath, float width, float height, Effect* effect)
  22. {
  23. return Sprite::create(imagePath, width, height, Rectangle(0, 0, -1, -1), 1, effect);
  24. }
  25. Sprite* Sprite::create(const char* imagePath, float width, float height,
  26. const Rectangle& source, unsigned int frameCount, Effect* effect)
  27. {
  28. GP_ASSERT(imagePath != NULL);
  29. GP_ASSERT(width >= -1 && height >= -1);
  30. GP_ASSERT(source.width >= -1 && source.height >= -1);
  31. GP_ASSERT(frameCount > 0);
  32. SpriteBatch* batch = SpriteBatch::create(imagePath, effect);
  33. batch->getSampler()->setWrapMode(Texture::CLAMP, Texture::CLAMP);
  34. batch->getSampler()->setFilterMode(Texture::Filter::LINEAR, Texture::Filter::LINEAR);
  35. batch->getStateBlock()->setDepthWrite(false);
  36. batch->getStateBlock()->setDepthTest(true);
  37. unsigned int imageWidth = batch->getSampler()->getTexture()->getWidth();
  38. unsigned int imageHeight = batch->getSampler()->getTexture()->getHeight();
  39. if (width == -1)
  40. width = imageWidth;
  41. if (height == -1)
  42. height = imageHeight;
  43. Sprite* sprite = new Sprite();
  44. sprite->_width = width;
  45. sprite->_height = height;
  46. sprite->_batch = batch;
  47. sprite->_frameCount = frameCount;
  48. sprite->_frames = new Rectangle[frameCount];
  49. sprite->_frames[0] = source;
  50. if (sprite->_frames[0].width == -1.0f)
  51. sprite->_frames[0].width = imageWidth;
  52. if (sprite->_frames[0].height == -1.0f)
  53. sprite->_frames[0].height = imageHeight;
  54. return sprite;
  55. }
  56. static bool parseBlendMode(const char* str, Sprite::BlendMode* blend)
  57. {
  58. GP_ASSERT(blend);
  59. if (!str)
  60. {
  61. *blend = Sprite::BLEND_NONE;
  62. return false;
  63. }
  64. if (strcmp(str, "BLEND_ALPHA") == 0)
  65. {
  66. *blend = Sprite::BLEND_ALPHA;
  67. }
  68. else if (strcmp(str, "BLEND_ADDITIVE") == 0)
  69. {
  70. *blend = Sprite::BLEND_ADDITIVE;
  71. }
  72. else if (strcmp(str, "BLEND_MULTIPLIED") == 0)
  73. {
  74. *blend = Sprite::BLEND_MULTIPLIED;
  75. }
  76. else if (strcmp(str, "BLEND_NONE") != 0)
  77. {
  78. GP_ERROR("Failed to get corresponding sprite blend mode for unsupported value '%s'.", str);
  79. *blend = Sprite::BLEND_NONE;
  80. return false;
  81. }
  82. else
  83. {
  84. *blend = Sprite::BLEND_NONE;
  85. }
  86. return true;
  87. }
  88. static bool parseFlipFlags(const char* str, Sprite::FlipFlags* flip)
  89. {
  90. GP_ASSERT(flip);
  91. if (!str)
  92. {
  93. *flip = Sprite::FLIP_NONE;
  94. return false;
  95. }
  96. if (strcmp(str, "FLIP_VERTICAL") == 0)
  97. {
  98. *flip = Sprite::FLIP_VERTICAL;
  99. }
  100. else if (strcmp(str, "FLIP_HORIZONTAL") == 0)
  101. {
  102. *flip = Sprite::FLIP_HORIZONTAL;
  103. }
  104. else if (strcmp(str, "FLIP_VERTICAL_HORIZONTAL") == 0)
  105. {
  106. *flip = (Sprite::FlipFlags)(Sprite::FLIP_VERTICAL | Sprite::FLIP_HORIZONTAL);
  107. }
  108. else if (strcmp(str, "FLIP_NONE") != 0)
  109. {
  110. GP_ERROR("Failed to get corresponding sprite flip flag for unsupported value '%s'.", str);
  111. *flip = Sprite::FLIP_NONE;
  112. return false;
  113. }
  114. else
  115. {
  116. *flip = Sprite::FLIP_NONE;
  117. }
  118. return true;
  119. }
  120. static bool parseOffset(const char* str, Sprite::Offset* offset)
  121. {
  122. GP_ASSERT(offset);
  123. if (!str)
  124. {
  125. *offset = Sprite::OFFSET_LEFT;
  126. return false;
  127. }
  128. if (strcmp(str, "OFFSET_LEFT") == 0)
  129. {
  130. *offset = Sprite::OFFSET_LEFT;
  131. }
  132. else if (strcmp(str, "OFFSET_HCENTER") == 0)
  133. {
  134. *offset = Sprite::OFFSET_HCENTER;
  135. }
  136. else if (strcmp(str, "OFFSET_RIGHT") == 0)
  137. {
  138. *offset = Sprite::OFFSET_RIGHT;
  139. }
  140. else if (strcmp(str, "OFFSET_TOP") == 0)
  141. {
  142. *offset = Sprite::OFFSET_TOP;
  143. }
  144. else if (strcmp(str, "OFFSET_VCENTER") == 0)
  145. {
  146. *offset = Sprite::OFFSET_VCENTER;
  147. }
  148. else if (strcmp(str, "OFFSET_BOTTOM") == 0)
  149. {
  150. *offset = Sprite::OFFSET_BOTTOM;
  151. }
  152. else if (strcmp(str, "OFFSET_ANCHOR") == 0)
  153. {
  154. *offset = Sprite::OFFSET_ANCHOR;
  155. }
  156. else if (strcmp(str, "OFFSET_TOP_LEFT") == 0)
  157. {
  158. *offset = Sprite::OFFSET_TOP_LEFT;
  159. }
  160. else if (strcmp(str, "OFFSET_VCENTER_LEFT") == 0)
  161. {
  162. *offset = Sprite::OFFSET_VCENTER_LEFT;
  163. }
  164. else if (strcmp(str, "OFFSET_BOTTOM_LEFT") == 0)
  165. {
  166. *offset = Sprite::OFFSET_BOTTOM_LEFT;
  167. }
  168. else if (strcmp(str, "OFFSET_TOP_HCENTER") == 0)
  169. {
  170. *offset = Sprite::OFFSET_TOP_HCENTER;
  171. }
  172. else if (strcmp(str, "OFFSET_VCENTER_HCENTER") == 0)
  173. {
  174. *offset = Sprite::OFFSET_VCENTER_HCENTER;
  175. }
  176. else if (strcmp(str, "OFFSET_BOTTOM_HCENTER") == 0)
  177. {
  178. *offset = Sprite::OFFSET_BOTTOM_HCENTER;
  179. }
  180. else if (strcmp(str, "OFFSET_TOP_RIGHT") == 0)
  181. {
  182. *offset = Sprite::OFFSET_TOP_RIGHT;
  183. }
  184. else if (strcmp(str, "OFFSET_VCENTER_RIGHT") == 0)
  185. {
  186. *offset = Sprite::OFFSET_VCENTER_RIGHT;
  187. }
  188. else if (strcmp(str, "OFFSET_BOTTOM_RIGHT") != 0)
  189. {
  190. GP_ERROR("Failed to get corresponding sprite offset for unsupported value '%s'.", str);
  191. *offset = Sprite::OFFSET_LEFT;
  192. return false;
  193. }
  194. else
  195. {
  196. *offset = Sprite::OFFSET_BOTTOM_RIGHT;
  197. }
  198. return true;
  199. }
  200. Sprite* Sprite::create(Properties* properties)
  201. {
  202. // Check if the Properties is valid and has a valid namespace.
  203. if (!properties || strcmp(properties->getNamespace(), "sprite") != 0)
  204. {
  205. GP_ERROR("Properties object must be non-null and have namespace equal to 'sprite'.");
  206. return NULL;
  207. }
  208. // Get image path.
  209. const char* imagePath = properties->getString("path");
  210. if (imagePath == NULL || strlen(imagePath) == 0)
  211. {
  212. GP_ERROR("Sprite is missing required image file path.");
  213. return NULL;
  214. }
  215. // Don't support loading custom effects
  216. Effect* effect = NULL;
  217. // Get width and height
  218. float width = -1.0f;
  219. float height = -1.0f;
  220. float widthPercentage = 0.0f;
  221. float heightPercentage = 0.0f;
  222. if (properties->exists("width"))
  223. {
  224. if (properties->getType("width") == Properties::NUMBER) //TODO: Verify that this works for "100" but fails for "100%"
  225. {
  226. width = properties->getFloat("width");
  227. }
  228. else
  229. {
  230. widthPercentage = properties->getFloat("width") / 100.0f;
  231. }
  232. }
  233. if (properties->exists("height"))
  234. {
  235. if (properties->getType("height") == Properties::NUMBER)
  236. {
  237. height = properties->getFloat("height");
  238. }
  239. else
  240. {
  241. heightPercentage = properties->getFloat("height") / 100.0f;
  242. }
  243. }
  244. Sprite* sprite;
  245. if (properties->exists("source"))
  246. {
  247. // Get source frame
  248. Rectangle source;
  249. properties->getVector4("source", (Vector4*)&source);
  250. // Get frame count
  251. int frameCount = properties->getInt("frameCount");
  252. if (frameCount < 0)
  253. {
  254. GP_WARN("Sprites require at least one frame. Defaulting to frame count 1.");
  255. }
  256. if (frameCount < 1)
  257. {
  258. frameCount = 1;
  259. }
  260. // Load sprite
  261. sprite = Sprite::create(imagePath, width, height, source, frameCount, effect);
  262. }
  263. else
  264. {
  265. // Load sprite
  266. sprite = Sprite::create(imagePath, width, height, effect);
  267. }
  268. // Edit scaling of sprites if needed
  269. if (widthPercentage != 0.0f || heightPercentage != 0.0f)
  270. {
  271. if (widthPercentage != 0.0f)
  272. {
  273. sprite->_width *= widthPercentage;
  274. sprite->_frames[0].width *= widthPercentage;
  275. }
  276. if (heightPercentage != 0.0f)
  277. {
  278. sprite->_height *= heightPercentage;
  279. sprite->_frames[0].height *= heightPercentage;
  280. }
  281. }
  282. // Get anchor
  283. Vector4 vect;
  284. if (properties->getVector2("anchor", (Vector2*)&vect))
  285. {
  286. sprite->setAnchor(*((Vector2*)&vect));
  287. }
  288. // Get color
  289. if (properties->exists("color"))
  290. {
  291. switch (properties->getType("color"))
  292. {
  293. case Properties::VECTOR3:
  294. vect.w = 1.0f;
  295. properties->getVector3("color", (Vector3*)&vect);
  296. break;
  297. case Properties::VECTOR4:
  298. properties->getVector4("color", &vect);
  299. break;
  300. case Properties::STRING:
  301. default:
  302. properties->getColor("color", &vect);
  303. break;
  304. }
  305. sprite->setColor(vect);
  306. }
  307. // Get opacity
  308. if (properties->exists("opacity"))
  309. {
  310. sprite->setOpacity(properties->getFloat("opacity"));
  311. }
  312. // Get blend mode
  313. BlendMode mode;
  314. if (parseBlendMode(properties->getString("blendMode"), &mode))
  315. {
  316. sprite->setBlendMode(mode);
  317. }
  318. // Get flip flags
  319. FlipFlags flags;
  320. if (parseFlipFlags(properties->getString("flip"), &flags))
  321. {
  322. sprite->setFlip(flags);
  323. }
  324. // Get sprite offset
  325. Offset offset;
  326. if (parseOffset(properties->getString("offset"), &offset))
  327. {
  328. sprite->setOffset(offset);
  329. }
  330. return sprite;
  331. }
  332. float Sprite::getWidth() const
  333. {
  334. return _width;
  335. }
  336. float Sprite::getHeight() const
  337. {
  338. return _height;
  339. }
  340. void Sprite::setOffset(Sprite::Offset offset)
  341. {
  342. _offset = offset;
  343. }
  344. Sprite::Offset Sprite::getOffset() const
  345. {
  346. return _offset;
  347. }
  348. void Sprite::setAnchor(const Vector2& anchor)
  349. {
  350. _anchor = anchor;
  351. }
  352. const Vector2& Sprite::getAnchor() const
  353. {
  354. return _anchor;
  355. }
  356. void Sprite::setFlip(int flipFlags)
  357. {
  358. _flipFlags = flipFlags;
  359. }
  360. int Sprite::getFlip() const
  361. {
  362. return _flipFlags;
  363. }
  364. void Sprite::setFrameSource(unsigned int frameIndex, const Rectangle& source)
  365. {
  366. GP_ASSERT(frameIndex < _frameCount);
  367. _frames[frameIndex] = source;
  368. }
  369. const Rectangle& Sprite::getFrameSource(unsigned int frameIndex) const
  370. {
  371. GP_ASSERT(frameIndex < _frameCount);
  372. return _frames[frameIndex];
  373. }
  374. void Sprite::computeFrames(unsigned int frameStride, unsigned int framePadding)
  375. {
  376. _frameStride = frameStride;
  377. _framePadding = framePadding;
  378. if (_frameCount < 2)
  379. return;
  380. unsigned int imageWidth = _batch->getSampler()->getTexture()->getWidth();
  381. unsigned int imageHeight = _batch->getSampler()->getTexture()->getHeight();
  382. float textureWidthRatio = 1.0f / imageWidth;
  383. float textureHeightRatio = 1.0f / imageHeight;
  384. // If we have a stride then compute the wrap width
  385. float strideWidth;
  386. if (_frameStride > 0)
  387. strideWidth = _frameStride * _frames[0].width;
  388. else
  389. strideWidth = imageWidth;
  390. // Mark the start as reference
  391. float x = _frames[0].x;
  392. float y = _frames[0].y;
  393. float width = _frames[0].width;
  394. float height = _frames[0].height;
  395. // Compute frames 1+
  396. for (unsigned int frameIndex = 1; frameIndex < _frameCount; frameIndex++)
  397. {
  398. _frames[frameIndex].x = x;
  399. _frames[frameIndex].y = y;
  400. _frames[frameIndex].width = _width;
  401. _frames[frameIndex].height = _height;
  402. x += _frames[frameIndex].width + (float)_framePadding;
  403. if (x >= imageWidth)
  404. {
  405. y += _frames[frameIndex].height + (float)_framePadding;
  406. if (y >= imageHeight)
  407. {
  408. y = 0.0f;
  409. }
  410. x = 0.0f;
  411. }
  412. }
  413. }
  414. unsigned int Sprite::getFrameCount() const
  415. {
  416. return _frameCount;
  417. }
  418. unsigned int Sprite::getFramePadding() const
  419. {
  420. return _framePadding;
  421. }
  422. unsigned int Sprite::getFrameStride() const
  423. {
  424. return _frameStride;
  425. }
  426. void Sprite::setFrameIndex(unsigned int index)
  427. {
  428. _frameIndex = index;
  429. }
  430. unsigned int Sprite::getFrameIndex() const
  431. {
  432. return _frameIndex;
  433. }
  434. void Sprite::setOpacity(float opacity)
  435. {
  436. _opacity = opacity;
  437. }
  438. float Sprite::getOpacity() const
  439. {
  440. return _opacity;
  441. }
  442. void Sprite::setColor(const Vector4& color)
  443. {
  444. _color = color;
  445. }
  446. const Vector4& Sprite::getColor() const
  447. {
  448. return _color;
  449. }
  450. Sprite::BlendMode Sprite::getBlendMode() const
  451. {
  452. return _blendMode;
  453. }
  454. void Sprite::setBlendMode(BlendMode mode)
  455. {
  456. switch (mode)
  457. {
  458. case BLEND_NONE:
  459. _batch->getStateBlock()->setBlend(false);
  460. break;
  461. case BLEND_ALPHA:
  462. _batch->getStateBlock()->setBlend(true);
  463. _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
  464. _batch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
  465. break;
  466. case BLEND_ADDITIVE:
  467. _batch->getStateBlock()->setBlend(true);
  468. _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
  469. _batch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE);
  470. break;
  471. case BLEND_MULTIPLIED:
  472. _batch->getStateBlock()->setBlend(true);
  473. _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_ZERO);
  474. _batch->getStateBlock()->setBlendDst(RenderState::BLEND_SRC_COLOR);
  475. break;
  476. default:
  477. GP_ERROR("Unsupported blend mode (%d).", mode);
  478. break;
  479. }
  480. }
  481. Texture::Sampler* Sprite::getSampler() const
  482. {
  483. return _batch->getSampler();
  484. }
  485. RenderState::StateBlock* Sprite::getStateBlock() const
  486. {
  487. return _batch->getStateBlock();
  488. }
  489. Material* Sprite::getMaterial() const
  490. {
  491. return _batch->getMaterial();
  492. }
  493. unsigned int Sprite::draw(bool wireframe)
  494. {
  495. // Apply scene camera projection and translation offsets
  496. Vector3 position = Vector3::zero();
  497. if (_node && _node->getScene())
  498. {
  499. Camera* activeCamera = _node->getScene()->getActiveCamera();
  500. if (activeCamera)
  501. {
  502. Node* cameraNode = _node->getScene()->getActiveCamera()->getNode();
  503. if (cameraNode)
  504. {
  505. // Scene projection
  506. Matrix projectionMatrix;
  507. projectionMatrix = _node->getProjectionMatrix();
  508. _batch->setProjectionMatrix(projectionMatrix);
  509. // Camera translation offsets
  510. position.x -= cameraNode->getTranslationWorld().x;
  511. position.y -= cameraNode->getTranslationWorld().y;
  512. }
  513. }
  514. // Apply node translation offsets
  515. Vector3 translation = _node->getTranslationWorld();
  516. position.x += translation.x;
  517. position.y += translation.y;
  518. position.z += translation.z;
  519. }
  520. // Apply local offset translation offsets
  521. if ((_offset & OFFSET_HCENTER) == OFFSET_HCENTER)
  522. position.x -= _width * 0.5;
  523. if ((_offset & OFFSET_RIGHT) == OFFSET_RIGHT)
  524. position.x -= _width;
  525. if ((_offset & OFFSET_VCENTER) == OFFSET_VCENTER)
  526. position.y -= _height * 0.5f;
  527. if ((_offset & OFFSET_TOP) == OFFSET_TOP)
  528. position.y -= _height;
  529. if ((_offset & OFFSET_ANCHOR) == OFFSET_ANCHOR)
  530. {
  531. position.x -= _width * _anchor.x;
  532. position.y -= _height * _anchor.y;
  533. }
  534. // Apply node scale and rotation
  535. float rotationAngle = 0.0f;
  536. Vector2 scale = Vector2(_width, _height);
  537. if (_node)
  538. {
  539. // Apply node rotation
  540. const Quaternion& rot = _node->getRotation();
  541. if (rot.x != 0.0f || rot.y != 0.0f || rot.z != 0.0f)
  542. rotationAngle = rot.toAxisAngle(NULL);
  543. // Apply node scale
  544. if (_node->getScaleX() != 1.0f)
  545. scale.x *= _node->getScaleX();
  546. if (_node->getScaleY() != 1.0f)
  547. scale.y *= _node->getScaleY();
  548. }
  549. // Apply flip flags
  550. if ((_flipFlags & FLIP_HORIZONTAL) == FLIP_HORIZONTAL)
  551. {
  552. position.x += scale.x;
  553. scale.x = -scale.x;
  554. }
  555. if ((_flipFlags & FLIP_VERTICAL) == FLIP_VERTICAL)
  556. {
  557. position.y += scale.y;
  558. scale.y = -scale.y;
  559. }
  560. // TODO: Proper batching from cache based on batching rules (image, layers, etc)
  561. _batch->start();
  562. _batch->draw(position, _frames[_frameIndex], scale, Vector4(_color.x, _color.y, _color.z, _color.w * _opacity),
  563. _anchor, rotationAngle);
  564. _batch->finish();
  565. return 1;
  566. }
  567. Drawable* Sprite::clone(NodeCloneContext& context)
  568. {
  569. Sprite* spriteClone = new Sprite();
  570. // Clone animations
  571. AnimationTarget::cloneInto(static_cast<AnimationTarget*>(spriteClone), context);
  572. // Get copied node if it exists
  573. if (Node* node = getNode())
  574. {
  575. Node* clonedNode = context.findClonedNode(node);
  576. if (clonedNode)
  577. {
  578. spriteClone->setNode(clonedNode);
  579. }
  580. }
  581. // Clone properties
  582. spriteClone->_width = _width;
  583. spriteClone->_height = _height;
  584. spriteClone->_offset = _offset;
  585. spriteClone->_anchor = _anchor;
  586. spriteClone->_flipFlags = _flipFlags;
  587. spriteClone->_opacity = _opacity;
  588. spriteClone->_color = _color;
  589. spriteClone->_blendMode = _blendMode;
  590. spriteClone->_frames = new Rectangle[_frameCount];
  591. memcpy(spriteClone->_frames, _frames, sizeof(Rectangle) * _frameCount);
  592. spriteClone->_frameCount = _frameCount;
  593. spriteClone->_frameStride = _frameStride;
  594. spriteClone->_framePadding = _framePadding;
  595. spriteClone->_frameIndex = _frameIndex;
  596. spriteClone->_batch = _batch;
  597. return spriteClone;
  598. }
  599. int Sprite::getPropertyId(TargetType type, const char* propertyIdStr)
  600. {
  601. GP_ASSERT(propertyIdStr);
  602. if (type == AnimationTarget::TRANSFORM)
  603. {
  604. if (strcmp(propertyIdStr, "ANIMATE_OPACITY") == 0)
  605. {
  606. return Sprite::ANIMATE_OPACITY;
  607. }
  608. else if (strcmp(propertyIdStr, "ANIMATE_COLOR") == 0)
  609. {
  610. return Sprite::ANIMATE_COLOR;
  611. }
  612. else if (strcmp(propertyIdStr, "ANIMATE_KEYFRAME") == 0)
  613. {
  614. return Sprite::ANIMATE_KEYFRAME;
  615. }
  616. }
  617. return AnimationTarget::getPropertyId(type, propertyIdStr);
  618. }
  619. unsigned int Sprite::getAnimationPropertyComponentCount(int propertyId) const
  620. {
  621. switch (propertyId)
  622. {
  623. case ANIMATE_OPACITY:
  624. return 1;
  625. case ANIMATE_COLOR:
  626. return 4;
  627. case ANIMATE_KEYFRAME:
  628. return 1;
  629. default:
  630. return -1;
  631. }
  632. }
  633. void Sprite::getAnimationPropertyValue(int propertyId, AnimationValue* value)
  634. {
  635. GP_ASSERT(value);
  636. switch (propertyId)
  637. {
  638. case ANIMATE_OPACITY:
  639. value->setFloat(0, _opacity);
  640. break;
  641. case ANIMATE_COLOR:
  642. value->setFloat(0, _color.x);
  643. value->setFloat(1, _color.y);
  644. value->setFloat(2, _color.z);
  645. value->setFloat(3, _color.w);
  646. break;
  647. case ANIMATE_KEYFRAME:
  648. value->setFloat(0, (float)_frameIndex);
  649. break;
  650. default:
  651. break;
  652. }
  653. }
  654. void Sprite::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
  655. {
  656. GP_ASSERT(value);
  657. switch(propertyId)
  658. {
  659. case ANIMATE_OPACITY:
  660. setOpacity(Curve::lerp(blendWeight, _opacity, value->getFloat(0)));
  661. break;
  662. case ANIMATE_COLOR:
  663. setColor(Vector4(Curve::lerp(blendWeight, _color.x, value->getFloat(0)),
  664. Curve::lerp(blendWeight, _color.x, value->getFloat(1)),
  665. Curve::lerp(blendWeight, _color.x, value->getFloat(2)),
  666. Curve::lerp(blendWeight, _color.x, value->getFloat(3))));
  667. break;
  668. case ANIMATE_KEYFRAME:
  669. _frameIndex = (unsigned int)value->getFloat(0);
  670. break;
  671. default:
  672. break;
  673. }
  674. }
  675. }