Rev 2097 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* mesh.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/
#include "mesh.h"
#include "drone.h"
#include "dingl.h"
#include "random.h"
#include "container.h"
#include "vector2d.h"
#include "console.h"
#include <string.h>
using namespace std;
mesh::mesh () {
num_polys = 0;
r = g = b = 0.0f;
}
void mesh::destroy () {
if (gl_pts) delete[] gl_pts;
if (clr) delete[] clr;
}
void mesh::add_poly (drone* d0, drone* d1, drone* d2, drone* d3) {
if (d0 && d1 && d2 && d3) {
++num_polys;
polys.push_back (poly (d0, d1, d2, d3));
int np = num_polys * 4;
if (np > n_glpts) {
if (gl_pts) delete[] gl_pts;
gl_pts = new int [2 * np];
if (clr) delete[] clr;
clr = new float [4 * np];
n_glpts = np;
}
}
}
void mesh::remove_poly (drone* pd) {
for (poly_iterator i = polys.begin (), j = polys.end (); i != j;) {
poly& pi = *i;
for (int k = 0; k < 4; ++k) {
if (pi.drones[k] == pd) {
i = polys.erase (i);
j = polys.end ();
--num_polys;
goto erased;
}
}
++i;
erased:
;
}
}
void mesh::draw () {
int c = 0, m = 0, n = 0;
for (poly_iterator i = polys.begin (), j = polys.end (); i != j; ++i) {
poly& p = *i;
for (int j = 0; j < 4; ++j) {
drone* pd = p.drones[j];
gl_pts[m++]= pd->sx;
gl_pts[m++]= pd->y;
clr[c++]=pd->r * pd->gab.amount;
clr[c++]=pd->g * pd->gab.amount;
clr[c++]=pd->b * pd->gab.amount;
clr[c++]=0.25f * pd->fdr.amount;
}
n += 4;
}
// draw the polygons
glEnableClientState (GL_COLOR_ARRAY);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glColorPointer (4, GL_FLOAT, 0, clr);
glVertexPointer (2, GL_INT, 0, gl_pts);
glDrawArrays (GL_QUADS, 0, n); // filled polygons
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glColorPointer (4, GL_FLOAT, 0, clr);
glVertexPointer (2, GL_INT, 0, gl_pts);
glDrawArrays (GL_QUADS, 0, n); // polygon outlines
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisableClientState (GL_COLOR_ARRAY);
}
mesh_data::mesh_data () : meshp(0) {
clear ();
}
void mesh_data::clear () {
mesh = 0;
rows = cols = 0;
row = col = 0;
rowcol = 0;
if (meshp) delete[] meshp;
meshp = 0;
n_meshp = 0;
drone_pend = 0;
drones_per_pend = 2;
apply_to_am_bpm = 1;
apply_to_fm_bpm = 1;
meshd.clear ();
orderer = 0;
order.clear ();
}
mesh_data::~mesh_data () {
if (meshp) delete[] meshp;
}
void mesh_data::set_mesh (int m, int r, int c) {
mesh = m;
rows = r;
cols = c;
rowcol = rows * cols;
int _2rowcol = 2 * rowcol;
if (rowcol > n_meshp) {
if (meshp) delete[] meshp;
meshp = new float [_2rowcol];
meshd.resize (rowcol);
n_meshp = rowcol;
}
memset (meshp, 0, _2rowcol * sizeof (float));
}
void mesh_data::gen_mesh_pts (const box<float>& region) {
if (mesh) {
float rl = (region.right - region.left);
float bt = (region.top - region.bottom);
int cols_1 = cols - 1, rows_1 = rows - 1;
col = rl * 1.0f / cols_1;
row = bt * 1.0f / rows_1;
float x, y = region.bottom;
int p = 0;
for (int i = 0; i < rows; ++i) {
x = region.left;
for (int j = 0; j < cols; ++j) {
meshp[p++] = x;
meshp[p++] = y;
x += col;
}
y += row;
}
}
}
void mesh_data::order_order () {
order.resize (rowcol);
if (orderer)
(*orderer)(order, this);
else {
ascending_rows_orderer asc;
asc (order);
}
}
void ascending_rows_orderer::operator() (std::vector<int>& order, mesh_data* md) {
for (int i = 0, j = order.size (); i < j; ++i) order[i] = i;
}
void descending_rows_orderer::operator () (std::vector<int>& order, mesh_data* md) {
for (int j = md->rows - 1, o = 0; j > -1; --j) {
int k = j * md->cols;
for (int i = 0; i < md->cols; ++i) order[o++]=k+i;
}
}
void ascending_cols_orderer::operator() (std::vector<int>& order, mesh_data* md) {
for (int i = 0, o = 0; i < md->cols; ++i) {
for (int j = 0; j < md->rows; ++j) {
int k = j * md->cols + i;
order[o++]=k;
}
}
}
void descending_cols_orderer::operator () (std::vector<int>& order, mesh_data* md) {
for (int i = 0, o = 0; i < md->cols; ++i) {
for (int j = md->rows - 1; j > -1; --j) {
int k = j * md->cols + i;
order[o++]=k;
}
}
}
void random_orderer::operator () (std::vector<int>& order, mesh_data* md) {
ascending_rows_orderer asc;
asc (order);
std::vector<int> orig_order = order;
int n = order.size (), m = n;
rnd<int> r;
for (int i = 0; i < n; ++i) {
r.set (0, m-1);
int j = r();
order[i] = orig_order[j];
erase_id (orig_order, j);
--m;
}
}
proximity_orderer::proximity_orderer (int so) {
sort_opt = so;
}
void proximity_orderer::get_xy (float& x, float& y, int m, int n, mesh_data* md) {
int p = m * md->cols + n;
int _2p = 2 * p;
x = md->meshp[_2p];
y = md->meshp[_2p+1];
}
void proximity_orderer::operator () (std::vector<int>& order, mesh_data* md) {
float px, py; get_xy (px, py, ROW, COL, md);
v_dist_id.resize (md->rowcol);
for (int i = 0, j = md->rowcol, k = 0; i < j; ++i, k += 2) {
float x = md->meshp[k];
float y = md->meshp[k+1];
double d2 = magnitude2 (px, py, x, y);
dist_id& did = v_dist_id[i];
did.d2 = d2;
did.id = i;
}
if (sort_opt == NEAREST)
sort (v_dist_id.begin (), v_dist_id.end (), asc);
else
sort (v_dist_id.begin (), v_dist_id.end (), desc);
for (int i = 0, j = order.size (); i < j; ++i) order[i]=v_dist_id[i].id;
v_dist_id.clear ();
}