Wow, p5.js is awesome
I just look for a screenX screenY equivalent
together with orbitControl()
Thanks for a great language!
Chrisir
Wow, p5.js is awesome
I just look for a screenX screenY equivalent
together with orbitControl()
Thanks for a great language!
Chrisir
I don’t understand a word here
How do I call it?
let screenCoor = projectWorldToCanvas( canvas, world ) ;
??
Thanks
Chrisir
fill(0,255,0);
translate(0,-37,0);
sphere(44);
let screenCoor = projectWorldToCanvas( canvas, world ) ;
pop();
}
function mousePressed() {
//projectWorldToCanvas(canvas, vWorld)
// let canvasMy ; projectWorldToCanvas(canvasMy , vWorld) ;
if (dist(mouseX, mouseY, 55, 55) < 46)
colFlag = !colFlag;
}
/* Project a vector from World to Canvas coordinates. */
function projectWorldToCanvas(canvas, vWorld) {
// Calculate the ModelViewProjection Matrix.
var mvp = (canvas.uMVMatrix.copy()).mult(canvas.uPMatrix);
// Transform the vector to Normalized Device Coordinate.
var vNDC = multMatrixVector(mvp, vWorld);
// Transform vector from NDC to Canvas coordinates.
var vCanvas = createVector();
vCanvas.x = 0.5 * (vNDC.x + 1.0) * canvas.GL.drawingBufferWidth;
vCanvas.y = 0.5 * (vNDC.y + 1.0) * canvas.GL.drawingBufferHeight;
vCanvas.z = 0.5 * (vNDC.z + 1.0);
return vCanvas;
}
if I call it like this:
var worldMy = createVector( 0,0,0 );
let screenCoor = projectWorldToCanvas( canvas, worldMy ) ;
I receive
TypeError: canvas.uMVMatrix is undefined (sketch: line 99)
p5.RendererGL: enabled webgl context
in
/* Project a vector from World to Canvas coordinates. */
function projectWorldToCanvas(canvas, vWorld) {
// Calculate the ModelViewProjection Matrix.
var mvp = (canvas.uMVMatrix.copy()).mult(canvas.uPMatrix); // !!!!!!!!!!!!!!!!!! HERE
// Transform the vector to Normalized Device Coordinate.
?
I gather that of the 3 funcs in Add screenX, screenY and screenZ · Issue #1553 · processing/p5.js · GitHub
I only need projectWorldToCanvas ?
and not the other?
That’s overly complicated…
Is canvas = 2D and world = 3D?
Thanks for your help!
Chrisir
I’ve seen that there are many others with the same problem. So I’ve decided to build a small library that adds this functionality to p5js.
You’ll find the library here:
And an example of how it’s used here:
https://editor.p5js.org/bohnacker/sketches/nUk3bVW7b
Thanks a ton!
Chrisir
I had a problem why my port didn’t work and turned out I had the column order swapped.
Here a version that looks like the processing java source. I didn’t do any cleanup, the name of the function is _zoomX
for example. The accepted answer seems also simpler, I drop this more for archive purposes.
const nonZero = function(a) {
const FLOAT_EPS = 1.4E-45;
return FLOAT_EPS <= Math.abs(a);
}
const m00 = 0; const m01 = 4; const m02 = 8; const m03 = 12;
const m10 = 1; const m11 = 5; const m12 = 9; const m13 = 13;
const m20 = 2; const m21 = 6; const m22 = 10; const m23 = 14;
const m30 = 3; const m31 = 7; const m32 = 11; const m33 = 15;
const screenXImpl_w = function(x, y, z, w) {
const projection = this._renderer.uPMatrix.mat4;
let ox =
projection[m00]*x + projection[m01]*y + projection[m02]*z + projection[m03]*w;
const ow =
projection[m30]*x + projection[m31]*y + projection[m32]*z + projection[m33]*w;
if (nonZero(ow)) {
ox /= ow;
}
const sx = width * (1 + ox) / 2.0;
return sx;
}
const screenYImpl_w = function(x, y, z, w) {
const projection = this._renderer.uPMatrix.mat4;
let oy =
projection[m10]*x + projection[m11]*y + projection[m12]*z + projection[m13]*w;
const ow =
projection[m30]*x + projection[m31]*y + projection[m32]*z + projection[m33]*w;
if (nonZero(ow)) {
oy /= ow;
}
let sy = height * (1 + oy) / 2.0;
// Turning value upside down because of Processing's inverted Y axis.
sy = height - sy;
return sy;
}
// const screenZImpl_w = function(x, y, z, w) {
// const projection = this._renderer.uPMatrix.mat4;
// let oz =
// projection.m20*x + projection.m21*y + projection.m22*z + projection.m23*w;
// const ow =
// projection.m30*x + projection.m31*y + projection.m32*z + projection.m33*w;
// if (nonZero(ow)) {
// oz /= ow;
// }
// const sz = (oz + 1) / 2.0;
// return sz;
// }
const _screenX = function(x, y, z) {
const modelview = this._renderer.uMVMatrix.mat4;
const ax =
modelview[m00]*x + modelview[m01]*y + modelview[m02]*z + modelview[m03];
const ay =
modelview[m10]*x + modelview[m11]*y + modelview[m12]*z + modelview[m13];
const az =
modelview[m20]*x + modelview[m21]*y + modelview[m22]*z + modelview[m23];
const aw =
modelview[m30]*x + modelview[m31]*y + modelview[m32]*z + modelview[m33];
return screenXImpl_w(ax, ay, az, aw);
}
const _screenY = function(x, y, z) {
const modelview = this._renderer.uMVMatrix.mat4;
const ax =
modelview[m00]*x + modelview[m01]*y + modelview[m02]*z + modelview[m03];
const ay =
modelview[m10]*x + modelview[m11]*y + modelview[m12]*z + modelview[m13];
const az =
modelview[m20]*x + modelview[m21]*y + modelview[m22]*z + modelview[m23];
const aw =
modelview[m30]*x + modelview[m31]*y + modelview[m32]*z + modelview[m33];
return screenYImpl_w(ax, ay, az, aw);
}
const _screenZ = function(x, y, z, w) {
const projection = this._renderer.uPMatrix.mat4;
let oz =
projection[m20]*x + projection[m21]*y + projection[m22]*z + projection[m23]*w;
const ow =
projection[m30]*x + projection[m31]*y + projection[m32]*z + projection[m33]*w;
if (nonZero(ow)) {
oz /= ow;
}
const sz = (oz + 1) / 2.0;
return sz;
}