javascript - Three.js程序返回:“无法读取未定义的属性'0'”
问题描述
以下代码用于对an object according to
四元数数据进行动画处理:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry = new THREE.BoxGeometry( 1, 0.3, 2 );
var material = new THREE.MeshBasicMaterial( { color: 0xf4b942 } );
var obj = new THREE.Mesh( geometry, material );
scene.add( obj );
var geometry = new THREE.BoxBufferGeometry(1, 0.3, 2 );
var edges = new THREE.EdgesGeometry(geometry);
var lines = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 0x000000 }));
scene.add( lines );
camera.position.z = 5;
renderer.render(scene,camera);
var xpos_o = obj.rotation.x;
var ypos_o = obj.rotation.y;
var zpos_o = obj.rotation.z;
var xpos_lo = lines.rotation.x;
var ypos_lo = lines.rotation.y;
var zpos_lo = lines.rotation.z;
let i = 0; let m = 0;
var animate = function (quat_data) {
requestAnimationFrame( animate );
if (m % 5 == 0 || m == 0) {
if (m !== 0) {i++;}
if (i >= quat_data.length){
obj.rotation.x = xpos_o;
obj.rotation.y = ypos_o;
obj.rotation.z = zpos_o;
lines.rotation.x = xpos_lo;
lines.rotation.y = ypos_lo;
lines.rotation.z = zpos_lo;
i=0;
}
let quat = quat_data[i];
var quaternion = new THREE.Quaternion(quat[0],quat[1],quat[2],quat[3]);
obj.applyQuaternion(quaternion);
lines.applyQuaternion(quaternion);
renderer.render( scene, camera );
}
m++;
}
var animate1 = function() {
var quat_data1 = [ [0.681492531,-0.014533572,0.711492547,-0.170668778 ],
[-0.81103207,0.125979118,0.555748976,-0.132257921 ],
[-0.459080697,-0.267181198,-0.846533742,0.035103342 ],
[0.874097952,-0.166578614,-0.244525976,0.385231457 ],
...
animate(quat_data1);
}
var animate2 = function() {
var quat_data2 = [[-0.395306087,-0.567475272,-0.168275478,-0.702416024 ],
[0.591221013,-0.226393713,-0.208636898,0.745435603 ],
[-0.279990579,0.754847831,0.56444738,-0.182233852 ],
[-0.419803039,-0.623439075,-0.538698243,-0.380648559 ],
[0.878036311,0.088829796,-0.024437397,0.469642749 ],
...
animate(quat_data2);
}
var animate3 = function() {
var quat_data3 = [ [-0.17958507,0.232682609,-0.217296778,-0.930800793 ],
[-0.178598829,0.228014038,-0.2182292,-0.931927075 ],
[-0.177601473,0.223351625,-0.219152185,-0.933029522 ],
[-0.176574343,0.218685883,-0.220066047,-0.934113976 ],
[-0.175533915,0.214015872,-0.22097227,-0.935177153 ],
[-0.174483815,0.209350901,-0.221866773,-0.936217247 ],
[-0.173407996,0.204681945,-0.222753878,-0.937238325 ],
...
animate(quat_data3);
}
我省略了一些quaternion
数据并用省略号替换以节省空间。开始部分简单地建立了场景的几何形状。animate 函数接受一个 s 数组quaternion
。每次迭代后requestAnimationFrame
,m 增加 1,每次达到 5 的倍数时,执行动画代码。(这是因为我想将 60 fps 转换requestAnimationFrame
为 12 fps。)动画代码将 i 增加 1(移动到下一个quaternion
)并应用quaternion
. 如果 i 超过数据数组的长度quaternion
,则它会循环回到数据的开头并重置对象的原始方向。
还有其他三个函数 、animate1
和animate2
,animate3
它们使用不同的quaternion
数据集来执行animate
函数。
当我单击要执行的 html 代码中的按钮时animate1
,控制台在以下行给出了问题中所述的错误:
var quaternion = new THREE.Quaternion(quat[0],quat[1],quat[2],quat[3]);
解决方案
问题是动画 ( requestAnimationFrame
) 在错误的位置和错误的回调目标执行。回调函数只传递一个参数,即时间值。
var animate = function (quat_data) { requestAnimationFrame( animate ); // [...] let quat = quat_data[i]; var quaternion = new THREE.Quaternion(quat[0],quat[1],quat[2],quat[3]); // [...] }
您所期望的是函数的输入animate
是动画数据数组,但它是单个时间值。
你必须这样做:
var animate = function (quat_data) {
requestAnimationFrame( function() { animate(quat_data); } );
// [...]
}
推荐阅读
- php - 如何使用 Postgresql 和 Codeigniter 更新多个表
- powershell - PowerShell如何根据字符串中值的变化将文本文件拆分为多个
- python - 如何使用 keras fit_generator 处理最后一批
- composer-php - 如何将作曲家用于基于服务器和前端的组件
- php - 用减号展开整数范围
- python - 重新排列行值
- html - 是什么导致滚动条落后于固定 div
- javafx - 如何平移 JavaFX LineChart
- android - Firestore Get:指定失败侦听器有用还是我们可以只使用 if(!task.isSuccessful())?
- java - 如何修改 Rod-Cutting 问题以使尺寸增加一倍以上