PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/ofxMovieClip/src/ofxMovieClip.cpp

https://github.com/trentbrooks/ofxMovieClip
C++ | 321 lines | 233 code | 58 blank | 30 comment | 36 complexity | 442ed819b1f5411e14f92c6fd0164dc4 MD5 | raw file
  1. #include "ofxMovieClip.h"
  2. //--------------------------------------------------------------
  3. template<typename ImageType>
  4. ofxMovieClip<ImageType>::ofxMovieClip(){
  5. playheadCount = 0;
  6. playMode = STEP_FORWARD;
  7. previousFrameTimeElapsed = 0;
  8. frameDelayInSeconds = 1.0 / 30.0; // default around 30fps
  9. frameLabelId = 0;
  10. width= height =-1;
  11. isCustomSize = false;
  12. playheadCopy = -1;
  13. loopCount = 0;
  14. loopOnFinish = true;
  15. loopComplete = false;
  16. yoyoOnFinish = false;
  17. activeAsset = NULL;
  18. pixelsTexture = NULL;
  19. }
  20. //--------------------------------------------------------------
  21. // template specialisation: ofTexture
  22. template<>
  23. void ofxMovieClip<ofTexture>::init(ofxImageSequenceLoader<ofTexture>* imageSequence, float frameDelay)
  24. {
  25. this->imageSequence = imageSequence;
  26. activeAsset = imageSequence->assetCollections[frameLabelId];
  27. this->frameDelayInSeconds = frameDelay;
  28. // auto grab the width and height of the first asset
  29. if(width == -1 && height == -1 && activeAsset->imageFrames.size() > 0) {
  30. width = activeAsset->imageFrames[0]->getWidth();
  31. height = activeAsset->imageFrames[0]->getHeight();
  32. }
  33. }
  34. // template specialisation: ofPixels
  35. template<>
  36. void ofxMovieClip<ofPixels>::init(ofxImageSequenceLoader<ofPixels>* imageSequence, float frameDelay)
  37. {
  38. pixelsTexture = new ofTexture(); // create a texture container for the ofPixels movieclip
  39. //pixelsTexture->allocate(ofGetWidth(), ofGetHeight(), GL_RGBA);
  40. this->imageSequence = imageSequence;
  41. activeAsset = imageSequence->assetCollections[frameLabelId];
  42. this->frameDelayInSeconds = frameDelay;
  43. // auto grab the width and height of the first asset
  44. // does not account for threaded image loads here...
  45. if(width == -1 && height == -1 && activeAsset->imageFrames.size() > 0) {
  46. width = activeAsset->imageFrames[0]->getWidth();
  47. height = activeAsset->imageFrames[0]->getHeight();
  48. }
  49. }
  50. // Play head controls
  51. //--------------------------------------------------------------
  52. template<typename ImageType>
  53. void ofxMovieClip<ImageType>::play() {
  54. loopComplete = false;
  55. playMode = STEP_FORWARD;
  56. }
  57. template<typename ImageType>
  58. void ofxMovieClip<ImageType>::reverse() {
  59. loopComplete = false;
  60. // need to reswap reversePlayheadCount if playing
  61. //reversePlayheadCount = frameInterval - playheadCount;
  62. playMode = STEP_REVERSE;
  63. }
  64. template<typename ImageType>
  65. void ofxMovieClip<ImageType>::stop() {
  66. loopComplete = false;
  67. playMode = STEP_STOP;
  68. }
  69. template<typename ImageType>
  70. void ofxMovieClip<ImageType>::restart() {
  71. loopComplete = false;
  72. playMode = STEP_FORWARD;
  73. playheadCount = 0;
  74. }
  75. template<typename ImageType>
  76. void ofxMovieClip<ImageType>::gotoAndPlay(int frameNumber) {
  77. loopComplete = false;
  78. playMode = STEP_FORWARD;
  79. playheadCount = ofClamp(frameNumber, 0, activeAsset->imageFramesSize - 1);
  80. }
  81. template<typename ImageType>
  82. void ofxMovieClip<ImageType>::gotoAndStop(int frameNumber) {
  83. loopComplete = false;
  84. playMode = STEP_STOP;
  85. playheadCount = ofClamp(frameNumber, 0, activeAsset->imageFramesSize - 1);
  86. }
  87. template<typename ImageType>
  88. void ofxMovieClip<ImageType>::gotoAndPlay(string frameLabel) {
  89. loopComplete = false;
  90. playMode = STEP_FORWARD;
  91. frameLabelId = imageSequence->getAssetsId(frameLabel);
  92. activeAsset = imageSequence->assetCollections[frameLabelId];
  93. playheadCount = 0;
  94. }
  95. template<typename ImageType>
  96. void ofxMovieClip<ImageType>::gotoAndStop(string frameLabel) {
  97. loopComplete = false;
  98. playMode = STEP_STOP;
  99. frameLabelId = imageSequence->getAssetsId(frameLabel);
  100. activeAsset = imageSequence->assetCollections[frameLabelId];
  101. playheadCount = 0;
  102. }
  103. template<typename ImageType>
  104. void ofxMovieClip<ImageType>::gotoAndPlay(string frameLabel, int frameNumber) {
  105. loopComplete = false;
  106. frameLabelId = imageSequence->getAssetsId(frameLabel);
  107. activeAsset = imageSequence->assetCollections[frameLabelId];
  108. gotoAndPlay(frameNumber);
  109. }
  110. template<typename ImageType>
  111. void ofxMovieClip<ImageType>::gotoAndStop(string frameLabel, int frameNumber) {
  112. loopComplete = false;
  113. frameLabelId = imageSequence->getAssetsId(frameLabel);
  114. activeAsset = imageSequence->assetCollections[frameLabelId];
  115. gotoAndStop(frameNumber);
  116. }
  117. //--------------------------------------------------------------
  118. // Drawing
  119. template<typename ImageType>
  120. void ofxMovieClip<ImageType>::draw() {
  121. if(isCustomSize)
  122. getTexturePtr()->draw(position.x, position.y, width, height);
  123. else
  124. getTexturePtr()->draw(position.x, position.y);
  125. tick(); // now gets called whenever a drawFrame is requested instead of manually
  126. }
  127. template<typename ImageType>
  128. void ofxMovieClip<ImageType>::draw(float x, float y) {
  129. if(isCustomSize)
  130. getTexturePtr()->draw(x, y, width, height);
  131. else
  132. getTexturePtr()->draw(x, y);
  133. tick(); // now gets called whenever a drawFrame is requested instead of manually
  134. }
  135. template<typename ImageType>
  136. void ofxMovieClip<ImageType>::draw(float x, float y, float w, float h) {
  137. getTexturePtr()->draw(x, y, w, h);
  138. tick(); // now gets called whenever a drawFrame is requested instead of manually
  139. }
  140. // Updates
  141. //--------------------------------------------------------------
  142. template<typename ImageType>
  143. void ofxMovieClip<ImageType>::tick()
  144. {
  145. switch (playMode)
  146. {
  147. case STEP_FORWARD:
  148. stepForward();
  149. break;
  150. case STEP_REVERSE:
  151. stepReverse();
  152. break;
  153. case STEP_STOP:
  154. break;
  155. default:
  156. break;
  157. }
  158. }
  159. template<typename ImageType>
  160. void ofxMovieClip<ImageType>::stepForward() {
  161. float elapsedFrameTimeDiff = ofGetElapsedTimef()-previousFrameTimeElapsed;
  162. if(elapsedFrameTimeDiff >= frameDelayInSeconds) {
  163. playheadCount++;
  164. if(playheadCount >= activeAsset->imageFramesSize ) {
  165. if(yoyoOnFinish) {
  166. playMode = STEP_REVERSE; // start playing back in reverse order
  167. playheadCount = activeAsset->imageFramesSize -1;
  168. } else if(loopOnFinish) {
  169. playheadCount = 0; // default behaviour
  170. } else if(loopCount > 1) {
  171. loopCount--;
  172. playheadCount = 0; // loop back to beginning but decrease counter
  173. } else {
  174. playheadCount = activeAsset->imageFramesSize -1; // just stop at last frame
  175. }
  176. loopComplete = true;
  177. }
  178. previousFrameTimeElapsed = ofGetElapsedTimef();
  179. }
  180. }
  181. template<typename ImageType>
  182. void ofxMovieClip<ImageType>::stepReverse() {
  183. float elapsedFrameTimeDiff = ofGetElapsedTimef()-previousFrameTimeElapsed;
  184. if(elapsedFrameTimeDiff >= frameDelayInSeconds) {
  185. playheadCount--;
  186. if(playheadCount < 0) {
  187. if(yoyoOnFinish) {
  188. playMode = STEP_FORWARD; // start playing back in reverse order
  189. playheadCount = 0;
  190. }
  191. else if(loopOnFinish) {
  192. playheadCount = activeAsset->imageFramesSize -1; // default behaviour
  193. } else if(loopCount > 1) {
  194. loopCount--;
  195. playheadCount = 0;
  196. } else {
  197. playheadCount = 0;
  198. }
  199. loopComplete = true;
  200. }
  201. previousFrameTimeElapsed = ofGetElapsedTimef();
  202. }
  203. }
  204. // Display position
  205. //--------------------------------------------------------------
  206. template<typename ImageType>
  207. void ofxMovieClip<ImageType>::setPosition(float x, float y)
  208. {
  209. position.x = x;
  210. position.y = y;
  211. }
  212. template<typename ImageType>
  213. void ofxMovieClip<ImageType>::setSize(float w, float h) {
  214. width = w;
  215. height = h;
  216. isCustomSize = true;
  217. }
  218. //--------------------------------------------------------------
  219. // only clears the internal pixels texture
  220. template<typename ImageType>
  221. void ofxMovieClip<ImageType>::clearTexture() {
  222. if(pixelsTexture) pixelsTexture->clear();
  223. }
  224. //--------------------------------------------------------------
  225. // template specialisation: ofTexture
  226. template<>
  227. ofTexture* ofxMovieClip<ofTexture>::getTexturePtr() {
  228. return activeAsset->imageFrames[playheadCount];
  229. }
  230. // template specialisation: ofPixels
  231. template<>
  232. ofTexture* ofxMovieClip<ofPixels>::getTexturePtr() {
  233. // only allocate + load if the playhead has changed, otherwise return cached copy
  234. if(playheadCopy != playheadCount) {
  235. ofPixels* px = activeAsset->imageFrames[playheadCount];
  236. playheadCopy = playheadCount;
  237. if(!px->isAllocated()) {
  238. // thread has not finished loading image yet - will not draw
  239. // should probably also hold the playhead until this has occured? atm, the playhead can be too fast for the loader
  240. //ofLog() << "1. Wrong px here: " << playheadCount << ", " << playheadCopy;
  241. return pixelsTexture;
  242. }
  243. if(!pixelsTexture->isAllocated()) {
  244. //ofLog() << "Allocated new pixels movieclip...";
  245. pixelsTexture->allocate(*px);
  246. width = pixelsTexture->getWidth();
  247. height = pixelsTexture->getHeight();
  248. }
  249. pixelsTexture->loadData(*px);
  250. }
  251. // always stops here unless the playhead is moving
  252. // try to allocate from loading assets (thread is prob still loading)
  253. if (!pixelsTexture->isAllocated()) {
  254. ofPixels* px = activeAsset->imageFrames[playheadCount];
  255. if (px->isAllocated()) {
  256. pixelsTexture->allocate(*px);
  257. pixelsTexture->loadData(*px);
  258. }
  259. }
  260. return pixelsTexture;
  261. }
  262. template class ofxMovieClip<ofTexture>;
  263. template class ofxMovieClip<ofPixels>;