【问题标题】:Three.JS: Move 3D cube with accelerometer data over x an y-axisThree.JS:在 x 和 y 轴上移动带有加速度计数据的 3D 立方体
【发布时间】:2021-05-05 11:24:01
【问题描述】:

关注my previous post

我正在开发一个 3D 模型,该模型根据加速度计和陀螺仪传感器的输入进行移动。 3D模型用three.js编写,旋转和平移的输入数据为JSON格式。目前 3D 立方体在 3D 空间中移动,但我有两个主要问题:

  1. 当加速度计值过高时,3D 立方体会移出边界。
  2. 3D 立方体似乎只在一个轴上移动,例如,即使有 X、Y 和 Z 值,对象也只在 Y 轴上平移,而不是 UP/DOWN。

我基本上希望 3D 立方体使用 X 轴数据仅向上/向下移动。以下是我的代码:

index.html

import * as THREE from "three";
import data from "../data/data.json"
import "./style.css"

const canvas = document.querySelector('#canvas');
const accelPanel = document.querySelector('#accelPanel');
const renderer = new THREE.WebGLRenderer({ canvas });

const fov = 70;
const aspect = 2;  // the canvas default
const near = 20;
const far = 500;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 50, 1.5);
camera.up.set(0, 0, 1);
camera.lookAt(0, 0, 0);

const scene = new THREE.Scene();
{
    const color = 0x00afaf;
    const intensity = 10;
    const light = new THREE.PointLight(color, intensity);
    scene.add(light);
}
const boxGeometry = new THREE.BoxGeometry();
const boxMaterial = new THREE.MeshBasicMaterial({ color: "green", wireframe: false });
const object = new THREE.Mesh(boxGeometry, boxMaterial);

var cubeAxis = new THREE.AxesHelper(3);
object.add(cubeAxis);

object.scale.set(5, 5, 5)
scene.add(object);
scene.background = new THREE.Color(0.22, 0.23, 0.22);

let currentIndex = 0
let time = data[currentIndex].time
let velocity = new THREE.Vector3()
requestAnimationFrame(render);

function render(dt) {
    dt *= 0.0001 // in seconds
    time += dt
    document.querySelector("#time").textContent = time.toFixed(2)

    // Find datapoint matching current time
    while (data[currentIndex].time < time) {
        currentIndex++
        if (currentIndex >= data.length) return
    }
    const { rotX, rotY, rotZ, accX, accY, accZ } = data[currentIndex]

    const acceleration = new THREE.Vector3( accX, accY, accZ)
    object.rotation.set(rotX, rotY, rotZ)
    object.position.add(velocity.clone().multiplyScalar(dt)).add(acceleration.clone().multiplyScalar(50 * dt ** 2))
    velocity.add(acceleration.clone().multiplyScalar(dt))

    resizeToClient();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

function resizeToClient() {
    const needResize = resizeRendererToDisplaySize()
    if (needResize) {
        const canvas = renderer.domElement;
        camera.aspect = canvas.clientWidth / canvas.clientHeight;
        camera.updateProjectionMatrix();
    }
}

function resizeRendererToDisplaySize() {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
        renderer.setSize(width, height, false);
    }
    return needResize;
}

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
</head>

<body>
    <canvas id="canvas" width="1500" height="800" style="border:1px solid #000000;"></canvas>
    <div id="accelPanel"></div>
    <div id="info">
        <div>t = <span id="time">0</span> s</div>
    </div>
</body>
</html>

我尝试修改这些负责旋转和定位的行:

object.rotation.set(rotX, rotY, rotZ)
object.position.add(velocity.clone().multiplyScalar(dt)).add(acceleration.clone().multiplyScalar(50 * dt ** 2))

但问题似乎不是来自他们。

这是输入数据的示例:

[
    {
        "time": 8029,
        "rotX": 0.836885376331281,
        "rotY": -0.05305800926062761,
        "rotZ": 0.03822271061867582,
        "accX": -0.0265087890625,
        "accY": -0.046376953125,
        "accZ": 0.0312451171875
    },
    {
        "time": 8030.000000000001,
        "rotX": 0.836885376331281,
        "rotY": -0.05305800926062761,
        "rotZ": 0.03822271061867582,
        "accX": -0.0265087890625,
        "accY": -0.046376953125,
        "accZ": 0.0312451171875
    },
    {
        "time": 8031,
        "rotX": 0.836885376331281,
        "rotY": -0.05305800926062761,
        "rotZ": 0.03822271061867582,
        "accX": -0.0265087890625,
        "accY": -0.046376953125,
        "accZ": 0.0312451171875
    }
]

这就是 accelerometerX 数据的样子 (Click here to download the data):

这些是向上和向下的运动,但不知何故,这在动画中没有显示。

有没有办法让3D立方体像下图一样移动(只有UP和DOWN,汽车只是为了说明):

查看 3D 立方体的实时预览,click here(来自我制作的 previous post)。

【问题讨论】:

  • 澄清一下,当您向上/向下旋转您的设备时,您是否试图在 Y 轴上移动汽车?还是当您向上/向下摇晃设备时?
  • 当设备上下移动时,只需想象一辆汽车驶过路面颠簸或坑洼,这需要可视化为上下

标签: javascript html three.js 3d


【解决方案1】:

看起来您正在对 position, velocity, and acceleration 向量进行各种乘法运算,很难衡量最终位置的大小。

你为什么不从简单的东西开始,比如object.position.y = accY * 30; 这样在[-0.1, 0.1] 范围内几乎看不到的数据会变成[-15, 15] 范围,然后你可以对其进行微调。

我注意到的另一个问题是您的相机位置是(0, 50, 1.5),从上到下看起来非常高,因此它不会让您看到任何 y 轴移动。如果您希望您的相机捕捉向上/向下运动,请不要将其放置得太高:camera.position.set(0, 0, 15) 就足够了。

【讨论】:

  • 好的,谢谢,我做了一些修改,一切似乎都很好,我会在清理后发布代码
猜你喜欢
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
相关资源
最近更新 更多