hsiao 5 年之前
父節點
當前提交
92c1a51e48
共有 10 個檔案被更改,包括 112 行新增647 行删除
  1. 18
    0
      public/index.html
  2. 0
    318
      public/scenes/foo.gltf
  3. 0
    169
      public/scenes/skybox.gltf
  4. 二進制
      public/textures/skybox.jpg
  5. 二進制
      public/textures/skybox2.jpg
  6. 40
    20
      src/controller.ts
  7. 32
    56
      src/index.ts
  8. 22
    0
      src/navigator.ts
  9. 0
    35
      src/shader_test.ts
  10. 0
    49
      src/utils.ts

+ 18
- 0
public/index.html 查看文件

@@ -8,8 +8,26 @@
8 8
             margin: 0;
9 9
             cursor: pointer;
10 10
         }
11
+        .mask {
12
+            position: fixed;
13
+            background-color: rgba(0, 0, 0, 0.6);
14
+            top:0;
15
+            left:0;
16
+            width: 100%;
17
+            height: 100%;
18
+        }
19
+        .mask h1{
20
+            margin-top: 100px;
21
+            font-size: 26px;
22
+            text-align: center;
23
+            line-height: 100px;
24
+            color: #ffffff;
25
+        }
11 26
     </style>
12 27
     
13 28
 </head>
14 29
 <body>
30
+    <div class="mask" id="mask">
31
+        <h1>点击鼠标开始,ESC键退出</h1>
32
+    </div>
15 33
 </body>

+ 0
- 318
public/scenes/foo.gltf
文件差異過大導致無法顯示
查看文件


+ 0
- 169
public/scenes/skybox.gltf
文件差異過大導致無法顯示
查看文件


二進制
public/textures/skybox.jpg 查看文件


二進制
public/textures/skybox2.jpg 查看文件


+ 40
- 20
src/controller.ts 查看文件

@@ -1,5 +1,5 @@
1 1
 import { Object3D, Raycaster, Camera, Scene, Euler, Vector3 } from "three";
2
-import { FooGame } from './index';
2
+import { ReeGame } from './index';
3 3
 
