1 /*
2 * mesh.cc
3 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
4 * DIN Is Noise is released under GNU Public License 2.0
5 * For more information, please visit https://dinisnoise.org/
6 */
7
8 #include "mesh.h"
9 #include "drone.h"
10 #include "dingl.h"
11 #include "random.h"
12 #include "container.h"
13 #include "vector2d.h"
14 #include "console.h"
15 #include <string.h>
16 using namespace std;
17
mesh()18 mesh::mesh () {
19 num_polys = 0;
20 r = g = b = 0.0f;
21 }
22
destroy()23 void mesh::destroy () {
24 if (gl_pts) delete[] gl_pts;
25 if (clr) delete[] clr;
26 }
27
add_poly(drone * d0,drone * d1,drone * d2,drone * d3)28 void mesh::add_poly (drone* d0, drone* d1, drone* d2, drone* d3) {
29 if (d0 && d1 && d2 && d3) {
30 ++num_polys;
31 polys.push_back (poly (d0, d1, d2, d3));
32 int np = num_polys * 4;
33 if (np > n_glpts) {
34 if (gl_pts) delete[] gl_pts;
35 gl_pts = new int [2 * np];
36 if (clr) delete[] clr;
37 clr = new float [4 * np];
38 n_glpts = np;
39 }
40 }
41 }
42
remove_poly(drone * pd)43 void mesh::remove_poly (drone* pd) {
44 for (poly_iterator i = polys.begin (), j = polys.end (); i != j;) {
45 poly& pi = *i;
46 for (int k = 0; k < 4; ++k) {
47 if (pi.drones[k] == pd) {
48 i = polys.erase (i);
49 j = polys.end ();
50 --num_polys;
51 goto erased;
52 }
53 }
54 ++i;
55 erased:
56 ;
57 }
58 }
59
draw()60 void mesh::draw () {
61 int c = 0, m = 0, n = 0;
62
63 for (poly_iterator i = polys.begin (), j = polys.end (); i != j; ++i) {
64 poly& p = *i;
65 for (int j = 0; j < 4; ++j) {
66 drone* pd = p.drones[j];
67 gl_pts[m++]= pd->sx;
68 gl_pts[m++]= pd->y;
69 clr[c++]=pd->r * pd->gab.amount;
70 clr[c++]=pd->g * pd->gab.amount;
71 clr[c++]=pd->b * pd->gab.amount;
72 clr[c++]=0.25f * pd->fdr.amount;
73 }
74 n += 4;
75 }
76
77 // draw the polygons
78 glEnableClientState (GL_COLOR_ARRAY);
79 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
80 glColorPointer (4, GL_FLOAT, 0, clr);
81 glVertexPointer (2, GL_INT, 0, gl_pts);
82 glDrawArrays (GL_QUADS, 0, n); // filled polygons
83
84 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
85 glColorPointer (4, GL_FLOAT, 0, clr);
86 glVertexPointer (2, GL_INT, 0, gl_pts);
87 glDrawArrays (GL_QUADS, 0, n); // polygon outlines
88 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
89 glDisableClientState (GL_COLOR_ARRAY);
90
91 }
92
mesh_data()93 mesh_data::mesh_data () : meshp(0) {
94 clear ();
95 }
96
clear()97 void mesh_data::clear () {
98 mesh = 0;
99 rows = cols = 0;
100 row = col = 0;
101 rowcol = 0;
102 if (meshp) delete[] meshp;
103 meshp = 0;
104 n_meshp = 0;
105
106 drone_pend = 0;
107 drones_per_pend = 2;
108 apply_to_am_bpm = 1;
109 apply_to_fm_bpm = 1;
110
111 meshd.clear ();
112 orderer = 0;
113 order.clear ();
114 }
115
~mesh_data()116 mesh_data::~mesh_data () {
117 if (meshp) delete[] meshp;
118 }
119
set_mesh(int m,int r,int c)120 void mesh_data::set_mesh (int m, int r, int c) {
121 mesh = m;
122 rows = r;
123 cols = c;
124 rowcol = rows * cols;
125 int _2rowcol = 2 * rowcol;
126 if (rowcol > n_meshp) {
127 if (meshp) delete[] meshp;
128 meshp = new float [_2rowcol];
129 meshd.resize (rowcol);
130 n_meshp = rowcol;
131 }
132 memset (meshp, 0, _2rowcol * sizeof (float));
133 }
134
gen_mesh_pts(const box<float> & region)135 void mesh_data::gen_mesh_pts (const box<float>& region) {
136 if (mesh) {
137 float rl = (region.right - region.left);
138 float bt = (region.top - region.bottom);
139 int cols_1 = cols - 1, rows_1 = rows - 1;
140 col = rl * 1.0f / cols_1;
141 row = bt * 1.0f / rows_1;
142 float x, y = region.bottom;
143 int p = 0;
144 for (int i = 0; i < rows; ++i) {
145 x = region.left;
146 for (int j = 0; j < cols; ++j) {
147 meshp[p++] = x;
148 meshp[p++] = y;
149 x += col;
150 }
151 y += row;
152 }
153 }
154 }
155
order_order()156 void mesh_data::order_order () {
157 order.resize (rowcol);
158 if (orderer)
159 (*orderer)(order, this);
160 else {
161 ascending_rows_orderer asc;
162 asc (order);
163 }
164 }
165
operator ()(std::vector<int> & order,mesh_data * md)166 void ascending_rows_orderer::operator() (std::vector<int>& order, mesh_data* md) {
167 for (int i = 0, j = order.size (); i < j; ++i) order[i] = i;
168 }
169
170
operator ()(std::vector<int> & order,mesh_data * md)171 void descending_rows_orderer::operator () (std::vector<int>& order, mesh_data* md) {
172 for (int j = md->rows - 1, o = 0; j > -1; --j) {
173 int k = j * md->cols;
174 for (int i = 0; i < md->cols; ++i) order[o++]=k+i;
175 }
176 }
177
operator ()(std::vector<int> & order,mesh_data * md)178 void ascending_cols_orderer::operator() (std::vector<int>& order, mesh_data* md) {
179 for (int i = 0, o = 0; i < md->cols; ++i) {
180 for (int j = 0; j < md->rows; ++j) {
181 int k = j * md->cols + i;
182 order[o++]=k;
183 }
184 }
185 }
186
operator ()(std::vector<int> & order,mesh_data * md)187 void descending_cols_orderer::operator () (std::vector<int>& order, mesh_data* md) {
188 for (int i = 0, o = 0; i < md->cols; ++i) {
189 for (int j = md->rows - 1; j > -1; --j) {
190 int k = j * md->cols + i;
191 order[o++]=k;
192 }
193 }
194 }
195
operator ()(std::vector<int> & order,mesh_data * md)196 void random_orderer::operator () (std::vector<int>& order, mesh_data* md) {
197
198 ascending_rows_orderer asc;
199 asc (order);
200 std::vector<int> orig_order = order;
201
202 int n = order.size (), m = n;
203 rnd<int> r;
204 for (int i = 0; i < n; ++i) {
205 r.set (0, m-1);
206 int j = r();
207 order[i] = orig_order[j];
208 erase_id (orig_order, j);
209 --m;
210 }
211
212 }
213
proximity_orderer(int so)214 proximity_orderer::proximity_orderer (int so) {
215 sort_opt = so;
216 }
217
get_xy(float & x,float & y,int m,int n,mesh_data * md)218 void proximity_orderer::get_xy (float& x, float& y, int m, int n, mesh_data* md) {
219 int p = m * md->cols + n;
220 int _2p = 2 * p;
221 x = md->meshp[_2p];
222 y = md->meshp[_2p+1];
223 }
224
operator ()(std::vector<int> & order,mesh_data * md)225 void proximity_orderer::operator () (std::vector<int>& order, mesh_data* md) {
226
227 float px, py; get_xy (px, py, ROW, COL, md);
228 v_dist_id.resize (md->rowcol);
229 for (int i = 0, j = md->rowcol, k = 0; i < j; ++i, k += 2) {
230 float x = md->meshp[k];
231 float y = md->meshp[k+1];
232 double d2 = magnitude2 (px, py, x, y);
233 dist_id& did = v_dist_id[i];
234 did.d2 = d2;
235 did.id = i;
236 }
237
238 if (sort_opt == NEAREST)
239 sort (v_dist_id.begin (), v_dist_id.end (), asc);
240 else
241 sort (v_dist_id.begin (), v_dist_id.end (), desc);
242
243 for (int i = 0, j = order.size (); i < j; ++i) order[i]=v_dist_id[i].id;
244 v_dist_id.clear ();
245
246 }
247