1. 程式人生 > >three添加和移除對象

three添加和移除對象

parameter mesh function remove listen inner set doctype 質變

創建場景
在第一章的地方就講過怎麽樣創建一個最基本的場景,這裏不重復了
html:部分

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcss.com/three.js/92/three.min.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script src="https://threejs.org/examples/js/libs/dat.gui.min.js"></script>
<title>場景</title>
<style>
body{
margin:0;padding:0;
overflow:hidden;
}
</style>
</head>
<body>
<div id="WebGL-output"></div>
</body>
js:部分

var scene,camera,renderer,axes;
function init(){
scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(-30,30,30);
camera.lookAt(scene.position);

renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0Xeeeeee));
renderer.shadowMapEnabled;
renderer.setSize(window.innerWidth,window.innerHeight);
document.getElementById("WebGL-output").appendChild(renderer.domElement);


axes = new THREE.AxesHelper(20);
scene.add(axes);

planeGeometry = new THREE.PlaneGeometry(60,30);
var planeMaterial = new THREE.MeshPhongMaterial({color:0xeeeeee});
var plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.position.set(15,0,0);
plane.rotation.x = -0.5*Math.PI;
scene.add(plane);

var stats = new Stats();
document.body.appendChild(stats.dom);

var controls = new THREE.TrackballControls(camera,renderer.domElement);
controls.maxDistance = 400.0;
controls.minDistance = 20.0;

var spotlight = new THREE.SpotLight(0xffffff);
var spotlightHelper = new THREE.SpotLightHelper(spotlight);
spotlight.position.set(-50,100,2);
spotlight.castShadow = true;
spotlight.shadow.mapSize.width = 2000; // default512
spotlight.shadow.mapSize.height = 2000; // default512
scene.add(spotlight);
scene.add(spotlightHelper);


function animate(){
requestAnimationFrame(animate);
renderer.render(scene,camera);
controls.update();
stats.update();
}

function onResize(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}

window.addEventListener(‘resize‘, onResize, false);
animate();
onResize();
}
init();

上面的代碼運行之後可以看到一個有點像是金屬材質的平面

創造

向這個場景中加入對象的方法,把這個方法放在gui組件裏面:
外部全作用域:

var guiControl = new function(){
this.addCube = function(){
var cubeSize = Math.ceil(Math.random()*3);//大小1-3之間 1,2,3
var cubeGeometry = new THREE.BoxGeometry(cubeSize,cubeSize,cubeSize);
var cubeMaterial = new THREE.MeshLambertMaterial({color:Math.random()*0xffffff});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

cube.castShadow = true;
cube.name = "方塊—" + scene.children.length;
console.log(planeGeometry.parameters.width);
cube.position.x = -16 + Math.round((Math.random() * planeGeometry.parameters.width));
cube.position.y = 2 + Math.round(Math.random() * 20);
cube.position.z = - 15 + Math.round((Math.random()*planeGeometry.parameters.height));
console.log("添加方塊:"+cube.name);
scene.add(cube);
}
}
這裏面有一個生成一個隨機顏色方塊的方法並放在了一個對象當中
在init方法中添加,初始化dat gui對象:

var gui = new dat.GUI(); gui.add(guiControl, ‘addCube‘);

然後運行,在右上角的gui面板中按addcube,就會在平面上隨機產生一個新的立方體
生成很多個立方體:
在init函數中添加代碼

function addmanycube(number){ for (var i = 0 ; i < number; i++){ guiControl.addCube(); } } addmanycube(50);

移除:

既然談到了創造,就不得不說毀滅,這是與創造相對應的
在gui控制組件對象中添加函數:

var guiControl = new function(){
...
this.removeCube = function(){
var allChildren = scene.children;
var lastObject = allChildren[allChildren.length-1];
if(lastObject instanceof THREE.Mesh){
scene.remove(lastObject);
this.numberOfObjects = scene.children.length;
}
}

...

}
然後將這個函數添加進gui控制組件中:

init(){ ... gui.add(guiControl, ‘removeCube‘); ... }

這個時候:點擊左上角的removeCube就會讓方塊消失一個:這裏的對象組類似於堆棧,先添加的方塊是最後移除的,後添加的方塊最先移除

獲取某個對象
方法:.getObjectById();
通過唯一的id標示來獲取對象;
之前已經生成過50個方塊,我們試試從其中獲取一個方塊 並且讓他的速度更快一些:

function animate(){
requestAnimationFrame(animate);
renderer.render(scene,camera);
scene.traverse(function (obj) {
if(obj instanceof THREE.Mesh && obj != plane){
//obj.rotation.x += guiControl.rotateSpeed;
obj.rotation.y += (guiControl.rotateSpeed);
}
});
var obj = scene.getObjectById(20);//獲取這個方塊
obj.rotation.y += 0.4;//讓這個方塊每幀比其他方塊快0.4
controls.update();
stats.update();
}
然後你就會發現我就是我,是不一樣的煙火,在所有速度都一樣塊的方塊中,有一個方塊有點不太一樣,它轉的比別人更快了。

添加霧化效果

這是一個內置的函數,可以添加霧化效果,在遠處的物體會被一層定義了顏色的霧覆蓋,這樣會讓畫面更有深度的感覺:
在gui控制器中添加霧化效果函數

var guiControl = new function(){
...
this.fog = function(){
scene.fog = new THREE.Fog( 0xffffff, 0.01, 100)//霧氣顏色,近處的距離, 遠處的距離
}
}

//在init函數中將這個方法添加控制按鈕
function init(){
...
gui.add(guiControl, ‘fog‘);
...
}
運行,點擊右上角的控制面板fog按鈕,場景就能產生霧化效果了

覆蓋材質

覆蓋材質是一個場景屬性,可以讓這個場景中所有對象的材質變成一樣:

scene.overrideMaterial = new THREE.MeshPhongMaterial({color:0xffffff});
這會讓整個場景中所有的對象的材質變得一樣:

包括其中的輔助線的材質都變掉了,這個屬性並不是很常用。

three添加和移除對象