我正在使用three.js尝试以下内容,其中有2种形状:“正方形”和“球形”.
每个对象都有一个与之关联的按钮.如果用户单击一个按钮,则会将相应的形状添加到场景中,但是,在任何时候,场景中只能有1个正方形和1个球体.
如果用户添加新的正方形,则应替换旧的正方形.我似乎无法通过下面的代码来实现这一目标.目前,我可以成功添加正方形和球形对象,当我单击以添加另一个正方形时,当前的正方形不会被替换.
请指教,谢谢!
<html>
<head>
<title>My second three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<button id="button1">Square1</button>
<button id="button2">Square2</button>
<button id="button3">Sphere</button>
<script src="js/three.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75,window.innerWidth/window.innerHeight,0.1,1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth,window.innerHeight );
document.body.appendChild( renderer.domElement );
loader.load( ‘square1.glb’,function ( geometry ) {
geometry.scene.traverse( function ( node ) {
if ( node.isMesh ){
square = node;
square.material.map.anisotropy = maxAnisotropy;
}
document.getElementById("button1").addEventListener("click",function(){
scene.remove(square);
scene.add(square);
});
});
loader.load( ‘square2.glb’,function ( geometry ) {
geometry.scene.traverse( function ( node ) {
if ( node.isMesh ){
square = node;
square.material.map.anisotropy = maxAnisotropy;
}
document.getElementById("button2").addEventListener("click",function(){
scene.remove(square);
scene.add(square);
});
});
loader.load( ‘sphere.glb’,function ( geometry ) {
geometry.scene.traverse( function ( node ) {
if ( node.isMesh ){
sphere = node;
sphere.material.map.anisotropy = maxAnisotropy;
}
document.getElementById("button3").addEventListener("click",function(){
scene.add(sphere);
});
});
var animate = function () {
requestAnimationFrame( animate );
renderer.render( scene,camera );
};
animate();
</script>
</body>
</html>
最佳答案
考虑跟踪< button>范围之外的“当前正方形”形状.单击处理程序,以确保用于在场景中添加和移除这些形状的逻辑能够按预期运行.
具体来说,您将要使用当前的正方形形状(如果存在)调用scene.remove(),而不是使用随后用以下方式调用scene.add()的shape对象来调用它:
/* Current code */
document.getElementById("button1").addEventListener("click",function(){
scene.remove(square); /* You're removing the square object here,*/
scene.add(square); /* and then adding the same square object to the scene */
});
您可能会发现按以下方式调整脚本很有用:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75,1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth,window.innerHeight );
document.body.appendChild( renderer.domElement );
/*
Not sure where you get your loader object from
*/
var loader = ''; // ??
/*
Add this to track current shapes
*/
var currentSquare = '';
var currentSphere = '';
/*
Define a general,reusable method for loading geometry
*/
function loadShape(filename,onLoaded) {
loader.load( filename,function ( geometry ) {
var foundMesh = '';
geometry.scene.traverse( function ( node ) {
if ( node.isMesh ){
foundMesh = node;
foundMesh.material.map.anisotropy = maxAnisotropy;
}
});
if(foundMesh) {
onLoaded(foundMesh)
}
}
}
/*
Use the general loader method defined above
*/
loadShape('square1.glb',function(nextSquare) {
document.getElementById("button1").addEventListener("click",function(){
/*
If current square exists,remove it
*/
if(currentSquare) {
scene.remove(currentSquare);
}
/*
Add the square for the button just clicked
and update currentSquare
*/
scene.add(nextSquare);
currentSquare = nextSquare;
});
})
loadShape('square2.glb',function(nextSquare) {
document.getElementById("button2").addEventListener("click",function(){
if(currentSquare) {
scene.remove(currentSquare);
}
scene.add(nextSquare);
currentSquare = nextSquare;
});
})
loadShape('sphere.glb',function(nextSphere) {
document.getElementById("button3").addEventListener("click",function(){
if(currentSphere) {
scene.remove(currentSphere);
}
scene.add(nextSphere);
currentSphere = nextSphere;
});
})
var animate = function () {
requestAnimationFrame( animate );
renderer.render( scene,camera );
};
animate();
希望这可以帮助!