title: How to translate the sphere along y-axis (it just go up, so not come down on translation) and how to deform
body: <p>how to move an object in up and down and make it deform when it touch the roof and bottom ? </p>
  
  <p>I have created a sphere which rotates and moves just up infinitely by translating along y-axis but now i have to move it down and i want it to deform when it collide up and bottom, Now my question are:
    (1) how can i make my sphere move up and down on y axis ?
    (2) How to deform when it touch the top ? and recover same shape back as the contact is finished with top or bottom while moving up and down.</p>
  
  <p>My code for rotating sphere is(I have followed Lesson 11 on Git Hub tutorials on this link <a href="https://github.com/gpjt/webgl-lessons/blob/master/lesson11/index.html" rel="nofollow">https://github.com/gpjt/webgl-lessons/blob/master/lesson11/index.html</a>):</p>
  
  <pre><code> var newRotationMatrix = mat4.create();
          mat4.identity(newRotationMatrix);          
          mat4.rotate(newRotationMatrix, degToRad(2 / 10), [0, 1, 0]);
          mat4.multiply(newRotationMatrix, [1,0,0], moonRotationMatrix);
          gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
  </code></pre>
  
  <p>The full function is :</p>
  
  <pre><code>function tick()
          {
              requestAnimFrame(tick);
              gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
              gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
              mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
  
              gl.uniform1i(shaderProgram.useLightingUniform, false);
              mat4.identity(mvMatrix);
              mat4.translate(mvMatrix, [0, 0, -6]);
              mat4.multiply(mvMatrix, moonRotationMatrix);
              gl.activeTexture(gl.TEXTURE0);
              gl.bindTexture(gl.TEXTURE_2D, moonTexture);
              gl.uniform1i(shaderProgram.samplerUniform, 0);
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
              gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, moonVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer);
              gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, moonVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer);
              gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, moonVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
              gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
              setMatrixUniforms();
  
            /*rotation part is below*/
              var newRotationMatrix = mat4.create();
              mat4.identity(newRotationMatrix);          
              mat4.rotate(newRotationMatrix, degToRad(2 / 10), [0, 1, 0]);
              mat4.multiply(newRotationMatrix, [1,0,0], moonRotationMatrix);
              gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
  
          }
  </code></pre>
  
  <p>What to add in this code that such that it will rotate and must touch top and bottom (letssay which are at the distance of 250 and -250 fromn the center along y-axis-as the motion has to be along y-axis) 
  and how to deform it when the sphere touches 250 while going up  and -250 whil going down and recover immediately as the contact between the sphere and top or bottom is finished, and this process should repeat infinitely.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>In this question moonVertexIndexBuffer contains the vertex of square in the tick function. 
  This my initfuffer function</p>
  
  <pre><code>function initBuffers(latitudeBands, longitudeBands)
          {           
              var radius = 1;
              var vertexPositionData = [];
              var normalData = [];
              var textureCoordData = [];
              for (var latNumber = 0; latNumber &lt;= latitudeBands; latNumber++)
              {
                  var theta = latNumber * Math.PI / latitudeBands;
                  var sinTheta = Math.sin(theta);
                  var cosTheta = Math.cos(theta);
                  for (var longNumber = 0; longNumber &lt;= longitudeBands; longNumber++)
                  {
                      var phi = longNumber * 2 * Math.PI / longitudeBands;
                      var sinPhi = Math.sin(phi);
                      var cosPhi = Math.cos(phi);
                      var x = cosPhi * sinTheta;
                      var y = cosTheta;
                      var z = sinPhi * sinTheta;
                      var u = 1 - (longNumber / longitudeBands);
                      var v = 1 - (latNumber / latitudeBands);
                      normalData.push(x);
                      normalData.push(y);
                      normalData.push(z);
                      textureCoordData.push(u);
                      textureCoordData.push(v);
                      vertexPositionData.push(radius * x);
                      vertexPositionData.push(radius * y);
                      vertexPositionData.push(radius * z);                   
                  }
              }
              alert("vertexPositionData:" + vertexPositionData);
              var indexData = [];
              for (var latNumber = 0; latNumber &lt; latitudeBands; latNumber++) {
                  for (var longNumber = 0; longNumber &lt; longitudeBands; longNumber++) {
                      var first = (latNumber * (longitudeBands + 1)) + longNumber;
                      var second = first + longitudeBands + 1;
                      indexData.push(first);
                      indexData.push(second);
                      indexData.push(first + 1);
                      indexData.push(second);
                      indexData.push(second + 1);
                      indexData.push(first + 1);
                      //console.log("four points for iteration" + latNumber, +longNumber + " are " + "1: " + first + "2 :" + (first + 1) + "3: " + (second) + "4 :" + (second + 1));
                  }
              }
              moonVertexNormalBuffer = gl.createBuffer();
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer);
              gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normalData), gl.STATIC_DRAW);
              moonVertexNormalBuffer.itemSize = 3;
              moonVertexNormalBuffer.numItems = normalData.length / 3;
  
              moonVertexTextureCoordBuffer = gl.createBuffer();
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer);
              gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordData), gl.STATIC_DRAW);
              moonVertexTextureCoordBuffer.itemSize = 2;
              moonVertexTextureCoordBuffer.numItems = textureCoordData.length / 2;
                         ///
              moonVertexPositionBuffer = gl.createBuffer();
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
              gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), gl.STATIC_DRAW);
              moonVertexPositionBuffer.itemSize = 3;
              moonVertexPositionBuffer.numItems = vertexPositionData.length / 3;
  
              moonVertexIndexBuffer = gl.createBuffer();
              gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
              gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), gl.DYNAMIC_DRAW);
              moonVertexIndexBuffer.itemSize = 1;
              moonVertexIndexBuffer.numItems = indexData.length;
          }
  
          function tick()
          {
              requestAnimFrame(tick);
              gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
              gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
              mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
              // var lighting = false;
              gl.uniform1i(shaderProgram.useLightingUniform, false);
  
              /*I removed some part here */
  
              mat4.identity(mvMatrix);
              mat4.translate(mvMatrix, [0, 0, -6]);
              mat4.multiply(mvMatrix, moonRotationMatrix);
              gl.activeTexture(gl.TEXTURE0);
              gl.bindTexture(gl.TEXTURE_2D, moonTexture);
              gl.uniform1i(shaderProgram.samplerUniform, 0);
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
              gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, moonVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer);
              gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, moonVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
              gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer);
              gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, moonVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
              gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
              setMatrixUniforms();
  
              var newRotationMatrix = mat4.create();
              mat4.identity(newRotationMatrix);
              mat4.rotate(newRotationMatrix, degToRad(2 / 10), [0, 1, 0], newRotationMatrix);
              mat4.multiply(newRotationMatrix, moonRotationMatrix, moonRotationMatrix);
  
              gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
  
          }
  </code></pre>
  
  <p>This is my vertex shader:</p>
  
  <pre><code> &lt;script id="shader-vs" type="x-shader/x-vertex"&gt;
          attribute vec3 aVertexPosition;
          attribute vec3 aVertexNormal;
          attribute vec2 aTextureCoord;
          uniform mat4 uMVMatrix;
          uniform mat4 uPMatrix;
          uniform mat3 uNMatrix;
          uniform vec3 uAmbientColor;
          uniform vec3 uLightingDirection;
          uniform vec3 uDirectionalColor;
          uniform bool uUseLighting;
          varying vec2 vTextureCoord;
          varying vec3 vLightWeighting;
          void main(void) {
          gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
          vTextureCoord = aTextureCoord;
          if (!uUseLighting) {
          vLightWeighting = vec3(1.0, 1.0, 1.0);
          } else {
          vec3 transformedNormal = uNMatrix * aVertexNormal;
          float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
          vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
          }
          }
      &lt;/script&gt;
  </code></pre>
  
  <p>And this is initshaders function</p>
  
  <pre><code> function initShaders()
          {
              var fragmentShader = getShader(gl, "shader-fs");
              var vertexShader = getShader(gl, "shader-vs");
              shaderProgram = gl.createProgram();
              gl.attachShader(shaderProgram, vertexShader);
              gl.attachShader(shaderProgram, fragmentShader);
              gl.linkProgram(shaderProgram);
              if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                  alert("Could not initialise shaders");
              }
              gl.useProgram(shaderProgram);
              shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
              gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
              shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
              gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
              shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
              gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
              shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
              shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
              shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
              shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
              shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
              shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
              shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection");
              shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor");
          }
  </code></pre>
  
  <p>**I am not able to understand how to move it up and down infinitely(translate it along y axis) as we have all the squares in an array, because sphere is made of squares (depending upon latitude and longitude passed in initBuffers() function)  **</p>
  
  <p><strong>MY try is this (but sphere just go up infinitely, never come back down, how to bring it down)?</strong></p>
  
  <pre><code>   var translation = [0, 0.5,0];
   function tick()
          {
            ....//I am elminating the code which was shown previously
            var translationMatrix = makeTranslation(translation[0], translation[1], translation[2]);
              mat4.multiply(moonRotationMatrix, translationMatrix, moonRotationMatrix);
          }
   function makeTranslation(tx, ty, tz) {
  
              return [
                 1, 0, 0, 0,
                 0, 1, 0, 0,
                 0, 0, 1, 0,
                 tx, ty, tz, 1
              ];
          }
  </code></pre>
  
  <p><strong>EDIT2: My try for scaling for deformation, after the first answer :</strong>
  In the vertex shader i kept uniform as suggested like this:</p>
  
  <pre><code> &lt;script id="shader-vs" type="x-shader/x-vertex"&gt;
          uniform  vec4 uScaleY;
          void main(void) {
          gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
           }
          }
      &lt;/script&gt;
  </code></pre>
  
  <p>And in initshader() i do this :</p>
  
  <pre><code>shaderProgram.uScaleYAttribute = gl.getUniformLocation(shaderProgram, "uScaleY");
  </code></pre>
  
  <p>In setuniform i do this :</p>
  
  <pre><code>var yScale =[0,1,0];
    function setMatrixUniforms()
    {
              gl.uniformMatrix4fv(shaderProgram.uScaleYAttribute, false, yScale);
    }
  </code></pre>
  
  <p>And in my tick() i try to do this :</p>
  
  <pre><code>  var newRotationMatrix = mat4.create();
          mat4.identity(newRotationMatrix);
          mat4.rotate(newRotationMatrix, degToRad(2 / 10), [0, 1, 0]);
          mat4.multiply(newRotationMatrix, moonRotationMatrix, moonRotationMatrix);
          translateMatrix = translation(translate[0], translate[1], translate[2]);
          mat4.multiply(moonRotationMatrix, translateMatrix,moonRotationMatrix);
          var maxY =1.5;
          var moonPosY = moonRotationMatrix[3 * 4 +1];
          if (moonPosY &gt; maxY || moonPosY &lt; (-maxY))
          {
              translate[1] *= -1;
          }
  
          var maxDiff = 0.05;
          var minDiff = 0.01;
          var diff = Math.abs(moonPosY - maxY);
  
          if (diff &lt; maxDiff)//sphere when go up
          {
              yScale = 1 - (minDiff - diff) * 0.1;
          }
              /*
          else if (moonPosY &gt; (-maxDiff)) // scaling when sphere come down
          {
              yScale = 1 - (minDiff - diff) * 0.1;
          }
          */
          gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
  </code></pre>
  
  <p>And the scaling do not work for deformation along y-axis while up and down touch of sphere at top and bottom, whats wrong in my code ?</p>