Procházet zdrojové kódy

Add babylon.js demo

customisations
alemart před 11 měsíci
rodič
revize
82c191b53b

+ 1222
- 0
demos/hello-babylon/NOTICE.html
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 75
- 0
demos/hello-babylon/README.html Zobrazit soubor

@@ -0,0 +1,75 @@
1
+<!doctype html>
2
+<html>
3
+    <head>
4
+        <meta charset="utf-8">
5
+        <title>encantAR.js WebAR demo with babylon.js</title>
6
+        <style>
7
+        body {
8
+            font-family: sans-serif;
9
+            background-color: whitesmoke;
10
+        }
11
+
12
+        a:any-link {
13
+            color: #7e56c2;
14
+            text-decoration: none;
15
+        }
16
+
17
+        a:hover {
18
+            text-decoration: underline;
19
+        }
20
+
21
+        li + li {
22
+            margin-top: 1em;
23
+        }
24
+
25
+        ul {
26
+            list-style-type: none;
27
+            padding-left: 1em;
28
+        }
29
+
30
+        img.qr-code {
31
+            display: block;
32
+            width: 256px;
33
+            image-rendering: pixelated;
34
+            border: 1px dashed black;
35
+        }
36
+
37
+        a img {
38
+            height: 5em;
39
+            border-radius: 4px;
40
+        }
41
+
42
+        @media screen and (min-width: 768px) {
43
+            a img {
44
+                height: 3em;
45
+            }
46
+        }
47
+        </style>
48
+    </head>
49
+    <body>
50
+        <h1>encantAR.js with babylon.js</h1>
51
+        <p>Scan the QR code to launch the web-based Augmented Reality experience. Next, scan <a href="../assets/mage.webp" target="_blank">this cartoon</a> or <a href="../assets/cat.webp" target="_blank">this picture</a>.</p>
52
+
53
+        <h2>Menu</h2>
54
+        <ul>
55
+            <li><a href="index.html">Launch the WebAR experience</a></li>
56
+            <li><a href="video.html">Test with a pre-recorded video</a></li>
57
+            <li><a href="NOTICE.html">See the attribution notices</a></li>
58
+            <li><a href="../">Try other WebAR demos</a></li>
59
+        </ul>
60
+
61
+        <h2>QR code</h2>
62
+        <img src="qr-code.gif" alt="QR code" class="qr-code">
63
+
64
+        <h2>Share</h2>
65
+        <p>This application is powered by <a href="https://alemart.github.io/encantar-js" target="_blank">encantAR.js: GPU-accelerated Augmented Reality for the web</a>.</p>
66
+        <div>
67
+            <a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Falemart.github.io/encantar-js&quote=%23encantar-js" target="_blank" rel="external" class="button"><img src="../assets/facebook.png" alt="Share on Facebook"></a>
68
+            <a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Falemart.github.io/encantar-js&hashtags=encantar-js" target="_blank" rel="external" class="button"><img src="../assets/twitter.png" alt="Share on X"></a>
69
+            <a href="https://wa.me/?text=https%3A%2F%2Falemart.github.io/encantar-js" target="_blank" rel="external" class="button"><img src="../assets/whatsapp.png" alt="Share via WhatsApp"></a>
70
+            <a href="https://t.me/share/url?url=https%3A%2F%2Falemart.github.io/encantar-js" target="_blank" rel="external" class="button"><img src="../assets/telegram.png" alt="Share via Telegram"></a>
71
+            <a href="https://github.com/sponsors/alemart" target="_blank" rel="external"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/alemart?style=for-the-badge&logo=github&label=Sponsor&labelColor=%237e56c2&color=%23ffd500"></a>
72
+        </div>
73
+    </body>
74
+</html>
75
+

+ 56
- 0
demos/hello-babylon/demo.css Zobrazit soubor

@@ -0,0 +1,56 @@
1
+body {
2
+    background-color: black;
3
+    background-image: url("../assets/poster.svg"), linear-gradient(black, 20%, #46346a);
4
+    background-position: center;
5
+    background-repeat: no-repeat;
6
+    height: 100vh;
7
+    margin: 0;
8
+    padding: 0;
9
+}
10
+
11
+#scan {
12
+    width: 100%;
13
+    height: 100%;
14
+    object-fit: contain;
15
+    opacity: 0.75;
16
+}
17
+
18
+#about {
19
+    position: absolute;
20
+    right: 0;
21
+    top: 0;
22
+
23
+    display: inline-block;
24
+    margin: 0;
25
+    padding: 0 0.25em;
26
+
27
+    color: #fff;
28
+    font-size: 48px;
29
+    font-weight: bold;
30
+    font-family: monospace;
31
+    text-decoration: none;
32
+    text-align: center;
33
+
34
+    border-bottom: 4px solid;
35
+    border-color: #5c3ba3;
36
+    background: linear-gradient(0deg, #7b5ec4 0%, #bb7aff 100%);
37
+    -webkit-tap-highlight-color: transparent;
38
+}
39
+
40
+#about:hover {
41
+    border-color: #6742b8;
42
+    background: linear-gradient(0deg, #8b72cb 0%, #c894ff 100%);
43
+}
44
+
45
+#about:active {
46
+    border-color: #a5a500;
47
+    background: linear-gradient(0deg, #cccc00 0%, #ffff00 100%);
48
+}
49
+
50
+#about::before {
51
+    content: '\24D8';
52
+}
53
+
54
+#about:focus {
55
+    outline: none;
56
+}

