diff options
Diffstat (limited to 'pointcloud.cpp')
-rw-r--r-- | pointcloud.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/pointcloud.cpp b/pointcloud.cpp new file mode 100644 index 0000000..417c31c --- /dev/null +++ b/pointcloud.cpp @@ -0,0 +1,183 @@ +/* + Copyright (C) 2015 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://opendigitalradio.org + */ +/* + This file is part of ODR-DPD. + + ODR-DPD is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + ODR-DPD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ODR-DPD. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "pointcloud.hpp" + +#include <iostream> +#include <vector> + +#include <SDL/SDL.h> +#include <GL/gl.h> +#include <GL/glu.h> +#include <algorithm> + +using namespace std; + +PointCloud::PointCloud(size_t num_points) : + m_num_points(num_points), + m_rxgain(1.0), + m_txgain(1.0) +{ + SDL_Init(SDL_INIT_VIDEO); + atexit(SDL_Quit); + SDL_WM_SetCaption("Point Cloud", NULL); + SDL_SetVideoMode(720,640, 32, SDL_OPENGL); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(6,(double)640/480,1,1000); +} + +// Not really a border, but you get the idea +vector<Point> PointCloud::generate_border(void) +{ + vector<Point> points(4); + points[0].x = 0; + points[0].y = 0; + + points[1].x = 1; + points[1].y = 0; + + points[2].x = 0; + points[2].y = 1; + + points[3].x = 1; + points[3].y = 1; + + for (auto &p : points) { + p.r = 255; + p.g = 255; + p.b = 0; + } + + return points; +} + +void PointCloud::push_samples(std::pair<std::vector<complexf>, std::vector<complexf> > &data) +{ + auto &rx = data.first; + auto &tx = data.second; + + if (rx.size() != tx.size()) { + throw std::runtime_error("RX and TX have different size"); + } + + std::lock_guard<std::mutex> lock(m_mutex); + + for (size_t i = 0; i < rx.size(); i++) { + Point p; + + // Magnitude is position + p.x = std::abs(rx[i]) * m_rxgain; + p.y = std::abs(tx[i]) * m_txgain; + p.z = 0.0; + + double arg_rx = std::arg(rx[i]); + double arg_tx = std::arg(tx[i]); + + // Phase is colour + p.r = p.g = p.b = 255; + if (arg_rx > arg_tx) { + int corr = 255 - 10 * (arg_rx - arg_tx); + + if (corr < 0) { + corr = 0; + } + + p.r = corr; + } + else { + int corr = 255 - 10 * (arg_tx - arg_rx); + + if (corr < 0) { + corr = 0; + } + + p.b = corr; + } + + m_points.push_back(p); + } + + if (m_points.size() > m_num_points + rx.size()) { + m_points.erase(m_points.begin(), m_points.begin() + rx.size()); + } +} + +void PointCloud::handle_event() +{ + SDL_Event event; + while (SDL_PollEvent(&event)) + { + switch(event.type){ + case SDL_QUIT: + throw sdl_quit(); + break; + } + } +} + +void PointCloud::draw() +{ + std::lock_guard<std::mutex> lock(m_mutex); + + size_t num_points_drawn = std::min(m_num_points, m_points.size()); + vector<Point> v(m_num_points); + for (size_t i = 0; i < num_points_drawn; i++) { + v[i] = m_points[i]; + } + + m_mutex.unlock(); + + vector<Point> border = generate_border(); + v.insert(v.end(), border.begin(), border.end()); + + glPushAttrib(GL_ALL_ATTRIB_BITS); + glPushMatrix(); + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + gluLookAt( + 0.5,0.5,10, + 0.5,0.5,0, + 0,1,0); + + glPointSize(4.0); + + glBegin(GL_POINTS); + for (size_t n = 0; n < v.size(); n++){ + glColor3ub(v[n].r, v[n].g, v[n].b); + glVertex3d(v[n].x, v[n].y, v[n].z); + } + glEnd(); + + glFlush(); + SDL_GL_SwapBuffers(); + + glPopMatrix(); + glPopAttrib(); +} + |