root/src/examples/flowingcanvas/canvaswriter.h @ 169:1dfd3178b6c5

Revision 169:1dfd3178b6c5, 5.9 KB (checked in by Andreas Schaefer <gentryx@…>, 14 months ago)

minor tweaks

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        particleMode(3),
66        cameraMode(1)
67    {}
68
69    virtual void initialized()
70    {}
71
72    virtual void stepFinished()
73    {
74        const typename Simulator<CanvasCell>::GridType *grid = sim->getGrid();
75
76        switch (particleMode) {
77        case 0:
78            drawForce(grid, SelectForceVario());
79            break;
80        case 1:
81            drawForce(grid, SelectForceFixed());
82            break;
83        case 2:
84            drawForce(grid, SelectForceTotal());
85            break;
86        case 3:
87            drawParticles(grid);
88            break;
89        default:
90            break;
91        }
92
93        switch (cameraMode) {
94        case 0:
95            drawAttribute(grid, SelectCameraPixel());
96            break;
97        case 1:
98            drawAttribute(grid, SelectCameraLevel());
99            break;
100        default:
101            break;
102        }
103    }
104
105    virtual void allDone()
106    {
107    }
108
109public slots:
110    virtual void cycleViewModeParticle()
111    {
112        particleMode = (particleMode + 1) % 4;
113    }
114
115    virtual void cycleViewModeCamera()
116    {
117        cameraMode = (cameraMode + 1) % 3;
118    }
119
120private:
121    QImage **outputFrame;
122    int particleMode;
123    int cameraMode;
124
125    template<typename SELECTOR>
126    void drawForce(const typename Simulator<CanvasCell>::GridType *grid, const SELECTOR& selector)
127    {
128        Coord<2> dim = sim->getInitializer()->gridDimensions();
129       
130        int spacingX = 10;
131        int spacingY = 10;
132        float factorX = 1.0 * (*outputFrame)->width()  / dim.x();
133        float factorY = 1.0 * (*outputFrame)->height() / dim.y();
134
135        QPainter p(*outputFrame);
136        p.setBrush(QBrush(Qt::black));
137        p.drawRect(0, 0, (*outputFrame)->width(), (*outputFrame)->height());
138        p.setBrush(QBrush(Qt::white));
139        p.setPen(QPen(Qt::white));
140
141        for (int y = 0; y < dim.y(); y += spacingY) {
142            for (int x = 0; x < dim.x(); x += spacingX) {
143                int startX = (x + 0.5) * factorX;
144                int startY = (y + 0.5) * factorY;
145                const CanvasCell& cell = grid->at(Coord<2>(x, y));
146                float force0 = selector(cell, 0);
147                float force1 = selector(cell, 1);
148                int offsetX = force0 * spacingX * factorX * 0.8;
149                int offsetY = force1 * spacingY * factorY * 0.8;
150                int endX = startX + offsetX;
151                int endY = startY + offsetY;
152                p.drawLine(startX, startY, endX, endY); 
153                QRectF rect(endX - spacingX * 0.1, endY - spacingY * 0.1, spacingX * 0.2, spacingY * 0.2);
154                p.drawEllipse(rect);
155            }
156        }
157    }
158
159    // fixme: erase background
160    // fixme: scale to image size
161    template<typename SELECTOR>
162    void drawAttribute(const typename Simulator<CanvasCell>::GridType *grid, const SELECTOR& selector)
163    {
164        Coord<2> dim = sim->getInitializer()->gridDimensions();
165       
166        for (int y = 0; y < dim.y(); ++y) {
167            for (int x = 0; x < dim.x(); ++x) {
168                (*outputFrame)->setPixel(x, y, selector(grid->at(Coord<2>(x, y))));
169            }
170        }
171    }
172
173    void drawParticles(const typename Simulator<CanvasCell>::GridType *grid)
174    {
175        Coord<2> dim = sim->getInitializer()->gridDimensions();
176        float factorX = 1.0 * (*outputFrame)->width()  / dim.x();
177        float factorY = 1.0 * (*outputFrame)->height() / dim.y();
178
179        QPainter p(*outputFrame);
180        p.setBrush(QBrush(Qt::black));
181        p.drawRect(0, 0, (*outputFrame)->width(), (*outputFrame)->height());
182        p.setBrush(QBrush(Qt::white));
183        p.setPen(QPen(Qt::white));
184       
185        for (int y = 0; y < dim.y(); ++y) {
186            for (int x = 0; x < dim.x(); ++x) {
187                const CanvasCell& cell = grid->at(Coord<2>(x, y));
188                for (int i = 0; i < cell.numParticles; ++i) {
189                    const CanvasCell::Particle& particle = cell.particles[i];
190                    QPoint origin(particle.pos[0] * factorX,
191                                  particle.pos[1] * factorY);
192                    QPoint direction(particle.vel[0] * 20,
193                                     particle.vel[1] * 20);
194                    QPoint end = origin + direction;
195                    QPoint offset(2, 2);
196                    QSize size(4, 4);
197                    QRectF rect(origin - offset, size);
198                    p.drawEllipse(rect);
199                    p.drawLine(origin, end);
200                }
201            }
202        }
203    }
204};
205
206}
207
208#endif
Note: See TracBrowser for help on using the browser.