+ 273
- 0
demos/hello-babylon/demo.js Zobrazit soubor

@@ -0,0 +1,273 @@
1
+/**
2
+ * Augmented Reality demo using the babylon.js plugin for encantar.js
3
+ * @author Alexandre Martins <alemartf(at)gmail.com> (https://github.com/alemart/encantar-js)
4
+ */
5
+
6
+(function() {
7
+
8
+/**
9
+ * Augmented Reality Demo
10
+ */
11
+class EnchantedDemo extends ARDemo
12
+{
13
+    /**
14
+     * Constructor
15
+     */
16
+    constructor()
17
+    {
18
+        super();
19
+
20
+        this._objects = { };
21
+    }
22
+
23
+    /**
24
+     * Start the AR session
25
+     * @returns {Promise<Session>}
26
+     */
27
+    async startSession()
28
+    {
29
+        if(!AR.isSupported()) {
30
+            throw new Error(
31
+                'This device is not compatible with this AR experience.\n\n' +
32
+                'User agent: ' + navigator.userAgent
33
+            );
34
+        }
35
+
36
+        const tracker = AR.Tracker.ImageTracker();
37
+        await tracker.database.add([
38
+        {
39
+            name: 'mage',
40
+            image: document.getElementById('mage')
41
+        },
42
+        {
43
+            name: 'cat',
44
+            image: document.getElementById('cat')
45
+        }
46
+        ]);
47
+
48
+        const viewport = AR.Viewport({
49
+            container: document.getElementById('ar-viewport'),
50
+            hudContainer: document.getElementById('ar-hud')
51
+        });
52
+
53
+        const video = document.getElementById('my-video');
54
+        const useWebcam = (video === null);
55
+        const source = useWebcam ? AR.Source.Camera() : AR.Source.Video(video);
56
+
57
+        const session = await AR.startSession({
58
+            mode: 'immersive',
59
+            viewport: viewport,
60
+            trackers: [ tracker ],
61
+            sources: [ source ],
62
+            stats: true,
63
+            gizmos: true,
64
+        });
65
+
66
+        const scan = document.getElementById('scan');
67
+
68
+        tracker.addEventListener('targetfound', event => {
69
+            session.gizmos.visible = false;
70
+            if(scan)
71
+                scan.hidden = true;
72
+
73
+            this._onTargetFound(event.referenceImage);
74
+        });
75
+
76
+        tracker.addEventListener('targetlost', event => {
77
+            session.gizmos.visible = true;
78
+            if(scan)
79
+                scan.hidden = false;
80
+
81
+            this._onTargetLost(event.referenceImage);
82
+        });
83
+
84
+        return session;
85
+    }
86
+
87
+    /**
88
+     * Initialization
89
+     * @param {ARSystem} ar
90
+     * @returns {Promise<void>}
91
+     */
92
+    async init(ar)
93
+    {
94
+        // Do not automatically play an animation when loading GLTF models
95
+        BABYLON.SceneLoader.OnPluginActivatedObservable.add(loader => {
96
+            if(loader.name == 'gltf') {
97
+                loader.animationStartMode = BABYLON.GLTFLoaderAnimationStartMode.NONE;
98
+            }
99
+        });
100
+
101
+        // Change the point of view - slightly
102
+        ar.root.position.y = -0.5;
103
+
104
+        // Initialize objects
105
+        this._initLight(ar);
106
+        this._initText(ar);
107
+        this._initMagicCircle(ar);
108
+
109
+        await Promise.all([
110
+            this._initMage(ar),
111
+            this._initCat(ar),
112
+        ]);
113
+    }
114
+
115
+    /**
116
+     * Animation loop
117
+     * @param {ARSystem} ar
118
+     * @returns {void}
119
+     */
120
+    update(ar)
121
+    {
122
+        const delta = ar.session.time.delta; // given in seconds
123
+
124
+        this._animateMagicCircle(delta);
125
+    }
126
+
127
+
128
+    // ------------------------------------------------------------------------
129
+
130
+
131
+    _initLight(ar)
132
+    {
133
+        const light = new BABYLON.HemisphericLight('light', BABYLON.Vector3.Down());
134
+        light.intensity = 1.0;
135
+        light.diffuse.set(1, 1, 0.9);
136
+        light.specular.set(0, 0, 0);
137
+    }
138
+
139
+    _initMagicCircle(ar)
140
+    {
141
+        // create a magic circle
142
+        const magicCircle = BABYLON.MeshBuilder.CreatePlane('magic-circle', {
143
+            width: 1,
144
+            height: 1,
145
+            sideOrientation: BABYLON.Mesh.DOUBLESIDE
146
+        });
147
+
148
+        magicCircle.material = new BABYLON.StandardMaterial('magic-circle-material');
149
+        magicCircle.material.diffuseTexture = new BABYLON.Texture('../assets/magic-circle.png');
150
+        magicCircle.material.diffuseTexture.hasAlpha = true;
151
+        magicCircle.material.useAlphaFromDiffuseTexture = true;
152
+        magicCircle.material.diffuseColor.set(0, 0, 0);
153
+        magicCircle.material.emissiveColor.set(1, 1, 1);
154
+        magicCircle.material.unlit = true;
155
+        magicCircle.rotation.set(-Math.PI / 2, 0, 0);
156
+        magicCircle.scaling.set(4, 4, 1);
157
+
158
+        // make it a child of ar.root
159
+        magicCircle.parent = ar.root;
160
+
161
+        // save a reference
162
+        this._objects.magicCircle = magicCircle;
163
+    }
164
+
165
+    _initText(ar)
166
+    {
167
+        const text = BABYLON.MeshBuilder.CreatePlane('text', {
168
+            width: 1,
169
+            height: 1,
170
+            sideOrientation: BABYLON.Mesh.DOUBLESIDE
171
+        });
172
+
173
+        text.material = new BABYLON.StandardMaterial('text-material');
174
+        text.material.diffuseTexture = new BABYLON.Texture('../assets/it-works.png');
175
+        text.material.diffuseTexture.hasAlpha = true;
176
+        text.material.useAlphaFromDiffuseTexture = true;
177
+        text.material.diffuseColor.set(0, 0, 0);
178
+        text.material.emissiveColor.set(1, 1, 1);
179
+        text.material.unlit = true;
180
+        text.position.set(0, 2, 0.5);
181
+        text.scaling.set(3, 1.5, 1);
182
+
183
+        text.parent = ar.root;
184
+
185
+        this._objects.text = text;
186
+    }
187
+
188
+    async _initMage(ar)
189
+    {
190
+        // load the mage
191
+        const gltf = await BABYLON.SceneLoader.ImportMeshAsync('', '../assets/', 'mage.glb');
192
+        const mage = gltf.meshes[0];
193
+        mage.scaling.set(0.7, 0.7, 0.7);
194
+
195
+        // play an animation
196
+        const anim = gltf.animationGroups.find(anim => anim.name == 'Idle');
197
+        if(anim)
198
+            anim.play(true);
199
+
200
+        // make the mage a child of ar.root
201
+        mage.parent = ar.root;
202
+
203
+        // save a reference
204
+        this._objects.mage = mage;
205
+    }
206
+
207
+    async _initCat(ar)
208
+    {
209
+        const gltf = await BABYLON.SceneLoader.ImportMeshAsync('', '../assets/', 'cat.glb');
210
+        const cat = gltf.meshes[0];
211
+        cat.scaling.set(0.7, 0.7, 0.7);
212
+
213
+        const anim = gltf.animationGroups.find(anim => anim.name == 'Cheer');
214
+        if(anim)
215
+            anim.play(true);
216
+
217
+        cat.parent = ar.root;
218
+
219
+        this._objects.cat = cat;
220
+    }
221
+
222
+    _animateMagicCircle(delta)
223
+    {
224
+        const TWO_PI = 2.0 * Math.PI;
225
+        const ROTATIONS_PER_SECOND = 1.0 / 8.0;
226
+
227
+        this._objects.magicCircle.rotate(BABYLON.Axis.Z, -TWO_PI * ROTATIONS_PER_SECOND * delta);
228
+    }
229
+
230
+    _onTargetFound(referenceImage)
231
+    {
232
+        // change the scene based on the tracked image
233
+        switch(referenceImage.name) {
234
+            case 'mage':
235
+                this._objects.mage.setEnabled(true);
236
+                this._objects.cat.setEnabled(false);
237
+                this._objects.text.setEnabled(false);
238
+                this._objects.magicCircle.material.emissiveColor.fromHexString('#beefff');
239
+                break;
240
+
241
+            case 'cat':
242
+                this._objects.mage.setEnabled(false);
243
+                this._objects.cat.setEnabled(true);
244
+                this._objects.text.setEnabled(true);
245
+                this._objects.magicCircle.material.emissiveColor.fromHexString('#ffffaa');
246
+                break;
247
+        }
248
+    }
249
+
250
+    _onTargetLost(referenceImage)
251
+    {
252
+    }
253
+}
254
+
255
+/**
256
+ * Start the Demo
257
+ * @returns {void}
258
+ */
259
+function main()
260
+{
261
+    const demo = new EnchantedDemo();
262
+
263
+    if(typeof encantar === 'undefined')
264
+        throw new Error(`Can't find the babylon.js plugin for encantar.js`);
265
+
266
+    encantar(demo).catch(error => {
267
+        alert(error.message);
268
+    });
269
+}
270
+
271
+document.addEventListener('DOMContentLoaded', main);
272
+
273
+})();

