3d 地球与卫星绕地飞行

1 创建场景
2 创建相机
3 创建地球模型
4 创建卫星中心
5 创建卫星圆环及卫星
6 创建控制器
7 创建渲染器

<template>
	<div class="home3dMap" id="home3dMap"></div>
</template>

<script>
import * as THREE from 'three'
import {
    
     OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
    
    
	name:"home3dMap",
	data(){
    
    
		return {
    
    
			scene:null,		//场景
			camera:null,   //相机
			meshMaterial:null,  //网络模型
			controls:null,  //控制器
			renderer:null,  //渲染器
			satellites:[],   //卫星(数组) 
		}
	},
	components:{
    
    },
	created(){
    
    },
	beforeDestroy(){
    
    },
	mounted(){
    
    
		//初始化
		this.init();
	},
	methods:{
    
    
		init(){
    
    
			this.createScene();   //创建场景
			this.createMesh();    //创建几何体
			this.createLight();   //创建光源
			this.createCamera();  //创建相机
			this.createRender();  //创建渲染器
			this.createControls();   //创建轨道控制器
			this.animate();
		},
		
		//创建场景
		createScene(){
    
    
			let scene = new THREE.Scene();
			this.scene = scene;
		},
		
		//创建几何体
		createMesh(){
    
    
			//地球
			let geometry = new THREE.SphereGeometry( 70, 32, 16);
			let earthImgSrc = require('@/assets/img/home/home3dMapBackground.png');
			//材质
			let earthMater = new THREE.MeshPhongMaterial({
    
    
				map: new THREE.TextureLoader().load(earthImgSrc),
				transparent:true,
				depthWrite:false,
			});
			//网络模型对象 -- 地球
			let meshMaterial = new THREE.Mesh(geometry,earthMater);
			
			//地球模型
			this.meshMaterial = meshMaterial;
			//添加到场景中
			this.scene.add(meshMaterial);
			//添加圆环
			this.initSatellite(meshMaterial);
			
		},
		
		//添加圆环
		initSatellite(meshMaterial){
    
    
			//返回一个卫星和轨道的组合体
			// satelliteSize/卫星大小   satelliteRadius/卫星旋转半径   rotation	/组合体的旋转方向     speed/卫星运动速度
			
			// 圆环图片
			let sadImgSrc = require('@/assets/img/control/satellite.png');
			//循环卫星   假设有3颗卫星
			for(let i=0; i<3; i++){
    
    
				let satelliteSize = 12,satelliteRadius=0,rotation={
    
    x:0,y:0,z:0},speed=0;
				if(i==0){
    
    
					satelliteRadius = 80;
					rotation.x = -Math.PI * 0.35;
					rotation.y = Math.PI * 0.25;
					rotation.z = 0;
					speed = 0.004;
				}else if(i==1){
    
    
					satelliteRadius =100;
					rotation.x = -Math.PI * 0.35;
					rotation.y = -Math.PI * 0.2;
					rotation.z = 0;
					speed = 0.005;
				}else{
    
    
					satelliteRadius = 86;
					rotation.x = -Math.PI * 0.25;
					rotation.y = Math.PI * 0.15;
					rotation.z = 0;
					speed = 0.003;
				}
				
				//卫星中心
				let earthGeometry = new THREE.SphereGeometry(0,0,0); 
				//材质
				let earthMater = new THREE.MeshPhongMaterial({
    
    
					color:0xa0a0a0,
				});
				let centerMesh = new THREE.Mesh(earthGeometry,earthMater);
				
				//卫星圆环
				let circleGeometry = new THREE.RingGeometry(satelliteRadius, satelliteRadius + 0.3, 100, 1);
				//材质
				let circleMater = new THREE.MeshBasicMaterial({
    
    
					color:0xffffff,
					side: THREE.DoubleSide
				})
				//网络模型对象 -- 卫星圆环
				let track = new THREE.Mesh(circleGeometry,circleMater);
				
				let satellite = new THREE.Sprite(new THREE.SpriteMaterial({
    
    
					map: new THREE.TextureLoader().load(sadImgSrc),
					blending: THREE.AdditiveBlending
				}));
				
				//卫星大小
				satellite.scale.x = satellite.scale.y = satellite.scale.z = 12;
				//卫星旋转半径
				satellite.position.set(satelliteRadius, 0, 0);
				
				let pivotPoint = new THREE.Object3D();
				pivotPoint.add(satellite);
				pivotPoint.add(track);
				//卫星中心模型添加卫星对象
				centerMesh.add(pivotPoint);
				centerMesh.rotation.set(rotation.x, rotation.y, rotation.z);
				//添加到场景中
				this.scene.add(centerMesh);
				//添加卫星
				this.satellites.push({
    
    satellite:centerMesh, speed:speed, address:rotation});
			}
		},

		//创建光源
		createLight(){
    
    
			// 环境光
			const ambientLight = new THREE.AmbientLight(0xcccccc, 2)
			this.scene.add(ambientLight)
			// 平行光
			let directionalLight = new THREE.DirectionalLight(0xffffff, 0.2)
			directionalLight.position.set(1, 0.2, 0).normalize()
			// 平行光2
			let directionalLight2 = new THREE.DirectionalLight(0xff2ffff, 0.2)
			directionalLight2.position.set(1, 0.2, 0.1).normalize()
			this.scene.add(directionalLight)
			this.scene.add(directionalLight2)
			// 平行光3
			let directionalLight3 = new THREE.DirectionalLight(0xffffff, 0)
			// 开启阴影
			directionalLight3.castShadow = true
			// 设置光边界
			// directionalLight3.shadow.camera.top = 18
			// directionalLight3.shadow.camera.bottom = -10
			// directionalLight3.shadow.camera.left = -52
			// directionalLight3.shadow.camera.right = 12
			this.scene.add(directionalLight3)
		},
		
		//创建相机
		createCamera(){
    
    
			//渲染区域  宽高为  960/685
			let camera = new THREE.PerspectiveCamera(60, 960 / 685, 1, 10000)
			//设置相机位置
			camera.position.set(50, -10, 200)
			//设置相机方向
			camera.lookAt(0, 0, 0)
			this.camera = camera;
			this.scene.add(this.camera);
		},
		
		//创建渲染器
		createRender(){
    
    
			let element = document.getElementById("home3dMap");
			//创建渲染器
			let renderer = new THREE.WebGLRenderer({
    
    antialias:true, alpha:true})
			renderer.setSize(960,685)   //设置渲染区域尺寸
			renderer.shadowMap.enabled = true;   //显示阴影
			renderer.shadowMap.type = THREE.PCFSoftShadowMap;
			renderer.setClearColor(0x3f3f3f, 0);   //设置背景颜色
			
			this.renderer = renderer;
						
			element.appendChild(this.renderer.domElement)
		},
		
		//创建轨道控制器
		createControls(){
    
    
			let controls = new OrbitControls(this.camera, this.renderer.domElement);
			controls.enableDamping = true;
			controls.maxZoom = Infinity;
			this.controls = controls;
		},
		
		//循环
		animate(){
    
    
			this.controls.update();  //控制阻尼器
			//地球自传
			this.meshMaterial.rotation.y += 0.0015;
			this.renderer.render(this.scene, this.camera);

			for(let i=0; i<this.satellites.length; i++){
    
    
				this.satellites[i].satellite.rotation.z -= this.satellites[i].speed;
			}
			requestAnimationFrame(this.animate.bind(this));
		},
	},
}
</script>

<style>
	.home3dMap{
    
    
		width:100%;
		height:100%;
	}
</style>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41752378/article/details/132104497