效果图
核心代码
export default ({
data(){
return {
test: "改变相机位置",
scene: '',
renderer: "",
camera: "",
controls: "", // 鼠标控件
fh: 2, // 地面高度
wallHeight: 18,
wallWeight: 1
}
},
methods: {
// 初始化场景
initScene() {
this.scene = new THREE.Scene()
},
// 初始化相机
initCamera(w = 500, h = 500) {
var camera = new THREE.PerspectiveCamera(45, w / h, 0.1, 10000);
camera.position.set(100, 100, 100);
this.camera = camera
},
initRenderer(w = 500, h = 500) {
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(w, h);
renderer.setClearColor(0x4682B4, 1.0);
document.getElementById("3dAPP").appendChild(renderer.domElement);
this.renderer = renderer
},
// 初始化灯光
initLight() {
var directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 模拟远处类似太阳的光源
directionalLight.color.setHSL(0.1, 1, 0.95);
directionalLight.position.set(0, 200, 0).normalize();
this.scene.add(directionalLight);
var ambient = new THREE.AmbientLight(0xffffff, 1); // AmbientLight 影响整个场景的光源
ambient.position.set(0, 0, 0);
this.scene.add(ambient);
},
// 初始化轨迹球控件 鼠标控件
initControls() {
var controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.5;
// 视角最小距离
controls.minDistance = 0;
// 视角最远距离
controls.maxDistance = 5000;
controls.enableKeys = true;
// 最大角度
// controls.maxPolarAngle = Math.PI / 2;
controls.target = new THREE.Vector3(10, 10, 10);
this.controls = controls
console.log(controls)
},
// 地面
createFloor() {
var loader = new THREE.TextureLoader();
var floor, floor1;
loader.load("./img/cz.jpg", (texture) => {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(30, 30);
var floorGeometry = new THREE.BoxGeometry(100, 100, this.fh);
var floorMaterial = new THREE.MeshBasicMaterial({
map: texture,
});
floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.rotation.x = -Math.PI / 2;
floor.position.set(0, 0, 0)
floor.name = "地面";
this.scene.add(floor);
});
},
/**
* @param i 某一块墙
* @param wallHeight 墙高
*
*/
createwall(i,width=100, wallHeight = this.wallHeight, wallWeight = this.wallWeight) {
var Geometry = new THREE.BoxGeometry(width, wallHeight, wallWeight);
var mtl = []
for (let i = 0; i < Geometry.faces.length; i++) {
mtl.push(
new THREE.MeshBasicMaterial({
color: new THREE.Color(Math.random() * 0xffffff)
})
)
}
var mesh = new THREE.Mesh(Geometry, mtl)
/*
刚好在地面
模型自身高度 h0
地面高度 h1
(地面高度 + 模型高度) / 2 即 (h0+h1)/2
*/
mesh.name = `wall${
i}`
/*
这里如果是做参数传入就不用写这么多 case 了
但是实际开发中 每一面墙肯定都是定制化的 有的墙面有壁画 门 窗 贴图等等
所以写 case 更贴近实际开发一点
当然一些共用的属性可以走参数
我这里直接上case了
*/
switch (i) {
case 1:
mesh.position.set(0, (this.fh + wallHeight) / 2, 49.5)
break;
case 2:
mesh.position.set(0, (this.fh + wallHeight) / 2, -49.5)
break;
case 3:
mesh.rotation.y = Math.PI/2
mesh.position.set(49.5, (this.fh + wallHeight) / 2, 0)
break;
case 4:
mesh.rotation.y = Math.PI/2
mesh.position.set(-49.5, (this.fh + wallHeight) / 2, 0)
break;
case 5:
mesh.position.set(0, (this.fh + wallHeight) / 2, 0)
break;
case 6:
mesh.rotation.y = Math.PI/2
mesh.position.set(-20, (this.fh + wallHeight) / 2, 25)
break;
case 7:
mesh.rotation.y = Math.PI/2
mesh.position.set(20, (this.fh + wallHeight) / 2, 25)
break;
case 8:
mesh.position.set(0, (this.fh + wallHeight) / 2, -12)
break;
case 9:
mesh.rotation.y = Math.PI/2
mesh.position.set(29.5, (this.fh + wallHeight) / 2, -31)
break;
case 10:
mesh.rotation.y = Math.PI/2
mesh.position.set(8, (this.fh + wallHeight) / 2, -31)
break;
case 11:
mesh.rotation.y = Math.PI/2
mesh.position.set(-18, (this.fh + wallHeight) / 2, -31)
break;
}
this.scene.add(mesh)
// console.log(Geometry)
},
// 模型
initContent() {
this.createFloor();
this.createwall(1)
this.createwall(2)
this.createwall(3)
this.createwall(4)
this.createwall(5)
this.createwall(6,50)
this.createwall(7,50)
this.createwall(8,60)
this.createwall(9,38)
this.createwall(10,38)
this.createwall(11,38)
},
animate() {
requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera);
// composer.render();
this.update();
// console.log(this.scene)
},
// 更新控件
update() {
// stats.update();
this.controls.update();
TWEEN.update();
},
init() {
this.initScene();
this.initCamera();
// 初始化渲染器
this.initRenderer(700, 700);
// 初始化模型
this.initContent();
// 初始化灯光
this.initLight();
this.initControls();
},
// changePOS() {
// this.camera.position.set(0, 300, 10)
// this.animate()
// }
},
mounted() {
this.init();
this.animate();
}
})