+ 24
- 0
demos/hello-babylon/index.html Zobrazit soubor

@@ -0,0 +1,24 @@
1
+<!doctype html>
2
+<html>
3
+    <head>
4
+        <meta charset="utf-8">
5
+        <meta name="viewport" content="width=device-width,initial-scale=1">
6
+        <title>encantAR.js WebAR demo with babylon.js</title>
7
+        <link href="demo.css" rel="stylesheet">
8
+        <script src="../../dist/encantar.min.js"></script>
9
+        <script src="https://cdn.jsdelivr.net/npm/babylonjs@7.29.0/babylon.min.js"></script>
10
+        <script src="https://cdn.jsdelivr.net/npm/babylonjs-loaders@7.29.0/babylonjs.loaders.min.js"></script>
11
+        <script src="../../plugins/babylon-with-encantar.js"></script>
12
+        <script src="demo.js"></script>
13
+    </head>
14
+    <body>
15
+        <div id="ar-viewport">
16
+            <div id="ar-hud" hidden>
17
+                <img id="scan" src="../assets/scan.png">
18
+                <a id="about" href="NOTICE.html"></a>
19
+            </div>
20
+        </div>
21
+        <img id="mage" src="../assets/mage.webp" hidden>
22
+        <img id="cat" src="../assets/cat.webp" hidden>
23
+    </body>
24
+</html>

