Bez popisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.ts 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import * as THREE from "three"
  2. import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
  3. import { Object3D, Mesh, ShaderMaterial, IcosahedronGeometry, TextureLoader, MeshStandardMaterial, Scene } from "three";
  4. import { GameController } from "./controller"
  5. import { VaringBox } from "./shader_test"
  6. export class FooGame {
  7. scene: THREE.Scene;
  8. camera: THREE.Camera;
  9. renderer: THREE.WebGLRenderer;
  10. cam_fov = 70; //视角大小
  11. cam_aspect = window.innerWidth / window.innerHeight;
  12. gltfLoader: GLTFLoader;
  13. textureLoader: TextureLoader;
  14. updateMap: Object;
  15. controller: GameController;
  16. constructor() {
  17. this.camera = new THREE.PerspectiveCamera(this.cam_fov, this.cam_aspect, 0.01, 10)
  18. this.camera.position.x = -1;
  19. this.camera.position.y = 1;
  20. this.camera.position.z = 1;
  21. this.scene = new THREE.Scene();
  22. this.renderer = new THREE.WebGLRenderer();
  23. this.renderer.setSize(window.innerWidth, window.innerHeight);
  24. document.body.appendChild(this.renderer.domElement);
  25. this.gltfLoader = new GLTFLoader();
  26. this.updateMap = {};
  27. this.controller = new GameController(document.body);
  28. this.controller.bindMoveKeys(this.camera);
  29. this.controller.bindMouseLookAt(this.camera, this.scene);
  30. this.textureLoader = new TextureLoader();
  31. this.animate();
  32. }
  33. animate() {
  34. requestAnimationFrame(() => {
  35. this.animate();
  36. });
  37. this.updateObjects(this.scene);
  38. this.renderer.render(this.scene, this.camera);
  39. }
  40. private updateObjects(obj: Object3D) {
  41. if ("update" in obj && (typeof obj["update"] == "function")) {
  42. var f: Function = obj["update"];
  43. f.call(obj, obj);
  44. }
  45. if (obj.children && obj.children.length > 0) {
  46. obj.children.forEach(child => {
  47. this.updateObjects(child);
  48. });
  49. }
  50. }
  51. findObjectByName(name: string, parent: Object3D = this.scene) {
  52. let obj = parent.getObjectByName(name);
  53. if (obj) return obj;
  54. if (parent.children && parent.children.length > 0) {
  55. parent.children.forEach(child => {
  56. obj = this.findObjectByName(name, child);
  57. if (obj) {
  58. return obj;
  59. }
  60. });
  61. }
  62. }
  63. static setUpdate(obj: Object3D, fn: Function) {
  64. Object.defineProperty(obj, "update", {
  65. writable: true,
  66. value: fn
  67. });
  68. }
  69. /**
  70. * 创建球体
  71. */
  72. createSphere() {
  73. let geo = new THREE.SphereBufferGeometry(15, 100,100);
  74. //let geo = new THREE.BoxBufferGeometry(5,5,5);
  75. let mat = new THREE.MeshStandardMaterial();
  76. mat.side = THREE.BackSide; //设置渲染面会背面
  77. mat.blending = THREE.NormalBlending;
  78. let obj = new THREE.Mesh(geo, mat);
  79. return obj;
  80. }
  81. /**
  82. * 加载场景
  83. * @param callback
  84. */
  85. loadScene(callback: Function) {
  86. this.gltfLoader.load("./scenes/foo.gltf", gltf => {
  87. this.scene.add(gltf.scene);
  88. let s = this.findObjectByName("Sphere");
  89. if(s && s instanceof Mesh){
  90. let mesh :Mesh = s;
  91. if(mesh.material instanceof MeshStandardMaterial){
  92. let mat:MeshStandardMaterial = mesh.material;
  93. mat .side = THREE.BackSide;
  94. }
  95. }
  96. /**
  97. * 加载二位图片作为场景背景
  98. */
  99. this.textureLoader.load("./textures/skybox2.jpg", (tex) => {
  100. //this.scene.background = tex; //直接设置二维背景
  101. //设置天空盒子背景
  102. let skybox = this.createSphere();
  103. if (skybox.material instanceof MeshStandardMaterial) {
  104. let mat: MeshStandardMaterial = skybox.material;
  105. mat.emissive = new THREE.Color(0x00ffff);
  106. mat.emissiveMap = tex;
  107. }
  108. //this.scene.add(skybox);
  109. });
  110. /**
  111. * 加载完毕,回调
  112. */
  113. callback();
  114. });
  115. }
  116. }
  117. let game = new FooGame();
  118. game.loadScene(() => {
  119. let vBox = new VaringBox();
  120. vBox.material.wireframe = true;
  121. let geo = new IcosahedronGeometry(1, 4);
  122. let box2 = new THREE.Mesh(geo, vBox.material);
  123. box2.position.x = 2;
  124. box2.position.z = 1;
  125. box2.position.y = 2;
  126. game.scene.add(box2);
  127. FooGame.setUpdate(box2, (obj: Mesh) => {
  128. obj.rotateY(0.01);
  129. obj.material = vBox.material;
  130. if (obj.material instanceof ShaderMaterial) {
  131. let mat: ShaderMaterial = obj.material;
  132. mat.uniforms.time.value = performance.now() / 500;
  133. }
  134. });
  135. game.camera.lookAt(new THREE.Vector3(0, 0, 0));
  136. })