Bläddra i källkod

Merge branch 'navigator' of hsiao/three-demo into master

肖中正 5 år sedan
förälder
incheckning
e91ce7d2fd
51 ändrade filer med 3201 tillägg och 447 borttagningar
  1. 19
    0
      public/index.html
  2. Binär
      public/scenes/campus/Assets/00ACC3C40649240DF9BD6F0AAFA56389.png
  3. Binär
      public/scenes/campus/Assets/0CAAE57A1FC2D9880117C70327C0766D.png
  4. Binär
      public/scenes/campus/Assets/0CC9142D64AB6E5082D13A75B37DDE7A.png
  5. Binär
      public/scenes/campus/Assets/11D39409EFDA73738D4CDC0619A7DAF6.png
  6. Binär
      public/scenes/campus/Assets/1798AB1545B6F6944BBB5B29E538F7E0.png
  7. Binär
      public/scenes/campus/Assets/17B157CB75B005E126B2CAA6C8D4A411.png
  8. Binär
      public/scenes/campus/Assets/1BC7DC99A71CB0580C4815D19D887143.png
  9. Binär
      public/scenes/campus/Assets/1F2B41E795D3CA14026AE36357315B1F.png
  10. Binär
      public/scenes/campus/Assets/218C8F7A5193B09F1414D85AB5678538.png
  11. Binär
      public/scenes/campus/Assets/2F6FF7766D95FF9177F7CEDED606F3E8.png
  12. Binär
      public/scenes/campus/Assets/3BC6B123A43889CB37533199B58E131B.png
  13. Binär
      public/scenes/campus/Assets/3E1AF388FCC01A6E4A8886EE6A7ED24C.png
  14. Binär
      public/scenes/campus/Assets/4DF5D4774BC5709DA9CD27F9614DDFB4.png
  15. Binär
      public/scenes/campus/Assets/51AE3B29BFC5259042CF85F2F4E29925.png
  16. Binär
      public/scenes/campus/Assets/546CB88B13BDAE73F1836E258A8128AC.png
  17. Binär
      public/scenes/campus/Assets/60DA469BAECB6A458836C9D7145954A0.png
  18. Binär
      public/scenes/campus/Assets/6C6D3EAE3EDB52581DF01C6301686C94.png
  19. Binär
      public/scenes/campus/Assets/6FF181DB67E10FA8628467102210C809.png
  20. Binär
      public/scenes/campus/Assets/724486ACAAB8B758059A3AE77E842655.png
  21. Binär
      public/scenes/campus/Assets/761CC41F9A3000C9048E64F5E3DB207E.png
  22. Binär
      public/scenes/campus/Assets/76584CD8BA814CFE3243DABBA61DA0FF.png
  23. Binär
      public/scenes/campus/Assets/77E5FFB9C9EC66D16BB49D3FF160629C.png
  24. Binär
      public/scenes/campus/Assets/793BD9CFAF44CE597D34074A714D48D9.png
  25. Binär
      public/scenes/campus/Assets/7FE51DCF8A388026BFCAE0F4C4BF0236.png
  26. Binär
      public/scenes/campus/Assets/80390CC69A7E3D8331F8D7C94A862B2D.png
  27. Binär
      public/scenes/campus/Assets/9906B1BA7E1524CEABBF1C9DD1CE3627.png
  28. Binär
      public/scenes/campus/Assets/9B18107ABB606F8BE1F9810D6BF298CE.png
  29. Binär
      public/scenes/campus/Assets/9B54F2BBCF60147EAE8B1037E5A0CBAC.png
  30. Binär
      public/scenes/campus/Assets/A2629F15A3CEB78E2100B247B37F898D.png
  31. Binär
      public/scenes/campus/Assets/C66527F4D6692A6601EBD445EE0DA514.png
  32. Binär
      public/scenes/campus/Assets/CF2A0E8DDE7C3F5C32D7D566A000D75C.png
  33. Binär
      public/scenes/campus/Assets/D36EBC54726C5D107F74895632D3FEF7.png
  34. Binär
      public/scenes/campus/Assets/D3942AAE506B2CF302009CE24B4750DA.png
  35. Binär
      public/scenes/campus/Assets/DBCD39AE9382BD8A286B8E456ABA987D.png
  36. Binär
      public/scenes/campus/Assets/DEB9BC496090FFA96A7A2D6B9550A056.png
  37. Binär
      public/scenes/campus/Assets/E168D926B640D775F707FDC46119D41F.png
  38. Binär
      public/scenes/campus/Assets/E2372AAC784391F034806F1032513AA2.png
  39. Binär
      public/scenes/campus/Assets/E2660024DCD28F3D66C20955368A57A7.png
  40. Binär
      public/scenes/campus/Assets/E46479FA144721C80781F0345AC4FF51.png
  41. Binär
      public/scenes/campus/Assets/FFAE02A1E8B2E46F6FC4BE9F703657C1.png
  42. Binär
      public/scenes/campus/Unity2GLTF.bin
  43. 2258
    0
      public/scenes/campus/Unity2GLTF.gltf
  44. 1
    0
      public/scenes/campus/index.json
  45. 1
    0
      public/scenes/campus/scene.json
  46. 0
    330
      public/scenes/foo.gltf
  47. 597
    0
      public/scenes/foo2.gltf
  48. 46
    0
      public/scenes/model.json
  49. 106
    15
      src/controller.ts
  50. 78
    102
      src/index.ts
  51. 95
    0
      src/navigator.ts

