项目要用到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>