Package scenes

Source Code of scenes.ElasticGrid

package scenes;

import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Random;

import org.apache.log4j.Logger;

import models.Shape3D;


import codeanticode.glgraphics.*;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PGraphics;
import processing.core.PMatrix3D;
import processing.core.PVector;

import remixlab.proscene.Frame;
import remixlab.proscene.Quaternion;
import utils.ConsoleIO;
import utils.Util;
import textures.FacesLoader;
import traer.physics.Particle;
import traer.physics.ParticleSystem;
import traer.physics.Spring;

public class ElasticGrid extends Scene{
 
  static Logger logger = Logger.getLogger(ElasticGrid.class);

  ////////////////////////////////////////////
  // EL SISTEMA DE PARTICULAS
  //////////////////////////////////////////// 
  private ParticleSystem ps;
  private Particle[][] particles;
  private Spring[][] springs;

  //////////////////////////////////////////// 
  // GLModel + vertices used for construction
  // texture
  ////////////////////////////////////////////
  private GLModel grid;
  private GLTexture texture;
  private ArrayList vertices;
  private ArrayList texCoords;
  private ArrayList normals;

  ////////////////////////////////////////////
  // variables que uso en la
  // actualizacion de los vertices
  ////////////////////////////////////////////
  private float x = 0;
  private float y = 0;
  private float z = 0;

  private float u = 0;
  private float v = 0;

  private int index = 0;

  private PVector currentVertex   = new PVector(x, y, z);
  private PVector destVertex     = new PVector(x, y, z);

  ////////////////////////////////////////////
  // vectores usados para calcular las normales de los
  // triangulos
  ////////////////////////////////////////////

  private PVector a = new PVector(x, y, z);
  private PVector b = new PVector(x, y, z);
  private PVector c = new PVector(x, y, z);

  private PVector[] triangle = new PVector[3];

  private PVector normal = new PVector(0, 0, 0);

  //////////////////////////////////////////// 
  // CONFIGURACION de la grilla
  ////////////////////////////////////////////

  private int grid_Columns = 100;
  private int grid_Rows = 100;

  private int grid_HNodes = grid_Columns + 1;
  private int grid_VNodes = grid_Rows + 1;

  private float grid_width = 12;
  private float grid_height = 9;

  private float particle_drag = .5f; // 1f
  private float particle_mass = 1.09f;
  private float particle_tick = 0.09f;


  public float spring_Strengh = 5;// 3f;
  public float spring_Damp =  1; //0.5f;

  private float spring_HLength =  grid_width / grid_HNodes;
  private float spring_VLength =  grid_height / grid_VNodes;

  private boolean fixCorners = false;

  ////////////////////////////////////////////
  // varios
  ////////////////////////////////////////////

  private Random random;

 
  ////////////////////////////////////////////
  // CONSTRUCTORES
  ////////////////////////////////////////////

  /**
   * La implementacion de Scene siempre tiene que lleva como parametro un PApplet
   * Scene necesita crear un GLGraphicsOffScreen ademas de los modelos
   * y texturas
   *
   * @param parent la aplicacion sobre la cual estoy instanciando esta escena
   * @param OUTPUT_W  a que tama�o lo quiero renderear
   * @param OUTPUT_H  a que tama�o lo quiero renderear
   */

  public ElasticGrid(PApplet parent, int OUTPUT_W, int OUTPUT_H) {

    super(parent, OUTPUT_W, OUTPUT_H);
   
    random = new Random();

    ps = new ParticleSystem( 0, 0, 0, particle_drag);

    // cada particula se conecta con el de abajo y el de la derecha
    particles   = new Particle[grid_HNodes][grid_VNodes];
    springs   = new Spring[(grid_HNodes) * (grid_VNodes)][2];                             

   
   
    // creamos los puntos de la grilla
    createGrid();

    // luego creamos el modelo
    createModel();

  }

 

  public void setTexture(GLTexture texture){
   
    this.texture = texture;

    logger.info("TEXTURE: " + texture.toString());
    grid.initTexures(1);  
    grid.setTexture(0, texture);
   
    logger.info("TEXCORD SIZE: " + texCoords.size());
   
    grid.updateTexCoords(0, texCoords);

  }



