Skip to content

Commit 5e53dc3

Browse files
committed
Add getWorldToScreenMatrix function in all renderers
1 parent fc3cac6 commit 5e53dc3

File tree

4 files changed

+35
-58
lines changed

4 files changed

+35
-58
lines changed

src/accessibility/outputs.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -540,14 +540,9 @@ function outputs(p5, fn){
540540

541541
//gets position of shape in the canvas
542542
fn._getPos = function (x, y) {
543-
const untransformedPosition = new DOMPointReadOnly(x, y);
544-
const currentTransform = this._renderer.isP3D ?
545-
new DOMMatrix(this._renderer.calculateCombinedMatrix()) :
546-
this.drawingContext.getTransform();
547-
const { x: transformedX, y: transformedY } = untransformedPosition
548-
.matrixTransform(currentTransform);
549-
const canvasWidth = this.width * this._renderer._pixelDensity;
550-
const canvasHeight = this.height * this._renderer._pixelDensity;
543+
const { x: transformedX, y: transformedY } = this.worldToScreen(new this.Vector(x, y));
544+
const canvasWidth = this.width;
545+
const canvasHeight = this.height;
551546
if (transformedX < 0.4 * canvasWidth) {
552547
if (transformedY < 0.4 * canvasHeight) {
553548
return 'top left';

src/core/environment.js

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,27 +1384,9 @@ function environment(p5, fn){
13841384
*
13851385
*/
13861386
fn.worldToScreen = function(worldPosition) {
1387-
const renderer = this._renderer;
1388-
if (renderer.drawingContext instanceof CanvasRenderingContext2D) {
1389-
// Handle 2D context
1390-
const transformMatrix = new DOMMatrix()
1391-
.scale(1 / renderer._pInst.pixelDensity())
1392-
.multiply(renderer.drawingContext.getTransform());
1393-
const screenCoordinates = transformMatrix.transformPoint(
1394-
new DOMPoint(worldPosition.x, worldPosition.y)
1395-
);
1396-
return new p5.Vector(screenCoordinates.x, screenCoordinates.y);
1397-
} else {
1398-
// Handle WebGL context (3D)
1399-
const modelViewMatrix = renderer.calculateCombinedMatrix();
1400-
const cameraCoordinates = modelViewMatrix.multiplyPoint(worldPosition);
1401-
const normalizedDeviceCoordinates =
1402-
renderer.states.uPMatrix.multiplyAndNormalizePoint(cameraCoordinates);
1403-
const screenX = (0.5 + 0.5 * normalizedDeviceCoordinates.x) * this.width;
1404-
const screenY = (0.5 - 0.5 * normalizedDeviceCoordinates.y) * this.height;
1405-
const screenZ = 0.5 + 0.5 * normalizedDeviceCoordinates.z;
1406-
return new Vector(screenX, screenY, screenZ);
1407-
}
1387+
const matrix = this._renderer.getWorldToScreenMatrix();
1388+
const screenPosition = matrix.multiplyAndNormalizePoint(worldPosition);
1389+
return screenPosition;
14081390
};
14091391
/**
14101392
* Converts 2D screen coordinates to 3D world coordinates.
@@ -1477,30 +1459,11 @@ function environment(p5, fn){
14771459
*
14781460
*/
14791461
fn.screenToWorld = function(screenPosition) {
1480-
const renderer = this._renderer;
1481-
if (renderer.drawingContext instanceof CanvasRenderingContext2D) {
1482-
// Handle 2D context
1483-
const inverseTransformMatrix = new DOMMatrix()
1484-
.multiply(renderer.drawingContext.getTransform().inverse())
1485-
.scale(renderer._pInst.pixelDensity());
1486-
const screenCoordinates = inverseTransformMatrix.transformPoint(
1487-
new DOMPoint(screenPosition.x, screenPosition.y)
1488-
);
1489-
return new p5.Vector(screenCoordinates.x, screenCoordinates.y);
1490-
} else {
1491-
const normalizedDeviceCoordinates = new p5.Vector(
1492-
screenPosition.x / this.width * 2 - 1,
1493-
screenPosition.y / this.height * -2 + 1,
1494-
screenPosition.z * 2 - 1,
1495-
);
1496-
let uPMatrixInverse = renderer.states.uPMatrix.copy()
1497-
uPMatrixInverse = uPMatrixInverse.invert(uPMatrixInverse);
1498-
let modelViewMatrixInverse = renderer.calculateCombinedMatrix();
1499-
modelViewMatrixInverse = modelViewMatrixInverse.invert(modelViewMatrixInverse);
1500-
const cameraCoordinates = uPMatrixInverse.multiplyAndNormalizePoint(normalizedDeviceCoordinates);
1501-
const worldPosition = modelViewMatrixInverse.multiplyPoint(cameraCoordinates);
1502-
return worldPosition;
1503-
}
1462+
let matrixInverse = this._renderer.getWorldToScreenMatrix();
1463+
matrixInverse = matrixInverse.invert(matrixInverse);
1464+
1465+
const worldPosition = matrixInverse.multiplyAndNormalizePoint(screenPosition);
1466+
return worldPosition;
15041467
};
15051468
}
15061469

src/core/p5.Renderer2D.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Element } from '../dom/p5.Element';
77
import { MediaElement } from '../dom/p5.MediaElement';
88
import { RGBHDR } from '../color/creating_reading';
99
import FilterRenderer2D from '../image/filterRenderer2D';
10+
import { Matrix } from '../math/p5.Matrix';
1011
import { PrimitiveToPath2DConverter } from '../shape/custom_shapes';
1112

1213

@@ -999,6 +1000,13 @@ class Renderer2D extends Renderer {
9991000
this.drawingContext.transform(a, b, c, d, e, f);
10001001
}
10011002

1003+
getWorldToScreenMatrix() {
1004+
let domMatrix = new DOMMatrix()
1005+
.scale(1 / this._pixelDensity)
1006+
.multiply(this.drawingContext.getTransform());
1007+
return new Matrix(domMatrix.toFloat32Array());
1008+
}
1009+
10021010
resetMatrix() {
10031011
this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);
10041012
this.drawingContext.scale(

src/webgl/p5.RendererGL.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,12 +1024,23 @@ class RendererGL extends Renderer {
10241024
this.clear(..._col._getRGBA());
10251025
}
10261026

1027-
// Combines the model and view matrices to get the uMVMatrix
1028-
// This method will be reusable wherever you need to update the combined matrix.
1029-
calculateCombinedMatrix() {
1027+
1028+
/**
1029+
* Get a matrix from world-space to screen-space
1030+
*/
1031+
getWorldToScreenMatrix() {
10301032
const modelMatrix = this.states.uModelMatrix;
10311033
const viewMatrix = this.states.uViewMatrix;
1032-
return modelMatrix.copy().mult(viewMatrix);
1034+
const projectionMatrix = this.states.uPMatrix;
1035+
const projectedToScreenMatrix = new Matrix(4);
1036+
projectedToScreenMatrix.scale(this.width, this.height, 1);
1037+
projectedToScreenMatrix.translate([0.5, 0.5, 0.5]);
1038+
projectedToScreenMatrix.scale(0.5, -0.5, 0.5);
1039+
1040+
const modelViewMatrix = modelMatrix.copy().mult(viewMatrix);
1041+
const modelViewProjectionMatrix = modelViewMatrix.mult(projectionMatrix);
1042+
const worldToScreenMatrix = modelViewProjectionMatrix.mult(projectedToScreenMatrix);
1043+
return worldToScreenMatrix;
10331044
}
10341045

10351046
//////////////////////////////////////////////
@@ -2204,7 +2215,7 @@ class RendererGL extends Renderer {
22042215
const modelMatrix = this.states.uModelMatrix;
22052216
const viewMatrix = this.states.uViewMatrix;
22062217
const projectionMatrix = this.states.uPMatrix;
2207-
const modelViewMatrix = this.calculateCombinedMatrix();
2218+
const modelViewMatrix = modelMatrix.copy().mult(viewMatrix);
22082219

22092220
shader.setUniform(
22102221
"uPerspective",

0 commit comments

Comments
 (0)