+ 19
- 0
public/index.html Visa fil

@@ -6,9 +6,28 @@
6 6
     <style>
7 7
         body{
8 8
             margin: 0;
9
+            cursor: pointer;
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;
9 25
         }
10 26
     </style>
11 27
     
12 28
 </head>
13 29
 <body>
30
+    <div class="mask" id="mask">
31
+        <h1>点击鼠标开始,ESC键退出</h1>
32
+    </div>
14 33
 </body>

Binär
public/scenes/campus/Assets/00ACC3C40649240DF9BD6F0AAFA56389.png Visa fil


Binär
public/scenes/campus/Assets/0CAAE57A1FC2D9880117C70327C0766D.png Visa fil


Binär
public/scenes/campus/Assets/0CC9142D64AB6E5082D13A75B37DDE7A.png Visa fil


Binär
public/scenes/campus/Assets/11D39409EFDA73738D4CDC0619A7DAF6.png Visa fil


Binär
public/scenes/campus/Assets/1798AB1545B6F6944BBB5B29E538F7E0.png Visa fil


Binär
public/scenes/campus/Assets/17B157CB75B005E126B2CAA6C8D4A411.png Visa fil


Binär
public/scenes/campus/Assets/1BC7DC99A71CB0580C4815D19D887143.png Visa fil


Binär
public/scenes/campus/Assets/1F2B41E795D3CA14026AE36357315B1F.png Visa fil


Binär
public/scenes/campus/Assets/218C8F7A5193B09F1414D85AB5678538.png Visa fil


Binär
public/scenes/campus/Assets/2F6FF7766D95FF9177F7CEDED606F3E8.png Visa fil


Binär
public/scenes/campus/Assets/3BC6B123A43889CB37533199B58E131B.png Visa fil


Binär
public/scenes/campus/Assets/3E1AF388FCC01A6E4A8886EE6A7ED24C.png Visa fil


Binär
public/scenes/campus/Assets/4DF5D4774BC5709DA9CD27F9614DDFB4.png Visa fil


Binär
public/scenes/campus/Assets/51AE3B29BFC5259042CF85F2F4E29925.png Visa fil


Binär
public/scenes/campus/Assets/546CB88B13BDAE73F1836E258A8128AC.png Visa fil


Binär
public/scenes/campus/Assets/60DA469BAECB6A458836C9D7145954A0.png Visa fil


Binär
public/scenes/campus/Assets/6C6D3EAE3EDB52581DF01C6301686C94.png Visa fil