binární
demos/hello-babylon/qr-code.gif Zobrazit soubor


+ 28
- 0
demos/hello-babylon/video.html Zobrazit soubor

@@ -0,0 +1,28 @@
1
+<!doctype html>
2
+<html>
3
+    <head>
4
+        <meta charset="utf-8">
5
+        <meta name="viewport" content="width=device-width,initial-scale=1">
6
+        <title>encantAR.js WebAR demo with babylon.js</title>
7
+        <link href="demo.css" rel="stylesheet">
8
+        <script src="../../dist/encantar.min.js"></script>
9
+        <script src="https://cdn.jsdelivr.net/npm/babylonjs@7.29.0/babylon.min.js"></script>
10
+        <script src="https://cdn.jsdelivr.net/npm/babylonjs-loaders@7.29.0/babylonjs.loaders.min.js"></script>
11
+        <script src="../../plugins/babylon-with-encantar.js"></script>
12
+        <script src="demo.js"></script>
13
+    </head>
14
+    <body>
15
+        <div id="ar-viewport">
16
+            <div id="ar-hud" hidden>
17
+                <img id="scan" src="../assets/scan.png">
18
+                <a id="about" href="NOTICE.html"></a>
19
+            </div>
20
+        </div>
21
+        <img id="mage" src="../assets/mage.webp" hidden>
22
+        <img id="cat" src="../assets/cat.webp" hidden>
23
+        <video id="my-video" hidden muted loop playsinline autoplay>
24
+            <source src="../assets/my-video.webm" type="video/webm" />
25
+            <source src="../assets/my-video.mp4" type="video/mp4" />
26
+        </video>
27
+    </body>
28
+</html>

+ 6
- 0
docs/demos.md Zobrazit soubor

@@ -25,6 +25,12 @@ Create an augmented scene with [A-Frame](https://aframe.io){ ._blank }. No knowl
25 25
 
26 26
 [Launch demo](/encantar-js/demos/hello-aframe/README.html){ ._blank .md-button }
27 27
 
28
+### WebAR with babylon.js
29
+
30
+Create an augmented scene with [babylon.js](https://www.babylonjs.com){ ._blank }.
31
+
32
+[Launch demo](/encantar-js/demos/hello-babylon/README.html){ ._blank .md-button }
33
+
28 34
 ### WebAR with three.js
29 35
 
30 36
 Create an augmented scene with [three.js](https://threejs.org){ ._blank }.

Načítá se…
Zrušit
Uložit