【发布时间】:2020-05-10 21:16:51
【问题描述】:
我在另一个论坛上问过,但我想我想更清楚地了解我的问题。
我的意图是什么? 目前我在我的android设备上的WebView中使用three.js并创建了一个场景,其中包含一个简单的框(应该用作边界框)和一个相机。我的相机需要与我的 android 设备交互,这意味着我通过动态移动设备来设置位置。这些向量来自一个名为 Direct Sparse Odometry 的 SLAM 算法,该算法重新创建了相机位置,我还可以使用 Android 提供的 WebViewInterface 使用 javascript 调用这些值。我的目标是在每次更改值时不使用 camera.lookAt()-Method 动态地“走动”盒子,因为如果我离开盒子,视图不应该再居中(就像 AR 应用程序一样) ),因此应动态创建视点,例如相机朝向对象的位置和旋转。我的目标是使用 three.js 将对象放置在真实世界对象上,以便稍后使用 DSO 扫描它,方法是在盒子周围走动以检测特征点。整个可视化应该用three.js创建。
什么是 DSO? DSO 是一个通过检测相机帧中的点来跟踪真实环境的库,由 Android 的相机 2 API 提供。这会向我发送一个具有当前姿势的 4x4 变换矩阵,我尝试将其应用于 three.js 的相机位置。由于该算法的复杂性,假设这给了我正确的值(以米为单位,但我也尝试将这些值乘以 10 或 100 以获得大于 0.XX 的结果)。
我的问题是什么? 即使值似乎是固定的,该框似乎也没有绝对位置。每次放置 Box 时,它似乎都会朝相反的方向移动。在对 dso 值进行了多次调整之后,我很清楚这是三个.js 发生的问题。 我还尝试应用场景/相机的矩阵和/或将盒子用作子对象(因为对象遗传),但盒子似乎在场景中没有绝对位置。我也无法旋转看起来很真实的对象。
附上,你会找到我的代码,但是 p 请注意,我使用动态虚拟值来替代 dso 值。
<body>
<canvas id="mCanvas">
</canvas>
</body>
<script>
// Var Init
var renderer, scene, camera, box, transformControl, orbitControl, geometry, material, poseMatrix;
var mPoints = [];
//Box coordinate
var xBCordinate, yBCordinate, zBCordinate, isScaled, posVec, startPosVec, lookPos, helper;
var process = false;
var scanActive = false;
var pointArr = [];
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer({canvas: document.getElementById("mCanvas"),
alpha: true});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.setClearColor(0xffffff, 0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.up.set(0, 0, 1); // Definition of coordinationsystem
// set initial scale position of camera
camera.position.x = 0;
camera.position.y = -0.5;
camera.position.z = 0.15;
scene.add(camera);
// set position to look at
camera.lookAt(0,2.5,-0.2);
// apply values
camera.updateMatrix();
// light
var light = new THREE.HemisphereLight( 0xeeeeee, 0x888888, 1 );
light.position.set( 0, -0.75, 2.5 );
scene.add(light);
placeBox();
}
function placeBox()
{
geometry = new THREE.BoxGeometry(0.5, 1, 0.5); //3,5,3
material = new THREE.MeshLambertMaterial({color: 0xfece46});
box = new THREE.Mesh(geometry, material);
box.position.set(0, 2.5, -0.2);
box.updateMatrix();
scene.add(box);
}
function animate() {
requestAnimationFrame(animate);
if(process == false){
setCurrentPose();
}
renderer.render(scene, camera);
}
function setCurrentPose(){
process = true;
// this is where I receive the position data via Android
// but lets try using random numbers between 0.01 - 0.99 (which are the results interval of dso)
moveRotateCamera();
}
function moveRotateCamera(){
// Create Vector to work with
posVec = new THREE.Vector3();
posVec.x = getRandomFloat(0.01, 0.99);
posVec.y = pgetRandomFloat(0.01, 0.99);
posVec.z = getRandomFloat(0.01, 0.99);
camera.position.x = posVec.x;
camera.position.y = (posVec.y) - 0.50; // minus initial scale position
camera.position.z = (posVec.z) + 0.15;
// camera.updateMatrix(); <- seem to change nothing such as UpdateWorldMatrix() etc.
// camera rotation tried to calculate with quaternions (result NaN) and/or euler by using former and current point.
process = false;
}
function getRandomFloat(min, max) {
return Math.random() * (max - min) + min;
}
// My attempts in trying to calculate the rotation
/*
function setQuaternionRotation(poseMatrix){
// TODO: delete if not needed!
// adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm, 2.12.2019, 2.34pm
mQuaternion = new THREE.Quaternion();
// Calculate Angle w
mQuaternion.w = ((Math.sqrt(Math.max(0, (1.0 + poseMatrix.elements[0] + poseMatrix.elements[5] + poseMatrix.elements[10])))/2.0));
//Sign x,y,z values of quaternion
mQuaternion.x = ((Math.sqrt(Math.max(0, (1.0 + poseMatrix.elements[0] - poseMatrix.elements[5] - poseMatrix.elements[10])))/2.0));
mQuaternion.y = ((Math.sqrt(Math.max(0, (1.0 - poseMatrix.elements[0] + poseMatrix.elements[5] - poseMatrix.elements[10])))/2.0));
mQuaternion.y = ((Math.sqrt(Math.max(0, (1.0 - poseMatrix.elements[0] - poseMatrix.elements[5] + poseMatrix.elements[10])))/2.0));
//Sign element values
mQuaternion.x = (Math.sign(mQuaternion.x * (poseMatrix.elements[6] - poseMatrix.elements[9])));
mQuaternion.y = (Math.sign(mQuaternion.y * (poseMatrix.elements[8] - poseMatrix.elements[2])));
mQuaternion.z = (Math.sign(mQuaternion.z * (poseMatrix.elements[1] - poseMatrix.elements[4])));
// debug
console.log("QuaternionVal: "+mQuaternion.x+ ", " +mQuaternion.y+", "+mQuaternion.z+", "+mQuaternion.w);
camera.applyQuaternion(mQuaternion);
camera.quaternion.normalize();
// debug
console.log("newCamRotation: "+camera.rotation.x +", "+camera.rotation.y+", "+ camera.rotation.z);
// camera.updateMatrix(true);
}
*/
</script>
你有什么建议吗?
非常感谢您!
最好的问候,
【问题讨论】:
标签: javascript android three.js augmented-reality