我正在尝试将一幅画直立在墙上(分别是垂直对齐的表面),但在正确旋转时遇到了困难。为了使示例保持较小,我删除了绘画材料并将问题转移到标线。正如您在最后两张图片中看到的那样,将标线放在墙上时非常扭曲。
我的目标是让局部 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);
}