Finding world coordinates from screen coordinates

守給你的承諾、 提交于 2019-11-29 23:27:45

问题


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 don't have the same API obviously. Using a ray and Matrix seemed very similar to many other solutions for other frameworks, but I'm still not grasping a possible solution here. For now just finding the coordinates X, Y, and Z and recording them into Console.Log is fine, later I was hoping to create a caption/tooltip to display the information, but there is other ways to display it also. But can someone at least tell me if this is possible to use a ray to collide with the objects? I'm not sure how collision works in XTK with meshes or any other files. Any hints right now would be great!!


回答1:


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.




回答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);


来源:https://stackoverflow.com/questions/11530198/finding-world-coordinates-from-screen-coordinates

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!