three.js模拟太阳系

发布时间:2023年12月20日

地球的旋转轨迹目前设置为了圆形,效果:

<template>
  <div>
    <el-container>
      <el-main>
        <div class="box-card-left">
          <div id="threejs" style="border: 1px solid red"></div>
          <div class="box-right">
          </div>
        </div>
      </el-main>
    </el-container>
  </div>
</template>
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
export default {
  data() {
    return {
      name: "",
      scene: null,
      camera: null,
      renderer: null,
      mesh: null,
      mesh_moon: null,
      geometry: null,
      group: null,
      group2: null,
      material: null,
      texture: null,
    };
  },
  created() {},
  mounted() {
    this.name = this.$route.query.name;
    this.init();
  },
  methods: {
    goBack() {
      this.$router.go(-1);
    },
    init() {
      /**
       * 本案例的思路:创建了三个球缓存几何体,分别进行了纹理贴图,创建组group1, group2,
       * 将地球和月球添加到一个group1中,设置group1的位置让其离开原点,
       * 将group1进行绕Y轴旋转,再将group1 添加到 group2中,将group2添加到场景对象中并进行绕Y轴旋转
       *  */
      // 1,创建场景对象
      this.scene = new this.$three.Scene();
      // 5,创建辅助坐标轴对象
      const axesHelper = new this.$three.AxesHelper(1000);
      this.scene.add(axesHelper);
      this.group = new this.$three.Group();
      this.group2 = new this.$three.Group();
      // 创建纹理贴图加载器对象
      this.createTextureLoader({imgName: 'sun.png', spotLight: true, camera: true, controls: true});
      this.createTextureLoader2({r:50});
    },
    // 创建纹理加载器  加载地球
    createTextureLoader2({imgName="earth.png", r=100, l1=32, l2=16}) {
       // 创建纹理贴图加载器对象
      const textureLoader = new this.$three.TextureLoader();
      textureLoader.load(require("../../assets/eleven/" + imgName), e => {
          // 3,创建网格材质对象
        let mesh = this.createGeometry( r, l1, l2, e);
        mesh.position.set(0,0,0);
        const worldPosition = new this.$three.Vector3();
        mesh.getWorldPosition(worldPosition);
        this.group.add(mesh);
        this.group.position.set(300,0,0);
        this.scene.add(this.group);
        this.createTextureLoader3({r:30});
        this.createCamera();
        this.createControls();
        this.renderFun();
      })
    },
    // 创建纹理加载器  加载月球
    createTextureLoader3({imgName="moon.jpeg", r=100, l1=32, l2=16}) {
       // 创建纹理贴图加载器对象
      const textureLoader = new this.$three.TextureLoader();
      textureLoader.load(require("../../assets/eleven/" + imgName), e => {
          // 3,创建网格材质对象
        this.mesh_moon = this.createGeometry( r, l1, l2, e);
        this.mesh_moon.position.set(100,0,0);
        this.group.add(this.mesh_moon);
        this.group2.add(this.group);
        this.scene.add(this.group2);
      })
    },
    // 创建纹理加载器  加载太阳
    createTextureLoader({imgName="earth.png", r=100, l1=32, l2=16, spotLight=false, camera=false,controls=false}) {
       // 创建纹理贴图加载器对象
      const textureLoader = new this.$three.TextureLoader();
      textureLoader.load(require("../../assets/eleven/" + imgName), e => {
          // 3,创建网格材质对象
        let mesh = this.createGeometry( r, l1, l2, e);
        this.scene.add(mesh);
        if(spotLight) {
          // 创建聚光源对象
          const spot_light = new this.$three.SpotLight(0xffffff, 1);
          // 设置聚光源位置
          spot_light.position.set(1000, 300, -100);
          // 设置聚光源指向的目标位置
          spot_light.target = mesh;
          this.scene.add(spot_light);
          // 创建聚光源辅助对象
          const spotLightHelper = new this.$three.SpotLightHelper(spot_light,0xffffff);
          this.scene.add(spotLightHelper);
        }
      })
    },
    // 6,创建透视投影相机对象
    createCamera() {
      this.camera = new this.$three.PerspectiveCamera(90, 1, 0.01,9000);
      this.camera.position.set(500,500,600); 
      // this.camera.updateProjectionMatrix();
      // 相机看向的是模型的位置
      this.camera.lookAt(0,0,0);
      // 7,创建渲染器对象
      this.renderer = new this.$three.WebGLRenderer();
      // 设置渲染器尺寸:宽度 1600, 高度:1000
      this.renderer.setSize(1600,1100);
      // 调用渲染方法
      this.renderer.render(this.scene, this.camera);
      document.getElementById("threejs").appendChild(this.renderer.domElement);
    },
    // 创建相机空间轨道控制器对象
    createControls() {
      const controls = new OrbitControls(this.camera, this.renderer.domElement);
      controls.addEventListener("change", () => {
        this.renderer.render(this.scene, this.camera);
      })
    },
    // 创建网格对象
    createGeometry(r, l1, l2, e) {
      let geometry = new this.$three.SphereGeometry(r, l1, l2);
      let material = new this.$three.MeshLambertMaterial({
          map: e
        });
      let mesh = new this.$three.Mesh(geometry, material);
      // this.scene.add(mesh);
      return mesh;
    },
    renderFun() {
      this.group.rotateY(0.02);
      this.group2.rotateY(0.01);
      if(this.mesh_moon) {
        this.mesh_moon.rotateY(0.02);
      }
      this.renderer.render(this.scene, this.camera);
      window.requestAnimationFrame(this.renderFun);
    }
  },
};
</script>
//
<style lang="less" scoped>
.msg {
  padding: 20px;
  text-align: left;
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
  .span {
    margin: 0 30px 30px 0;
    // white-space: nowrap;
  }
  .p {
    text-align: left;
  }
}
.box-card-left {
  display: flex;
  align-items: flex-start;
  flex-direction: row;

  width: 100%;
  .box-right {
    text-align: left;
    padding: 10px;
    .xyz {
      width: 100px;
      margin-left: 20px;
    }
    .box-btn {
      margin-left: 20px;
    }
  }
}
</style>

文章来源:https://blog.csdn.net/yinge0508/article/details/135023337
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。