Subversion Repositories DIN Is Noise

Rev

Rev 1370 | Rev 1558 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* mesh.cc
* DIN Is Noise is copyright (c) 2006-2020 Jagannathan Sampath
* 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 <string.h>

#include <fstream>
using namespace std;

mesh::mesh () {
  num_polys = 0;
  rnd<float> rd (0.0f, 1.0f);
  r = rd (); g = rd (); b = rd ();
}

void mesh::destroy () {
  if (gl_pts) delete[] gl_pts;
}

void mesh::add_poly (drone* d0, drone* d1, drone* d2, drone* 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];
    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 () {
  // draw drone mesh
  int m = 0, n = 0;

  // run thru polygons of the mesh
  for (poly_iterator i = polys.begin (), j = polys.end (); i != j; ++i) {
    poly& p = *i;
    for (int j = 0; j < 4; ++j) { // each polygon contains 4 drones
      drone* pd = p.drones[j];
      // add drone position to draw below
      gl_pts[m++]= pd->sx;
      gl_pts[m++]= pd->y;
      ++n;
    }
  }

  // draw the polygons
  glColor4f (r, g, b, 0.1f);
  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  glVertexPointer (2, GL_INT, 0, gl_pts);
  glDrawArrays (GL_QUADS, 0, n); // draw filled polygons

  glColor4f (1, 1, 1, 1);
  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
  glVertexPointer (2, GL_INT, 0, gl_pts);
  glDrawArrays (GL_QUADS, 0, n); // draw polygon outlines
  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);

}

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 int [_2rowcol];
    meshd.resize (rowcol);
    n_meshp = rowcol;
  }
  memset (meshp, 0, _2rowcol * sizeof (int));
}

void mesh_data::gen_mesh_pts (const box<int>& 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 (int& x, int& 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) {

  int 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) {
    int x = md->meshp[k];
    int y = md->meshp[k+1];
    int 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 ();

}