从屏幕坐标中查找世界坐标

时间:2012-07-17 20:16:45

标签: xtk

这个问题有很多答案,但我不确定它们是否都适用于XTK,例如在Three.JS中看到多个答案,但当然XTK和Three.JS没有相同的API明显。使用光线和Matrix似乎与其他框架的许多其他解决方案非常相似,但我仍然没有在这里抓住可能的解决方案。现在只需找到坐标X,Y和Z并将它们记录到Console.Log中就可以了,稍后我希望创建一个标题/工具提示来显示信息,但还有其他方法可以显示它。但有人至少可以告诉我,是否可以使用光线与物体碰撞?我不确定XTK中的碰撞如何与网格或任何其他文件一起使用。现在任何提示都会很棒!

2 个答案:

答案 0 :(得分:4)

这是我在xtk中取消项目的功能。如果你看错了,请告诉我。现在有了结果点和摄像机位置,我应该能够找到我的交叉点。为了使计算速度更快,我将在拾取事件中调用它,因此我只需要尝试与给定对象的交叉点。如果我有时间,我也会尝试测试边界框。

Nota bene:最后一行不是必需的,我可以处理光线而不是点。

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;
};

修改

Here,在我的回购中,您可以在camera3D.js和renderer3D.js中找到函数,以便在xtk中进行高效的3D拾取。

答案 1 :(得分:2)

现在这不容易实现。我想你可以抓住相机的视图矩阵来计算位置。如果你这样做,那么将它作为内置功能重新引入XTK会很棒!

目前,只能进行对象拾取(r是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);