How to link grid to image as a height map

Hi @asymmetric,

just for the sake of completness … I extended to 3D
Removed all the mouse picking stuff, as picking in 3D is another topic and would go beyond the scope here…

Cheers
— mnse

float scl = 8.;
int rows, cols;
int halfWidth;
int halfHeight;
boolean mode = true;

GridPoint[][] grid;
PImage img;

class GridPoint {
  PVector position;
  PVector oposition;
  PVector uv;
  boolean locked;
  float phase;
  public GridPoint(float x, float y, float z, float u, float v, boolean plocked) {
    position  = new PVector(x, y, z);
    oposition = position.copy();
    uv = new PVector(u, v);    
    locked = plocked;
    phase = 0;
  }

  public void reset() {
    position = oposition.copy();
  }

  // automover 
  public void move() {
    if (!locked) {
      PVector wc = new PVector(position.x/25., position.y/25.);
      position.z=25.*sin((sqrt(wc.x*wc.x + wc.y*wc.y)+phase));
      phase-=0.1;
    }
  }

  public void render() {
    pushMatrix();
    pushStyle();
    noStroke();
    if (locked)
      fill(255, 0, 0);
    else
      fill(0, 255, 0);
    translate(position.x, position.y, position.z);
    box(3.);
    popStyle();
    popMatrix();
  }
}


void setup() {
  size(800, 800, P3D);
  halfWidth=width/2;
  halfHeight=height/2;
  textureMode(NORMAL);

  rows = floor(height/scl)+1;
  cols = floor(width/scl)+1;
  grid= new GridPoint[rows][cols];
  for (int y = 0; y < rows; y++) {
    for (int x = 0; x < cols; x++) {
      float sx = x*scl;
      float sy = y*scl;
      grid[y][x] = new GridPoint(sx-halfWidth, sy-halfHeight, 0.0, sx/((cols-1)*scl), sy/((rows-1)*scl), false /*(x==0|y==0|x==cols-1||y==rows-1)*/);
    }
  } 
  img = loadImage("image.jpg");
}

void updateRandom() {
  for (int y = 0; y < rows; y ++) {
    for (int x = 0; x < cols; x++) {
      grid[y][x].move();
    }
  }
}

void draw() {
  background(0, 0, 64);
  updateRandom();
  directionalLight(255, 255, 255, 0, 0, -1);

  translate(halfWidth, halfHeight, -400.);
  rotateX(radians(55));

  noStroke();
  if (mousePressed)
    stroke(96);

  for (int y = 0; y < rows-1; y ++) {
    beginShape (TRIANGLE_STRIP); // or (TRIANGLE_STRIP),(QUAD_STRIP), 
    texture(img); // on textured mode set the texture
    // common triangle strips
    for (int x = 0; x < cols; x++) {
      GridPoint ca = grid[y][x];
      GridPoint cb = grid[y+1][x];
      GridPoint cc = grid[y][x<cols-1 ? x+1 : x-1];
      // this normal is good enough here
      PVector n = PVector.sub(cb.position, ca.position).normalize().cross(PVector.sub(cc.position, ca.position).normalize()); 
      normal(n.x, n.y, n.z);
      vertex(ca.position.x, ca.position.y, ca.position.z, ca.uv.x, ca.uv.y);     
      normal(n.x, n.y, n.z);            
      vertex(cb.position.x, cb.position.y, cb.position.z, cb.uv.x, cb.uv.y);
    }
    endShape();
  }
  if (mousePressed) {
    for (int y = 0; y < rows; y ++) {
      for (int x = 0; x < cols; x++) {
        grid[y][x].render();
      }
    }
  }
}
1 Like