Finding world coordinates from screen coordinates

前端 未结 2 1216
囚心锁ツ
囚心锁ツ 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条回答
  • right now this is not easily possible. I guess you could grab the view matrix of the camera to calculate the position. If you do so, it would be great to bring it back into XTK as built-in functionality!

    Currently, only object picking is possible like this (r is a X.renderer3D):

    /**
    * Picks an object at a position defined by display coordinates. If
    * X.renderer3D.config['PICKING_ENABLED'] is FALSE, this function always returns
    * -1.
    *
    * @param {!number} x The X-value of the display coordinates.
    * @param {!number} y The Y-value of the display coordinates.
    * @return {number} The ID of the found X.object or -1 if no X.object was found.
    */
    var pick = r.pick($X, $Y);
    
    0 讨论(0)
  • 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.

    0 讨论(0)
提交回复
热议问题