Binär
public/scenes/campus/Assets/6FF181DB67E10FA8628467102210C809.png Visa fil


Binär
public/scenes/campus/Assets/724486ACAAB8B758059A3AE77E842655.png Visa fil


Binär
public/scenes/campus/Assets/761CC41F9A3000C9048E64F5E3DB207E.png Visa fil


Binär
public/scenes/campus/Assets/76584CD8BA814CFE3243DABBA61DA0FF.png Visa fil


Binär
public/scenes/campus/Assets/77E5FFB9C9EC66D16BB49D3FF160629C.png Visa fil


Binär
public/scenes/campus/Assets/793BD9CFAF44CE597D34074A714D48D9.png Visa fil


Binär
public/scenes/campus/Assets/7FE51DCF8A388026BFCAE0F4C4BF0236.png Visa fil


Binär
public/scenes/campus/Assets/80390CC69A7E3D8331F8D7C94A862B2D.png Visa fil


Binär
public/scenes/campus/Assets/9906B1BA7E1524CEABBF1C9DD1CE3627.png Visa fil


Binär
public/scenes/campus/Assets/9B18107ABB606F8BE1F9810D6BF298CE.png Visa fil


Binär
public/scenes/campus/Assets/9B54F2BBCF60147EAE8B1037E5A0CBAC.png Visa fil


Binär
public/scenes/campus/Assets/A2629F15A3CEB78E2100B247B37F898D.png Visa fil


Binär
public/scenes/campus/Assets/C66527F4D6692A6601EBD445EE0DA514.png Visa fil


Binär
public/scenes/campus/Assets/CF2A0E8DDE7C3F5C32D7D566A000D75C.png Visa fil


Binär
public/scenes/campus/Assets/D36EBC54726C5D107F74895632D3FEF7.png Visa fil


Binär
public/scenes/campus/Assets/D3942AAE506B2CF302009CE24B4750DA.png Visa fil


Binär
public/scenes/campus/Assets/DBCD39AE9382BD8A286B8E456ABA987D.png Visa fil


Binär
public/scenes/campus/Assets/DEB9BC496090FFA96A7A2D6B9550A056.png Visa fil


Binär
public/scenes/campus/Assets/E168D926B640D775F707FDC46119D41F.png Visa fil


Binär
public/scenes/campus/Assets/E2372AAC784391F034806F1032513AA2.png Visa fil


Binär
public/scenes/campus/Assets/E2660024DCD28F3D66C20955368A57A7.png Visa fil


Binär
public/scenes/campus/Assets/E46479FA144721C80781F0345AC4FF51.png Visa fil


Binär
public/scenes/campus/Assets/FFAE02A1E8B2E46F6FC4BE9F703657C1.png Visa fil


Binär
public/scenes/campus/Unity2GLTF.bin Visa fil


+ 2258
- 0
public/scenes/campus/Unity2GLTF.gltf
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 1
- 0
public/scenes/campus/index.json Visa fil

@@ -0,0 +1 @@
1
+{"date":"2020/04/27 16:46:52","author":"uinnvoa","description":"","license":"优锘科技版权所有","camInfo":{"eye":"-25.916 33.351 -6.956","target":"-9.081 7.755 10.079"},"version":"1.1.0"}

+ 1
- 0
public/scenes/campus/scene.json Visa fil

@@ -0,0 +1 @@
1
+{"camInfo":{"eye":"-25.916 33.351 -6.956","target":"-9.081 7.755 10.079"},"id":"0","gltfid":"node_World_-15956","outdoors":{"id":"1","gltfid":"node_FloorPlan_-15966","structure":{"placements":[{"id":"-57192","gltfid":"node_CombinePlacement_-57192"},{"id":"-57202","gltfid":"node_CombinePlacement_-57202"},{"id":"-57212","gltfid":"node_CombinePlacement_-57212"}]}}}

+ 0
- 330
public/scenes/foo.gltf
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 597
- 0
public/scenes/foo2.gltf
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 46
- 0
public/scenes/model.json Visa fil

