【问题标题】:Three.js WebXR(AR) place object upright on a wall (how to rotate properly)Three.js WebXR(AR) 将物体竖立在墙上(如何正确旋转)
【发布时间】:2020-11-16 20:29:43
【问题描述】:

我正在尝试将一幅画竖直放置在墙上(分别是垂直对齐的表面),但无法正确旋转。为了保持示例小,我删除了绘画材料并将问题转移到标线。正如您在最后两张图片中看到的那样,将标线放置在墙上时非常扭曲。

我的目标是让局部 x 轴始终与地板平行,并且局部 z 轴指向下方。

这与标线的 z 轴在聚焦在地板上时始终面向相机这一侧面事实有关吗?

我试图通过反向旋转来移除不需要的旋转并更改欧拉顺序,但在我看来这是一个更普遍的问题。有人知道如何解决这个问题吗?我无法解决它或找到合适的解决方案,感谢任何帮助。

我从这里得到了主要代码:https://github.com/mrdoob/three.js/blob/master/examples/webxr_ar_hittest.html

import * as THREE from 'three'
import { ARButton } from 'three/examples/jsm/webxr/ARButton'

var camera
var scene 
var renderer
var arbutton
var controller
var reticle

var hitTestSource = null
var hitTestSourceRequested = false

init()
renderer.setAnimationLoop(render);

function init() {
    renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.xr.enabled = true;

    arbutton = ARButton.createButton(renderer, { 
        requiredFeatures: ['hit-test'],
        optionalFeatures: ['dom-overlay'],
        domOverlay: { root: document.getElementById('arOverlay') } 
    })
    document.body.appendChild(arbutton);

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 20);

    var light = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 1);
    light.position.set(0.5, 1, 0.25);
    scene.add(light);

    reticle = new THREE.Mesh(new THREE.RingBufferGeometry(0.15, 0.2, 32).rotateX(-Math.PI/2), new THREE.MeshBasicMaterial());
    reticle.matrixAutoUpdate = false;
    reticle.visible = false;
    scene.add(reticle);
    reticle.add(new THREE.AxesHelper(0.5));
    reticle.add(new THREE.Mesh(new THREE.PlaneBufferGeometry(0.1, 0.1), new THREE.MeshBasicMaterial()))

    controller = renderer.xr.getController(0);
    scene.add(controller);

    scene.add(new THREE.AxesHelper(1));
}

function render(timestamp, frame) {
    if(frame){
        var referenceSpace = renderer.xr.getReferenceSpace();
        var session = renderer.xr.getSession();

        if (hitTestSourceRequested === false) {
            session.requestReferenceSpace('viewer').then(function (referenceSpace) {
                session.requestHitTestSource({ space: referenceSpace }).then(function (source) {
                    hitTestSource = source;
                });
            });
            session.addEventListener('end', function () {
                hitTestSourceRequested = false;
                hitTestSource = null;
            });
            hitTestSourceRequested = true;
        }

        if (hitTestSource) {
            var hitTestResults = frame.getHitTestResults(hitTestSource);
            if (hitTestResults.length) {
                var hit = hitTestResults[0];
                reticle.visible = true;
                reticle.matrix.fromArray(hit.getPose(referenceSpace).transform.matrix);

                // TODO apply some additional rotation here

            } else {
                reticle.visible = false;
            }
        }
    
    }
    renderer.render(scene, camera);
}


【问题讨论】:

  • 根据我对 XR 的有限经验,这应该由 AR 引擎处理,它应该从环境和设备传感器收集方向提示。也就是说,您的输入(托盘)可能会混淆它。当您将其瞄准为光滑的规则表面(如墙壁)时,它会做同样的事情吗?
  • 是的,瞄准真实墙壁时也会出现同样的问题。调色板的识别度更高。

标签: javascript three.js rotation augmented-reality webxr


【解决方案1】:

我想出了一个解决方法,我将标线绕 y 轴旋转到 xz 平面的角度。

let aX = new Vector3()
reticle.matrix.extractBasis(aX, new Vector(), new Vector())

let yUp = new Vector3(0,1,0)
let alpha = Math.asin(aX.dot(yUp)) 
                    
let m = new Matrix4()
m.makeRotationY(Math.PI+alpha) 

reticle.matrix.multiply(m)                    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-28
    • 2012-09-28
    • 2013-07-17
    • 2018-09-28
    • 2017-02-21
    • 2021-01-08
    • 2020-08-11
    • 2017-01-19
    相关资源
    最近更新 更多