Sprite.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  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)
  225. {
  226. // Number only (200)
  227. width = properties->getFloat("width");
  228. }
  229. else
  230. {
  231. // Number and something else (200%)
  232. widthPercentage = properties->getFloat("width") / 100.0f;
  233. }
  234. }
  235. if (properties->exists("height"))
  236. {
  237. if (properties->getType("height") == Properties::NUMBER)
  238. {
  239. height = properties->getFloat("height");
  240. }
  241. else
  242. {
  243. heightPercentage = properties->getFloat("height") / 100.0f;
  244. }
  245. }
  246. Sprite* sprite;
  247. if (properties->exists("source"))
  248. {
  249. // Get source frame
  250. Rectangle source;
  251. properties->getVector4("source", (Vector4*)&source);
  252. // Get frame count
  253. int frameCount = properties->getInt("frameCount");
  254. if (frameCount < 0)
  255. {
  256. GP_WARN("Sprites require at least one frame. Defaulting to frame count 1.");
  257. }
  258. if (frameCount < 1)
  259. {
  260. frameCount = 1;
  261. }
  262. // Load sprite
  263. sprite = Sprite::create(imagePath, width, height, source, frameCount, effect);
  264. }
  265. else
  266. {
  267. // Load sprite
  268. sprite = Sprite::create(imagePath, width, height, effect);
  269. }
  270. // Edit scaling of sprites if needed
  271. if (widthPercentage != 0.0f || heightPercentage != 0.0f)
  272. {
  273. if (widthPercentage != 0.0f)
  274. {
  275. sprite->_width *= widthPercentage;
  276. sprite->_frames[0].width *= widthPercentage;
  277. }
  278. if (heightPercentage != 0.0f)
  279. {
  280. sprite->_height *= heightPercentage;
  281. sprite->_frames[0].height *= heightPercentage;
  282. }
  283. }
  284. // Get anchor
  285. Vector4 vect;
  286. if (properties->getVector2("anchor", (Vector2*)&vect))
  287. {
  288. sprite->setAnchor(*((Vector2*)&vect));
  289. }
  290. // Get color
  291. if (properties->exists("color"))
  292. {
  293. switch (properties->getType("color"))
  294. {
  295. case Properties::VECTOR3:
  296. vect.w = 1.0f;
  297. properties->getVector3("color", (Vector3*)&vect);
  298. break;
  299. case Properties::VECTOR4:
  300. properties->getVector4("color", &vect);
  301. break;
  302. case Properties::STRING:
  303. default:
  304. properties->getColor("color", &vect);
  305. break;
  306. }
  307. sprite->setColor(vect);
  308. }
  309. // Get opacity
  310. if (properties->exists("opacity"))
  311. {
  312. sprite->setOpacity(properties->getFloat("opacity"));
  313. }
  314. // Get blend mode
  315. BlendMode mode;
  316. if (parseBlendMode(properties->getString("blendMode"), &mode))
  317. {
  318. sprite->setBlendMode(mode);
  319. }
  320. // Get flip flags
  321. FlipFlags flags;
  322. if (parseFlipFlags(properties->getString("flip"), &flags))
  323. {
  324. sprite->setFlip(flags);
  325. }
  326. // Get sprite offset
  327. Offset offset;
  328. if (parseOffset(properties->getString("offset"), &offset))
  329. {
  330. sprite->setOffset(offset);
  331. }
  332. return sprite;
  333. }
  334. float Sprite::getWidth() const
  335. {
  336. return _width;
  337. }
  338. float Sprite::getHeight() const
  339. {
  340. return _height;
  341. }
  342. void Sprite::setOffset(Sprite::Offset offset)
  343. {
  344. _offset = offset;
  345. }
  346. Sprite::Offset Sprite::getOffset() const
  347. {
  348. return _offset;
  349. }
  350. void Sprite::setAnchor(const Vector2& anchor)
  351. {
  352. _anchor = anchor;
  353. }
  354. const Vector2& Sprite::getAnchor() const
  355. {
  356. return _anchor;
  357. }
  358. void Sprite::setFlip(int flipFlags)
  359. {
  360. _flipFlags = flipFlags;
  361. }
  362. int Sprite::getFlip() const
  363. {
  364. return _flipFlags;
  365. }
  366. void Sprite::setFrameSource(unsigned int frameIndex, const Rectangle& source)
  367. {
  368. GP_ASSERT(frameIndex < _frameCount);
  369. _frames[frameIndex] = source;
  370. }
  371. const Rectangle& Sprite::getFrameSource(unsigned int frameIndex) const
  372. {
  373. GP_ASSERT(frameIndex < _frameCount);
  374. return _frames[frameIndex];
  375. }
  376. void Sprite::computeFrames(unsigned int frameStride, unsigned int framePadding)
  377. {
  378. _frameStride = frameStride;
  379. _framePadding = framePadding;
  380. if (_frameCount < 2)
  381. return;
  382. unsigned int imageWidth = _batch->getSampler()->getTexture()->getWidth();
  383. unsigned int imageHeight = _batch->getSampler()->getTexture()->getHeight();
  384. float textureWidthRatio = 1.0f / imageWidth;
  385. float textureHeightRatio = 1.0f / imageHeight;
  386. // If we have a stride then compute the wrap width
  387. float strideWidth;
  388. if (_frameStride > 0)
  389. strideWidth = _frameStride * _frames[0].width;
  390. else
  391. strideWidth = imageWidth;
  392. // Mark the start as reference
  393. float x = _frames[0].x;
  394. float y = _frames[0].y;
  395. float width = _frames[0].width;
  396. float height = _frames[0].height;
  397. // Compute frames 1+
  398. for (unsigned int frameIndex = 1; frameIndex < _frameCount; frameIndex++)
  399. {
  400. _frames[frameIndex].x = x;
  401. _frames[frameIndex].y = y;
  402. _frames[frameIndex].width = _width;
  403. _frames[frameIndex].height = _height;
  404. x += _frames[frameIndex].width + (float)_framePadding;
  405. if (x >= imageWidth)
  406. {
  407. y += _frames[frameIndex].height + (float)_framePadding;
  408. if (y >= imageHeight)
  409. {
  410. y = 0.0f;
  411. }
  412. x = 0.0f;
  413. }
  414. }
  415. }
  416. unsigned int Sprite::getFrameCount() const
  417. {
  418. return _frameCount;
  419. }
  420. unsigned int Sprite::getFramePadding() const
  421. {
  422. return _framePadding;
  423. }
  424. unsigned int Sprite::getFrameStride() const
  425. {
  426. return _frameStride;
  427. }
  428. void Sprite::setFrameIndex(unsigned int index)
  429. {
  430. _frameIndex = index;
  431. }
  432. unsigned int Sprite::getFrameIndex() const
  433. {
  434. return _frameIndex;
  435. }
  436. void Sprite::setOpacity(float opacity)
  437. {
  438. _opacity = opacity;
  439. }
  440. float Sprite::getOpacity() const
  441. {
  442. return _opacity;
  443. }
  444. void Sprite::setColor(const Vector4& color)
  445. {
  446. _color = color;
  447. }
  448. const Vector4& Sprite::getColor() const
  449. {
  450. return _color;
  451. }
  452. Sprite::BlendMode Sprite::getBlendMode() const
  453. {
  454. return _blendMode;
  455. }
  456. void Sprite::setBlendMode(BlendMode mode)
  457. {
  458. switch (mode)
  459. {
  460. case BLEND_NONE:
  461. _batch->getStateBlock()->setBlend(false);
  462. break;
  463. case BLEND_ALPHA:
  464. _batch->getStateBlock()->setBlend(true);
  465. _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
  466. _batch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
  467. break;
  468. case BLEND_ADDITIVE:
  469. _batch->getStateBlock()->setBlend(true);
  470. _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
  471. _batch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE);
  472. break;
  473. case BLEND_MULTIPLIED:
  474. _batch->getStateBlock()->setBlend(true);
  475. _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_ZERO);
  476. _batch->getStateBlock()->setBlendDst(RenderState::BLEND_SRC_COLOR);
  477. break;
  478. default:
  479. GP_ERROR("Unsupported blend mode (%d).", mode);
  480. break;
  481. }
  482. }
  483. Texture::Sampler* Sprite::getSampler() const
  484. {
  485. return _batch->getSampler();
  486. }
  487. RenderState::StateBlock* Sprite::getStateBlock() const
  488. {
  489. return _batch->getStateBlock();
  490. }
  491. Material* Sprite::getMaterial() const
  492. {
  493. return _batch->getMaterial();
  494. }
  495. unsigned int Sprite::draw(bool wireframe)
  496. {
  497. // Apply scene camera projection and translation offsets
  498. Vector3 position = Vector3::zero();
  499. if (_node && _node->getScene())
  500. {
  501. Camera* activeCamera = _node->getScene()->getActiveCamera();
  502. if (activeCamera)
  503. {
  504. Node* cameraNode = _node->getScene()->getActiveCamera()->getNode();
  505. if (cameraNode)
  506. {
  507. // Scene projection
  508. Matrix projectionMatrix;
  509. projectionMatrix = _node->getProjectionMatrix();
  510. _batch->setProjectionMatrix(projectionMatrix);
  511. // Camera translation offsets
  512. position.x -= cameraNode->getTranslationWorld().x;
  513. position.y -= cameraNode->getTranslationWorld().y;
  514. }
  515. }
  516. // Apply node translation offsets
  517. Vector3 translation = _node->getTranslationWorld();
  518. position.x += translation.x;
  519. position.y += translation.y;
  520. position.z += translation.z;
  521. }
  522. // Apply local offset translation offsets
  523. if ((_offset & OFFSET_HCENTER) == OFFSET_HCENTER)
  524. position.x -= _width * 0.5;
  525. if ((_offset & OFFSET_RIGHT) == OFFSET_RIGHT)
  526. position.x -= _width;
  527. if ((_offset & OFFSET_VCENTER) == OFFSET_VCENTER)
  528. position.y -= _height * 0.5f;
  529. if ((_offset & OFFSET_TOP) == OFFSET_TOP)
  530. position.y -= _height;
  531. if ((_offset & OFFSET_ANCHOR) == OFFSET_ANCHOR)
  532. {
  533. position.x -= _width * _anchor.x;
  534. position.y -= _height * _anchor.y;
  535. }
  536. // Apply node scale and rotation
  537. float rotationAngle = 0.0f;
  538. Vector2 scale = Vector2(_width, _height);
  539. if (_node)
  540. {
  541. // Apply node rotation
  542. const Quaternion& rot = _node->getRotation();
  543. if (rot.x != 0.0f || rot.y != 0.0f || rot.z != 0.0f)
  544. rotationAngle = rot.toAxisAngle(NULL);
  545. // Apply node scale
  546. if (_node->getScaleX() != 1.0f)
  547. scale.x *= _node->getScaleX();
  548. if (_node->getScaleY() != 1.0f)
  549. scale.y *= _node->getScaleY();
  550. }
  551. // Apply flip flags
  552. if ((_flipFlags & FLIP_HORIZONTAL) == FLIP_HORIZONTAL)
  553. {
  554. position.x += scale.x;
  555. scale.x = -scale.x;
  556. }
  557. if ((_flipFlags & FLIP_VERTICAL) == FLIP_VERTICAL)
  558. {
  559. position.y += scale.y;
  560. scale.y = -scale.y;
  561. }
  562. // TODO: Proper batching from cache based on batching rules (image, layers, etc)
  563. _batch->start();
  564. _batch->draw(position, _frames[_frameIndex], scale, Vector4(_color.x, _color.y, _color.z, _color.w * _opacity),
  565. _anchor, rotationAngle);
  566. _batch->finish();
  567. return 1;
  568. }
  569. Drawable* Sprite::clone(NodeCloneContext& context)
  570. {
  571. Sprite* spriteClone = new Sprite();
  572. // Clone animations
  573. AnimationTarget::cloneInto(static_cast<AnimationTarget*>(spriteClone), context);
  574. // Get copied node if it exists
  575. if (Node* node = getNode())
  576. {
  577. Node* clonedNode = context.findClonedNode(node);
  578. if (clonedNode)
  579. {
  580. spriteClone->setNode(clonedNode);
  581. }
  582. }
  583. // Clone properties
  584. spriteClone->_width = _width;
  585. spriteClone->_height = _height;
  586. spriteClone->_offset = _offset;
  587. spriteClone->_anchor = _anchor;
  588. spriteClone->_flipFlags = _flipFlags;
  589. spriteClone->_opacity = _opacity;
  590. spriteClone->_color = _color;
  591. spriteClone->_blendMode = _blendMode;
  592. spriteClone->_frames = new Rectangle[_frameCount];
  593. memcpy(spriteClone->_frames, _frames, sizeof(Rectangle) * _frameCount);
  594. spriteClone->_frameCount = _frameCount;
  595. spriteClone->_frameStride = _frameStride;
  596. spriteClone->_framePadding = _framePadding;
  597. spriteClone->_frameIndex = _frameIndex;
  598. spriteClone->_batch = _batch;
  599. return spriteClone;
  600. }
  601. int Sprite::getPropertyId(TargetType type, const char* propertyIdStr)
  602. {
  603. GP_ASSERT(propertyIdStr);
  604. if (type == AnimationTarget::TRANSFORM)
  605. {
  606. if (strcmp(propertyIdStr, "ANIMATE_OPACITY") == 0)
  607. {
  608. return Sprite::ANIMATE_OPACITY;
  609. }
  610. else if (strcmp(propertyIdStr, "ANIMATE_COLOR") == 0)
  611. {
  612. return Sprite::ANIMATE_COLOR;
  613. }
  614. else if (strcmp(propertyIdStr, "ANIMATE_KEYFRAME") == 0)
  615. {
  616. return Sprite::ANIMATE_KEYFRAME;
  617. }
  618. }
  619. return AnimationTarget::getPropertyId(type, propertyIdStr);
  620. }
  621. unsigned int Sprite::getAnimationPropertyComponentCount(int propertyId) const
  622. {
  623. switch (propertyId)
  624. {
  625. case ANIMATE_OPACITY:
  626. return 1;
  627. case ANIMATE_COLOR:
  628. return 4;
  629. case ANIMATE_KEYFRAME:
  630. return 1;
  631. default:
  632. return -1;
  633. }
  634. }
  635. void Sprite::getAnimationPropertyValue(int propertyId, AnimationValue* value)
  636. {
  637. GP_ASSERT(value);
  638. switch (propertyId)
  639. {
  640. case ANIMATE_OPACITY:
  641. value->setFloat(0, _opacity);
  642. break;
  643. case ANIMATE_COLOR:
  644. value->setFloat(0, _color.x);
  645. value->setFloat(1, _color.y);
  646. value->setFloat(2, _color.z);
  647. value->setFloat(3, _color.w);
  648. break;
  649. case ANIMATE_KEYFRAME:
  650. value->setFloat(0, (float)_frameIndex);
  651. break;
  652. default:
  653. break;
  654. }
  655. }
  656. void Sprite::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
  657. {
  658. GP_ASSERT(value);
  659. switch(propertyId)
  660. {
  661. case ANIMATE_OPACITY:
  662. setOpacity(Curve::lerp(blendWeight, _opacity, value->getFloat(0)));
  663. break;
  664. case ANIMATE_COLOR:
  665. setColor(Vector4(Curve::lerp(blendWeight, _color.x, value->getFloat(0)),
  666. Curve::lerp(blendWeight, _color.x, value->getFloat(1)),
  667. Curve::lerp(blendWeight, _color.x, value->getFloat(2)),
  668. Curve::lerp(blendWeight, _color.x, value->getFloat(3))));
  669. break;
  670. case ANIMATE_KEYFRAME:
  671. _frameIndex = (unsigned int)value->getFloat(0);
  672. break;
  673. default:
  674. break;
  675. }
  676. }
  677. }