Finding world coordinates from screen coordinates

前端 未结 2 1215
囚心锁ツ
囚心锁ツ 2021-01-03 08:14

There\'s many answers to this problem, but I\'m not sure that they all work with XTK, such as seeing multiple answers for this in Three.JS, but of course XTK and Three.JS do

2条回答
  •  迷失自我
    2021-01-03 09:02

    Here is my function to unproject in xtk. Please tell me if you see mistakes. Now with the resulting point and the camera position I should be able to find my intersections. To make the computation faster for the following step, I'll call it in a pick event and so I'll only have to try the intersections with a given object. If I've time i'll also try with testing the bounding boxes.

    Nota bene : the last lines are not required, I could work on the ray instead of the point.

    X.camera3D.prototype.unproject = function (x,y) {
    
      // get the 4x4 model-view matrix
      var mvMatrix = this._view;
    
      // create the 4x4 projection matrix from the flatten gl version
      var pMatrix = new X.matrix(4,4);
      for (var i=0 ; i<16 ; i++) {
        pMatrix.setValueAt(i - 4*Math.floor(i/4), Math.floor(i/4), this._perspective[i]);
      }
      // compute the product and inverse it
      var mvpMatrxix = pMatrix.multiply(mwMatrix); /** Edit : wrong product corrected **/
      var inverse_mvpMatrix = mvpMatrxix.getInverse();
      if (!goog.isDefAndNotNull(inverse_mvpMatrix)) throw new Error("Could not inverse the transformation matrix.");
    
      // check if x & y are map in [-1,1] interval (required for the computations)
      if (x<-1 || x>1 || y<-1 || y>1) throw new Error("Invalid x or y coordinate, it must be between -1 and 1");
    
      // fill the 4x1 normalized (in [-1,1]⁴) vector of the point of the screen in word camera world's basis
      var point4f = new X.matrix(4,1);
      point4f.setValueAt(0, 0, x);
      point4f.setValueAt(1, 0, y);
      point4f.setValueAt(2, 0, -1.0); // 2*?-1, with ?=0 for near plan and ?=1 for far plan
      point4f.setValueAt(3, 0, 1.0); // homogeneous coordinate arbitrary set at 1
    
      // compute the picked ray in the world's basis in homogeneous coordinates
      var ray4f = inverse_mvpMatrix.multiply(point4f);
      if (ray4f.getValueAt(3,0)==0) throw new Error("Ray is not valid.");
      // return in not-homogeneous coordinates to compute the 3D direction vector
      var point3f = new X.matrix(3,1);
      point3f.setValueAt(0, 0, ray4f.getValueAt(0, 0) / ray4f.getValueAt(3, 0) );
      point3f.setValueAt(1, 0, ray4f.getValueAt(1, 0) / ray4f.getValueAt(3, 0) );
      point3f.setValueAt(2, 0, ray4f.getValueAt(2, 0) / ray4f.getValueAt(3, 0) );
      return point3f;
    };
    

    Edit

    Here, in my repo, you can find functions in camera3D.js and renderer3D.js for efficient 3D picking in xtk.

提交回复
热议问题