Subversion Repositories DIN Is Noise

Rev

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

/*
* gravity.cc
* DIN Is Noise is copyright (c) 2006-2020 Jagannathan Sampath
* For more information, please visit https://dinisnoise.org/
*/


#include "gravity.h"
#include "font.h"
#include "vector2d.h"
#include "drone.h"
#include "console.h"
#include <fstream>
using namespace std;

extern int mousex, mouseyy;
extern void make_arrow (float* A, int k, float x, float y, float ux, float uy, float vx, float vy, float u, float v);

gravity_t::gravity_t () {
  handle_size = 7;
  strength = 0;
  hitt = NOTHING;
  lmb_clicked = 0;
  tracked_drone = 0;
  mag0 = 50;
  mag = 0;
  keep_size = 0;
}

void gravity_t::calc (int calc_mag) {
  direction (base2tip, base, tip);
  perpendicular (p_base2tip, base2tip);
  bottomleft (base.x - handle_size, base.y - handle_size);
  topright (base.x + handle_size, base.y + handle_size);
  textpos (topright.x + 7, bottomleft.y);
  gx = strength * base2tip.x; gy = strength * base2tip.y;
  gl_base[0]=bottomleft.x; gl_base[1]=bottomleft.y;
  gl_base[2]=topright.x; gl_base[3]=gl_base[1];
  gl_base[4]=gl_base[2];gl_base[5]=topright.y;
  gl_base[6]=gl_base[0];gl_base[7]=gl_base[5];
  make_arrow (gl_arrow, 0, base.x, base.y, base2tip.x, base2tip.y, p_base2tip.x, p_base2tip.y, 0.6f, 0.2f);
  if (calc_mag) mag = magnitude (base2tip);
}

void gravity_t::set (point<int>& what, int mx, int my, int calc_mag) {
  what.x = mx;
  what.y = my;
  calc (calc_mag);
}

void gravity_t::set_strength (float s) {
  strength = s;
  gx = strength * base2tip.x;
  gy = strength * base2tip.y;
}

int gravity_t::hit (const point<int>& what, int mx, int my) {
  double m = magnitude (what.x, what.y, mx, my);
  if (m <= handle_size) return 1; else return 0;
}

int gravity_t::handle_input () {
  if (is_lmb (this)) {
    if (lmb_clicked == 0) {
      lmb_clicked = 1;
      if (hitt != NOTHING) {
        hitt = NEXT_TO_NOTHING;
      } else {
        if (hit (tip, mousex, mouseyy)) {
          hitt = TIP; // edit tip
          is_lmb.tie = this;
        } else
        if (hit (base, mousex, mouseyy)) {
          hitt = BASE; // edit base
          is_lmb.tie = this;
        }
      }
    }
  } else {
    if (hitt == NOTHING); else
    if (hitt == NEXT_TO_NOTHING) {
      stop_editing ();
    } else if (hitt == TIP) { // update tip
      set (tip, mousex, mouseyy);
    } else if (hitt == BASE) { // update base
      set (tip, mousex + base2tip.x, mouseyy + base2tip.y, 0);
      set (base, mousex, mouseyy, 0);
    }
    lmb_clicked = 0;
  }
  return hitt;
}

void gravity_t::load (ifstream& file) {
  string ignore;
  int bx, by, tx, ty; file >> ignore >> bx >> by >> tx >> ty;
  set (base, bx, by);
  set (tip, tx, ty);
  file >> strength >> visible >> keep_size;
}

void gravity_t::save (ofstream& file) {
  file << "gravity " << base.x << SPC << base.y << SPC << tip.x << SPC << tip.y << SPC << strength << SPC << visible << SPC << keep_size << endl;
}

void gravity_t::draw () {
  glColor3f (1, 0.6, 0.5);
  draw_string ("Gravity", textpos.x, textpos.y);
  glVertexPointer (2, GL_INT, 0, gl_base);
  glDrawArrays (GL_LINE_LOOP, 0, 4);
  glVertexPointer (2, GL_FLOAT, 0, gl_arrow);
  glDrawArrays (GL_LINES, 0, 6);
}

void gravity_t::reset (int ks) {
  keep_size = ks;
  double m;
  if (keep_size) m = mag; else m = mag0;
  tip.x = base.x;
  tip.y = base.y - m;
  calc (0);
  mag = m;
}

void gravity_t::dir (float x, float y) {
  tip.x = base.x + mag * x;
  tip.y = base.y + mag * y;
  calc (0);
}

void gravity_t::track () {}

int gravity_t::stop_editing () {
  if (hitt != NOTHING) {
    hitt = NOTHING;
    is_lmb.clear (this);
    return 1;
  }
  return 0;
}