Movimiento del Sólido



Con el objeto creado anteriormente se pretende trasladar su posición según donde un usuario haga click. Esto se logra transformado las posiciones del centro del objeto a las dadas por el click tanto en X y Y.

El codigo de este ejercicio seria:

var rotacionObj = 1.0;
 var posX =0.5;
 var posY =0;

main();

function main() {
  const canvas = document.querySelector('#glcanvas3');
  const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');

  if (!gl) {
    alert('Unable to initialize WebGL. Your browser or machine may not support it.');
    return;
  }

  const vsSource = `
    attribute vec4 aVertexPosition;
    attribute vec4 aVertexColor;
    uniform mat4 uModelViewMatrix;
    uniform mat4 uProjectionMatrix;
    varying lowp vec4 vColor;
    void main(void) {
      gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
      vColor = aVertexColor;
    }`
  ;
  const fsSource = `
    varying lowp vec4 vColor;
    void main(void) {
      gl_FragColor = vColor;
    }
  `;

  const shaderProgram = initShaderProgram(gl, vsSource, fsSource);

  const programInfo = {
    program: shaderProgram,
    attribLocations: {
      vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
      vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'),
    },
    uniformLocations: {
      projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
      modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
    },
  };

  const buffers = initBuffers(gl);

  var then = 0;

  function render(now) {    
    now *= 0.009;
    const deltaTime = now - then;
    then = now;
    gl.canvas.addEventListener("mousedown", function (event){
    posX = 2*event.clientX/gl.canvas.width-1;
    posY = 2*(gl.canvas.height-event.clientY)/gl.canvas.height-1;
    });  
    
      drawScene(gl, programInfo, buffers, deltaTime, posX, posY);

      requestAnimationFrame(render);
  }
  
  drawScene(gl, programInfo, buffers, 0, 0, 0);
  requestAnimationFrame(render);
}

function initBuffers(gl) {
  
  const verticesBuffer = gl.createBuffer();

  gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer);
  
  const vertices = [
    
   -1.0, -1.0,  1.0,
    0.0,  1.0,  0.0,  1.0,    
    
    1.0, -1.0,  1.0,
    1.0,  0.0,  0.0,  1.0,   
    
    0.0,  2.0,  0.0,
    0.0,  0.0,  1.0,  1.0,    
    
    1.0, -1.0, -1.0,
    1.0,  1.0,  0.0,  1.0,    
    
   -1.0, -1.0, -1.0,
    1.0,  1.0,  1.0,  1.0,  
    
    0.0,  -2.0,  0.0,
    0.0,  0.0,  1.0,  1.0,
        
  ];

  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
  
  const indexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);

  const indices = [            
    0,  1,  2,  
    3,  4,  2,
    0,  1,  5,
    3,  4,  0,
    5,   
  ];

  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
      new Uint16Array(indices), gl.STATIC_DRAW);

  return {
    vertices: verticesBuffer,
    indices: indexBuffer,
  };
}

function drawScene(gl, programInfo, buffers, deltaTime, xMouse, yMouse) {
  gl.viewport(0, 0, gl.canvas.clientWidth, gl.canvas.clientHeight);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clearDepth(1.0);              
  gl.enable(gl.DEPTH_TEST);
  gl.depthFunc(gl.LEQUAL);  

  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  
  const fieldOfView = 45 * Math.PI / 180;   // in radians
  const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
  const zNear = 0.1;
  const zFar = 100.0;
  const projectionMatrix = mat4.create();
  const zObject = 25;
  
  mat4.perspective(projectionMatrix,
                   fieldOfView,
                   aspect,
                   zNear,
                   zFar);
  
  const modelViewMatrix = mat4.create();
  
  mat4.translate(modelViewMatrix,    
                 modelViewMatrix,    
                 [zObject*Math.tan(45/2)*xMouse, zObject*Math.tan(45/2)*yMouse, -zObject]);  
  
  mat4.rotate(modelViewMatrix, 
              modelViewMatrix, 
              rotacionObj * .2,
              [0,1,0]);      

  {
    const numComponentsPosition = 3;
    const numComponentsColors = 4;
    const type = gl.FLOAT;
    const sizeFloat = 4;
    const normalize = false;
    const positionOffset = 0;
    const colorOffset = numComponentsPosition * sizeFloat;
    const stride  = (numComponentsPosition + numComponentsColors) * sizeFloat;
    
    gl.bindBuffer(gl.ARRAY_BUFFER, buffers.vertices);
    gl.vertexAttribPointer(
        programInfo.attribLocations.vertexPosition,
        numComponentsPosition,
        type,
        normalize,
        stride,
        positionOffset);
    gl.enableVertexAttribArray(
        programInfo.attribLocations.vertexPosition);
       
    gl.vertexAttribPointer(
        programInfo.attribLocations.vertexColor,
        numComponentsColors,
        type,
        normalize,
        stride,
        colorOffset);
    gl.enableVertexAttribArray(
        programInfo.attribLocations.vertexColor);
    
  }
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices);
  gl.useProgram(programInfo.program);
  gl.uniformMatrix4fv(
      programInfo.uniformLocations.projectionMatrix,
      false,
      projectionMatrix);
  gl.uniformMatrix4fv(
      programInfo.uniformLocations.modelViewMatrix,
      false,
      modelViewMatrix);

  {
    const vertexCount = 13;
    gl.drawElements(gl.TRIANGLE_STRIP, vertexCount, gl.UNSIGNED_SHORT, 0);
  }
  rotacionObj += deltaTime;
  }
function initShaderProgram(gl, vsSource, fsSource) {
  const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
  const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);

  const shaderProgram = gl.createProgram();
  gl.attachShader(shaderProgram, vertexShader);
  gl.attachShader(shaderProgram, fragmentShader);
  gl.linkProgram(shaderProgram);

  if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
    return null;
  }

  return shaderProgram;
}
function loadShader(gl, type, source) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}


Acá vemos que se agrego un evento de mouseDown en donde se toman las coordenadas del click dentro del viewport y se actualizan las variables posX y posY definidas al comienzo con un valor de 0. Luego de tener dichas coordenadas, se procede a renderizar la nueva escena creada con la posición actualizada del objeto en cuestión.

function render(now) {    
    now *= 0.009;
    const deltaTime = now - then;
    then = now;
    gl.canvas.addEventListener("mousedown", function (event){
    posX = 2*event.clientX/gl.canvas.width-1;
    posY = 2*(gl.canvas.height-event.clientY)/gl.canvas.height-1;
    });  
    
      drawScene(gl, programInfo, buffers, deltaTime, posX, posY);

      requestAnimationFrame(render);
  }

Finalmente si se desea interactuar con el ejercicio Haz Click Aqui! y para ver la plantilla de seguimiento Visita este Link!

Comentarios

Entradas populares