浏览代码

Update three.js demo

customisations
alemart 11 个月前
父节点
当前提交
57e3e99331
共有 4 个文件被更改,包括 72 次插入58 次删除
  1. 二进制
      demos/assets/mage.glb
  2. 二进制
      demos/assets/magic-circle.png
  3. 1
    1
      demos/hello-three/NOTICE.html
  4. 71
    57
      demos/hello-three/demo.js

二进制
demos/assets/mage.glb 查看文件


二进制
demos/assets/magic-circle.png 查看文件


+ 1
- 1
demos/hello-three/NOTICE.html 查看文件

35
                 <a href="https://threejs.org" target="_blank" rel="external">https://threejs.org</a>
35
                 <a href="https://threejs.org" target="_blank" rel="external">https://threejs.org</a>
36
             </li>
36
             </li>
37
         </ol>
37
         </ol>
38
-        <p>This application also contains a 3D model from asset pack "Animated Characters 2" by <a href="https://kenney.nl" target="_blank" rel="external">Kenney</a>, released under the <a href="#cc0">Creative Commons Zero 1.0 Universal</a>.</p>
38
+        <p>This application also contains a 3D model of a mage from "Adventurers Character Pack" by <a href="https://kaylousberg.com" target="_blank" rel="external">Kay Lousberg</a>, released under the <a href="#cc0">Creative Commons Zero 1.0 Universal</a>.</p>
39
         <hr>
39
         <hr>
40
 
40
 
41
         <h2 id="lgpl">GNU Lesser General Public License</h2>
41
         <h2 id="lgpl">GNU Lesser General Public License</h2>

+ 71
- 57
demos/hello-three/demo.js 查看文件

2
 
2
 
3
     const my = { };
3
     const my = { };
4
 
4
 
5
-    async function initialize(ar)
5
+    // initialize the virtual scene
6
+    async function init(ar)
6
     {
7
     {
7
         // add lights
8
         // add lights
8
-        const ambientLight = new THREE.AmbientLight(0xb7b7b7);
9
-        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.4);
10
-        directionalLight.position.set(0, 0, -1);
11
-        directionalLight.target.position.set(0, 0, 0);
12
-        ar.scene.add(directionalLight);
9
+        const ambientLight = new THREE.AmbientLight(0xffffff);
13
         ar.scene.add(ambientLight);
10
         ar.scene.add(ambientLight);
14
 
11
 
15
-        // create a group of objects as a child of ar.root
16
-        const group = createGroup('in-front');
17
-        //const group = createGroup('on-top'); // try this option!
12
+        const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0);
13
+        directionalLight.position.set(0, 1, 0);
14
+        ar.root.add(directionalLight);
15
+
16
+        //const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight, 0.5);
17
+        //ar.scene.add(directionalLightHelper);
18
+
19
+        // create a group as a child of ar.root, which is aligned to the physical scene
20
+        const group = createMainGroup(true);
21
+        group.position.set(0, -0.5, 0);
22
+        group.scale.set(0.7, 0.7, 0.7);
18
         ar.root.add(group);
23
         ar.root.add(group);
19
 
24
 
20
-        // create cubes
21
-        const cubeA = createCube(-0.75, 0, 0xffff00);
22
-        const cubeB = createCube(0.75, 0, 0x00ff00);
23
-        group.add(cubeA, cubeB);
25
+        // create the magic circle
26
+        const magicCircle = createPlane('../assets/magic-circle.png');
27
+        magicCircle.material.transparent = true;
28
+        magicCircle.material.opacity = 0.85;
29
+        magicCircle.material.color = new THREE.Color(0xbeefff);
30
+        magicCircle.scale.set(6, 6, 1);
31
+        group.add(magicCircle);
24
 
32
 
25
-        // create the ground
26
-        const ground = createGround(0x3d5afe);
27
-        group.add(ground);
33
+        // load the mage
34
+        const gltf = await loadGLTF('../assets/mage.glb');
35
+        const mage = gltf.scene;
36
+        group.add(mage);
28
 
37
 
29
-        // load a 3D model
30
-        const modelURL = '../assets/my-3d-model.glb';
31
-        const model = await loadModel(modelURL);
32
-        group.add(model);
38
+        // prepare the animation of the mage
39
+        const animationAction = createAnimationAction(gltf, 'Idle');
40
+        animationAction.loop = THREE.LoopRepeat;
41
+        animationAction.play();
33
 
42
 
34
         // export objects
43
         // export objects
35
-        my.cubes = [ cubeA, cubeB ];
36
         my.group = group;
44
         my.group = group;
37
-        my.model = model;
38
-        my.ground = ground;
45
+        my.magicCircle = magicCircle;
46
+        my.mage = mage;
47
+        my.animationAction = animationAction;
39
     }
