diff --git a/package-lock.json b/package-lock.json index def3ab1e93..4d7561f0f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17798,4 +17798,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/webgl/3d_primitives.js b/src/webgl/3d_primitives.js index 63bc4213de..9dc5d65622 100644 --- a/src/webgl/3d_primitives.js +++ b/src/webgl/3d_primitives.js @@ -2481,7 +2481,7 @@ p5.RendererGL.prototype.triangle = function(args) { // this matrix multiplication transforms those two unit vectors // onto the required vector prior to rendering, and moves the // origin appropriately. - const uMVMatrix = this.uMVMatrix.copy(); + const uModelMatrix = this.uModelMatrix.copy(); try { // triangle orientation. const orientation = Math.sign(x1*y2-x2*y1 + x2*y3-x3*y2 + x3*y1-x1*y3); @@ -2490,13 +2490,13 @@ p5.RendererGL.prototype.triangle = function(args) { x3 - x1, y3 - y1, 0, 0, // the resulting unit Y-axis 0, 0, orientation, 0, // the resulting unit Z-axis (Reflect the specified order of vertices) x1, y1, 0, 1 // the resulting origin - ]).mult(this.uMVMatrix); + ]).mult(this.uModelMatrix); - this.uMVMatrix = mult; + this.uModelMatrix = mult; this.drawBuffers(gId); } finally { - this.uMVMatrix = uMVMatrix; + this.uModelMatrix = uModelMatrix; } return this; @@ -2618,15 +2618,15 @@ p5.RendererGL.prototype.arc = function(...args) { this.createBuffers(gId, arcGeom); } - const uMVMatrix = this.uMVMatrix.copy(); + const uModelMatrix = this.uModelMatrix.copy(); try { - this.uMVMatrix.translate([x, y, 0]); - this.uMVMatrix.scale(width, height, 1); + this.uModelMatrix.translate([x, y, 0]); + this.uModelMatrix.scale(width, height, 1); this.drawBuffers(gId); } finally { - this.uMVMatrix = uMVMatrix; + this.uModelMatrix = uModelMatrix; } return this; @@ -2678,14 +2678,14 @@ p5.RendererGL.prototype.rect = function(args) { // opposite corners at (0,0) & (1,1). // // before rendering, this square is scaled & moved to the required location. - const uMVMatrix = this.uMVMatrix.copy(); + const uModelMatrix = this.uModelMatrix.copy(); try { - this.uMVMatrix.translate([x, y, 0]); - this.uMVMatrix.scale(width, height, 1); + this.uModelMatrix.translate([x, y, 0]); + this.uModelMatrix.scale(width, height, 1); this.drawBuffers(gId); } finally { - this.uMVMatrix = uMVMatrix; + this.uModelMatrix = uModelMatrix; } } else { // Use Immediate mode to round the rectangle corner, diff --git a/src/webgl/GeometryBuilder.js b/src/webgl/GeometryBuilder.js index 502f4b2bee..ac78ec7e94 100644 --- a/src/webgl/GeometryBuilder.js +++ b/src/webgl/GeometryBuilder.js @@ -11,7 +11,7 @@ class GeometryBuilder { this.renderer = renderer; renderer._pInst.push(); this.identityMatrix = new p5.Matrix(); - renderer.uMVMatrix = new p5.Matrix(); + renderer.uModelMatrix = new p5.Matrix(); this.geometry = new p5.Geometry(); this.geometry.gid = `_p5_GeometryBuilder_${GeometryBuilder.nextGeometryId}`; GeometryBuilder.nextGeometryId++; @@ -25,7 +25,7 @@ class GeometryBuilder { transformVertices(vertices) { if (!this.hasTransform) return vertices; - return vertices.map(v => this.renderer.uMVMatrix.multiplyPoint(v)); + return vertices.map(v => this.renderer.uModelMatrix.multiplyPoint(v)); } /** @@ -46,11 +46,11 @@ class GeometryBuilder { * transformations. */ addGeometry(input) { - this.hasTransform = !this.renderer.uMVMatrix.mat4 + this.hasTransform = !this.renderer.uModelMatrix.mat4 .every((v, i) => v === this.identityMatrix.mat4[i]); if (this.hasTransform) { - this.renderer.uNMatrix.inverseTranspose(this.renderer.uMVMatrix); + this.renderer.uNMatrix.inverseTranspose(this.renderer.uModelMatrix); } let startIdx = this.geometry.vertices.length; diff --git a/src/webgl/interaction.js b/src/webgl/interaction.js index 6245becfce..42e063c0b9 100644 --- a/src/webgl/interaction.js +++ b/src/webgl/interaction.js @@ -813,7 +813,7 @@ p5.prototype._grid = function(size, numDivs, xOff, yOff, zOff) { this._renderer.curStrokeColor[1] * 255, this._renderer.curStrokeColor[2] * 255 ); - this._renderer.uMVMatrix.set(this._renderer._curCamera.cameraMatrix); + this._renderer.uModelMatrix.reset(); // Lines along X axis for (let q = 0; q <= numDivs; q++) { @@ -860,7 +860,7 @@ p5.prototype._axesIcon = function(size, xOff, yOff, zOff) { return function() { this.push(); - this._renderer.uMVMatrix.set(this._renderer._curCamera.cameraMatrix); + this._renderer.uModelMatrix.reset(); // X axis this.strokeWeight(2); diff --git a/src/webgl/p5.Camera.js b/src/webgl/p5.Camera.js index 104d2e2aaf..b2d510242d 100644 --- a/src/webgl/p5.Camera.js +++ b/src/webgl/p5.Camera.js @@ -2915,7 +2915,8 @@ p5.Camera = class Camera { this.cameraMatrix.translate([tx, ty, tz]); if (this._isActive()) { - this._renderer.uMVMatrix.set(this.cameraMatrix); + this._renderer.uModelMatrix.reset(); + this._renderer.uViewMatrix.set(this.cameraMatrix); } return this; } @@ -3242,13 +3243,12 @@ p5.Camera = class Camera { this.cameraMatrix = cam.cameraMatrix.copy(); this.projMatrix = cam.projMatrix.copy(); - // If the target camera is active, update uMVMatrix and uPMatrix. if (this._isActive()) { - this._renderer.uMVMatrix.mat4 = this.cameraMatrix.mat4.slice(); - this._renderer.uPMatrix.mat4 = this.projMatrix.mat4.slice(); + this._renderer.uModelMatrix.reset(); + this._renderer.uViewMatrix.set(this.cameraMatrix); + this._renderer.uPMatrix.set(this.projMatrix); } } - /** * Sets the camera’s position and orientation to values that are in-between * those of two other cameras. diff --git a/src/webgl/p5.Framebuffer.js b/src/webgl/p5.Framebuffer.js index e4f85fcbda..0ff0955691 100644 --- a/src/webgl/p5.Framebuffer.js +++ b/src/webgl/p5.Framebuffer.js @@ -846,9 +846,10 @@ class Framebuffer { // RendererGL.reset() does, but this does not try to clear any buffers; // it only sets the camera. this.target.setCamera(this.defaultCamera); - this.target._renderer.uMVMatrix.set( - this.target._renderer._curCamera.cameraMatrix - ); + this.target.resetMatrix(); + this.target._renderer.uViewMatrix + .set(this.target._renderer._curCamera.cameraMatrix); + this.target._renderer.uModelMatrix.reset(); this.target._renderer._applyStencilTestIfClipping(); } diff --git a/src/webgl/p5.Matrix.js b/src/webgl/p5.Matrix.js index 9e2a096f5d..da664bd9ec 100644 --- a/src/webgl/p5.Matrix.js +++ b/src/webgl/p5.Matrix.js @@ -47,6 +47,15 @@ p5.Matrix = class { return this; } + reset() { + if (this.mat3) { + this.mat3.set([1, 0, 0, 0, 1, 0, 0, 0, 1]); + } else if (this.mat4) { + this.mat4.set([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); + } + return this; + } + /** * Replace the entire contents of a 4x4 matrix. * If providing an array or a p5.Matrix, the values will be copied without diff --git a/src/webgl/p5.RendererGL.Retained.js b/src/webgl/p5.RendererGL.Retained.js index 9bd05739c8..49f2dd772b 100644 --- a/src/webgl/p5.RendererGL.Retained.js +++ b/src/webgl/p5.RendererGL.Retained.js @@ -195,15 +195,16 @@ p5.RendererGL.prototype.drawBuffersScaled = function( scaleY, scaleZ ) { - const uMVMatrix = this.uMVMatrix.copy(); + let originalModelMatrix = this.uModelMatrix.copy(); try { - this.uMVMatrix.scale(scaleX, scaleY, scaleZ); + this.uModelMatrix.scale(scaleX, scaleY, scaleZ); + this.drawBuffers(gId); } finally { - this.uMVMatrix = uMVMatrix; + + this.uModelMatrix = originalModelMatrix; } }; - p5.RendererGL.prototype._drawArrays = function(drawMode, gId) { this.GL.drawArrays( drawMode, diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 660f7d378b..5816d2c61c 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -536,6 +536,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { * model view, projection, & normal * matrices */ + this.uModelMatrix = new p5.Matrix(); + this.uViewMatrix = new p5.Matrix(); this.uMVMatrix = new p5.Matrix(); this.uPMatrix = new p5.Matrix(); this.uNMatrix = new p5.Matrix('mat3'); @@ -894,7 +896,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { _update() { // reset model view and apply initial camera transform // (containing only look at info; no projection). - this.uMVMatrix.set(this._curCamera.cameraMatrix); + this.uModelMatrix.reset(); + this.uViewMatrix.set(this._curCamera.cameraMatrix); // reset light data for new frame. @@ -1528,9 +1531,9 @@ p5.RendererGL = class RendererGL extends p5.Renderer { applyMatrix(a, b, c, d, e, f) { if (arguments.length === 16) { - p5.Matrix.prototype.apply.apply(this.uMVMatrix, arguments); + p5.Matrix.prototype.apply.apply(this.uModelMatrix, arguments); } else { - this.uMVMatrix.apply([ + this.uModelMatrix.apply([ a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, @@ -1554,7 +1557,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { y = x.y; x = x.x; } - this.uMVMatrix.translate([x, y, z]); + this.uModelMatrix.translate([x, y, z]); return this; } @@ -1567,7 +1570,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { * @chainable */ scale(x, y, z) { - this.uMVMatrix.scale(x, y, z); + this.uModelMatrix.scale(x, y, z); return this; } @@ -1575,7 +1578,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { if (typeof axis === 'undefined') { return this.rotateZ(rad); } - p5.Matrix.prototype.rotate.apply(this.uMVMatrix, arguments); + p5.Matrix.prototype.rotate.apply(this.uModelMatrix, arguments); return this; } @@ -1601,7 +1604,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { // add webgl-specific style properties const properties = style.properties; - properties.uMVMatrix = this.uMVMatrix.copy(); + properties.uModelMatrix = this.uModelMatrix.copy(); + properties.uViewMatrix = this.uViewMatrix.copy(); properties.uPMatrix = this.uPMatrix.copy(); properties._curCamera = this._curCamera; @@ -1688,7 +1692,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } } resetMatrix() { - this.uMVMatrix.set(this._curCamera.cameraMatrix); + this.uModelMatrix.reset(); + this.uViewMatrix.set(this._curCamera.cameraMatrix); return this; } diff --git a/src/webgl/p5.Shader.js b/src/webgl/p5.Shader.js index 48ac91a8c3..e12430ae9d 100644 --- a/src/webgl/p5.Shader.js +++ b/src/webgl/p5.Shader.js @@ -577,9 +577,11 @@ p5.Shader = class { } _setMatrixUniforms() { - const viewMatrix = this._renderer._curCamera.cameraMatrix; + const modelMatrix = this._renderer.uModelMatrix; + const viewMatrix = this._renderer.uViewMatrix; const projectionMatrix = this._renderer.uPMatrix; - const modelViewMatrix = this._renderer.uMVMatrix; + const modelViewMatrix = (modelMatrix.copy()).mult(viewMatrix); + this._renderer.uMVMatrix = modelViewMatrix; const modelViewProjectionMatrix = modelViewMatrix.copy(); modelViewProjectionMatrix.mult(projectionMatrix); @@ -589,6 +591,7 @@ p5.Shader = class { } this.setUniform('uViewMatrix', viewMatrix.mat4); this.setUniform('uProjectionMatrix', projectionMatrix.mat4); + this.setUniform('uModelMatrix', modelMatrix.mat4); this.setUniform('uModelViewMatrix', modelViewMatrix.mat4); this.setUniform( 'uModelViewProjectionMatrix', @@ -599,8 +602,7 @@ p5.Shader = class { this.setUniform('uNormalMatrix', this._renderer.uNMatrix.mat3); } if (this.uniforms.uCameraRotation) { - this._renderer.curMatrix.inverseTranspose(this._renderer. - _curCamera.cameraMatrix); + this._renderer.curMatrix.inverseTranspose(this._renderer.uViewMatrix); this.setUniform('uCameraRotation', this._renderer.curMatrix.mat3); } } diff --git a/test/unit/webgl/p5.Camera.js b/test/unit/webgl/p5.Camera.js index aa682d0c11..96a5165d14 100644 --- a/test/unit/webgl/p5.Camera.js +++ b/test/unit/webgl/p5.Camera.js @@ -392,7 +392,7 @@ suite('p5.Camera', function() { // the renderer's matrix will also change. assert.deepEqual( copyCam.cameraMatrix.mat4, - myp5._renderer.uMVMatrix.mat4 + myp5._renderer.uViewMatrix.mat4 ); assert.deepEqual( copyCam.projMatrix.mat4, diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js index 1c2672b587..ec80d71c0a 100644 --- a/test/unit/webgl/p5.RendererGL.js +++ b/test/unit/webgl/p5.RendererGL.js @@ -593,13 +593,26 @@ suite('p5.RendererGL', function() { suite('push() and pop() work in WEBGL Mode', function() { test('push/pop and translation works as expected in WEBGL Mode', function(done) { myp5.createCanvas(100, 100, myp5.WEBGL); - var modelView = myp5._renderer.uMVMatrix.copy(); + var modelMatrixBefore = myp5._renderer.uModelMatrix.copy(); + var viewMatrixBefore = myp5._renderer.uViewMatrix.copy(); + myp5.push(); + // Change view + myp5.camera(0, 0, -500); + // Change model myp5.rotateX(Math.random(0, 100)); myp5.translate(20, 100, 5); - assert.notEqual(modelView.mat4, myp5._renderer.uMVMatrix.mat4); + // Check if the model matrix has changed + assert.notDeepEqual(modelMatrixBefore.mat4, + myp5._renderer.uModelMatrix.mat4); + // Check if the view matrix has changed + assert.notDeepEqual(viewMatrixBefore.mat4, + myp5._renderer.uViewMatrix.mat4); myp5.pop(); - assert.deepEqual(modelView.mat4, myp5._renderer.uMVMatrix.mat4); + // Check if both the model and view matrices are restored after popping + assert.deepEqual(modelMatrixBefore.mat4, + myp5._renderer.uModelMatrix.mat4); + assert.deepEqual(viewMatrixBefore.mat4, myp5._renderer.uViewMatrix.mat4); done(); });