使用three.js,并改编了此处提供的West Langley文章中的说明: Three.js:添加和删除旋转对象的子代,我设置了一个WebGL场景,在该场景中添加了五个立方体网格。最初,所有对象都是场景的子级,然后,将它们附加到第五个“ parentCube”多维数据集,并沿Y轴平移100个单位,从而平移其他四个多维数据集,然后分离它们。
之后,我想独立地将“ parentCube”多维数据集(以前是四个多维数据集的父级)转换回原点,但是,当我执行该转换时,其他四个多维数据集网格也将与前一个父级多维数据集网格一起转换,甚至当我拆下它们时。
这可能是一个非常基本的问题,但是考虑到以上所有详细信息,如何在不影响其他多维数据集的位置的情况下独立转换“ parentCube”呢?我的支队哪里出问题了?任何帮助,将不胜感激。谢谢 :)
这是我用来执行上述所有操作的代码示例:
//Create parentCube mesh
var parentCube = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 10, 10, 10), new THREE.MeshBasicMaterial({ color: 0xa1ff11, wireframe: true }));
scene.add(parentCube);
//...create materials for the child cubes....
//create child cube mesh
for(var i = 0; i < 4; i++)
cubeMesh[i] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 30, 30, 30), materials[i]);
//--> Set child cube world positions before the attachment to parentCube mesh
cubeMesh[0].position.set((100 / 2),(100 / 2),(100 / 2));
cubeMesh[1].position.set(-(100 / 2),(100 / 2),(100 / 2));
cubeMesh[2].position.set(-(100 / 2),-(100 / 2),(100 / 2));
cubeMesh[3].position.set((100 / 2),-(100 / 2),(100 / 2));
//Add child cubes to the scene
for(var i = 0; i < cubeMesh.length; i++)
scene.add(cubeMesh[i]);
//attach child cubeMesh[i] to parentCube mesh
for(var i = 0; i < 4; i++)
THREE.SceneUtils.attach(cubeMesh[i], scene, parentCube);
//--> Set positions of child elements after attachment to parentCube
cubeMesh[0].position.set((100 / 2),(100 / 2),(100 / 2));
cubeMesh[1].position.set(-(100 / 2),(100 / 2),(100 / 2));
cubeMesh[2].position.set(-(100 / 2),(100 / 2),-(100 / 2));
cubeMesh[3].position.set((100 / 2),(100 / 2),-(100 / 2));
//translate parentCube
parentCube.position.set(0,150,0);
parentCube.updateMatrixWorld();
//Attempt to detach child objects from parentCube
//And make them children of the scene
for(var i = 0; i < 4; i++)
{
cubeMesh[i].updateMatrixWorld();
THREE.SceneUtils.detach(cubeMesh[i], parentCube, scene);
}
//Attempt to translate parentCube back to origin
parentCube.position.set(0,0,0);
}
你的代码行
THREE.SceneUtils.detach(cubeMesh[i], scene, parentCube);
应该
THREE.SceneUtils.detach(cubeMesh[i], parentCube, scene);
我已经用你的示例进行了演示,我认为应该是正确的方法。
的HTML
<body>
<button onclick="attachChild();">attach</button>
<button onclick="detachChild();">dettach</button>
</body>
的JavaScript
var camera, scene, renderer;
var geometry, material1, material2;
var parentCube;
var cubeMesh = [];
var cameraControls;
var attached = true;
window.onload = function() {
init();
animate();
}
function init() {
camera = new THREE.PerspectiveCamera(75, 2, 1, 10000);
camera.position.z = 400;
camera.position.y = 100;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry(200, 200, 200);
material1 = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
//Create parentCube mesh
parentCube = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material1);
scene.add(parentCube);
//...create materials for the child cubes....
material2 = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
//create child cube mesh
cubeMesh[0] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material2);
cubeMesh[1] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material2);
cubeMesh[2] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material2);
cubeMesh[3] = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100, 1, 1, 1), material2);
//--> Set child cube world positions before the attachment to parentCube mesh
cubeMesh[0].position.set(100,100,0);
cubeMesh[1].position.set(-100,100,0);
cubeMesh[2].position.set(-100,-100,0);
cubeMesh[3].position.set(100,-100,0);
//Add child cubes to the scene
for (var i = 0; i < 4; i++)
parentCube.add(cubeMesh[i]);
//translate parentCube
parentCube.position.set(0,50,0);
renderer = new THREE.CanvasRenderer();
renderer.setSize(600, 300);
document.body.appendChild(renderer.domElement);
// CONTROLS
cameraControls = new THREE.OrbitControls(camera);
cameraControls.addEventListener( 'change', render );
}
function animate() {
cameraControls.update();
requestAnimationFrame(animate);
parentCube.rotation.z += 0.01;
render ();
}
function render () {
renderer.render(scene, camera);
}
function attachChild () {
if (attached) {
alert ("already attached");
} else {
for (var i = 0; i < 4; i++)
THREE.SceneUtils.attach(cubeMesh[i], scene, parentCube);
attached = true;
}
}
function detachChild () {
if ( ! attached) {
alert ("not attached");
} else {
for (var i = 0; i < 4; i++)
THREE.SceneUtils.detach(cubeMesh[i], parentCube, scene);
attached = false;
}
}
特别注意,我将孩子直接添加到父对象(而不是场景),并且我认为它们从一开始就是附加的。之后,分离并重新连接它们可以按预期工作
如何将其用于Rubik的立方体模拟?
我只是创建添加到场景中的所有多维数据集。
然后,要执行移动,你必须
效果很好。另外,由于我是WebGL开发的新手,所以我想知道:是否总是需要在将子元素作为对象绑定到对象(在这种情况下,将cubeMesh [i]附加到parentCube)后在世界空间中重新放置子元素?已经做完了吗?还是有一些更简单的解决方法?每当我父对象时,即使我在附加之前为孩子分配了世界空间位置,子对象也会占据父对象的位置。提前致谢。
进行附加时,网格物体不应更改世界坐标。因此,如果以前已定位,则它应该保持全球位置,并且您无需执行任何其他操作。如果不是这种情况,请发布更多代码,我来看一下
我更新了主要问题的代码,以反映评论中提出的问题。在创建了cubeMesh [i]子多维数据集(在对parentCube的附件之前)之后,我设置了它们的全局位置。将cubeMesh [i]附加到parentCube之后,我必须再次重置它们在世界空间中的位置(请参考代码中带箭头的注释部分)。如果在附件之后不执行此操作,则所有cubeMesh [i]网格都将重新放置在parentCubes的位置,从而失去其原始世界空间的位置。谢谢。
我相信问题在于,在设置对象位置并将它们附加到父对象之间,您还没有经过任何渲染。如果是这样,这是一种真正的方法吗(您真的需要将它们附加到父对象上吗?),为什么不将它们添加到父对象而不是场景中呢?
谢谢你的例子。从中了解了很多。我实际上是在对Rubik的多维数据集进行建模和动画处理,因此cubeMesh [i](子多维数据集)将被动态地附加和分离到parentCube cube / object3D()(使用了哪个)。