How to get the values of the current matrix (after translate, scale, rotateY...)?

To see if I could get from it the Global position, the global scale, the global rotations x y z after using translate(), rotate x,y, z, scale()… multiple times

:slight_smile:

Take a look at screenToWorld and worldToScreen to see if they do what you need.

There is also access to the underlying matrix via something like:

renderer = createCanvas(w, h)
// ...
console.log(new DOMMatrix(...renderer.getWorldToScreenMatrix().mat4))

…but it’s an internal API that may change in the future.

Hello @EricRogerGarcia

GitHub issue #4743 may be of interest:

I was able to:

• Show the current model matrix in the console
• Recover the same global coordinates that Processing’s modelX/Y/Z() returns using a helper (not included) that emulates those functions.

As an exercise, I took some vertices, applied transformations, then multiplied them by the model matrix to obtain their global coordinates.
I then displayed these to confirm.

:)

Thank you :slight_smile:

I’m going to see if I can write a globalCoordinates() function that returns the position of the origin (in relative coordinates) in global coordinates based on the current transformation matrix.

It should be:

                                  0   globalX
                                  0   globalY
current-transformation-matrix .   0 = globalZ
                                  1      1

It should do the trick !

:slight_smile:

P.S. It was an opportunity to review the matrix mathematics and to learn about 4x4 transformation matrix!

Reference for now : markdown

to begin with :

function transformationMatrix() { // return an Array with 16 numbers
  // may change if P5js API modification so this function is needed (may be used several times) !
  return Array.from(G.canvas.uMVMatrix.copy().matrix);
}

N.B. G is a static class for global things

with G.canvas=createCanvas(…) in setup()

(uMVMatrix.matrix is a “Float32Array” !? )

Well… it doesn’t work… and I don’t know why for now !

In draw, I use translate(5,6,7) and my result for globalCoordinates() should be (5,6,7) but it is (0,0,0). I wonder what I did wrong !

"use strict";
// tests Tranformation matrix

function setup() {
  G.canvas = createCanvas(500, 400, WEBGL);
  noLoop();
}


function draw() {
  background(200);
  translate(5, 6, 7);
  let v = globalCoordinates();
  print("x: "+v.x);
  print("y: "+v.y);
  print("z: "+v.z);
}

class G { // static class, G for Global
  static canvas=null; // initialized in setup()
}

function transformationMatrix() { // return an Array with 16 numbers
  // may change if P5js API modification so this function is needed (may be used several times) !
  let myReturn=G.canvas.uMVMatrix.copy().matrix;
  myReturn=Array.from(myReturn);
  return myReturn;
}

function mulTMV(tm, v) { // (transformation matrix, vector) : result vector

  // a b c d   x   ax+by+cz+dw
  // e f g h   y   ex+fy+gz+hw
  // i j k l . z = ix+jy+kz+lw
  // m n o p   w   mx+ny+oz+pw

  let a=tm[0];
  let b=tm[1];
  let c=tm[2];
  let d=tm[3];
  let e=tm[4];
  let f=tm[5];
  let g=tm[6];
  let h=tm[7];
  let i=tm[8];
  let j=tm[9];
  let k=tm[10];
  let l=tm[11];
  let m=tm[12];
  let n=tm[13];
  let o=tm[14];
  let p=tm[15];
  let x=v.x;
  let y=v.y;
  let z=v.z;
  let w=1;
  let result=createVector(0, 0, 0);
  result.x=a*x+b*y+c*z+d*w;
  result.y=e*x+f*y+g*z+h*w;
  result.z=i*x+j*y+k*z+l*w;
  return result;
}

function globalCoordinates() {
  return mulTMV(transformationMatrix(), createVector(0, 0, 0));
}

Hello @EricRogerGarcia ,

Hint:

I have done a lot of work with matrices in Processing and now migrating this to p5.js and learning a lot along the way!

:)

Hello,

where can I look to your code ? (processing and p5js !) to see what I can learn ?

:slight_smile:

I’m going to look at this thanks

How to access the code ? (a simple link maybe ?) :slight_smile: - thanks ! lol

Anyway, I’ve already found the math for all the transformations with (4x4) matrices. :slight_smile:

I’m going to update a math documentation on my repository in some times :slight_smile:

I’m going to have to find the transformation matrix to write / p5js camera (cf code in next message) to apply for correcting my transformationMatrix() function now ! so this isn’t finished yet !

I think I’m going to store the transformation matrix for each Node3D (just storing variables is fast) and compute the globalCoordinates with them only when it is needed not to have to use many times cosinus and sinus functions (they are slow) for each node3D each frame (as I use the parents global variables now) … or something like that :slight_smile: I’m still thinking about this… for a bit later !

Now it works !!!