  public void renderScene(){
    model(grid);
  }


  public void update(){   

    int index = 0;
    ps.tick(particle_tick);

    ///////////////////////////////////////

    for(int ix = 0; ix < grid_Rows ; ix++){
      for (int jy = 0; jy < grid_Columns ; jy++) {

        // PRIMER TRIANGULO
        // PUNTO 0

        x = particles[ix][jy].position().x();
        y = particles[ix][jy].position().y();
        z = particles[ix][jy].position().z();       

        a.set(x, y, z);

        // PUNTO 1

        x = particles[ix][jy+1].position().x();
        y = particles[ix][jy+1].position().y();
        z = particles[ix][jy+1].position().z();

        b.set(x, y, z);

        // PUNTO 2

        x = particles[ix+1][jy].position().x();
        y = particles[ix+1][jy].position().y();
        z = particles[ix+1][jy].position().z();       

        c.set(x, y, z);

        //////////////////////////////////////////////////////////////
        // CALCULAR LA NORMAL PARA EL PRIMER TRIANGULO

        triangle[0] = a;
        triangle[1] = b;
        triangle[2] = c;

        normal = getNormal(triangle);
        // normal.normalize();

        for(int i = 0 ; i < triangle.length; i++){

          ((PVector) vertices.get(index)).set(triangle[i]);
          ((PVector) normals.get(index)).set(normal);

          index++;

        }

        //////////////////////////////////////////////////////////////

        // SEGUNDO TRIANGULO
        // PUNTO 3

        x = particles[ix][jy+1].position().x();
        y = particles[ix][jy+1].position().y();
        z = particles[ix][jy+1].position().z();       


        a.set(x,y,z);       


        // PUNTO 4

        x = particles[ix+1][jy+1].position().x();
        y = particles[ix+1][jy+1].position().y();
        z = particles[ix+1][jy+1].position().z();       

        b.set(x,y,z);       

        // PUNTO 5

        x = particles[ix+1][jy].position().x();
        y = particles[ix+1][jy].position().y();
        z = particles[ix+1][jy].position().z();       


        c.set(x,y,z);       


        //////////////////////////////////////////////////////////////
        // CALCULAR LA NORMAL PARA EL SEGUNDO TRIANGULO

        triangle[0] = a;
        triangle[1] = b;
        triangle[2] = c;

        normal = getNormal(triangle);
        // normal.normalize();

        for(int i = 0 ; i < triangle.length; i++){   

          ((PVector) vertices.get(index)).set(triangle[i]);
          ((PVector) normals.get(index)).set(normal);

          index++;

        }

        //////////////////////////////////////////////////////////////

      }
    }

    grid.updateVertices(vertices);
    grid.updateNormals(normals);
  }

  private PVector getNormal (PVector[] triangle){

    /*  
     * v1 = A-B, y
     * v2 = A-C
     * y un vector perpendicular al tri�ngulo (no tiene porqu� ser �nico)
     * es el propucto cruz entre estos vectores:
     * n = (v1 x v2)
     */

    return  PVector.sub(triangle[2], triangle[1]).cross(PVector.sub(triangle[1], triangle[0]));

  }


  private void printVertex(int ix, int jy){
    System.out.print(
        "I: " +ix+ " " +
        "J: " +jy+ " " +
        "X: " +x+ " " +
        "Y: " +y+ " " +
        "Z: " +z+ " " +
        "U: " +u+ " " +
        "V: " +v);
    System.out.println();
  }


  void addVertex(float x, float y, float z, float u, float v)
  {
    PVector vert = new PVector(x, y, z);
    PVector texCoord = new PVector(u, v);
    PVector vertNorm = PVector.div(vert, vert.mag());

    vertices.add(vert);
    texCoords.add(texCoord);
    normals.add(vertNorm);
  }


