| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- #include "TimeSeriesCanvas.h"
- #include "../CommonInterfaces/Common2dCanvasInterface.h"
- #include "LinearMath/btAlignedObjectArray.h"
- #include "TimeSeriesFontData.h"
- #include "LinearMath/btVector3.h"
- #include <stdio.h>
- struct DataSource
- {
- unsigned char m_red;
- unsigned char m_green;
- unsigned char m_blue;
- float m_lastValue;
- bool m_hasLastValue;
- DataSource()
- : m_hasLastValue(false)
- {
- }
- };
- struct TimeSeriesInternalData
- {
- btAlignedObjectArray<DataSource> m_dataSources;
- struct Common2dCanvasInterface* m_canvasInterface;
- int m_canvasIndex;
- int m_width;
- int m_height;
- float m_pixelsPerUnit;
- float m_zero;
- int m_timeTicks;
- int m_ticksPerSecond;
- float m_yScale;
- int m_bar;
- unsigned char m_backgroundRed;
- unsigned char m_backgroundGreen;
- unsigned char m_backgroundBlue;
- unsigned char m_backgroundAlpha;
- unsigned char m_textColorRed;
- unsigned char m_textColorGreen;
- unsigned char m_textColorBlue;
- unsigned char m_textColorAlpha;
- float getTime()
- {
- return m_timeTicks / (float)m_ticksPerSecond;
- }
- TimeSeriesInternalData(int width, int height)
- : m_width(width),
- m_height(height),
- m_pixelsPerUnit(-100),
- m_zero(height / 2.0),
- m_timeTicks(0),
- m_ticksPerSecond(100),
- m_yScale(1),
- m_bar(0),
- m_backgroundRed(255),
- m_backgroundGreen(255),
- m_backgroundBlue(255),
- m_backgroundAlpha(255),
- m_textColorRed(0),
- m_textColorGreen(0),
- m_textColorBlue(255),
- m_textColorAlpha(255)
- {
- }
- };
- TimeSeriesCanvas::TimeSeriesCanvas(struct Common2dCanvasInterface* canvasInterface, int width, int height, const char* windowTitle)
- {
- m_internalData = new TimeSeriesInternalData(width, height);
- m_internalData->m_canvasInterface = canvasInterface;
- if (canvasInterface)
- {
- m_internalData->m_canvasIndex = m_internalData->m_canvasInterface->createCanvas(windowTitle, m_internalData->m_width, m_internalData->m_height, 20, 50);
- }
- }
- void TimeSeriesCanvas::addDataSource(const char* dataSourceLabel, unsigned char red, unsigned char green, unsigned char blue)
- {
- DataSource dataSource;
- dataSource.m_red = red;
- dataSource.m_green = green;
- dataSource.m_blue = blue;
- dataSource.m_lastValue = 0;
- dataSource.m_hasLastValue = false;
- if (dataSourceLabel)
- {
- int numSources = m_internalData->m_dataSources.size();
- int row = numSources % 3;
- int column = numSources / 3;
- grapicalPrintf(dataSourceLabel, sTimeSeriesFontData, 50 + 200 * column, m_internalData->m_height - 48 + row * 16,
- red, green, blue, 255);
- }
- m_internalData->m_dataSources.push_back(dataSource);
- }
- void TimeSeriesCanvas::setupTimeSeries(float yScale, int ticksPerSecond, int startTime, bool clearCanvas)
- {
- if (0 == m_internalData->m_canvasInterface)
- return;
- m_internalData->m_pixelsPerUnit = -(m_internalData->m_height / 3.f) / yScale;
- m_internalData->m_ticksPerSecond = ticksPerSecond;
- m_internalData->m_yScale = yScale;
- m_internalData->m_dataSources.clear();
- if (clearCanvas)
- {
- for (int i = 0; i < m_internalData->m_width; i++)
- {
- for (int j = 0; j < m_internalData->m_height; j++)
- {
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, i, j,
- m_internalData->m_backgroundRed,
- m_internalData->m_backgroundGreen,
- m_internalData->m_backgroundBlue,
- m_internalData->m_backgroundAlpha);
- }
- }
- }
- float zeroPixelCoord = m_internalData->m_zero;
- float pixelsPerUnit = m_internalData->m_pixelsPerUnit;
- float yPos = zeroPixelCoord + pixelsPerUnit * yScale;
- float yNeg = zeroPixelCoord + pixelsPerUnit * -yScale;
- grapicalPrintf("0", sTimeSeriesFontData, 2, zeroPixelCoord, m_internalData->m_textColorRed, m_internalData->m_textColorGreen, m_internalData->m_textColorBlue, m_internalData->m_textColorAlpha);
- char label[1024];
- sprintf(label, "%2.1f", yScale);
- grapicalPrintf(label, sTimeSeriesFontData, 2, yPos, m_internalData->m_textColorRed, m_internalData->m_textColorGreen, m_internalData->m_textColorBlue, m_internalData->m_textColorAlpha);
- sprintf(label, "%2.1f", -yScale);
- grapicalPrintf(label, sTimeSeriesFontData, 2, yNeg, m_internalData->m_textColorRed, m_internalData->m_textColorGreen, m_internalData->m_textColorBlue, m_internalData->m_textColorAlpha);
- m_internalData->m_canvasInterface->refreshImageData(m_internalData->m_canvasIndex);
- }
- TimeSeriesCanvas::~TimeSeriesCanvas()
- {
- if (m_internalData->m_canvasInterface && m_internalData->m_canvasIndex >= 0)
- {
- m_internalData->m_canvasInterface->destroyCanvas(m_internalData->m_canvasIndex);
- }
- delete m_internalData;
- }
- float TimeSeriesCanvas::getCurrentTime() const
- {
- return m_internalData->getTime();
- }
- void TimeSeriesCanvas::grapicalPrintf(const char* str, void* fontData, int rasterposx, int rasterposy, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
- {
- unsigned char c;
- int x = 0;
- int xx = 0;
- while ((c = (unsigned char)*str++))
- {
- x = xx;
- unsigned char* fontPtr = (unsigned char*)fontData;
- char ch = c - 32;
- int sx = ch % 16;
- int sy = ch / 16;
- for (int i = sx * 16; i < (sx * 16 + 16); i++)
- {
- int y = 0;
- for (int j = sy * 16; j < (sy * 16 + 16); j++)
- {
- unsigned char packedColor = (fontPtr[i * 3 + 255 * 256 * 3 - (256 * j) * 3]);
- //float colorf = packedColor ? 0.f : 1.f;
- float colorf = packedColor / 255.f; // ? 0.f : 1.f;
- btVector4 rgba(colorf, colorf, colorf, 1.f);
- if (colorf)
- {
- if ((rasterposx + x >= 0) && (rasterposx + x < m_internalData->m_width) &&
- (rasterposy + y >= 0) && (rasterposy + y < m_internalData->m_height))
- {
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, rasterposx + x, rasterposy + y,
- red, green, blue, alpha);
- }
- }
- y++;
- }
- x++;
- }
- xx += 10;
- }
- }
- void TimeSeriesCanvas::shift1PixelToLeft()
- {
- int resetVal = 10;
- int countdown = resetVal;
- //shift pixture one pixel to the left
- for (int j = 50; j < m_internalData->m_height - 48; j++)
- {
- for (int i = 40; i < this->m_internalData->m_width; i++)
- {
- unsigned char red, green, blue, alpha;
- m_internalData->m_canvasInterface->getPixel(m_internalData->m_canvasIndex, i, j, red, green, blue, alpha);
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, i - 1, j, red, green, blue, alpha);
- }
- if (!m_internalData->m_bar)
- {
- if (!countdown--)
- {
- countdown = resetVal;
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1, j, 0, 0, 0, 255);
- }
- else
- {
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1, j, 255, 255, 255, 255);
- }
- }
- else
- {
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1, j, 255, 255, 255, 255);
- }
- }
- {
- int resetVal = 2;
- static int countdown = resetVal;
- if (!countdown--)
- {
- countdown = resetVal;
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1, m_internalData->m_zero, 0, 0, 0, 255);
- }
- }
- {
- int resetVal = 10;
- static int countdown = resetVal;
- if (!countdown--)
- {
- countdown = resetVal;
- float zeroPixelCoord = m_internalData->m_zero;
- float pixelsPerUnit = m_internalData->m_pixelsPerUnit;
- float yPos = zeroPixelCoord + pixelsPerUnit * m_internalData->m_yScale;
- float yNeg = zeroPixelCoord + pixelsPerUnit * -m_internalData->m_yScale;
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1,
- yPos, 0, 0, 0, 255);
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1,
- yNeg, 0, 0, 0, 255);
- }
- }
- if (!m_internalData->m_bar)
- {
- char buf[1024];
- float time = m_internalData->getTime();
- sprintf(buf, "%2.0f", time);
- grapicalPrintf(buf, sTimeSeriesFontData, m_internalData->m_width - 25, m_internalData->m_zero + 3, 0, 0, 0, 255);
- m_internalData->m_bar = m_internalData->m_ticksPerSecond;
- }
- m_internalData->m_timeTicks++;
- m_internalData->m_bar--;
- }
- void TimeSeriesCanvas::insertDataAtCurrentTime(float orgV, int dataSourceIndex, bool connectToPrevious)
- {
- if (0 == m_internalData->m_canvasInterface)
- return;
- btAssert(dataSourceIndex < m_internalData->m_dataSources.size());
- float zero = m_internalData->m_zero;
- float amp = m_internalData->m_pixelsPerUnit;
- //insert some new value(s) in the right-most column
- {
- // float time = m_internalData->getTime();
- float v = zero + amp * orgV;
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1, v,
- m_internalData->m_dataSources[dataSourceIndex].m_red,
- m_internalData->m_dataSources[dataSourceIndex].m_green,
- m_internalData->m_dataSources[dataSourceIndex].m_blue,
- 255);
- if (connectToPrevious && m_internalData->m_dataSources[dataSourceIndex].m_hasLastValue)
- {
- for (int value = m_internalData->m_dataSources[dataSourceIndex].m_lastValue; value <= v; value++)
- {
- if (value >= 0 && value < float(m_internalData->m_height - 1))
- {
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1, value,
- m_internalData->m_dataSources[dataSourceIndex].m_red,
- m_internalData->m_dataSources[dataSourceIndex].m_green,
- m_internalData->m_dataSources[dataSourceIndex].m_blue,
- 255);
- }
- }
- for (int value = v; value <= m_internalData->m_dataSources[dataSourceIndex].m_lastValue; value++)
- {
- if (value >= 0 && value < float(m_internalData->m_height - 1))
- {
- m_internalData->m_canvasInterface->setPixel(m_internalData->m_canvasIndex, m_internalData->m_width - 1, value,
- m_internalData->m_dataSources[dataSourceIndex].m_red,
- m_internalData->m_dataSources[dataSourceIndex].m_green,
- m_internalData->m_dataSources[dataSourceIndex].m_blue,
- 255);
- }
- }
- }
- m_internalData->m_dataSources[dataSourceIndex].m_lastValue = v;
- m_internalData->m_dataSources[dataSourceIndex].m_hasLastValue = true;
- }
- }
- void TimeSeriesCanvas::nextTick()
- {
- shift1PixelToLeft();
- m_internalData->m_canvasInterface->refreshImageData(m_internalData->m_canvasIndex);
- }
|