Small optimization to transform matrix update

This commit is contained in:
Felipe Alfonso 2017-01-31 17:24:51 -03:00
parent 1c062e3e2d
commit 6566a387b5
5 changed files with 91 additions and 71 deletions

View file

@ -128,6 +128,10 @@ Transform.prototype.updateRoot = function ()
var transformStack = this.transformStack;
var childStack = this.childStack;
var childrenArray = this.flatChildrenArray;
var currentTransform = this.localMatrix;
var cos = Math.cos;
var sin = Math.sin;
if (this.dirty)
{
var counts = this.flattenTree(this.children, this.flatRenderArray, childrenArray, 0, 0);
@ -135,19 +139,70 @@ Transform.prototype.updateRoot = function ()
this.renderCount = counts[1];
this.dirty = false;
}
this.updateLocal();
currentTransform = this.localMatrix;
this.localMatrix.loadIdentity();
this.localMatrix.translate(this.positionX, this.positionY);
this.localMatrix.rotate(this.rotation);
this.localMatrix.scale(this.scaleX, this.scaleY);
currentTransform = this.localMatrix.matrix;
for (var index = 0, length = this.childCount; index < length; ++index)
{
var child = childrenArray[index];
if (child !== currentChild)
{
child.update(currentTransform);
// inlined transformation
var parent = currentTransform;
var world = child.worldMatrix.matrix;
var rotation = child.rotation;
var local = child.localMatrix.matrix;
var transX = child.positionX;
var transY = child.positionY;
var scaleX = child.scaleX;
var scaleY = child.scaleY;
var rotation = child.rotation;
var tcos = 1;
var tsin = 0;
var p0 = parent[0];
var p1 = parent[1];
var p2 = parent[2];
var p3 = parent[3];
var p4 = parent[4];
var p5 = parent[5];
// Rotate + Scale + Translate
if (rotation !== 0)
{
tcos = cos(rotation);
tsin = sin(rotation);
}
var l0 = tcos * scaleX;
var l1 = tsin * scaleX;
var l2 = -tsin * scaleY;
var l3 = tcos * scaleY;
// Apply world transformation
world[0] = l0 * p0 + l1 * p2;
world[1] = l0 * p1 + l1 * p3;
world[2] = l2 * p0 + l3 * p2;
world[3] = l2 * p1 + l3 * p3;
world[4] = transX * p0 + transY * p2 + p4;
world[5] = transX * p1 + transY * p3 + p5;
// Store local transformation
local[0] = l0;
local[1] = l1;
local[2] = l2;
local[3] = l3;
local[4] = transX;
local[5] = transY;
if (child.hasChildren)
{
transformStack[stackLength] = currentTransform;
childStack[stackLength++] = currentChild;
currentTransform = child.worldMatrix;
currentTransform = local;
currentChild = child;
}
}
@ -158,41 +213,7 @@ Transform.prototype.updateRoot = function ()
}
}
};
Transform.prototype.update = function (parentTransformMatrix)
{
if (!this.dirtyLocal)
{
return;
}
var parent = parentTransformMatrix.matrix;
var world = this.worldMatrix.matrix;
var rotation = this.rotation;
var localm = this.localMatrix.loadIdentity();
localm.translate(this.positionX, this.positionY);
localm.rotate(rotation);
localm.scale(this.scaleX, this.scaleY);
var local = localm.matrix;
world[0] = parent[0] * local[0] + parent[1] * local[2];
world[1] = parent[0] * local[1] + parent[1] * local[3];
world[2] = parent[2] * local[0] + parent[3] * local[2];
world[3] = parent[2] * local[1] + parent[3] * local[3];
world[4] = parent[4] * local[0] + parent[5] * local[2] + local[4];
world[5] = parent[4] * local[1] + parent[5] * local[3] + local[5];
this.dirtyLocal = false;
};
Transform.prototype.updateLocal = function ()
{
var local = this.localMatrix.loadIdentity();
local.translate(this.positionX, this.positionY);
local.rotate(this.rotation);
local.scale(this.scaleX, this.scaleY);
};
Object.defineProperties(Transform.prototype,{
worldPositionX: {
enumarable: true,

View file

@ -258,7 +258,6 @@ WebGLRenderer.prototype = {
*/
render: function (state, interpolationPercentage)
{
var batch = this.batch;
// Could move to the State Systems or MainLoop
for (var c = 0; c < state.sys.children.list.length; c++)
@ -266,7 +265,7 @@ WebGLRenderer.prototype = {
var child = state.sys.children.list[c];
child.renderWebGL(this, child, interpolationPercentage);
var batch = this.batch;
if (batch && batch.isFull())
{
batch.flush();

View file

@ -91,13 +91,13 @@ SpriteBatch32.prototype = {
//CreateAttribDesc(gl, program, 'a_color', 3, 5121, true, CONST.VERTEX_SIZE, 36)
CreateAttribDesc(gl, program, 'a_position', 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 0),
CreateAttribDesc(gl, program, 'a_tex_coord', 2, gl.FLOAT, false, CONST.VERTEX_SIZE, 8),
//CreateAttribDesc(gl, program, 'transform_a', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 16),
//CreateAttribDesc(gl, program, 'transform_b', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 20),
//CreateAttribDesc(gl, program, 'transform_c', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 24),
//CreateAttribDesc(gl, program, 'transform_d', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 28),
CreateAttribDesc(gl, program, 'transform_tx', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 16),
CreateAttribDesc(gl, program, 'transform_ty', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 20),
CreateAttribDesc(gl, program, 'a_color', 3, gl.UNSIGNED_BYTE, true, CONST.VERTEX_SIZE, 24)
CreateAttribDesc(gl, program, 'transform_a', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 16),
CreateAttribDesc(gl, program, 'transform_b', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 20),
CreateAttribDesc(gl, program, 'transform_c', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 24),
CreateAttribDesc(gl, program, 'transform_d', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 28),
CreateAttribDesc(gl, program, 'transform_tx', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 32),
CreateAttribDesc(gl, program, 'transform_ty', 1, gl.FLOAT, false, CONST.VERTEX_SIZE, 36),
CreateAttribDesc(gl, program, 'a_color', 3, gl.UNSIGNED_BYTE, true, CONST.VERTEX_SIZE, 40)
];
var vertexArray = new VertexArray(CreateBuffer(gl, gl.ARRAY_BUFFER, gl.STREAM_DRAW, null, vertexDataBuffer.getByteCapacity()), attribArray);
@ -172,10 +172,10 @@ SpriteBatch32.prototype = {
vertexBufferF32[vertexOffset++] = y;
vertexBufferF32[vertexOffset++] = uvs.x0;
vertexBufferF32[vertexOffset++] = uvs.y0;
//vertexBufferF32[vertexOffset++] = a;
//vertexBufferF32[vertexOffset++] = b;
//vertexBufferF32[vertexOffset++] = c;
//vertexBufferF32[vertexOffset++] = d;
vertexBufferF32[vertexOffset++] = a;
vertexBufferF32[vertexOffset++] = b;
vertexBufferF32[vertexOffset++] = c;
vertexBufferF32[vertexOffset++] = d;
vertexBufferF32[vertexOffset++] = tx;
vertexBufferF32[vertexOffset++] = ty;
vertexBufferU32[vertexOffset++] = vertexColor.topLeft;
@ -184,10 +184,10 @@ SpriteBatch32.prototype = {
vertexBufferF32[vertexOffset++] = y + height;
vertexBufferF32[vertexOffset++] = uvs.x1;
vertexBufferF32[vertexOffset++] = uvs.y1;
//vertexBufferF32[vertexOffset++] = a;
//vertexBufferF32[vertexOffset++] = b;
//vertexBufferF32[vertexOffset++] = c;
//vertexBufferF32[vertexOffset++] = d;
vertexBufferF32[vertexOffset++] = a;
vertexBufferF32[vertexOffset++] = b;
vertexBufferF32[vertexOffset++] = c;
vertexBufferF32[vertexOffset++] = d;
vertexBufferF32[vertexOffset++] = tx;
vertexBufferF32[vertexOffset++] = ty;
vertexBufferU32[vertexOffset++] = vertexColor.bottomLeft;
@ -196,10 +196,10 @@ SpriteBatch32.prototype = {
vertexBufferF32[vertexOffset++] = y + height;
vertexBufferF32[vertexOffset++] = uvs.x2;
vertexBufferF32[vertexOffset++] = uvs.y2;
//vertexBufferF32[vertexOffset++] = a;
//vertexBufferF32[vertexOffset++] = b;
//vertexBufferF32[vertexOffset++] = c;
//vertexBufferF32[vertexOffset++] = d;
vertexBufferF32[vertexOffset++] = a;
vertexBufferF32[vertexOffset++] = b;
vertexBufferF32[vertexOffset++] = c;
vertexBufferF32[vertexOffset++] = d;
vertexBufferF32[vertexOffset++] = tx;
vertexBufferF32[vertexOffset++] = ty;
vertexBufferU32[vertexOffset++] = vertexColor.bottomRight;
@ -208,10 +208,10 @@ SpriteBatch32.prototype = {
vertexBufferF32[vertexOffset++] = y;
vertexBufferF32[vertexOffset++] = uvs.x3;
vertexBufferF32[vertexOffset++] = uvs.y3;
//vertexBufferF32[vertexOffset++] = a;
//vertexBufferF32[vertexOffset++] = b;
//vertexBufferF32[vertexOffset++] = c;
//vertexBufferF32[vertexOffset++] = d;
vertexBufferF32[vertexOffset++] = a;
vertexBufferF32[vertexOffset++] = b;
vertexBufferF32[vertexOffset++] = c;
vertexBufferF32[vertexOffset++] = d;
vertexBufferF32[vertexOffset++] = tx;
vertexBufferF32[vertexOffset++] = ty;
vertexBufferU32[vertexOffset++] = vertexColor.topRight;

View file

@ -2,10 +2,10 @@ module.exports = [
'uniform mat4 u_view_matrix;',
'attribute vec2 a_position;',
'attribute vec2 a_tex_coord;',
//'attribute float transform_a;',
//'attribute float transform_b;',
//'attribute float transform_c;',
//'attribute float transform_d;',
'attribute float transform_a;',
'attribute float transform_b;',
'attribute float transform_c;',
'attribute float transform_d;',
'attribute float transform_tx;',
'attribute float transform_ty;',
'attribute vec3 a_color;',
@ -13,8 +13,8 @@ module.exports = [
'varying vec3 v_color;',
'void main () {',
' vec2 t_position;',
' t_position.x = a_position.x + transform_tx;',
' t_position.y = a_position.y + transform_ty;',
' t_position.x = a_position.x * transform_a + a_position.y * transform_c + transform_tx;',
' t_position.y = a_position.x * transform_b + a_position.y * transform_d + transform_ty;',
' gl_Position = u_view_matrix * vec4(t_position, 1.0, 1.0);',
' v_tex_coord = a_tex_coord;',
' v_color = a_color;',

View file

@ -4,13 +4,13 @@ var VertexShader = require('./VertexShader');
var CONST = {
// VERTEX_SIZE = (sizeof(vec2) * 4) + (sizeof(float) + sizeof(uint32))
VERTEX_SIZE: 28,//44,
VERTEX_SIZE: 44,
INDEX_SIZE: 2,
SPRITE_VERTEX_COUNT: 4,
SPRITE_INDEX_COUNT: 6,
// How many 32-bit components does the vertex have.
SPRITE_VERTEX_COMPONENT_COUNT: 7,
SPRITE_VERTEX_COMPONENT_COUNT: 11,
// Can't be bigger since index are 16-bit
MAX_SPRITES: 10000,