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