48
     }
40
 
49
 
41
-    function animate(ar)
50
+    // animate the virtual scene
51
+    function animate(ar, deltaSeconds)
42
     {
52
     {
43
-        const ROTATION_CYCLES_PER_SECOND = 1.0;
44
         const TWO_PI = 2.0 * Math.PI;
53
         const TWO_PI = 2.0 * Math.PI;
45
-        const delta = ar.session.time.delta;
54
+        const ROTATIONS_PER_SECOND = 0.25;
55
+
56
+        // animate the mage
57
+        const mixer = my.animationAction.getMixer();
58
+        mixer.update(deltaSeconds);
46
 
59
 
47
-        // rotate the cubes
48
-        for(const cube of my.cubes)
49
-            cube.rotateY(TWO_PI * ROTATION_CYCLES_PER_SECOND * delta);
60
+        // animate the magic circle
61
+        my.magicCircle.rotateZ(TWO_PI * ROTATIONS_PER_SECOND * deltaSeconds);
50
     }
62
     }
51
 
63
 
52
-    function createGroup(mode = 'in-front')
64
+    function createMainGroup(frontView = false)
53
     {
65
     {
54
         const group = new THREE.Group();
66
         const group = new THREE.Group();
55
 
67
 
56
-        if(mode == 'in-front') {
57
-            group.rotation.set(-Math.PI/2, 0, 0);
58
-            group.position.set(0, -0.5, 0.5);
59
-        }
60
-        else if(mode == 'on-top') {
61
-            group.rotation.set(0, 0, 0);
62
-            group.position.set(0, 0, 0);
63
-        }
68
+        // top view is the default
69
+        if(frontView)
70
+            group.rotateX(-Math.PI / 2);
64
 
71
 
65
         return group;
72
         return group;
66
     }
73
     }
67
 
74
 
68
-    function createCube(x, y, color, length = 0.25)
75
+    async function loadGLTF(filepath, yAxisIsUp = true)
69
     {
76
     {
70
-        const geometry = new THREE.BoxGeometry(length, length, length);
71
-        const material = new THREE.MeshPhongMaterial({ color });
72
-        const cube = new THREE.Mesh(geometry, material);
77
+        const loader = new THREE.GLTFLoader();
78
+        const gltf = await loader.loadAsync(filepath);
73
 
79
 
74
-        cube.position.set(x, y, 1.25);
80
+        // glTF defines +y as up. We expect +z to be up.
81
+        if(yAxisIsUp)
82
+            gltf.scene.rotateX(Math.PI / 2);
75
 
83
 
76
-        return cube;
84
+        return gltf;
77
     }
85
     }
78
 
86
 
79
-    function createGround(color)
87
+    function createAnimationAction(gltf, name = null)
80
     {
88
     {
81
-        const geometry = new THREE.RingGeometry(0.001, 1, 8);
82
-        const material = new THREE.MeshPhongMaterial({ color: color, side: THREE.DoubleSide });
83
-        const ground = new THREE.Mesh(geometry, material);
89
+        const mixer = new THREE.AnimationMixer(gltf.scene);
90
+        const clips = gltf.animations;
91
+
92
+        if(clips.length == 0)
93
+            throw new Error('No animation clips');
84
 
94
 
85
-        material.transparent = true;
86
-        material.opacity = 0.75;
95
+        const clip = (name !== null) ? THREE.AnimationClip.findByName(clips, name) : clips[0];
96
+        const action = mixer.clipAction(clip);
87
 
97
 
88
-        return ground;
98
+        return action;
89
     }
99
     }
90
 
100
 
91
-    async function loadModel(filepath)
101
+    function createPlane(imagepath)
92
     {
102
     {
93
-        const loader = new THREE.GLTFLoader();
94
-        const gltf = await loader.loadAsync(filepath);
95
-        const model = gltf.scene;
103
+        const texture = new THREE.TextureLoader().load(imagepath);
104
+        const geometry = new THREE.PlaneGeometry(1, 1);
105
+        const material = new THREE.MeshBasicMaterial({
106
+            map: texture,
107
+            side: THREE.DoubleSide,
108
+        });
109
+        const mesh = new THREE.Mesh(geometry, material);
96
 
110
 
97
-        return model;
111
+        return mesh;
98
     }
112
     }
99
 
113
 
100
     async function startARSession()
114
     async function startARSession()
152
     }
166
     }
153
 
167
 
154
     // enchant!
168
     // enchant!
155
-    encantar(startARSession, animate, initialize);
169
+    encantar(startARSession, animate, init);
156
 
170
 
157
 });
171
 });

正在加载...
取消
保存