@@ -0,0 +1,46 @@
1
+{
2
+	"metadata": {
3
+		"version": 4.5,
4
+		"type": "Object",
5
+		"generator": "Object3D.toJSON"
6
+	},
7
+	"geometries": [
8
+		{
9
+			"uuid": "7A6FECB8-F13F-4A7D-A536-F5965EA50825",
10
+			"type": "TorusBufferGeometry",
11
+			"radius": 1,
12
+			"tube": 0.4,
13
+			"radialSegments": 8,
14
+			"tubularSegments": 6,
15
+			"arc": 6.283185
16
+		}],
17
+	"materials": [
18
+		{
19
+			"uuid": "8ABC72E1-6354-44F6-AA61-F68253ED93DE",
20
+			"type": "MeshStandardMaterial",
21
+			"color": 16777215,
22
+			"roughness": 0.5,
23
+			"metalness": 0.5,
24
+			"emissive": 32832,
25
+			"depthFunc": 3,
26
+			"depthTest": true,
27
+			"depthWrite": true,
28
+			"stencilWrite": false,
29
+			"stencilWriteMask": 255,
30
+			"stencilFunc": 519,
31
+			"stencilRef": 0,
32
+			"stencilFuncMask": 255,
33
+			"stencilFail": 7680,
34
+			"stencilZFail": 7680,
35
+			"stencilZPass": 7680
36
+		}],
37
+	"object": {
38
+		"uuid": "7C61FBE2-0D96-493A-AD3F-BF6EA21C4305",
39
+		"type": "Mesh",
40
+		"name": "abc",
41
+		"layers": 1,
42
+		"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,-1.862864,1],
43
+		"geometry": "7A6FECB8-F13F-4A7D-A536-F5965EA50825",
44
+		"material": "8ABC72E1-6354-44F6-AA61-F68253ED93DE"
45
+	}
46
+}

+ 106
- 15
src/controller.ts Visa fil

@@ -1,38 +1,129 @@
1
+import { Object3D, Raycaster, Camera, Scene, Euler, Vector3 } from "three";
2
+import { ReeGame } from './index';
1 3
 
