root/src/examples/flowingcanvas/canvaswriter.h @ 166:064e0c4d99fe

Revision 166:064e0c4d99fe, 5.6 KB (checked in by Andreas Schaefer <gentryx@…>, 14 months ago)

simulation and visualization now run synchronously. not perfect, but it'll do

Line 
1#ifndef _libgeodecomp_examples_flowingcanvas_canvaswriter_h_
2#define _libgeodecomp_examples_flowingcanvas_canvaswriter_h_
3
4#include <QImage>
5#include <QPainter>
6#include <libgeodecomp/io/writer.h>
7#include <libgeodecomp/examples/flowingcanvas/canvascell.h>
8
9namespace LibGeoDecomp {
10
11class CanvasWriter : public QObject, public Writer<CanvasCell>
12{
13    Q_OBJECT
14
15public:
16    class SelectForceFixed
17    {
18    public:
19        float operator()(const CanvasCell& cell, const int& index) const
20        {
21            return cell.forceFixed[index];
22        }
23    };
24
25    class SelectForceVario
26    {
27    public:
28        float operator()(const CanvasCell& cell, const int& index) const
29        {
30            return cell.forceVario[index];
31        }
32    };
33
34    class SelectForceTotal
35    {
36    public:
37        float operator()(const CanvasCell& cell, const int& index) const
38        {
39            return cell.forceTotal[index];
40        }
41    };
42
43    class SelectCameraLevel
44    {
45    public:
46        unsigned operator()(const CanvasCell& cell) const
47        {
48            return (0xff << 24) + ((int)(cell.cameraLevel * 250) << 16);
49        }
50    };
51
52    class SelectCameraPixel
53    {
54    public:
55        unsigned operator()(const CanvasCell& cell) const
56        {
57            return cell.cameraPixel;
58        }
59    };
60
61    CanvasWriter(QImage **_outputFrame,
62                 MonolithicSimulator<CanvasCell> *_sim) :
63        Writer<CanvasCell>("foo", _sim, 1),
64        outputFrame(_outputFrame),
65        mode(5)
66    {}
67
68    virtual void initialized()
69    {}
70
71    virtual void stepFinished()
72    {
73        switch (mode) {
74        case 0:
75            drawAttribute(SelectCameraPixel());
76            break;
77        case 1:
78            drawAttribute(SelectCameraLevel());
79            break;
80        case 2:
81            drawForce(SelectForceVario());
82            break;
83        case 3:
84            drawForce(SelectForceFixed());
85            break;
86        case 4:
87            drawForce(SelectForceTotal());
88            break;
89        case 5:
90            drawParticles();
91            break;
92        default:
93            break;
94        }
95    }
96
97    virtual void allDone()
98    {
99    }
100
101public slots:
102    virtual void cycleViewMode()
103    {
104        mode = (mode + 1) % 6;
105    }
106
107private:
108    QImage **outputFrame;
109    int mode;
110
111    template<typename SELECTOR>
112    void drawForce(const SELECTOR& selector)
113    {
114        Coord<2> dim = sim->getInitializer()->gridDimensions();
115        const typename Simulator<CanvasCell>::GridType *grid = sim->getGrid();
116       
117        int spacingX = 10;
118        int spacingY = 10;
119        float factorX = 1.0 * (*outputFrame)->width()  / dim.x();
120        float factorY = 1.0 * (*outputFrame)->height() / dim.y();
121
122        QPainter p(*outputFrame);
123        p.setBrush(QBrush(Qt::black));
124        p.drawRect(0, 0, (*outputFrame)->width(), (*outputFrame)->height());
125        p.setBrush(QBrush(Qt::white));
126        p.setPen(QPen(Qt::white));
127
128        for (int y = 0; y < dim.y(); y += spacingY) {
129            for (int x = 0; x < dim.x(); x += spacingX) {
130                int startX = (x + 0.5) * factorX;
131                int startY = (y + 0.5) * factorY;
132                const CanvasCell& cell = grid->at(Coord<2>(x, y));
133                float force0 = selector(cell, 0);
134                float force1 = selector(cell, 1);
135                int offsetX = force0 * spacingX * factorX * 0.8;
136                int offsetY = force1 * spacingY * factorY * 0.8;
137                int endX = startX + offsetX;
138                int endY = startY + offsetY;
139                p.drawLine(startX, startY, endX, endY); 
140                QRectF rect(endX - spacingX * 0.1, endY - spacingY * 0.1, spacingX * 0.2, spacingY * 0.2);
141                p.drawEllipse(rect);
142            }
143        }
144    }
145
146    // fixme: erase background
147    // fixme: scale to image size
148    template<typename SELECTOR>
149    void drawAttribute(const SELECTOR& selector)
150    {
151        Coord<2> dim = sim->getInitializer()->gridDimensions();
152        const typename Simulator<CanvasCell>::GridType *grid = sim->getGrid();
153       
154        for (int y = 0; y < dim.y(); ++y) {
155            for (int x = 0; x < dim.x(); ++x) {
156                (*outputFrame)->setPixel(x, y, selector(grid->at(Coord<2>(x, y))));
157            }
158        }
159    }
160
161    void drawParticles()
162    {
163        Coord<2> dim = sim->getInitializer()->gridDimensions();
164        const typename Simulator<CanvasCell>::GridType *grid = sim->getGrid();
165
166        float factorX = 1.0 * (*outputFrame)->width()  / dim.x();
167        float factorY = 1.0 * (*outputFrame)->height() / dim.y();
168
169        QPainter p(*outputFrame);
170        p.setBrush(QBrush(Qt::black));
171        p.drawRect(0, 0, (*outputFrame)->width(), (*outputFrame)->height());
172        p.setBrush(QBrush(Qt::white));
173        p.setPen(QPen(Qt::white));
174
175        for (int y = 0; y < dim.y(); ++y) {
176            for (int x = 0; x < dim.x(); ++x) {
177                const CanvasCell& cell = grid->at(Coord<2>(x, y));
178                for (int i = 0; i < cell.numParticles; ++i) {
179                    const CanvasCell::Particle& particle = cell.particles[i];
180                    QPoint origin(particle.pos[0] * factorX,
181                                  particle.pos[1] * factorY);
182                    QPoint direction(particle.vel[0] * 20,
183                                     particle.vel[1] * 20);
184                    QPoint end = origin + direction;
185                    QPoint offset(2, 2);
186                    QSize size(4, 4);
187                    QRectF rect(origin - offset, size);
188                    p.drawEllipse(rect);
189                    p.drawLine(origin, end);
190                }
191            }
192        }
193    }
194};
195
196}
197
198#endif
Note: See TracBrowser for help on using the browser.