TimeSeriesCanvas.cpp 9.7 KB

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