2015-10-15 63 views
1

如何上下移动物体并使其在碰到屋顶和底部时变形?如何沿y轴平移球体(它只是上升,所以不会翻译下来)以及如何变形

我已经创建了一个球体,它通过沿y轴平移而无限旋转和移动,但现在我不得不将它向下移动,并且当它碰撞到底部时我想要它变形,现在我的问题是: ( 1)我如何让我的球体在y轴上上下移动? (2)如何在接触顶部时变形?并在上下移动的过程中恢复与顶部或底部完成接触相同的形状。

我的旋转球是(我按照第11课上的Git枢纽教程这个链接https://github.com/gpjt/webgl-lessons/blob/master/lesson11/index.html上)代码:

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); 

完整的功能是:

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); 

     } 

怎么在这个加代码,它将旋转并且必须接触顶部和底部(letssay,距离y轴中心250和-250处,因为运动必须沿着y轴) 以及如何使其变形当球体在上升时触及250,并且-250 wh如果球体与顶部或底部之间的接触完成,立即恢复并立即恢复,并且该过程应该无限重复。

编辑:

在这个问题上moonVertexIndexBuffer包含广场上打勾功能顶点。 这是我initfuffer功能

function initBuffers(latitudeBands, longitudeBands) 
     {   
      var radius = 1; 
      var vertexPositionData = []; 
      var normalData = []; 
      var textureCoordData = []; 
      for (var latNumber = 0; latNumber <= latitudeBands; latNumber++) 
      { 
       var theta = latNumber * Math.PI/latitudeBands; 
       var sinTheta = Math.sin(theta); 
       var cosTheta = Math.cos(theta); 
       for (var longNumber = 0; longNumber <= 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 < latitudeBands; latNumber++) { 
       for (var longNumber = 0; longNumber < 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); 

     } 

这是我的顶点着色器:

<script id="shader-vs" type="x-shader/x-vertex"> 
     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; 
     } 
     } 
    </script> 

这是initshaders功能

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"); 
     } 

**我无法理解如何将它移因为球体是由正方形构成的(取决于在initBuffers()中传递的纬度和经度func(因为我们有一个数组中的所有方块) )**

我的尝试是这样的(但球体只是无限上升,永远不会回落,如何把它)?

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 
      ]; 
     } 

EDIT2: 在顶点着色器我保持一致的建议是这样的::我的缩放变形,第一个答案后尝试

<script id="shader-vs" type="x-shader/x-vertex"> 
     uniform vec4 uScaleY; 
     void main(void) { 
     gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); 
     } 
     } 
    </script> 

而且在initshader()我做到这一点:

shaderProgram.uScaleYAttribute = gl.getUniformLocation(shaderProgram, "uScaleY"); 

在setuniform我这样做:

var yScale =[0,1,0]; 
    function setMatrixUniforms() 
    { 
      gl.uniformMatrix4fv(shaderProgram.uScaleYAttribute, false, yScale); 
    } 

在我的蜱()我尝试这样做:

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 > maxY || moonPosY < (-maxY)) 
     { 
      translate[1] *= -1; 
     } 

     var maxDiff = 0.05; 
     var minDiff = 0.01; 
     var diff = Math.abs(moonPosY - maxY); 

     if (diff < maxDiff)//sphere when go up 
     { 
      yScale = 1 - (minDiff - diff) * 0.1; 
     } 
      /* 
     else if (moonPosY > (-maxDiff)) // scaling when sphere come down 
     { 
      yScale = 1 - (minDiff - diff) * 0.1; 
     } 
     */ 
     gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0); 

而且比例不沿y轴变形工作,同时向上和向下的顶部和底部,什么球的触摸我的代码错了?

回答

1

更改您的tick,以便跟踪总翻译并反转满足阈值时使用的翻译矢量。

它会是这样的:

var maxY = 100; 
var moonPosY = moonRotationMatrix[/*row*/ 3 * 4 + /*col*/ 1]; 

if (moonPosY < maxY || moonPosY < (-maxY)) { 
    translation = translation.map(a => -a); 
    // or simply 
    // translation[1] *= -1; 
    // if you want to reverse it just on Y axis 
} 

使其变形,这取决于你想要的变形,但如果你只是想壁球沿Y轴,您可以添加一个统一的,以你的顶点着色器的Y规模和填充类似的东西:

var yScale = 1; 
var maxDiff = 10; 

var diff = Math.abs(moonPosY - maxY); 

if (diff < maxDiff) { 
    yScale = 1 - (minDiff - diff) * 0.1; 
} 
+0

谢谢你的上下运动,它是像天堂工作:)。为变形,我正在尝试你的逻辑,因为它的作品,我会标记你的答案,直到然后请求生存+1与你的答案..再次感谢:) – struggling

+0

请参阅编辑的问题,变形不工作,我已更新我的代码,我无法知道我做错了什么,我试着回顾一下你的方法。你能否让我知道我做错了什么,请相应地更新你的答案,以便我将你标记为答案(第一部分为我工作,但不是第二部分) – struggling

+0

又是什么样的这个minDiff?我也无法理解你的第二个答案的逻辑,实际上我想在撞墙时像球一样变形。 – struggling

相关问题