TimeSeriesCanvas.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #include "TimeSeriesCanvas.h"
  2. #include "../CommonInterfaces/Common2dCanvasInterface.h"
  3. #include "LinearMath/btAlignedObjectArray.h"
  4. #include "TimeSeriesFontData.h"
  5. #include "LinearMath/btVector3.h"
  6. #include <stdio.h>
  7. struct DataSource
  8. {
  9. unsigned char m_red;
  10. unsigned char m_green;
  11. unsigned char m_blue;
  12. float m_lastValue;
  13. bool m_hasLastValue;
  14. DataSource()
  15. :m_hasLastValue(false)
  16. {
  17. }
  18. };
  19. struct TimeSeriesInternalData
  20. {
  21. btAlignedObjectArray<DataSource> m_dataSources;
  22. struct Common2dCanvasInterface* m_canvasInterface;
  23. int m_canvasIndex;
  24. int m_width;
  25. int m_height;
  26. float m_pixelsPerUnit;
  27. float m_zero;
  28. int m_timeTicks;
  29. int m_ticksPerSecond;
  30. float m_yScale;
  31. int m_bar;
  32. unsigned char m_backgroundRed;
  33. unsigned char m_backgroundGreen;
  34. unsigned char m_backgroundBlue;
  35. unsigned char m_backgroundAlpha;
  36. unsigned char m_textColorRed;
  37. unsigned char m_textColorGreen;
  38. unsigned char m_textColorBlue;
  39. unsigned char m_textColorAlpha;
  40. float getTime()
  41. {
  42. return m_timeTicks/(float)m_ticksPerSecond;
  43. }
  44. TimeSeriesInternalData(int width, int height)
  45. :m_width(width),
  46. m_height(height),
  47. m_pixelsPerUnit(-100),
  48. m_zero(height/2.0),
  49. m_timeTicks(0),
  50. m_ticksPerSecond(100),
  51. m_yScale(1),
  52. m_bar(0),
  53. m_backgroundRed(255),
  54. m_backgroundGreen(255),
  55. m_backgroundBlue(255),
  56. m_backgroundAlpha(255),
  57. m_textColorRed(0),
  58. m_textColorGreen(0),
  59. m_textColorBlue(255),
  60. m_textColorAlpha(255)
  61. {
  62. }
  63. };
  64. TimeSeriesCanvas::TimeSeriesCanvas(struct Common2dCanvasInterface* canvasInterface, int width, int height, const char* windowTitle)
  65. {
  66. btAssert(canvasInterface);
  67. m_internalData = new TimeSeriesInternalData(width,height);
  68. m_internalData->m_canvasInterface = canvasInterface;
  69. m_internalData->m_canvasIndex = m_internalData->m_canvasInterface->createCanvas(windowTitle,m_internalData->m_width,m_internalData->m_height);
  70. }
  71. void TimeSeriesCanvas::addDataSource(const char* dataSourceLabel, unsigned char red,unsigned char green,unsigned char blue)
  72. {
  73. DataSource dataSource;
  74. dataSource.m_red = red;
  75. dataSource.m_green = green;
  76. dataSource.m_blue = blue;
  77. dataSource.m_lastValue = 0;
  78. dataSource.m_hasLastValue = false;
  79. if (dataSourceLabel)
  80. {
  81. int numSources = m_internalData->m_dataSources.size();
  82. int row = numSources%3;
  83. int column = numSources/3;
  84. grapicalPrintf(dataSourceLabel, sTimeSeriesFontData, 50+200*column,m_internalData->m_height-48+row*16,
  85. red, green,blue,255);
  86. }
  87. m_internalData->m_dataSources.push_back(dataSource);
  88. }
  89. void TimeSeriesCanvas::setupTimeSeries(float yScale, int ticksPerSecond, int startTime)
  90. {
  91. m_internalData->m_pixelsPerUnit = -(m_internalData->m_height/3.f)/yScale;
  92. m_internalData->m_ticksPerSecond = ticksPerSecond;
  93. m_internalData->m_yScale = yScale;
  94. m_internalData->m_dataSources.clear();
  95. for (int i=0;i<m_internalData->m_width;i++)
  96. {
  97. for (int j=0;j<m_internalData->m_height;j++)
  98. {
  99. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,i,j,
  100. m_internalData->m_backgroundRed,
  101. m_internalData->m_backgroundGreen,
  102. m_internalData->m_backgroundBlue,
  103. m_internalData->m_backgroundAlpha);
  104. }
  105. }
  106. float zeroPixelCoord = m_internalData->m_zero;
  107. float pixelsPerUnit = m_internalData->m_pixelsPerUnit;
  108. float yPos = zeroPixelCoord+pixelsPerUnit*yScale;
  109. float yNeg = zeroPixelCoord+pixelsPerUnit*-yScale;
  110. grapicalPrintf("0", sTimeSeriesFontData, 2,zeroPixelCoord,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha);
  111. char label[1024];
  112. sprintf(label,"%2.1f", yScale);
  113. grapicalPrintf(label, sTimeSeriesFontData, 2,yPos,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha);
  114. sprintf(label,"%2.1f", -yScale);
  115. grapicalPrintf(label, sTimeSeriesFontData, 2,yNeg,m_internalData->m_textColorRed,m_internalData->m_textColorGreen,m_internalData->m_textColorBlue,m_internalData->m_textColorAlpha);
  116. m_internalData->m_canvasInterface->refreshImageData(m_internalData->m_canvasIndex);
  117. }
  118. TimeSeriesCanvas::~TimeSeriesCanvas()
  119. {
  120. if (m_internalData->m_canvasInterface && m_internalData->m_canvasIndex>=0)
  121. {
  122. m_internalData->m_canvasInterface->destroyCanvas(m_internalData->m_canvasIndex);
  123. }
  124. delete m_internalData;
  125. }
  126. float TimeSeriesCanvas::getCurrentTime() const
  127. {
  128. return m_internalData->getTime();
  129. }
  130. void TimeSeriesCanvas::grapicalPrintf(const char* str, void* fontData, int rasterposx,int rasterposy, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
  131. {
  132. unsigned char c;
  133. int x=0;
  134. int xx=0;
  135. while ((c = (unsigned char) *str++)) {
  136. x=xx;
  137. unsigned char* fontPtr = (unsigned char*) fontData;
  138. char ch = c-32;
  139. int sx=ch%16;
  140. int sy=ch/16;
  141. for (int i=sx*16;i<(sx*16+16);i++)
  142. {
  143. int y=0;
  144. for (int j=sy*16;j<(sy*16+16);j++)
  145. {
  146. unsigned char packedColor = (fontPtr[i*3+255*256*3-(256*j)*3]);
  147. //float colorf = packedColor ? 0.f : 1.f;
  148. float colorf = packedColor/255.f;// ? 0.f : 1.f;
  149. btVector4 rgba(colorf,colorf,colorf,1.f);
  150. if (colorf)
  151. {
  152. if ((rasterposx+x>=0) && (rasterposx+x < m_internalData->m_width) &&
  153. (rasterposy+y>=0) && (rasterposy+y<m_internalData->m_height))
  154. {
  155. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,rasterposx+x,rasterposy+y,
  156. red,green,blue,alpha);
  157. }
  158. }
  159. y++;
  160. }
  161. x++;
  162. }
  163. xx+=10;
  164. }
  165. }
  166. void TimeSeriesCanvas::shift1PixelToLeft()
  167. {
  168. int resetVal = 10;
  169. int countdown = resetVal;
  170. //shift pixture one pixel to the left
  171. for (int j=0;j<m_internalData->m_height-48;j++)
  172. {
  173. for (int i=40;i<this->m_internalData->m_width;i++)
  174. {
  175. unsigned char red, green, blue, alpha;
  176. m_internalData->m_canvasInterface->getPixel(m_internalData->m_canvasIndex,i,j,red,green,blue,alpha);
  177. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,i-1,j,red,green,blue,alpha);
  178. }
  179. if (!m_internalData->m_bar)
  180. {
  181. if (!countdown--)
  182. {
  183. countdown=resetVal;
  184. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,j,0,0,0,255);
  185. } else
  186. {
  187. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,j,255,255,255,255);
  188. }
  189. } else
  190. {
  191. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,j,255,255,255,255);
  192. }
  193. }
  194. {
  195. int resetVal = 2;
  196. static int countdown = resetVal;
  197. if (!countdown--)
  198. {
  199. countdown=resetVal;
  200. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,m_internalData->m_zero,0,0,0,255);
  201. }
  202. }
  203. {
  204. int resetVal = 10;
  205. static int countdown = resetVal;
  206. if (!countdown--)
  207. {
  208. countdown=resetVal;
  209. float zeroPixelCoord = m_internalData->m_zero;
  210. float pixelsPerUnit = m_internalData->m_pixelsPerUnit;
  211. float yPos = zeroPixelCoord+pixelsPerUnit*m_internalData->m_yScale;
  212. float yNeg = zeroPixelCoord+pixelsPerUnit*-m_internalData->m_yScale;
  213. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,
  214. yPos,0,0,0,255);
  215. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,
  216. yNeg,0,0,0,255);
  217. }
  218. }
  219. if (!m_internalData->m_bar)
  220. {
  221. char buf[1024];
  222. float time = m_internalData->getTime();
  223. sprintf(buf,"%2.0f",time);
  224. grapicalPrintf(buf, sTimeSeriesFontData, m_internalData->m_width-25,m_internalData->m_zero+3,0,0,0,255);
  225. m_internalData->m_bar=m_internalData->m_ticksPerSecond;
  226. }
  227. m_internalData->m_timeTicks++;
  228. m_internalData->m_bar--;
  229. }
  230. void TimeSeriesCanvas::insertDataAtCurrentTime(float orgV, int dataSourceIndex, bool connectToPrevious)
  231. {
  232. btAssert(dataSourceIndex < m_internalData->m_dataSources.size());
  233. float zero = m_internalData->m_zero;
  234. float amp = m_internalData->m_pixelsPerUnit;
  235. //insert some new value(s) in the right-most column
  236. {
  237. float time = m_internalData->getTime();
  238. float v = zero+amp*orgV;
  239. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,v,
  240. m_internalData->m_dataSources[dataSourceIndex].m_red,
  241. m_internalData->m_dataSources[dataSourceIndex].m_green,
  242. m_internalData->m_dataSources[dataSourceIndex].m_blue,
  243. 255
  244. );
  245. if (connectToPrevious && m_internalData->m_dataSources[dataSourceIndex].m_hasLastValue)
  246. {
  247. for (int value=m_internalData->m_dataSources[dataSourceIndex].m_lastValue;value<=v;value++)
  248. {
  249. if (value>=0 && value < float(m_internalData->m_height-1))
  250. {
  251. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,value,
  252. m_internalData->m_dataSources[dataSourceIndex].m_red,
  253. m_internalData->m_dataSources[dataSourceIndex].m_green,
  254. m_internalData->m_dataSources[dataSourceIndex].m_blue,
  255. 255
  256. );
  257. }
  258. }
  259. for (int value=v;value<=m_internalData->m_dataSources[dataSourceIndex].m_lastValue;value++)
  260. {
  261. if (value>=0 && value < float(m_internalData->m_height-1))
  262. {
  263. m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex,m_internalData->m_width-1,value,
  264. m_internalData->m_dataSources[dataSourceIndex].m_red,
  265. m_internalData->m_dataSources[dataSourceIndex].m_green,
  266. m_internalData->m_dataSources[dataSourceIndex].m_blue,
  267. 255);
  268. }
  269. }
  270. }
  271. m_internalData->m_dataSources[dataSourceIndex].m_lastValue = v;
  272. m_internalData->m_dataSources[dataSourceIndex].m_hasLastValue = true;
  273. }
  274. }
  275. void TimeSeriesCanvas::nextTick()
  276. {
  277. shift1PixelToLeft();
  278. m_internalData->m_canvasInterface->refreshImageData(m_internalData->m_canvasIndex);
  279. }