Package de.fhpotsdam.unfolding.texture

Source Code of de.fhpotsdam.unfolding.texture.TextureDistorter

package de.fhpotsdam.unfolding.texture;

import java.util.ArrayList;

import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PGraphics;
import processing.core.PImage;
import processing.core.PShape;
import processing.core.PVector;

public class TextureDistorter {

  public boolean mouse3DRotate = false;
  public boolean osc3DRotate = false;
  public float lightX;
  public float lightY;

  PShape meshModel;

  // Mesh parameters
  protected int meshWidth;
  protected int meshHeight;
  protected int meshStep;

  public Distorter distorter;

  // 2D grid (for 2D mesh), but each point can be 3D
  protected int uSteps;
  protected int vSteps;
  protected PVector[][] origGrid;
  protected PVector[][] distortedGrid;

  protected ArrayList<PVector> vertices;
  protected ArrayList<PVector> texCoords;
  protected ArrayList<PVector> normals;

  public TextureDistorter(PApplet p, int meshWidth, int meshHeight, int meshStep) {
    this.meshWidth = meshWidth;
    this.meshHeight = meshHeight;
    this.meshStep = meshStep;

    this.uSteps = meshWidth / meshStep + 1;
    this.vSteps = meshHeight / meshStep + 1;

    initGrids();
    createMesh(distortedGrid);

    meshModel = null;
  }

  public TextureDistorter(PApplet papplet, float width, float height, int meshStep) {
    this(papplet, (int) width, (int) height, meshStep);
  }

  public void setDistorter(Distorter distorter) {
    this.distorter = distorter;
  }

  int frameCount = 0;

  public void draw(PGraphics g, PImage texture) {
    frameCount++;
   
    // REVISIT
    // Distort by texture to extrude by pixel brightness
    distortGridByTexture(texture);

    // distortGrid();

    distortMesh();

    // createMesh(distortedGrid);
   
    if (meshModel == null) {
      // create
      meshModel = g.createShape();
      meshModel.beginShape(PConstants.TRIANGLE_STRIP);
      meshModel.texture(texture);
      for (int i = 0; i < vertices.size(); i++) {
        PVector vert = vertices.get(i);       
        PVector tcoord = texCoords.get(i);
        if (g.is3D()) {
          PVector norm = normals.get(i);
          meshModel.normal(norm.x, norm.y, norm.z);
          meshModel.vertex(vert.x, vert.y, vert.z, tcoord.x, tcoord.y);
        } else {
          meshModel.vertex(vert.x, vert.y, tcoord.x, tcoord.y);
        }       
      }
      meshModel.endShape();     
    } else {
      // update using setter methods
      meshModel.setTexture(texture);
      for (int i = 0; i < vertices.size(); i++) {
        PVector vert = vertices.get(i);      
        PVector tcoord = texCoords.get(i);
        if (g.is3D()) {
          PVector norm = normals.get(i);
          meshModel.setNormal(i, norm.x, norm.y, norm.z);
          meshModel.setVertex(i, vert.x, vert.y, vert.z);
        } else {
          meshModel.setVertex(i, vert.x, vert.y);         
        }              
        meshModel.setTextureUV(i, tcoord.x, tcoord.y);
      }
    }
   
    g.background(0);

    if (mouse3DRotate || osc3DRotate) {
      PApplet p = PAppletFactory.getInstance();

      if (showLight) {
        // Simple 3D lighting
        g.directionalLight(204, 204, 204, lightX, lightY, -1);
      }

      g.translate(400, 300);

      if (mouse3DRotate) {
        float rotX = (p.mouseX / (float) p.width - 0.5f) * 2f * PApplet.PI;
        float rotZ = (p.mouseY / (float) p.height - 0.5f) * 2f * PApplet.PI;
        g.rotateX(rotX);
        g.rotateZ(rotZ);
      } else if (osc3DRotate) {
        g.rotateX(rotX);
        g.rotateY(rotY);
        g.rotateZ(rotZ);
      }

      g.translate(-400, -300);
    }

    g.shape(meshModel);
  }

  public float rotX, rotY, rotZ;
  public boolean showLight;

  protected void initGrids() {
    origGrid = new PVector[uSteps][vSteps];
    distortedGrid = new PVector[uSteps][vSteps];

    for (int u = 0; u < uSteps; u++) {
      for (int v = 0; v < vSteps; v++) {
        origGrid[u][v] = new PVector(u * meshStep, v * meshStep, 0);
        distortedGrid[u][v] = new PVector(0, 0, 0);
      }
    }
  }

  protected void distortGridByTexture(PImage texture) {
    texture.loadPixels();
    for (int u = 0; u < uSteps; u++) {
      for (int v = 0; v < vSteps; v++) {
        int x = u * meshStep;
        int y = v * meshStep;
        int col = texture.get(x, y);
        // PApplet.println(x + "," + y + ": " + col);
        distorter.distort(origGrid[u][v], distortedGrid[u][v], col);
      }
    }
  }