4 4
 export class GameController {
5 5
     root: HTMLElement;
@@ -8,31 +8,34 @@ export class GameController {
8 8
     axisZ = new Vector3(0, 0, 1).normalize();
9 9
 
10 10
     private vec: Vector3 = new Vector3();
11
-    private raycaster: Raycaster;
11
+    private game: ReeGame;
12
+    private startFlag = false;
13
+    private mask: HTMLElement;
12 14
 
13
-    constructor(root: HTMLElement) {
15
+    constructor(root: HTMLElement, mask: HTMLElement, game: ReeGame) {
14 16
         this.root = root;
15 17
         this.callbackMap = {};
16
-
18
+        this.game = game;
17 19
         this.mouse = { dx: 0, dy: 0 }
18
-        this.raycaster = new Raycaster();
20
+        this.mask = mask;
19 21
 
20
-        this.root.onmouseup = () => {
21
-            document.body.style.cursor = "none";
22
-            this.root.requestPointerLock();
23
-        };
24
-
25
-        this.onKey_ESC();
26
-        this.bindKey();
22
+        this.onPointLockChange();
23
+        this.onStartSignal();
24
+        this.onKey();
25
+        this.bindMouseLookAt(game.camera, game.scene);
26
+        this.bindMoveKeys(game.camera);
27 27
     }
28 28
 
29 29
     bindMouseLookAt(obj: Camera, scene: Scene) {
30
+
30 31
         let cam = obj;
31 32
         let eu: Euler = new Euler(0, 0, 0, 'YXZ');
32 33
         let PI_2 = Math.PI / 2;
33 34
 
34 35
         this.root.onmousemove = (event) => {
35
-            //event.preventDefault();
36
+            if (!this.startFlag) return;
37
+
38
+            event.preventDefault();
36 39
             this.mouse.dx = event.movementX;
37 40
             this.mouse.dy = event.movementY;
38 41
 
@@ -90,20 +93,37 @@ export class GameController {
90 93
     private onKey_D(callback: Function) {
91 94
         this.callbackMap[68] = callback;
92 95
     }
93
-    private onKey_ESC() {
94
-        this.callbackMap[27] = () => {
95
-            document.body.style.cursor = "pointer";
96
-            document.exitPointerLock();
96
+    private onPointLockChange() {
97
+        document.onpointerlockchange = (e) => {
98
+            if (document.pointerLockElement) {
99
+                this.startFlag = true;
100
+            } else {
101
+                this.startFlag = false;
102
+                let mask = document.getElementById("mask")
103
+                if (mask)
104
+                    mask.style.opacity = "0.9";
105
+                document.body.style.cursor = "pointer";
106
+                document.exitPointerLock();
107
+            }
108
+
97 109
         };
98 110
     }
99
-
100
-    private bindKey() {
111
+    private onStartSignal() {
112
+        this.root.onmouseup = () => {
113
+            document.body.style.cursor = "none";
114
+            this.mask.style.opacity = "0";
115
+            this.root.requestPointerLock();
116
+            this.startFlag = true;
117
+        };
118
+    }
119
+    private onKey() {
101 120
         this.root.onkeypress = (event) => {
121
+            if (!this.startFlag) return;
102 122
             let c = event.keyCode;
103
-             
104 123
             if (this.callbackMap[c]) {
105 124
                 this.callbackMap[c]();
106 125
             }
126
+
107 127
         };
108 128
     }
109 129
 }

+ 32
- 56
src/index.ts 查看文件

@@ -1,28 +1,23 @@
1 1
 import * as THREE from "three"
2 2
 import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
3
-import { Object3D, Mesh, ShaderMaterial, IcosahedronGeometry, TextureLoader, MeshStandardMaterial, Scene, HemisphereLight, Color, DirectionalLight, Vector3, AmbientLight, PlaneBufferGeometry, MeshPhongMaterial } from "three";
3
+import { Object3D, Mesh, TextureLoader, HemisphereLight, Color, AmbientLight, PlaneBufferGeometry, MeshPhongMaterial } from "three";
4 4
 
5 5
 import { GameController } from "./controller"
6
-import { VaringBox } from "./shader_test"
7
-import { GameUtils } from './utils';
8 6
 
9
-export class FooGame {
7
+export class ReeGame {
10 8
 
11 9
     scene: THREE.Scene;
12 10
     camera: THREE.Camera;
13
-    renderer: THREE.WebGLRenderer;
14
-
15
-    light: THREE.Light;
16
-
17
-    cam_fov = 70; //视角大小
18
-    cam_aspect = window.innerWidth / window.innerHeight;
11
+    private renderer: THREE.WebGLRenderer;
12
+    private light: THREE.Light;
13
+    private cam_fov = 70; //视角大小
14
+    private cam_aspect = window.innerWidth / window.innerHeight;
19 15
 
20 16
     gltfLoader: GLTFLoader;
21 17
     textureLoader: TextureLoader;
22 18
 
23
-    updateMap: Object;
24
-
25
-    controller: GameController;
19
+    private controller: GameController;
20
+    private renderFlag: boolean = true;
26 21
 
27 22
     constructor() {
28 23
         this.camera = new THREE.PerspectiveCamera(this.cam_fov, this.cam_aspect, 1, 1000)
@@ -43,24 +38,20 @@ export class FooGame {
43 38
         document.body.appendChild(this.renderer.domElement);
44 39
 
45 40
         this.gltfLoader = new GLTFLoader();
46
-
47
-        this.updateMap = {};
48
-
49
-        this.controller = new GameController(document.body);
50
-        this.controller.bindMoveKeys(this.camera);
51
-        this.controller.bindMouseLookAt(this.camera, this.scene);
52
-
41
+        let mask = document.getElementById("mask") || new HTMLElement();
42
+        this.controller = new GameController(document.body, mask, this);
53 43
         this.textureLoader = new TextureLoader();
54
-
55 44
         this.animate();
56 45
     }
57 46
 
58
-    animate() {
47
+    private animate() {
59 48
         requestAnimationFrame(() => {
60 49
             this.animate();
61 50
         });
62
-        this.updateObjects(this.scene);
63
-        this.renderer.render(this.scene, this.camera);
51
+        if (this.renderFlag) {
52
+            this.updateObjects(this.scene);
53
+            this.renderer.render(this.scene, this.camera);
54
+        }
64 55
     }
65 56
 
66 57
 
@@ -78,6 +69,12 @@ export class FooGame {
78 69
         }
79 70
     }
80 71
 
72
+    stop() {
73
+        this.renderFlag = false;
74
+    }
75
+    start() {
76
+        this.renderFlag = true;
77
+    }
81 78
     findObjectByName(name: string, parent: Object3D = this.scene) {
82 79
         let obj = parent.getObjectByName(name);
83 80
         if (obj) return obj;
@@ -110,44 +107,23 @@ export class FooGame {
110 107
 
111 108
             this.scene.add(gltf.scene);
112 109
             this.scene.background = new THREE.Color('rgb(191,196,234)');
110
+            //添加一个地板
111
+            let geoGround = new PlaneBufferGeometry(200, 200, 100, 200);
112
+            let matGround = new MeshPhongMaterial({
113
+                color: "rgb(100,100,100)"
114
+            });
115
+            let ground = new Mesh(geoGround, matGround);
116
+            ground.rotation.x = -Math.PI / 2;
117
+            ground.position.y = -2;
118
+            this.scene.add(ground);
113 119
 
114 120
             callback();
115 121
         });
116 122
     }
117 123
 }
118 124
 
119
-let game = new FooGame();
120
-
125
+let game = new ReeGame();
121 126
 game.loadScene(() => {
122 127
 
123
-    /*let mat = GameUtils.makeRandomObjects(game.scene, 500);
124
-    FooGame.setUpdate(game.scene, (obj: Object3D) => {
125
-        mat.uniforms.time.value = performance.now() / 500;
126
-    });
127
-*/
128
-
129
-    let geoGround = new PlaneBufferGeometry(200, 200, 100, 200);
130
-    let matGround = new MeshPhongMaterial({
131
-        color: "rgb(50,50,50)"
132
-    });
133
-
134
-    let ground = new Mesh(geoGround, matGround);
135
-    ground.rotation.x = -Math.PI / 2;
136
-    ground.position.y = -2;
137
-    game.scene.add(ground);
138
-    game.camera.lookAt(new THREE.Vector3(0, 0, 0));
139
-
140
-
141
-    /**
142
-     * 设置天空盒子
143
-     */
144
-    let skybox = game.findObjectByName("Sphere");
145
-    if (skybox instanceof Mesh) {
146
-        let mesh: Mesh = skybox;
147
-        if (mesh.material instanceof MeshStandardMaterial) {
148
-            let mat: MeshStandardMaterial = mesh.material;
149
-            mat.side = THREE.BackSide;
150
-        }
151
-    }
152
-})
128
+});
153 129
 

+ 22
- 0
src/navigator.ts 查看文件

@@ -0,0 +1,22 @@
1
+
2
+import { Object3D, Vector3 } from 'three';
3
+
4
+export class KeyPoint {
5
+    point: Vector3 | Object3D = new Vector3();
6
+    lookAt: Vector3 | Object3D = new Vector3();
7
+}
8
+
9
+export class OrbitNavigator {
10
+    private target: Object3D;
11
+    private points: KeyPoint[];
12
+
13
+    constructor(target: Object3D, points: KeyPoint[]) {
14
+        this.target = target;
15
+        this.points = points || [];
16
+    }
17
+
18
+    start() {
19
+
20
+    }
21
+
22
+}

+ 0
- 35
src/shader_test.ts 查看文件

@@ -1,35 +0,0 @@
1
-import * as THREE from "three"
2
-import { IcosahedronGeometry, MeshStandardMaterial, Mesh, ShaderMaterial } from "three";
3
-
4
-export class VaringBox {
5
-    material: ShaderMaterial;
6
-    private vertexShader = `
7
-        uniform float time;
8
-        varying vec3 vPos;
9
-        void main() {
10
-            vPos=position;
11
-            vPos.x += sin( time + vPos.z * 4.0 ) / 4.0;
12
-            vPos.y += cos( time + vPos.z * 4.0 ) / 4.0;
13
-            gl_Position = projectionMatrix * modelViewMatrix * vec4( vPos, 1.0 );
14
-        }
15
-        `;
16
-
17
-    private fragmentShader = `
18
-        varying vec3 vPos;
19
-        void main() {
20
-            gl_FragColor = vec4( vPos*2.0, 1.0 );
21
-        }
22
-        `;
23
-
24
-    constructor() {
25
-        this.material = new ShaderMaterial({
26
-            uniforms: {
27
-                time: {
28
-                    value: 0
29
-                }
30
-            },
31
-            vertexShader: this.vertexShader,
32
-            fragmentShader: this.fragmentShader
33
-        });
34
-    }
35
-}

+ 0
- 49
src/utils.ts 查看文件

@@ -1,49 +0,0 @@
1
-
2
-import { Object3D, BoxBufferGeometry, Color, MeshPhongMaterial, Material, IcosahedronBufferGeometry, TorusKnotBufferGeometry, SphereBufferGeometry } from 'three';
3
-import { Scene } from 'three';
4
-import { MeshStandardMaterial } from 'three';
5
-import { Mesh } from 'three';
6
-import { VaringBox } from './shader_test';
7
-import { ShaderMaterial } from 'three';
8
-import { FooGame } from './index';
9
-export class GameUtils {
10
-
11
-    static makeRandomObjects(scene: Scene, n: number = 100): ShaderMaterial {
12
-        let vBox = new VaringBox();
13
-        let geo = new BoxBufferGeometry(1, 1, 1);
14
-        let geo2 = new IcosahedronBufferGeometry(1, 3);
15
-        let geo3 = new SphereBufferGeometry(1, 40,40);
16
-
17
-        for (let i = 0; i < n; i++) {
18
-            let temp;
19
-            if (i % 2)
20
-                temp = new Mesh(geo, vBox.material);
21
-            if (i % 3) {
22
-                temp = new Mesh(geo3,vBox.material);
23
-            }
24
-            else
25
-                temp = new Mesh(geo2, vBox.material);
26
-
27
-            temp.position.set(Math.random() * 50, Math.random() * 10, Math.random() * 50);
28
-            temp.scale.set(
29
-                Math.random() * 2,
30
-                Math.random() * 2,
31
-                Math.random() * 2
32
-            )
33
-           FooGame.setUpdate(temp,(obj:Mesh)=>{
34
-                obj.position.x += Math.sin(performance.now()*0.0003+ obj.position.z);
35
-                obj.position.y += Math.sin(performance.now()*0.0002+ 4*obj.position.z);  
36
-            });
37
-            scene.add(temp);
38
-        }
39
-
40
-        return vBox.material;
41
-    }
42
-
43
-    static makeBox(): Mesh {
44
-        let vBox = new VaringBox();
45
-        let geo = new BoxBufferGeometry(1, 1, 1);
46
-
47
-        return new Mesh(geo, vBox.material);
48
-    }
49
-}

Loading…
取消
儲存