From c7bf10c25f08ed4167d3ae8f4ec3e116b362af14 Mon Sep 17 00:00:00 2001
From: Dave Pagurek <davepagurek@gmail.com>
Date: Wed, 22 May 2024 08:54:59 -0400
Subject: [PATCH] Only swap out the view matrix when switching cameras

---
 src/webgl/p5.Camera.js           |  2 +-
 test/unit/webgl/p5.RendererGL.js | 31 +++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/webgl/p5.Camera.js b/src/webgl/p5.Camera.js
index b2d510242d..67361657ba 100644
--- a/src/webgl/p5.Camera.js
+++ b/src/webgl/p5.Camera.js
@@ -2915,7 +2915,6 @@ p5.Camera = class Camera {
     this.cameraMatrix.translate([tx, ty, tz]);
 
     if (this._isActive()) {
-      this._renderer.uModelMatrix.reset();
       this._renderer.uViewMatrix.set(this.cameraMatrix);
     }
     return this;
@@ -3882,6 +3881,7 @@ p5.prototype.setCamera = function (cam) {
 
   // set the projection matrix (which is not normally updated each frame)
   this._renderer.uPMatrix.set(cam.projMatrix);
+  this._renderer.uViewMatrix.set(cam.cameraMatrix);
 };
 
 export default p5.Camera;
diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js
index ec80d71c0a..3c7e3df1a2 100644
--- a/test/unit/webgl/p5.RendererGL.js
+++ b/test/unit/webgl/p5.RendererGL.js
@@ -845,6 +845,37 @@ suite('p5.RendererGL', function() {
     });
   });
 
+  suite('applying cameras', function() {
+    test('changing cameras keeps transforms', function() {
+      myp5.createCanvas(50, 50, myp5.WEBGL);
+
+      const origModelMatrix = myp5._renderer.uModelMatrix.copy();
+
+      const cam2 = myp5.createCamera();
+      cam2.setPosition(0, 0, -500);
+      const cam1 = myp5.createCamera();
+
+      // cam1 is applied right now so technically this is redundant
+      myp5.setCamera(cam1);
+      const cam1Matrix = cam1.cameraMatrix.copy();
+      assert.deepEqual(myp5._renderer.uViewMatrix.mat4, cam1Matrix.mat4);
+
+      // Translation only changes the model matrix
+      myp5.translate(100, 0, 0);
+      assert.notDeepEqual(
+        myp5._renderer.uModelMatrix.mat4,
+        origModelMatrix.mat4
+      );
+      assert.deepEqual(myp5._renderer.uViewMatrix.mat4, cam1Matrix.mat4);
+
+      // Switchnig cameras only changes the view matrix
+      const transformedModel = myp5._renderer.uModelMatrix.copy();
+      myp5.setCamera(cam2);
+      assert.deepEqual(myp5._renderer.uModelMatrix.mat4, transformedModel.mat4);
+      assert.notDeepEqual(myp5._renderer.uViewMatrix.mat4, cam1Matrix.mat4);
+    });
+  });
+
   suite('materials', function() {
     test('ambient color defaults to the fill color', function() {
       myp5.createCanvas(100, 100, myp5.WEBGL);