  protected void distortGrid() {
    for (int u = 0; u < uSteps; u++) {
      for (int v = 0; v < vSteps; v++) {
        // distortedGrid[u][v] = distorter.distort(origGrid[u][v]);

        // FIXME Test distorting a single grid vector
        int value = (u > 30 && u < 40 && v == 21) ? 1 : 0;
        distorter.distort(origGrid[u][v], distortedGrid[u][v], value);
      }
    }
  }

  protected void createMesh(PVector[][] grid) {
    vertices = new ArrayList<PVector>();
    texCoords = new ArrayList<PVector>();
    normals = new ArrayList<PVector>();

    // create all mesh vectors (triangles)
    for (int v = 0; v < vSteps - 1; v++) {
      int lastU = 0;
      for (int u = 0; u < uSteps; u++) {
        addVertex(grid[u][v].x, grid[u][v].y, grid[u][v].z, u, v);
        addVertex(grid[u][v + 1].x, grid[u][v + 1].y, grid[u][v + 1].z, u, v + 1);
        lastU = u;
      }
      // Adds degenerate triangle to jump back to left side of grid
      addVertex(grid[lastU][v + 1].x, grid[lastU][v + 1].y, grid[lastU][v + 1].z, lastU, v + 1);
      addVertex(grid[0][v + 1].x, grid[0][v + 1].y, grid[0][v + 1].z, 0, v + 1);
    }
  }

  int index = 0;

  protected void distortMesh() {
    // Uses global index to access vertices in global lists
    index = 0;

    for (int v = 0; v < vSteps - 1; v++) {
      int lastU = 0;
      for (int u = 0; u < uSteps; u++) {
        distortVertex(distortedGrid[u][v].x, distortedGrid[u][v].y, distortedGrid[u][v].z, u, v);
        distortVertex(distortedGrid[u][v + 1].x, distortedGrid[u][v + 1].y, distortedGrid[u][v + 1].z, u, v + 1);
        lastU = u;
      }
      // Adds degenerate triangle to jump back to left side of grid
      distortVertex(distortedGrid[lastU][v + 1].x, distortedGrid[lastU][v + 1].y, distortedGrid[lastU][v + 1].z,
          lastU, v + 1);
      distortVertex(distortedGrid[0][v + 1].x, distortedGrid[0][v + 1].y, distortedGrid[0][v + 1].z, 0, v + 1);
    }
  }

  protected void distortVertex(float x, float y, float z, float u, float v) {
    PVector vert = vertices.get(index);
    vert.set(x, y, z);

    // texCoord stays the same

    PVector vertNorm = normals.get(index);
    PVector.div(vert, vert.mag(), vertNorm);

    index++;
  }

  /**
   * Adds vertex, texture coordinates, and normals.
   */
  protected void addVertex(float x, float y, float z, float u, float v) {
    PVector vert = new PVector(x, y, z);
    PVector texCoord = new PVector(u / (uSteps - 1), v / (vSteps - 1));
    PVector vertNorm = PVector.div(vert, vert.mag());
    vertices.add(vert);
    texCoords.add(texCoord);
    normals.add(vertNorm);
  }

  // protected void createMesh(PVector[][] grid) {
  // vertices = new ArrayList<PVector>();
  // texCoords = new ArrayList<PVector>();
  // normals = new ArrayList<PVector>();
  //
  // for (int v = 0; v < vSteps - 1; v++) {
  // int lastU = 0;
  // for (int u = 0; u < uSteps; u++) {
  // addVertex(grid[u][v].x, grid[u][v].y, grid[u][v].z, u, v);
  // addVertex(grid[u][v + 1].x, grid[u][v + 1].y, grid[u][v + 1].z, u, v + 1);
  // lastU = u;
  // }
  // // Adds degenerate triangle to jump back to left side of grid
  // addVertex(grid[lastU][v + 1].x, grid[lastU][v + 1].y, grid[lastU][v + 1].z, lastU, v + 1);
  // addVertex(grid[0][v + 1].x, grid[0][v + 1].y, grid[0][v + 1].z, 0, v + 1);
  // }
  // }
  //
  // /**
  // * Adds vertex, texture coordinates, and normals.
  // */
  // protected void addVertex(float x, float y, float z, float u, float v) {
  // PVector vert = new PVector(x, y, z);
  // PVector texCoord = new PVector(u / (uSteps - 1), v / (vSteps - 1));
  // PVector vertNorm = PVector.div(vert, vert.mag());
  // vertices.add(vert);
  // texCoords.add(texCoord);
  // normals.add(vertNorm);
  // }

}
TOP

Related Classes of de.fhpotsdam.unfolding.texture.TextureDistorter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.