2 4
 export class GameController {
3 5
     root: HTMLElement;
4
-
6
+    mouse: { dx: number, dy: number };
5 7
     callbackMap: any;
8
+    axisZ = new Vector3(0, 0, 1).normalize();
9
+
10
+    private vec: Vector3 = new Vector3();
11
+    private game: ReeGame;
12
+    private startFlag = false;
13
+    private mask: HTMLElement;
6 14
 
7
-    constructor(root: HTMLElement) {
15
+    constructor(root: HTMLElement, mask: HTMLElement, game: ReeGame) {
8 16
         this.root = root;
9 17
         this.callbackMap = {};
10
-        this.bindKey();
18
+        this.game = game;
19
+        this.mouse = { dx: 0, dy: 0 }
20
+        this.mask = mask;
21
+
22
+        this.onPointLockChange();
23
+        this.onStartSignal();
24
+        this.onKey();
25
+        this.bindMouseLookAt(game.camera, game.scene);
26
+        this.bindMoveKeys(game.camera);
27
+    }
28
+
29
+    bindMouseLookAt(obj: Camera, scene: Scene) {
30
+
31
+        let cam = obj;
32
+        let eu: Euler = new Euler(0, 0, 0, 'YXZ');
33
+        let PI_2 = Math.PI / 2;
34
+
35
+        this.root.onmousemove = (event) => {
36
+            if (!this.startFlag) return;
37
+
38
+            event.preventDefault();
39
+            this.mouse.dx = event.movementX;
40
+            this.mouse.dy = event.movementY;
41
+
42
+            eu.setFromQuaternion(cam.quaternion);
43
+            eu.x -= this.mouse.dy * 0.001;
44
+            eu.y -= this.mouse.dx * 0.001;
45
+            eu.x = Math.max(- PI_2, Math.min(PI_2, eu.x));
46
+            cam.quaternion.setFromEuler(eu);
47
+
48
+        };
49
+    }
50
+
51
+    bindMoveKeys(box: Object3D) {
52
+        this.onKey_A(() => {
53
+            if (box) {
54
+                //旋转矩阵的x向量
55
+                this.vec.setFromMatrixColumn(box.matrix, 0);
56
+                box.position.addScaledVector(this.vec, -0.1);
57
+            }
58
+        });
59
+        this.onKey_D(() => {
60
+            if (box) {
61
+                //旋转矩阵的x向量
62
+                this.vec.setFromMatrixColumn(box.matrix, 0);
63
+                box.position.addScaledVector(this.vec, 0.1);
64
+            }
65
+        });
66
+        this.onKey_S(() => {
67
+            if (box) {
68
+                this.vec.setFromMatrixColumn(box.matrix, 0);
69
+                this.vec.crossVectors(box.up, this.vec);
70
+                box.position.addScaledVector(this.vec, -0.1);
71
+            }
72
+        });
73
+        this.onKey_W(() => {
74
+            if (box) {
75
+                this.vec.setFromMatrixColumn(box.matrix, 0);
76
+                this.vec.crossVectors(box.up, this.vec);
77
+                box.position.addScaledVector(this.vec, 0.1);
78
+            }
79
+        });
11 80
     }
12 81
 
13
-    onKey_A(callback: Function) {
14
-        this.callbackMap["A"] = callback;
82
+    private onKey_A(callback: Function) {
83
+        this.callbackMap[65] = callback;
15 84
     }
16 85
 
17
-    onKey_S(callback: Function) {
18
-        this.callbackMap["S"] = callback;
86
+    private onKey_S(callback: Function) {
87
+        this.callbackMap[83] = callback;
19 88
     }
20 89
 
21
-    onKey_W(callback: Function) {
22
-        this.callbackMap["W"] = callback;
90
+    private onKey_W(callback: Function) {
91
+        this.callbackMap[87] = callback;
23 92
     }
24
-    onKey_D(callback: Function) {
25
-        this.callbackMap["D"] = callback;
93
+    private onKey_D(callback: Function) {
94
+        this.callbackMap[68] = callback;
26 95
     }
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
+            }
27 108
 
28
-    private bindKey() {
109
+        };
110
+    }
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() {
29 120
         this.root.onkeypress = (event) => {
30
-            let c = event.key.toUpperCase();
121
+            if (!this.startFlag) return;
122
+            let c = event.keyCode;
31 123
             if (this.callbackMap[c]) {
32 124
                 this.callbackMap[c]();
33 125
             }
34
-        };
35
-        console.log(this.root);
36 126
 
127
+        };
37 128
     }
38 129
 }

+ 78
- 102
src/index.ts Visa fil

@@ -1,77 +1,65 @@
1 1
 import * as THREE from "three"
2 2
 import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
3
-import { Object3D, Mesh, ShaderMaterial } from "three";
3
+import { Object3D, Mesh, TextureLoader, HemisphereLight, Color, AmbientLight, PlaneBufferGeometry, MeshPhongMaterial, Vector3, Scene } from "three";
4 4
 
5 5
 import { GameController } from "./controller"
6
+import { OrbitNavigator, KeyPoint } from "./navigator";
6 7
 
7
-
8
-export class FooGame {
8
+export class ReeGame {
9 9
 
10 10
     scene: THREE.Scene;
11 11
     camera: THREE.Camera;
12
-    renderer: THREE.WebGLRenderer;
13
-
14
-    cam_fov = 70; //视角大小
15
-    cam_aspect = window.innerWidth / window.innerHeight;
12
+    private renderer: THREE.WebGLRenderer;
13
+    private light: THREE.Light;
14
+    private cam_fov = 70; //视角大小
15
+    private cam_aspect = window.innerWidth / window.innerHeight;
16 16
 
17
-    loader: GLTFLoader;
17
+    gltfLoader: GLTFLoader;
18
+    textureLoader: TextureLoader;
18 19
 
19
-    updateMap: Object;
20
-
21
-    controller: GameController;
20
+    private controller: GameController;
21
+    private renderFlag: boolean = true;
22 22
 
23 23
     constructor() {
24
-        this.camera = new THREE.PerspectiveCamera(this.cam_fov, this.cam_aspect, 0.01, 10)
25
-        this.camera.position.x = 0;
26
-        this.camera.position.y = 3;
27
-        this.camera.position.z = 5;
24
+        this.camera = new THREE.PerspectiveCamera(this.cam_fov, this.cam_aspect, 1, 1000)
25
+        this.camera.position.x = -1;
26
+        this.camera.position.y = 2;
27
+        this.camera.position.z = 1;
28 28
 
29 29
         this.scene = new THREE.Scene();
30
+        this.scene.add(this.camera);
31
+
32
+        this.light = new HemisphereLight(new Color(0XFFFFFF), new Color(0x000000), 1);
33
+        this.light.position.set(0, 15, 0);
30 34
 
35
+        this.scene.add(new AmbientLight(new Color(0xffffff), 1));
36
+        this.scene.add(this.light);
31 37
         this.renderer = new THREE.WebGLRenderer();
32 38
         this.renderer.setSize(window.innerWidth, window.innerHeight);
33 39
 
34 40
         document.body.appendChild(this.renderer.domElement);
35 41
 
36
-        this.loader = new GLTFLoader();
37
-
38
-        this.updateMap = {};
39
-
40
-        this.controller = new GameController(document.body);
41
-
42
+        this.gltfLoader = new GLTFLoader();
43
+        let mask = document.getElementById("mask") || new HTMLElement();
44
+        this.controller = new GameController(document.body, mask, this);
45
+        this.textureLoader = new TextureLoader();
42 46
         this.animate();
43
-        //this.loadScene();
44
-    }
45
-
46
-    bindKeyAction(box: Object3D) {
47
-        this.controller.onKey_A(() => {
48
-            if (box) box.position.x -= 0.1;
49
-        });
50
-        this.controller.onKey_D(() => {
51
-            if (box) box.position.x += 0.1;
52
-        });
53
-        this.controller.onKey_S(() => {
54
-            if (box) box.position.z += 0.1;
55
-        });
56
-        this.controller.onKey_W(() => {
57
-            if (box) box.position.z -= 0.1;
58
-        });
59
-
60 47
     }
61 48
 
62
-    animate() {
49
+    private animate() {
63 50
         requestAnimationFrame(() => {
64 51
             this.animate();
65 52
         });
66
-        this.updateObjects(this.scene);
67
-        this.renderer.render(this.scene, this.camera);
53
+        if (this.renderFlag) {
54
+            this.updateObjects(this.scene);
55
+            this.renderer.render(this.scene, this.camera);
56
+        }
68 57
     }
69 58
 
70 59
     private updateObjects(obj: Object3D) {
71 60
 
72
-        if ("update" in obj && (typeof obj["update"] == "function")) {
73
-            var f: Function = obj["update"];
74
-            f.call(obj, obj);
61
+        if (obj.userData.update && (typeof obj.userData.update == "function")) {
62
+            obj.userData.update.call(obj, obj);
75 63
         }
76 64
 
77 65
         if (obj.children && obj.children.length > 0) {
@@ -81,6 +69,12 @@ export class FooGame {
81 69
         }
82 70
     }
83 71
 
72
+    stop() {
73
+        this.renderFlag = false;
74
+    }
75
+    start() {
76
+        this.renderFlag = true;
77
+    }
84 78
     findObjectByName(name: string, parent: Object3D = this.scene) {
85 79
         let obj = parent.getObjectByName(name);
86 80
         if (obj) return obj;
@@ -95,73 +89,55 @@ export class FooGame {
95 89
         }
96 90
     }
97 91
 
98
-    setUpdate(obj: Object3D, fn: Function) {
99
-        Object.defineProperty(obj, "update", {
100
-            writable: true,
101
-            value: fn
102
-        });
92
+    static setUpdate(obj: Object3D, fn: Function) {
93
+        let v = fn;
94
+
95
+        if (obj.userData.update && (typeof obj.userData.update == "function")) {
96
+            var f: Function = obj.userData.update;
97
+            v = () => {
98
+                f.call(obj, obj);
99
+                fn.call(obj, obj);
100
+            };
101
+        }
102
+        obj.userData.update = v;
103 103
     }
104 104
 
105
+    /**
106
+     * 加载场景
107
+     * @param callback 
108
+     */
105 109
     loadScene(callback: Function) {
106
-        this.loader.load("./scenes/foo.gltf", gltf => {
110
+
111
+        this.gltfLoader.load("./scenes/campus/Unity2GLTF.gltf", gltf => {
107 112
             this.scene.add(gltf.scene);
108
-            let box = this.scene.getObjectByName("Box");
109
-            box && this.camera.lookAt(box.position);
113
+            this.scene.background = new THREE.Color('rgb(191,196,234)');
114
+            //添加一个地板
115
+            let geoGround = new PlaneBufferGeometry(200, 200, 100, 200);
116
+            let matGround = new MeshPhongMaterial({
117
+                color: "rgb(100,100,100)"
118
+            });
119
+            let ground = new Mesh(geoGround, matGround);
120
+            ground.rotation.x = -Math.PI / 2;
121
+            ground.position.y = -2;
122
+            this.scene.add(ground);
123
+
110 124
             callback();
111 125
         });
112 126
     }
113 127
 }
114 128
 
115
-let game = new FooGame();
116
-
117
-let vertexShader =  `
118
-uniform float time;
119
-varying vec3 vPos;
120
-void main() {
121
-	vPos=position;
122
-	vPos.x += sin(time * vPos.z) * 2.0;
123
-	vPos.y += cos(time * vPos.z) * 2.0;
124
-	//vPos.z += tan(time * vPos.z) * 4.0;
125
-	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
126
-}
127
-`;
128
-
129
-let fragmentShader =  `
130
-varying vec3 vPos;
131
-void main() {
132
-	gl_FragColor = vec4( vPos, 1.0 );
133
-}
134
-`;
135
-
129
+let game = new ReeGame();
136 130
 game.loadScene(() => {
137
-    let box = game.scene.getObjectByName("Box");
138
-    if (box) {
139
-        game.bindKeyAction(box);
140
-        let mat:ShaderMaterial;
141
-        if (box instanceof Mesh) {
142
-            let mesh: Mesh = box;
143
-            
144
-            mat = new ShaderMaterial({
145
-                uniforms: {
146
-                    time: {
147
-                        value: 0
148
-                    }
149
-                },
150
-                vertexShader: vertexShader,
151
-                fragmentShader: fragmentShader
152
-            });
153
-            mesh.material = mat;
154
-        }
155
-
156
-        game.setUpdate(box, (obj: Object3D) => {
157
-            //game.camera.rotateOnAxis(obj.position, 0.01)
158
-            //obj.position.x += performance.now() * 0.000001;
159
-            //obj.position.z += performance.now() * 0.000001;
160
-            obj.rotateY(0.01);
161 131
 
162
-            //game.camera.lookAt(obj.position)
163
-            mat.uniforms.time.value = performance.now()/500;
164
-        });
165
-    }
166
-})
132
+    let points: KeyPoint[] = [];
133
+    points.push(new KeyPoint(new Vector3(2, 2, 2), new Vector3(0, 2, 0)));
134
+    points.push(new KeyPoint(new Vector3(-20, 15, -20), new Vector3(0, 2, 0)));
135
+    points.push(new KeyPoint(new Vector3(-20, 15, 20), new Vector3(0, 2, 0)));
136
+    points.push(new KeyPoint(new Vector3(20, 15, 20), new Vector3(0, 2, 0)));
137
+    points.push(new KeyPoint(new Vector3(20, 20, -20),new Vector3(0, 2, 0)));
138
+    points.push(new KeyPoint(new Vector3(2, 2, 2)));
139
+    let nav: OrbitNavigator = new OrbitNavigator(game.camera, points, 200, true);
140
+
141
+    nav.start();
142
+});
167 143
 

+ 95
- 0
src/navigator.ts Visa fil

@@ -0,0 +1,95 @@
1
+
2
+import { Object3D, Vector3 } from 'three';
3
+import { ReeGame } from './index';
4
+
5
+export class KeyPoint {
6
+    point: Vector3 | Object3D = new Vector3();
7
+    lookAt?: Vector3 | Object3D;
8
+
9
+    constructor(p: Vector3 | Object3D, look?: Vector3 | Object3D) {
10
+        this.point = p;
11
+        this.lookAt = look;
12
+    }
13
+}
14
+
15
+export class OrbitNavigator {
16
+    private speed: number;
17
+    private loop: boolean;
18
+    private translateDelta: number;
19
+    private target: Object3D;
20
+    private points: KeyPoint[];
21
+    private idxMax: number;
22
+    private idxP0 = 0; // 当前下一个位置索引
23
+    private p0: Vector3 = new Vector3(); //上一个关键点
24
+    private p1: Vector3 = new Vector3(); //下一个关键点
25
+    private lookAt: Vector3 | undefined;
26
+    private direction: Vector3 = new Vector3(); //当前前进方向
27
+
28
+    private vec: Vector3 = new Vector3();
29
+
30
+    constructor(target: Object3D, points: KeyPoint[], speed: number, loop: boolean = true) {
31
+        this.target = target;
32
+        this.points = points || [];
33
+        this.idxMax = points.length - 2;
34
+
35
+        this.speed = speed;
36
+        this.translateDelta = speed * 0.001;
37
+        this.loop = loop;
38
+    }
39
+
40
+    start() {
41
+        this.idxP0 = 0;
42
+        this.calcDirection();
43
+
44
+        this.target.position.set(this.p0.x, this.p0.y, this.p0.z);
45
+        ReeGame.setUpdate(this.target, (obj: Object3D) => {
46
+            this.update(obj);
47
+        });
48
+        console.log("start");
49
+
50
+    }
51
+
52
+    restart() {
53
+        this.idxP0 = 0;
54
+        this.calcDirection();
55
+
56
+        this.target.position.set(this.p0.x, this.p0.y, this.p0.z);
57
+    }
58
+    private update(obj: Object3D) {
59
+
60
+        if (obj.position.distanceTo(this.p1) <= 0.1) {
61
+            this.idxP0++;
62
+            this.calcDirection();
63
+        }
64
+
65
+        if(this.lookAt){
66
+            obj.lookAt(this.lookAt);
67
+        }
68
+        obj.position.addScaledVector(this.direction, this.translateDelta);
69
+    }
70
+
71
+    private calcDirection() {
72
+        if (this.idxP0 > this.idxMax) {
73
+            if (this.loop) {
74
+                this.restart();
75
+            }
76
+            else {
77
+                this.direction = new Vector3(0, 0, 0);
78
+                return;
79
+            }
80
+        }
81
+
82
+        let p0 = this.points[this.idxP0].point;
83
+        let p1 = this.points[this.idxP0 + 1].point;
84
+        let lookAt = this.points[this.idxP0].lookAt;
85
+
86
+        this.lookAt = lookAt && lookAt instanceof Vector3 ? lookAt : lookAt?.position;
87
+        this.p0 = p0 instanceof Vector3 ? p0 : p0.position;
88
+        this.p1 = p1 instanceof Vector3 ? p1 : p1.position;
89
+        this.vec = this.vec.subVectors(this.p1, this.p0);
90
+        this.direction = this.vec.normalize();
91
+
92
+
93
+    }
94
+
95
+}

Laddar…
Avbryt
Spara