Threejs:为什么添加Axes Helper会更改元素的Id



我有以下问题。当我将轴辅助程序添加到场景中时,所有元素的Id都会增加一。这方面的问题是,我想根据元素的Id来选择它们。所以在添加Helper之后,我无法选择正确的元素。

如果我把新的THREE.AxesHelp((放在这个函数之外,问题就不存在了。那么,为什么将Axis Helper放在init函数中是个问题呢?

init() {
// ---------------------- General settings ----------------------
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 60, window.innerWidth/window.innerHeight, 0.1, 1000 );     
camera.position.x = 8.3;
camera.position.y = 11.7;
camera.position.z = -8;
camera.lookAt( new THREE.Vector3( 0, 0, 0 ) );
const ambiLight = new THREE.AmbientLight( 0xFFFFFF, 0.5 );
scene.add(ambiLight);
const spotLight = new THREE.SpotLight( 0xFFFFFF, 0.6 );
spotLight.position.set( 13.6, 20.1, -13.9 );
spotLight.castShadow = true;
scene.add( spotLight );
// ---------------------- Load Object ----------------------
const gltfLoader = new THREE.GLTFLoader();
gltfLoader.load( "model/M-62300-00-811-0_002.glb", function( gltf ) {
model = gltf.scene;
model.rotateX( -Math.PI/2 );
scene.add( model );
console.log( model );
model.getObjectById( 120 ).visible = false;     // initial foundation
model.getObjectById( 120 ).children[0].material.color.set( "#959595" );
model.getObjectById( 121 ).visible = false;     // initial person
});
// ---------------------- Renderer settings ----------------------
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
document.body.appendChild( renderer.domElement );
renderer.setClearColor( 0xffffff, 0 );
// ---------------------- Orbit Controls settings ----------------------
const controls = new THREE.OrbitControls( camera, renderer.domElement );
// ---------------------- Axes helper ----------------------
const axesHelper = new THREE.AxesHelper( 3 );
axesHelper.position.y = 2;
scene.add( axesHelper );
// ---------------------- Call functions ----------------------
createPanel();
update( renderer, scene, camera, controls );
}

Object3D按创建顺序从0开始递增设置其ID。因此,如果之前创建了更多对象,则之前检查的ID将发生偏移。

如果在init()函数中创建轴辅助对象,则它们的对象将在GLTF加载之前创建。这是因为GLTFLoader是异步的,所以后面的代码会继续执行,只有当GLTF加载完成时,回调中的代码才会运行。到那时,您的轴辅助对象已经创建,您的ID将发生偏移。

如果你只是想改变这一点,你可以在创建GLTF模型后,简单地在回调中创建你的axis辅助对象。像这样:

const gltfLoader = new THREE.GLTFLoader();
gltfLoader.load( "model/M-62300-00-811-0_002.glb", function( gltf ) {
model = gltf.scene;
model.rotateX( -Math.PI/2 );
scene.add( model );
console.log( model );
model.getObjectById( 120 ).visible = false;     // initial foundation
model.getObjectById( 120 ).children[0].material.color.set( "#959595" );
model.getObjectById( 121 ).visible = false;     // initial person
const axesHelper = new THREE.AxesHelper( 3 );
axesHelper.position.y = 2;
scene.add( axesHelper );
});

但是,ID不应该像这样保持不变,因为将来您可能会添加更多的对象,并再次导致相同的问题。相反,如果您知道要访问哪些子项,则可以通过model.children(如果需要,可以递归(或traverse()获取它们,或者取决于如何识别您选择的子项。有关详细信息,请参见Object3D文档。

最新更新