項目要用到web3d 但是webgl學習起來太麻煩,先用three.js庫寫這點,初期做個記錄。
關於框架的基本搭建和js引入,場景相機等的基本添加就不說明了,隨便搜一下就一堆說明,重點說下如何在牆壁上挖一個門出來。
首先使用了ThreeBSP.js的類庫
<script src="js/ThreeBSP.js"></script>
然後是主要代碼:
var sphere1BSP = new ThreeBSP(cube);
var cube2BSP = new ThreeBSP(door_cube);
resultBSP = sphere1BSP.subtract(cube2BSP);
result = resultBSP.toMesh();
result.material.shading = THREE.FlatShading;
result.geometry.computeFaceNormals();
通過兩個幾何體生成BSP對象,然後通過對象1的的substract函數來減去對象2,然後生成最後的對象,相當於在牆上把門給挖除了。
大概邏輯就這個樣子,很簡單,做個備註,以防止自己忘記。大家不要糾結變量的名字之類的,半成品做個紀念而已
把整個代碼也貼上吧,不要忘記,哇咔咔
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100%; }
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/ThreeBSP.js"></script>
<script>
var scene;
function initScene(){
scene = new THREE.Scene();
}
function updateControls() {
controls.update();
}
var camera;
function initCamera(){
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 40;
camera.position.y = 40;
camera.position.x = 20;
camera.lookAt({x:0,y:0,z:0});
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', updateControls );
}
var renderer;
function initRender(){
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.setClearColor(0xFFFFFF, 1.0);
}
var light;
function initLight() {
// A start
// 第二個參數是光源強度,你可以改變它試一下
light = new THREE.DirectionalLight(0xFF0000,1);
// 位置不同,方向光作用於物體的面也不同,看到的物體各個面的顏色也不一樣
light.position.set(0,0,1);
scene.add(light);
// A end
}
function initObject(){
// 座標軸
var axis = new THREE.AxisHelper(20);
// 在場景中添加座標軸
scene.add(axis);
// 地面
var floor = new THREE.BoxGeometry( 70, 100, 1);
//var floorMaterial = new THREE.MeshBasicMaterial( {color: '#87CEEB', wireframe: false } );
var floorMaterial = new THREE.MeshBasicMaterial( {color: '#87CEEB', wireframe: false } );
var texture = THREE.ImageUtils.loadTexture("images/floor.jpg",null,function(t)
{
});
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(40, 40);
var material = new THREE.MeshBasicMaterial({map:texture});
var floorCube = new THREE.Mesh( floor, material );
scene.add( floorCube );
floorCube.rotation.x += 0.5*Math.PI;
// 牆面
var cubeGeometry = new THREE.BoxGeometry(1, 10, 60);
// 創建牆面材料
//var cubeMaterial = new THREE.MeshBasicMaterial({ color: '#8B0A50', wireframe: false});
var cubeMaterial = new THREE.MeshBasicMaterial({ color: '#8B0A50', wireframe: false});
/************各個面設置不同的紋理*********/
var matArray = [];
//matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
matArray.push(new THREE.MeshBasicMaterial({color: 0xafc0ca}));
matArray.push(new THREE.MeshBasicMaterial({color: 0xd6e4ec}));
matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
var faceMaterial = new THREE.MeshFaceMaterial(matArray);
var matArray = [];
matArray.push(new THREE.MeshBasicMaterial({color: 0xafc0ca}));
matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
matArray.push(new THREE.MeshBasicMaterial({color: 0xd6e4ec}));
matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
matArray.push(new THREE.MeshBasicMaterial({color: 0x9cb2d1}));
var faceMaterial1 = new THREE.MeshFaceMaterial(matArray);
// 合成立方體
//var cube = new THREE.Mesh( cubeGeometry, cubeMaterial );
var cube = new THREE.Mesh( cubeGeometry, faceMaterial1 );
// 設置牆面位置
cube.position.x = -15;
cube.position.y = 5;
cube.position.z = 0;
// 在場景中添加牆面
scene.add(cube);
// 牆面1
var cubeGeometry = new THREE.BoxGeometry(1, 10, 30);
// 合成立方體
var cube = new THREE.Mesh( cubeGeometry, faceMaterial1 );
// 設置牆面位置
cube.position.x = 0;
cube.position.y = 5;
cube.position.z = 30;
cube.rotation.y += 0.5*Math.PI;
// 在場景中添加牆面
scene.add(cube);
// 牆面2
var cubeGeometry = new THREE.BoxGeometry(1, 10, 60);
// 合成立方體
var cube = new THREE.Mesh( cubeGeometry, faceMaterial );
// 設置牆面位置
cube.position.x = 15;
cube.position.y = 5;
cube.position.z = 0;
// 在場景中添加牆面
scene.add(cube);
// 牆面3
var cubeGeometry = new THREE.BoxGeometry(1, 10, 30);
// 合成立方體
//var cube = new THREE.Mesh( cubeGeometry, faceMaterial );
var cube = new THREE.Mesh( cubeGeometry ); // 設置牆面位置
cube.position.x = 0;
cube.position.y = 5;
cube.position.z = -30;
cube.rotation.y += 0.5*Math.PI;
// 在場景中添加牆面
// scene.add(cube);
// 門
var door = new THREE.BoxGeometry(1, 8, 9);
// 創建門材料
//var doorMaterial = new THREE.MeshBasicMaterial({ color: '#FFFF00', wireframe: true,transparent:true,opacity:0.6});
//var door_cube = new THREE.Mesh( door, faceMaterial);
var door_cube = new THREE.Mesh( door);
// 設置門位置
door_cube.position.x = 0;
door_cube.position.y = 5;
door_cube.position.z = -30;
door_cube.rotation.y += 0.5*Math.PI;
//scene.add(cube);
var sphere1BSP = new ThreeBSP(cube);
var cube2BSP = new ThreeBSP(door_cube);
resultBSP = sphere1BSP.subtract(cube2BSP);
result = resultBSP.toMesh();
result.material.shading = THREE.FlatShading;
result.geometry.computeFaceNormals();
result.geometry.computeVertexNormals();
result.material.needsUpdate = true;
result.geometry.buffersNeedUpdate = true;
result.geometry.uvsNeedUpdate = true;
scene.add(result);
//var l = new THREE.Line( drawShape().createPointsGeometry(10), new THREE.LineBasicMaterial({color:0xff3333, linewidth:2}));
//scene.add(l);
/*var options = {
amount: 10,
bevelThickness: 2,
bevelSize: 1,
bevelSegments: 3,
bevelEnabled: true,
curveSegments: 12,
steps: 1
};
shape = createMesh(new THREE.ExtrudeGeometry(drawShape(), options));*/
}
function drawShape(){
var shape = new THREE.Shape();
shape.moveTo(10, 10);
shape.lineTo(10, 40);
shape.lineTo(40, 40);
shape.lineTo(10, 10);
return shape;
}
function render() {
requestAnimationFrame( render );
//cube.rotation.x += 0.1;
//cube.rotation.y += 0.1;
renderer.render( scene, camera );
}
init();
render();
function init(){
initRender();
initScene();
initCamera();
//initLight();
initObject();
}
</script>
</body>
</html>