Unfortunately, it’s complicated to get the Transformation Matrix from P5js because it takes into account the camera!!!

I’m going to have to figure out how to take that into account specifically :(( !!!

(cf comments in the code in transformationMatrix() !)

"use strict";
// tests Tranformation matrix 2 : works now !

function setup() {
  G.canvas = createCanvas(500, 400, WEBGL);
}

function draw() {
  background(200);
  let v = globalCoordinates();
  print("Before:");
  print("x: "+v.x);
  print("y: "+v.y);
  print("z: "+v.z);
  transformationMatrix().print();
  translate(5, 6, 7);
  v = globalCoordinates();
  print("After:");
  print("x: "+v.x);
  print("y: "+v.y);
  print("z: "+v.z);
  transformationMatrix().print();
  if (frameCount==1) noLoop();
}

class G { // static class, G for Global
  static canvas=null; // initialized in setup()
}

class Matrix {
  constructor(m=[1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1]) { //not sure the default is correct lol !
      
    this.a=m[0];
    this.b=m[4];
    this.c=m[8];
    this.d=m[12];
    this.e=m[1];
    this.f=m[5];
    this.g=m[9];
    this.h=m[13];
    this.i=m[8];
    this.j=m[6];
    this.k=m[10];
    this.l=m[14];
    this.m=m[3];
    this.n=m[7];
    this.o=m[11];
    this.p=m[15];
    
    //  a, b, c, d
    //  e, f, g, h
    //  i, j, k, l
    //  m, n, o, p
    
    // Indices of m :
    //  0, 4, 8,12
    //  1, 5, 9,13
    //  2, 6,10,14
    //  3, 7,11,15
  }

  print() {
    let l=3; // left
    let r=1; // right
    print(nfs(this.a, l, r)+nfs(this.b, l, r)+nfs(this.c, l, r)+nfs(this.d, l, r));
    print(nfs(this.e, l, r)+nfs(this.f, l, r)+nfs(this.g, l, r)+nfs(this.h, l, r));
    print(nfs(this.i, l, r)+nfs(this.j, l, r)+nfs(this.k, l, r)+nfs(this.l, l, r));
    print(nfs(this.m, l, r)+nfs(this.n, l, r)+nfs(this.o, l, r)+nfs(this.p, l, r));
  }
}

function transformationMatrix() { 
  // may change if P5js API modification so this function is needed (may be used several times) !
  let myReturn=G.canvas.uMVMatrix.copy().matrix; // return a Float32Array with 16 numbers
  myReturn=Array.from(myReturn);
  myReturn=new Matrix(myReturn);
  myReturn.l+=800; // to take into account the default camera,
  /*
   so here you need to make a correction based on the camera settings (TODO :(( ), 
   as they are not directly accessible in P5JS :
   put them in the global coordinates: G and update them manually each time the camera is modified.
  */
  return myReturn;
}

function multMV(m, v) { // (Matrix, vector) : vector

  // a b c d   x   ax+by+cz+dw
  // e f g h   y   ex+fy+gz+hw
  // i j k l . z = ix+jy+kz+lw
  // m n o p   w   mx+ny+oz+pw

  // m n o p : 0 0 0 1  and w=1 !

  let result=createVector(0, 0, 0);
  result.x=m.a*v.x+m.b*v.y+m.c*v.z+m.d;
  result.y=m.e*v.x+m.f*v.y+m.g*v.z+m.h;
  result.z=m.i*v.x+m.j*v.y+m.k*v.z+m.l;
  return result;
}

function globalCoordinates() {
  return multMV(transformationMatrix(), createVector(0, 0, 0));
}

I will post in the gallery in the future.

:)

Ok, I’ll let it go because on second thought, I’m going to do it another way.

I 'm going to calculate the transformation matrices myself for each Node (2D or 3D) but not systematically (in each frame) and as little as possible, that is, only when the application needs them and only if the calculation has not already been done before (and also that nothing has changed since the last calculation).

Only the transformation matrices of moving objects (in the world) whose global coordinates must be met will be recalculated regularly… which concerns a small number of objects in general.

In total, this should make the programs faster.

P.S. Using the P5js Transformation Matrix in each frame does not seem like a good idea to me, since I would have to multiply it by a complicated matrix based on the camera to obtain the world T.M. for each Node, which would be slower in generals. In addition, there’s no need to take into account the two different systems (2D and 3D) of P5js !

:slight_smile:

I write and test a little sketch based on the new classes and functions for this and I come back here

:slight_smile:

OK, this works !!! (2D)

(3D soon)

and in 3D here ! :slight_smile:

Nice sketch :grin:

You might want to turn off loop protection in this sketch. Click on Preferences scroll down to the last option and turn it off.

Done thanks !

:grinning_face: