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 但我有两个主要问题:
- 加速度计值过高时 3D 立方体移出边界。
- 好像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)
就足够了。
正在关注
我正在开发一个基于来自加速度计和陀螺仪传感器的输入移动的 3D 模型。 3D模型是用three.js写的,旋转和平移的输入数据是JSON格式。目前 3D 立方体在 3D 中移动 space 但我有两个主要问题:
- 加速度计值过高时 3D 立方体移出边界。
- 好像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)
就足够了。