  /////////////////////////////////////////////
  // FUNCIONAMIENTO DE LA GRILLA
  /////////////////////////////////////////////
 
 
  public void noiseShake(float tick, float amplification){

    for(int i = 1; i < grid_HNodes - 1; i++){
      for(int j = 1; j < grid_VNodes - 1; j++){

       
        particles[i][j].position().add(         
          0,
          0,
          amplification * ( -0.5f +  parent.noise(i * 0.07f , j * 0.07f, tick * 0.01f))
        )
      }
    }       
  }

 

  public void shake(float value){

    for(int i = 0; i < grid_HNodes; i++){
      for(int j = 0; j < grid_VNodes; j++){

        particles[i][j].velocity().add(         
            0,
            0,
            Util.map(random.nextFloat(), 0.f, 1.f, -5 * value, 5 * value)
        )
      }
    }       
  }


  public void flock(float noiseTick){
   
    parent.noiseDetail(10);
   
    for(int i = 1; i < grid_HNodes - 1; i++){
      for(int j = 1; j < grid_VNodes - 1; j++){

        float zcoord = -0.5f + parent.noise(i,j,noiseTick);

        particles[i][j].position().add(         
            0,
            0,
            zcoord * .1f
        )
      }
    }         
  }

 


  private void createGrid(){

    //////////////////////////////////////////////////
    // ESTRUCTURA GRILLA CENTRADA
    ///////////////////////////////////////////////////

    float x, y, z;

    for (int ix = 0; ix < grid_VNodes; ix++){
      for (int jy = 0; jy < grid_HNodes; jy++){            

        ///////////////////////////////////////////////////////
        // creo los puntos de la grilla
        ///////////////////////////////////////////////////////

        // para centrar la grilla
        // tengo que compensar que el numero de columnas en realidad es
        // el numero de vertices. La cantidad de columnas es el numero de vertices
        // menos 1

        x =  (-grid_width  + grid_width / grid_VNodes) / 2.f  + ix * grid_width / grid_VNodes;
        y =  (-grid_height + grid_height / grid_HNodes) / 2.f + jy * grid_height / grid_HNodes;
        z = 0.0f;

        ///////////////////////////////////////////////////////
        // sistema de particulas
        ///////////////////////////////////////////////////////

        particles[ix][jy] =  ps.makeParticle(
            particle_mass,
            x ,
            y,
            z);
      }
    }

    if(fixCorners){
      // dejo fijas las cuatro de las esquinas       
      particles[0][0].makeFixed();
      particles[0][grid_VNodes - 1].makeFixed();
      particles[grid_HNodes - 1][0].makeFixed();
      particles[grid_HNodes - 1][grid_VNodes - 1].makeFixed();
   
    }else{

      // fijo las de los costados
      for(int i = 0 ; i < grid_HNodes; i++) particles[0][i].makeFixed();
      for(int i = 0 ; i < grid_HNodes; i++) particles[grid_HNodes - 1][i].makeFixed();


      for(int i = 0 ; i < grid_VNodes; i++) particles[i][0].makeFixed();
      for(int i = 0 ; i < grid_VNodes; i++) particles[i][grid_VNodes - 1].makeFixed();
      // fijo arriba y abajo
     

    }
   
    // conecto todo
    // voy a recorrer todas las particulas teniendo la precaucion
    // de que la si llegue al borde solo conecte hacia abajo
    // o hacia la derecha segun corresponda
    // hacia abajo evitando la ultima fila porque no conecta con nada
    // hacia la derecha evitando la ultima columna porque no conecta con nada
    for (int i = 0; i < grid_HNodes ; i++){                                           
      for (int j = 0; j < grid_VNodes ; j++){                     


        // si no llegue abajo de todo
        // conecto este con el de abajo
        if(j != grid_VNodes - 1){
          springs[(i * grid_HNodes) + j][0] = ps.makeSpring(                           

              particles[i][j], particles[i][j+1],
              spring_Strengh ,
              spring_Damp,
              spring_VLength
          );
        }

        // si no llegue al borde de la derecha
        // conecto este con el de derecha
        if(i != grid_HNodes - 1){
          springs[(i * grid_HNodes) + j][1] = ps.makeSpring(                           

              particles[i][j], particles[i + 1][j],
              spring_Strengh,
              spring_Damp,
              spring_HLength
          );                           
        }
      }
    }

    // como no conecte ni la ultima fila ni la ultima columna
    // el ultimo nodo lo conecto a mano pero al reves...           
    springs[grid_HNodes - 1][0] = ps.makeSpring(                           

        particles[grid_Columns-1][grid_Rows-1], particles[grid_Columns-1][ grid_Rows - 2],
        spring_Strengh ,
        spring_Damp,
        spring_VLength
    );

    springs[(grid_Columns * grid_Rows) - 1][1] = ps.makeSpring(                           

        particles[grid_Columns-1][grid_Rows-1], particles[grid_Columns-2][ grid_Rows - 1],
        spring_Strengh ,
        spring_Damp,
        spring_HLength
    );
  }



  private void createModel(){


    vertices   = new ArrayList();
    texCoords   = new ArrayList();
    normals   = new ArrayList();

    x = 0;
    y = 0;
    z = 0;

    u = 0;
    v = 0;

    // creo los puntos que van a componer al modelo
    // para cada vertice hay una particula asociada

    for(int ix = 0; ix < grid_Rows; ix++){
      for (int jy = 0; jy < grid_Columns; jy++) {

        // PRIMER TRIANGULO
        // PUNTO 0

        x = particles[ix][jy].position().x();
        y = particles[ix][jy].position().y();
        z = particles[ix][jy].position().z();       

        u = (float) (1.0 / grid_Rows) * ix;
        v = (float) (1.0 / grid_Columns) * jy;

        addVertex(x, y, z, u, v);
        printVertex(ix, jy);

        // PUNTO 1

        x = particles[ix][jy+1].position().x();
        y = particles[ix][jy+1].position().y();
        z = particles[ix][jy+1].position().z();

        u = (float) (1.0 / grid_Rows) * ix;
        v = (float) (1.0 / grid_Columns) * (jy + 1);

        addVertex(x, y, z, u, v);
        printVertex(ix, jy);

        // PUNTO 2

        x = particles[ix+1][jy].position().x();
        y = particles[ix+1][jy].position().y();
        z = particles[ix+1][jy].position().z();       

        u = (float) (1.0 / grid_Rows) * (ix + 1);
        v = (float) (1.0 / grid_Columns) * jy;

        addVertex(x, y, z, u, v);
        printVertex(ix, jy);

        // SEGUNDO TRIANGULO
        // PUNTO 3

        x = particles[ix][jy+1].position().x();
        y = particles[ix][jy+1].position().y();
        z = particles[ix][jy+1].position().z();       

        u = (float) (1.0 / grid_Rows) * ix;
        v = (float) (1.0 / grid_Columns) * (jy + 1);

        addVertex(x, y, z, u, v);
        printVertex(ix, jy);

        // PUNTO 4

        x = particles[ix+1][jy+1].position().x();
        y = particles[ix+1][jy+1].position().y();
        z = particles[ix+1][jy+1].position().z();       

        u = (float) (1.0 / grid_Rows) * (ix + 1);
        v = (float) (1.0 / grid_Columns) * (jy + 1);

        addVertex(x, y, z, u, v);
        printVertex(ix, jy);

        // PUNTO 5

        x = particles[ix+1][jy].position().x();
        y = particles[ix+1][jy].position().y();
        z = particles[ix+1][jy].position().z();       

        u = (float) (1.0 / grid_Rows) * (ix + 1);
        v = (float) (1.0 / grid_Columns) * jy;

        addVertex(x, y, z, u, v);
        printVertex(ix, jy);

      }
    }

    // una vez que tengo todos los puntos de la grilla
    // creo el modelo

    grid = new GLModel(
        parent,
        vertices.size(),
        PConstants.TRIANGLES,
        GLModel.STATIC);

    grid.updateVertices(vertices)
   
    //Sets the normals.
    grid.initNormals();
    grid.updateNormals(normals);

    // Sets the colors of all the vertices to white.

    grid.setBlendMode(PConstants.BLEND);

    grid.setTint(255,255,255,255);


  }

}
TOP

Related Classes of scenes.ElasticGrid

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.