屏幕坐标世界坐标转换,参考:https://www.babylonjs-playground.com/#1EJNKR#83
网上大多数都是抄的这个。
核心代码,如下:
public screenToWorld(point: Vector2): Vector3 { //https://www.babylonjs-playground.com/#1EJNKR#83 const viewport: Viewport = this.camera.viewport.toGlobal(this.engine.getRenderWidth(), this.engine.getRenderHeight()); return Vector3.Unproject(new Vector3(point.x, point.y, 0), viewport.width, viewport.height, Matrix.Identity(), this.camera.getViewMatrix(), this.camera.getProjectionMatrix()); } public worldToSceen(point: Vector3): Vector3 { const viewPort: Viewport = this.camera.viewport.toGlobal(this.engine.getRenderWidth(), this.engine.getRenderHeight()); return Vector3.Project(point, Matrix.Identity(), this.scene.getTransformMatrix(), viewPort); }
用了Vector3d的Project和Unproject方法。
世界坐标是3维的,屏幕坐标是2维的。2维转3维,必须加个约束,要不转不过去;3维转2维,必须加个约束,要不有无穷多解。
上面的方法,加的约束就是ViewPort对应的平面。
屏幕坐标如何转到指定的平面呢?
比如,拖动地面上的物体,点击屏幕在地面上创建物体等等。
一种是使用pick方法,参见:https://www.babylonjs-playground.com/#12ZRI0#5
核心代码:
public screenToGround(point: Vector2): Vector3 { // https://www.babylonjs-playground.com/#12ZRI0#5 const pickinfo: PickingInfo = this.scene.pick(point.x, point.y, (mesh: Mesh) => { return mesh == this.ground; }); if (pickinfo.hit) { return pickinfo.pickedPoint; } return null; }
还有一种是直接计算射线和平面的交点。参考:https://www.babylonjs-playground.com/#1BGF1O#1
核心代码:
public intersectRayPlane(pRay: Ray, pPlane: Plane): Vector3 { let tIsecPoint: Vector3 = null; const tDot: number = Vector3.Dot(pRay.direction, pPlane.normal); if (tDot !== 0.0) { const t: number = -pPlane.signedDistanceTo(pRay.origin) / tDot; if (t >= 0.0) { const tDirS: Vector3 = pRay.direction.scale(t); tIsecPoint = pRay.origin.add(tDirS); } } return tIsecPoint; } public screenToPlane(point: Vector2, plane: Plane): Vector3 { // https://www.babylonjs-playground.com/#1BGF1O#1 const tRay: Ray = this.scene.createPickingRay(this.scene.pointerX, this.scene.pointerY, BABYLON.Matrix.Identity(), this.camera); return this.intersectRayPlane(tRay, plane); }
以上两个方法的案例都是从这里找到的:https://www.html5gamedevs.com/topic/28075-pick-at-ground-level/
这个也可以看看:https://www.babylonjs-playground.com/#1BGF1O#3
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。