import * as THREE from "three" import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' import { Object3D, Mesh, ShaderMaterial, IcosahedronGeometry, TextureLoader, MeshStandardMaterial, Scene, HemisphereLight, Color, DirectionalLight, Vector3, AmbientLight, PlaneBufferGeometry, MeshPhongMaterial } from "three"; import { GameController } from "./controller" import { VaringBox } from "./shader_test" import { GameUtils } from './utils'; export class FooGame { scene: THREE.Scene; camera: THREE.Camera; renderer: THREE.WebGLRenderer; light: THREE.Light; cam_fov = 70; //视角大小 cam_aspect = window.innerWidth / window.innerHeight; gltfLoader: GLTFLoader; textureLoader: TextureLoader; updateMap: Object; controller: GameController; constructor() { this.camera = new THREE.PerspectiveCamera(this.cam_fov, this.cam_aspect, 1, 1000) this.camera.position.x = -1; this.camera.position.y = 2; this.camera.position.z = 1; this.scene = new THREE.Scene(); this.light = new HemisphereLight(new Color(0XFFFFFF), new Color(0x000000), 1); this.light.position.set(0, 15, 0); this.scene.add(new AmbientLight(new Color(0xffffff), 1)); this.scene.add(this.light); this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(this.renderer.domElement); this.gltfLoader = new GLTFLoader(); this.updateMap = {}; this.controller = new GameController(document.body); this.controller.bindMoveKeys(this.camera); this.controller.bindMouseLookAt(this.camera, this.scene); this.textureLoader = new TextureLoader(); this.animate(); } animate() { requestAnimationFrame(() => { this.animate(); }); this.updateObjects(this.scene); this.renderer.render(this.scene, this.camera); } private updateObjects(obj: Object3D) { if ("update" in obj && (typeof obj["update"] == "function")) { var f: Function = obj["update"]; f.call(obj, obj); } if (obj.children && obj.children.length > 0) { obj.children.forEach(child => { this.updateObjects(child); }); } } findObjectByName(name: string, parent: Object3D = this.scene) { let obj = parent.getObjectByName(name); if (obj) return obj; if (parent.children && parent.children.length > 0) { parent.children.forEach(child => { obj = this.findObjectByName(name, child); if (obj) { return obj; } }); } } static setUpdate(obj: Object3D, fn: Function) { Object.defineProperty(obj, "update", { writable: true, value: fn }); } /** * 加载场景 * @param callback */ loadScene(callback: Function) { this.gltfLoader.load("./scenes/campus/Unity2GLTF.gltf", gltf => { console.log(gltf); this.scene.add(gltf.scene); this.scene.background = new THREE.Color('rgb(191,196,234)'); callback(); }); } } let game = new FooGame(); game.loadScene(() => { /*let mat = GameUtils.makeRandomObjects(game.scene, 500); FooGame.setUpdate(game.scene, (obj: Object3D) => { mat.uniforms.time.value = performance.now() / 500; }); */ let geoGround = new PlaneBufferGeometry(200, 200, 100, 200); let matGround = new MeshPhongMaterial({ color: "rgb(50,50,50)" }); let ground = new Mesh(geoGround, matGround); ground.rotation.x = -Math.PI / 2; ground.position.y = -2; game.scene.add(ground); game.camera.lookAt(new THREE.Vector3(0, 0, 0)); /** * 设置天空盒子 */ let skybox = game.findObjectByName("Sphere"); if (skybox instanceof Mesh) { let mesh: Mesh = skybox; if (mesh.material instanceof MeshStandardMaterial) { let mat: MeshStandardMaterial = mesh.material; mat.side = THREE.BackSide; } } })