2

I've created a cube in WebGL. I have an animation in mind but am struggling with make it come together.

The full code is roughly 150 lns of code so here's a working sample: Working Plunkr Code

Here's a video wireframe of the animation, I'm trying to achieve: https://youtu.be/sZeBm8EM3mw

1 -The animations sets an anchor point to the bottom left of the cube.

2 -The animation scales the cube from the anchor point.

3 -The animations rotates the cube from the anchor point roughly halfway through scale.

shaders: (Vertex)

attribute vec4 coords;
attribute float pointSize;
uniform mat4 transformMatrix;
attribute vec4 colors;
varying vec4 varyingColors;
uniform mat4 perspectiveMatrix;
void main(void) {
    gl_Position = perspectiveMatrix * transformMatrix  * coords;
    gl_PointSize = pointSize;
    varyingColors = colors;
}

(Fragment)

precision mediump float;
uniform vec4 color;
varying vec4 varyingColors;
void main(void) {
    gl_FragColor = varyingColors;
}

I'm using gl-matrix to do wall the matrix transformation

Transformations would go in the draw fn and use the gl-matrix mat4.

function draw() {

  var transformMatrix = gl.getUniformLocation(shaderProgram, "transformMatrix");
  gl.uniformMatrix4fv(transformMatrix, false, matrix);
  // mat4.rotateY(matrix, matrix, 0.01); // This is example of rotations
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_BYTE, 0);
  requestAnimationFrame(draw);
}
Armeen Moon
  • 18,061
  • 35
  • 120
  • 233

1 Answers1

3

You must add what is called a "Pivot" in your transformation. The usual and simple transformation is defined as follow:

transform = scale * rotate * translate;

where:

scale =      |  rotate =    |  translate = 

Sx  0  0  0  |  Xx Xy Xz 0  |  1  0  0  0
0   Sy 0  0  |  Yx Yy Yz 0  |  0  1  0  0
0   0  Sz 0  |  Zx Zy Zz 0  |  0  0  1  0
0   0  0  1  |  0  0  0  1  |  Tx Ty Tz 1

To performs the rotation/scale around a Pivot Point (anchor) you must add a Pivot matrix describing the Pivot position (relative to object center):

pivot = 

1  0  0  0
0  1  0  0
0  0  1  0
Px Py Pz 1

And your transformation formula becomes the follow:

transform = inverse(pivot) * scale * rotate * pivot * translate;

Problem is that, while the scale * rotate * translate is easy to optimize (simplify to avoid real matrix multiplications), with pivot this become more tricky to optimize.

Note: You also can inspire from this documentation, which is the Maya API Transform Class documentation, which provide an 'overkill' transformation formula. I used this in the past to understand how transformations works.

  • QQ: couldfromRotationTranslationScaleOrigin() from gl-matrix be the proper transformation formula? http://glmatrix.net/docs/mat4.js.html#line1094 – Armeen Moon Oct 12 '17 at 03:48
  • Yes, it appear to be the formula in well optimized form. the `out[12] = v[0] + ox` is the last `pivot * translate` while `- (out[0] * ox + out[4] * oy + out[8] * oz)` corresponds to `inverse(pivot) * scale * rotate`. –  Oct 12 '17 at 08:17