Three.JS:在 x 和 y 轴上移动带有加速度计数据的 3D 立方体

Three.JS: Move 3D cube with accelerometer data over x an y-axis

正在关注

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

  1. 加速度计值过高时 3D 立方体移出边界。
  2. 好像3D立方体只在一个轴上移动,比如虽然有X、Y、Z值,但物体只在Y轴平移,没有UP/DOWN。

我基本上希望 3D 立方体仅 UP/DOWN 使用 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立方体像下图那样移动(只有上下移动,汽车只是为了说明):

查看 3D 立方体的实时预览,click here (it is from the 我制作的)。

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

你为什么不从一些简单的开始,比如object.position.y = accY * 30;所以在[-0.1, 0.1]范围内几乎看不到的数据变成了[-15, 15]范围,然后你就可以了-调整它。

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