在使用 WebXR 和 dom-overlay 时,我正在尝试在 a-frame AR 场景中实现与 3d 模型的一些交互。
所以我设法实现了命中测试,并且可以在检测到的平面上创建和放置 3d 对象。dom-overlay 也适用于添加普通的可交互 html/css 按钮。但是对我来说不能正常工作的是与创建的 3d 对象的交互。当触摸移动屏幕时,我尝试激活从相机位置到平移的 2D 点的光线投射。
我创建了一个将不同示例合并在一起的小示例(命中测试、dom-overlay、raycast-direction 的计算):https
://glitch.com/edit/#!/ Famous-outstanding-brother
所以,首先你需要检测到一个平面,一个标线会出现,你可以放置小盒子。当您切换左下角的开关时,命中测试将关闭,您应该“触摸”创建的框,以便它们改变颜色。要使用 a-frame raycaster,我会在“叠加层”上收听触摸事件(因为其他事件不会触发,我认为这是获取接触点的 ax/y 坐标的唯一方法)并自己设置方向. 在屏幕中央,它确实工作得很好。
GIF:Hit-Test 和来自屏幕中心接触点的光线投射效果很好
但是,您的触摸越靠近屏幕边缘,它就越不精确。如果 3d 对象离得更远一点,改变盒子颜色的正确接触点就会移位(你需要更靠近中心点触摸)。所以我猜光线投射方向的计算有点错误?!?
GIF:屏幕边缘的光线投射方向关闭
component.camera = component.el.sceneEl.camera;
component.camera.parent.updateMatrixWorld();
const screenPosition = {x: ev.touches[0].screenX, y: ev.touches[0].screenY};
const origin = new THREE.Vector3();
const direction = new THREE.Vector3();
const raycasterConfig = {origin: origin, direction: direction};
origin.setFromMatrixPosition(component.camera.matrixWorld);
const normalizedScreenPosition = {x: screenPosition.x/document.body.clientWidth * 2 -1, y: -(screenPosition.y/document.body.clientHeight) * 2 + 1};
const matrix = new THREE.Matrix4();
const matrixInverse = matrix.copy(component.camera.projectionMatrix).invert();
direction.set(normalizedScreenPosition.x, normalizedScreenPosition.y, 0.5).applyMatrix4(matrixInverse).applyMatrix4(component.camera.matrixWorld).sub(origin).normalize();
component.el.setAttribute("raycaster", raycasterConfig);
我在网上搜索,但找不到实际使用这些设置的示例。我只是在问自己,如果我只是盲目并且有简单的方法,或者是否真的有一些无法解决的问题(目前)。
所以任何帮助将不胜感激!