Procházet zdrojové kódy

Upload demos. Create a mkdocs hook to copy the demos to the website

customisations
alemart před 1 rokem
rodič
revize
b7d372b5bf
58 změnil soubory, kde provedl 9332 přidání a 318 odebrání
  1. 35
    24
      README.md
  2. 33
    0
      demos/NOTICE.txt
  3. 183
    0
      demos/assets/FontLoader.js
  4. 4010
    0
      demos/assets/GLTFLoader.js
  5. 51
    0
      demos/assets/TextGeometry.js
  6. 3971
    0
      demos/assets/aframe-particle-system-component.js
  7. 2
    0
      demos/assets/aframe-particle-system-component.min.js
  8. 3
    3
      demos/assets/aframe-with-martins.js
  9. 0
    0
      demos/assets/bird.png
  10. 29
    0
      demos/assets/demo.css
  11. 1
    0
      demos/assets/helvetiker_bold.typeface.json
  12. 0
    0
      demos/assets/it-works.png
  13. binární
      demos/assets/my-3d-model.glb
  14. 14
    0
      demos/assets/my-reference-image.html
  15. 0
    0
      demos/assets/my-reference-image.webp
  16. binární
      demos/assets/my-video.webm
  17. binární
      demos/assets/particle.png
  18. 0
    0
      demos/assets/scan.png
  19. 3
    3
      demos/assets/three-with-martins.js
  20. 81
    0
      demos/hello-aframe/demo.js
  21. 59
    0
      demos/hello-aframe/index.html
  22. 181
    0
      demos/hello-three/demo.js
  23. 24
    0
      demos/hello-three/index.html
  24. 28
    7
      demos/hello-webgl/demo.js
  25. 23
    0
      demos/hello-webgl/index.html
  26. 93
    0
      demos/hello-world/demo.js
  27. 21
    0
      demos/hello-world/index.html
  28. 72
    0
      demos/simple-webcam/demo.js
  29. 20
    0
      demos/simple-webcam/index.html
  30. 211
    0
      demos/touch-interaction/demo.js
  31. 25
    0
      demos/touch-interaction/index.html
  32. 1
    1
      docs/demo/index.md
  33. 2
    2
      docs/demo/instructions.md
  34. 0
    110
      docs/demos.md
  35. 115
    0
      docs/gallery.md
  36. 1
    1
      docs/getting-started/create-the-augmented-scene.md
  37. 21
    0
      docs/hooks.py
  38. binární
      docs/img/qr-demo-hello-aframe.gif
  39. binární
      docs/img/qr-demo-hello-aframe.png
  40. binární
      docs/img/qr-demo-hello-three.gif
  41. binární
      docs/img/qr-demo-hello-three.png
  42. binární
      docs/img/qr-demo-hello-webgl.gif
  43. binární
      docs/img/qr-demo-hello-webgl.png
  44. binární
      docs/img/qr-demo-hello-world.gif
  45. binární
      docs/img/qr-demo-hello-world.png
  46. binární
      docs/img/qr-demo-interactivity-three.png
  47. binární
      docs/img/qr-demo-simple-webcam.gif
  48. binární
      docs/img/qr-demo-touch-interaction.gif
  49. 0
    129
      docs/license/PolyForm-Perimeter-1.0.0-1.md
  50. 11
    0
      docs_overrides/basic_demo.html
  51. 0
    10
      docs_overrides/demo/demo.css
  52. 0
    21
      docs_overrides/demo/index.html
  53. 0
    1
      docs_overrides/dist/aframe-with-martins.js
  54. 0
    1
      docs_overrides/dist/martins.js
  55. 0
    1
      docs_overrides/dist/martins.min.js
  56. 0
    1
      docs_overrides/dist/three-with-martins.js
  57. 7
    2
      mkdocs.yml
  58. 1
    1
      webpack.config.js

+ 35
- 24
README.md Zobrazit soubor

@@ -10,7 +10,41 @@ Create amazing Augmented Reality experiences with **MARTINS.js**, a GPU-accelera
10 10
 
11 11
 :books: Technical documentation is available at <https://alemart.github.io/martins-js/>.
12 12
 
13
-:mailbox: [Contact me](https://github.com/alemart) for freelance work if you're not a developer.
13
+## Try WebAR right now!
14
+
15
+1. Scan or tap the QR code below with a mobile device.
16
+2. A [web page](https://alemart.github.io/martins-js/demo/) will be opened. It's the WebAR experience.
17
+3. The web page will request access to your webcam. Authorize it.
18
+4. Scan the cartoon below.
19
+5. Enjoy! :wink:
20
+
21
+>
22
+> **Guidelines for WebAR:**
23
+>
24
+> - WebGL2 and WebAssembly are required. Use a [compatible browser](#browser-compatibility).
25
+> - Don't move the camera too quickly - it produces motion blur.
26
+> - The physical environment should be properly illuminated.
27
+> - Avoid low-quality cameras (cameras of common smartphones are OK).
28
+>
29
+
30
+[![WebAR demo](https://alemart.github.io/martins-js/demo/reference-image-with-qr-code.webp)](https://alemart.github.io/martins-js/demo/)
31
+
32
+Other demos available [here](https://alemart.github.io/martins-js/gallery/).
33
+
34
+## Try in your own machine
35
+
36
+Try the demos in your own machine:
37
+
38
+1. Run on a console:
39
+
40
+```sh
41
+git clone git@github.com:alemart/martins-js.git
42
+cd martins-js
43
+npm start
44
+```
45
+
46
+2. Open https://localhost:8000/demos/
47
+3. Pick a demo and have fun!
14 48
 
15 49
 ## What can you do with Web-based Augmented Reality?
16 50
 
@@ -22,8 +56,6 @@ Lots of exciting things that run in the web browser!
22 56
 * Tech demos
23 57
 * ...and more!
24 58
 
25
-[Try a demo!](#try-webar-right-now)
26
-
27 59
 ## Why use MARTINS.js?
28 60
 
29 61
 Here is why MARTINS.js is a great choice for creating Augmented Reality experiences:
@@ -34,27 +66,6 @@ Here is why MARTINS.js is a great choice for creating Augmented Reality experien
34 66
 * **Fully standalone!** MARTINS.js has in it everything it needs to analyze the environment and help you create AR. There are no additional requirements. No need of WebXR.
35 67
 * **Easy to get started!** MARTINS.js can be used with a `<script>` tag in your page. A static HTML page is enough to get started.
36 68
 
37
-## Try WebAR right now!
38
-
39
-1. Scan or tap the QR code below with a mobile device.
40
-2. A [web page](https://alemart.github.io/martins-js/demo/) will be opened. It's the WebAR experience.
41
-3. The web page will request access to your webcam. Authorize it.
42
-4. Scan the cartoon below.
43
-5. Enjoy! :wink:
44
-
45
->
46
-> **Guidelines for WebAR:**
47
->
48
-> - WebGL2 and WebAssembly are required. Use a [compatible browser](#browser-compatibility).
49
-> - Don't move the camera too quickly - it produces motion blur.
50
-> - The physical environment should be properly illuminated.
51
-> - Avoid low-quality cameras (cameras of common smartphones are OK).
52
->
53
-
54
-[![WebAR demo](https://alemart.github.io/martins-js/demo/reference-image-with-qr-code.webp)](https://alemart.github.io/martins-js/demo/)
55
-
56
-Other demos available [here](https://alemart.github.io/martins-js/demos/).
57
-
58 69
 ## Features
59 70
 
60 71
 Currently supported features:

+ 33
- 0
demos/NOTICE.txt Zobrazit soubor

@@ -0,0 +1,33 @@
1
+MARTINS.js WebAR engine developed by Alexandre Martins (https://github.com/alemart)
2
+
3
+MARTINS.js: GPU-accelerated Augmented Reality for the web
4
+Copyright (c) Alexandre Martins
5
+https://github.com/alemart/martins-js
6
+
7
+Speedy Vision: GPU-accelerated Computer Vision for JavaScript
8
+Copyright (c) Alexandre Martins
9
+https://github.com/alemart/speedy-vision
10
+
11
+A-Frame: A web framework for building virtual reality experiences
12
+Copyright (c) A-Frame authors
13
+https://aframe.io
14
+
15
+Babylon.js: a powerful, beautiful, simple, and open game and rendering engine packed into a friendly JavaScript framework
16
+Copyright (c) Microsoft Corporation and Babylon.js contributors
17
+https://www.babylonjs.com
18
+
19
+Three.js: JavaScript 3D Library
20
+Copyright (c) Three.js authors
21
+https://threejs.org
22
+
23
+aframe-particle-system-component: Particle systems for A-Frame
24
+Copyright (c) IdeaSpace
25
+https://github.com/IdeaSpaceVR/aframe-particle-system-component
26
+
27
+ShaderParticleEngine: A GLSL-heavy particle engine for THREE.js
28
+Copyright (c) Luke Moody (squarefeet)
29
+https://github.com/squarefeet/ShaderParticleEngine
30
+
31
+three-bmfont-text: renders BMFont files in ThreeJS with word-wrapping
32
+Copyright (c) Jam3 (mattdesl)
33
+https://github.com/Jam3/three-bmfont-text

+ 183
- 0
demos/assets/FontLoader.js Zobrazit soubor

@@ -0,0 +1,183 @@
1
+( function () {
2
+
3
+	class FontLoader extends THREE.Loader {
4
+
5
+		constructor( manager ) {
6
+
7
+			super( manager );
8
+
9
+		}
10
+
11
+		load( url, onLoad, onProgress, onError ) {
12
+
13
+			const scope = this;
14
+			const loader = new THREE.FileLoader( this.manager );
15
+			loader.setPath( this.path );
16
+			loader.setRequestHeader( this.requestHeader );
17
+			loader.setWithCredentials( scope.withCredentials );
18
+			loader.load( url, function ( text ) {
19
+
20
+				let json;
21
+
22
+				try {
23
+
24
+					json = JSON.parse( text );
25
+
26
+				} catch ( e ) {
27
+
28
+					console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );
29
+					json = JSON.parse( text.substring( 65, text.length - 2 ) );
30
+
31
+				}
32
+
33
+				const font = scope.parse( json );
34
+				if ( onLoad ) onLoad( font );
35
+
36
+			}, onProgress, onError );
37
+
38
+		}
39
+
40
+		parse( json ) {
41
+
42
+			return new Font( json );
43
+
44
+		}
45
+
46
+	} //
47
+
48
+
49
+	class Font {
50
+
51
+		constructor( data ) {
52
+
53
+			this.type = 'Font';
54
+			this.data = data;
55
+
56
+		}
57
+
58
+		generateShapes( text, size = 100 ) {
59
+
60
+			const shapes = [];
61
+			const paths = createPaths( text, size, this.data );
62
+
63
+			for ( let p = 0, pl = paths.length; p < pl; p ++ ) {
64
+
65
+				Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
66
+
67
+			}
68
+
69
+			return shapes;
70
+
71
+		}
72
+
73
+	}
74
+
75
+	function createPaths( text, size, data ) {
76
+
77
+		const chars = Array.from( text );
78
+		const scale = size / data.resolution;
79
+		const line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
80
+		const paths = [];
81
+		let offsetX = 0,
82
+			offsetY = 0;
83
+
84
+		for ( let i = 0; i < chars.length; i ++ ) {
85
+
86
+			const char = chars[ i ];
87
+
88
+			if ( char === '\n' ) {
89
+
90
+				offsetX = 0;
91
+				offsetY -= line_height;
92
+
93
+			} else {
94
+
95
+				const ret = createPath( char, scale, offsetX, offsetY, data );
96
+				offsetX += ret.offsetX;
97
+				paths.push( ret.path );
98
+
99
+			}
100
+
101
+		}
102
+
103
+		return paths;
104
+
105
+	}
106
+
107
+	function createPath( char, scale, offsetX, offsetY, data ) {
108
+
109
+		const glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
110
+
111
+		if ( ! glyph ) {
112
+
113
+			console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
114
+			return;
115
+
116
+		}
117
+
118
+		const path = new THREE.ShapePath();
119
+		let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
120
+
121
+		if ( glyph.o ) {
122
+
123
+			const outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
124
+
125
+			for ( let i = 0, l = outline.length; i < l; ) {
126
+
127
+				const action = outline[ i ++ ];
128
+
129
+				switch ( action ) {
130
+
131
+					case 'm':
132
+						// moveTo
133
+						x = outline[ i ++ ] * scale + offsetX;
134
+						y = outline[ i ++ ] * scale + offsetY;
135
+						path.moveTo( x, y );
136
+						break;
137
+
138
+					case 'l':
139
+						// lineTo
140
+						x = outline[ i ++ ] * scale + offsetX;
141
+						y = outline[ i ++ ] * scale + offsetY;
142
+						path.lineTo( x, y );
143
+						break;
144
+
145
+					case 'q':
146
+						// quadraticCurveTo
147
+						cpx = outline[ i ++ ] * scale + offsetX;
148
+						cpy = outline[ i ++ ] * scale + offsetY;
149
+						cpx1 = outline[ i ++ ] * scale + offsetX;
150
+						cpy1 = outline[ i ++ ] * scale + offsetY;
151
+						path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
152
+						break;
153
+
154
+					case 'b':
155
+						// bezierCurveTo
156
+						cpx = outline[ i ++ ] * scale + offsetX;
157
+						cpy = outline[ i ++ ] * scale + offsetY;
158
+						cpx1 = outline[ i ++ ] * scale + offsetX;
159
+						cpy1 = outline[ i ++ ] * scale + offsetY;
160
+						cpx2 = outline[ i ++ ] * scale + offsetX;
161
+						cpy2 = outline[ i ++ ] * scale + offsetY;
162
+						path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
163
+						break;
164
+
165
+				}
166
+
167
+			}
168
+
169
+		}
170
+
171
+		return {
172
+			offsetX: glyph.ha * scale,
173
+			path: path
174
+		};
175
+
176
+	}
177
+
178
+	Font.prototype.isFont = true;
179
+
180
+	THREE.Font = Font;
181
+	THREE.FontLoader = FontLoader;
182
+
183
+} )();

+ 4010
- 0
demos/assets/GLTFLoader.js
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 51
- 0
demos/assets/TextGeometry.js Zobrazit soubor

@@ -0,0 +1,51 @@
1
+( function () {
2
+
3
+	/**
4
+ * Text = 3D Text
5
+ *
6
+ * parameters = {
7
+ *  font: <THREE.Font>, // font
8
+ *
9
+ *  size: <float>, // size of the text
10
+ *  height: <float>, // thickness to extrude text
11
+ *  curveSegments: <int>, // number of points on the curves
12
+ *
13
+ *  bevelEnabled: <bool>, // turn on bevel
14
+ *  bevelThickness: <float>, // how deep into text bevel goes
15
+ *  bevelSize: <float>, // how far from text outline (including bevelOffset) is bevel
16
+ *  bevelOffset: <float> // how far from text outline does bevel start
17
+ * }
18
+ */
19
+
20
+	class TextGeometry extends THREE.ExtrudeGeometry {
21
+
22
+		constructor( text, parameters = {} ) {
23
+
24
+			const font = parameters.font;
25
+
26
+			if ( font === undefined ) {
27
+
28
+				super(); // generate default extrude geometry
29
+
30
+			} else {
31
+
32
+				const shapes = font.generateShapes( text, parameters.size ); // translate parameters to THREE.ExtrudeGeometry API
33
+
34
+				parameters.depth = parameters.height !== undefined ? parameters.height : 50; // defaults
35
+
36
+				if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
37
+				if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
38
+				if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
39
+				super( shapes, parameters );
40
+
41
+			}
42
+
43
+			this.type = 'TextGeometry';
44
+
45
+		}
46
+
47
+	}
48
+
49
+	THREE.TextGeometry = TextGeometry;
50
+
51
+} )();

+ 3971
- 0
demos/assets/aframe-particle-system-component.js
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 2
- 0
demos/assets/aframe-particle-system-component.min.js
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


dist/aframe-with-martins.js → demos/assets/aframe-with-martins.js Zobrazit soubor

@@ -1,13 +1,13 @@
1 1
 /**
2 2
  * @file MARTINS.js & AFRAME glue code
3
- * @version 1.0.1
3
+ * @version 1.0.2
4 4
  * @author Alexandre Martins (https://github.com/alemart)
5
- * @license AGPL-3.0-only or PolyForm-Perimeter-1.0.0
5
+ * @license AGPL-3.0
6 6
  */
7 7
 
8 8
 /* Usage of the indicated versions is encouraged */
9 9
 __THIS_GLUE_CODE_HAS_BEEN_TESTED_WITH__({
10
-    'MARTINS.js': { version: '0.1.1' },
10
+    'MARTINS.js': { version: '0.1.2' },
11 11
         'AFRAME': { version: '1.3.0' }
12 12
 });
13 13
 

docs_overrides/demo/bird.png → demos/assets/bird.png Zobrazit soubor


+ 29
- 0
demos/assets/demo.css Zobrazit soubor

@@ -0,0 +1,29 @@
1
+body {
2
+    background-color: #3d5afe;
3
+}
4
+
5
+#scan {
6
+    width: 100%;
7
+    height: 100%;
8
+    object-fit: contain;
9
+    opacity: 0.75;
10
+}
11
+
12
+#toggle-webcam {
13
+    display: inline-block;
14
+    width: 64px;
15
+    height: 64px;
16
+
17
+    border: 0;
18
+    font-size: 36px;
19
+    color: #fff;
20
+    background: none;
21
+
22
+    position: absolute;
23
+    right: 0;
24
+    top: 0;
25
+}
26
+
27
+#toggle-webcam:hover {
28
+    cursor: pointer;
29
+}

+ 1
- 0
demos/assets/helvetiker_bold.typeface.json
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


docs_overrides/demo/it-works.png → demos/assets/it-works.png Zobrazit soubor


binární
demos/assets/my-3d-model.glb Zobrazit soubor


+ 14
- 0
demos/assets/my-reference-image.html Zobrazit soubor

@@ -0,0 +1,14 @@
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>WebAR Reference Image</title>
7
+        <style>
8
+        img { max-width: 100%; }
9
+        </style>
10
+    </head>
11
+    <body>
12
+        <img src="my-reference-image.webp" alt="Reference Image">
13
+    </body>
14
+</html>

docs_overrides/demo/my-reference-image.webp → demos/assets/my-reference-image.webp Zobrazit soubor


binární
demos/assets/my-video.webm Zobrazit soubor


binární
demos/assets/particle.png Zobrazit soubor


docs_overrides/demo/scan.png → demos/assets/scan.png Zobrazit soubor


dist/three-with-martins.js → demos/assets/three-with-martins.js Zobrazit soubor

@@ -1,13 +1,13 @@
1 1
 /**
2 2
  * @file MARTINS.js & THREE.js glue code
3
- * @version 1.0.1
3
+ * @version 1.0.2
4 4
  * @author Alexandre Martins (https://github.com/alemart)
5
- * @license AGPL-3.0-only or PolyForm-Perimeter-1.0.0
5
+ * @license AGPL-3.0
6 6
  */
7 7
 
8 8
 /* Usage of the indicated versions is encouraged */
9 9
 __THIS_GLUE_CODE_HAS_BEEN_TESTED_WITH__({
10
-    'MARTINS.js': { version: '0.1.1' },
10
+    'MARTINS.js': { version: '0.1.2' },
11 11
       'THREE.js': { version: '138' }
12 12
 });
13 13
 

+ 81
- 0
demos/hello-aframe/demo.js Zobrazit soubor

@@ -0,0 +1,81 @@
1
+/**
2
+ * @file MARTINS.js WebAR demo using A-Frame
3
+ * @version 1.0.2
4
+ * @author Alexandre Martins (https://github.com/alemart)
5
+ * @license AGPL-3.0
6
+ */
7
+
8
+async function startARSession(canvas)
9
+{
10
+    if(!Martins.isSupported()) {
11
+        throw new Error(
12
+            'Use a browser/device compatible with WebGL2 and WebAssembly. ' +
13
+            'Your user agent is ' + navigator.userAgent
14
+        );
15
+    }
16
+
17
+    if(!(canvas instanceof HTMLCanvasElement))
18
+        throw new Error(`startARSession expects a <canvas>`);
19
+
20
+    //Martins.Settings.powerPreference = 'low-power';
21
+
22
+    const tracker = Martins.Tracker.ImageTracker();
23
+    await tracker.database.add([{
24
+        name: 'my-reference-image',
25
+        image: document.getElementById('my-reference-image')
26
+    }]);
27
+
28
+    const viewport = Martins.Viewport({
29
+        canvas: canvas,
30
+        container: document.getElementById('ar-viewport'),
31
+        hudContainer: document.getElementById('ar-hud')
32
+    });
33
+
34
+    //const useWebcam = true;
35
+    const useWebcam = (location.search.substr(1) == 'webcam');
36
+    const video = document.getElementById('my-video');
37
+    const source = !useWebcam ? Martins.Source.Video(video) : Martins.Source.Camera();
38
+
39
+    const session = await Martins.startSession({
40
+        mode: 'immersive',
41
+        viewport: viewport,
42
+        trackers: [ tracker ],
43
+        sources: [ source ],
44
+        stats: true,
45
+        gizmos: true,
46
+    });
47
+
48
+    const scan = document.getElementById('scan');
49
+
50
+    tracker.addEventListener('targetfound', event => {
51
+        session.gizmos.visible = false;
52
+        if(scan)
53
+            scan.hidden = true;
54
+    });
55
+
56
+    tracker.addEventListener('targetlost', event => {
57
+        session.gizmos.visible = true;
58
+        if(scan)
59
+            scan.hidden = false;
60
+    });
61
+
62
+    return session;
63
+}
64
+
65
+// Toggle webcam
66
+window.addEventListener('load', () => {
67
+    const page = location.href.replace(/\?.*$/, '');
68
+    const usingWebcam = (location.search.substr(1) == 'webcam');
69
+    const button = document.getElementById('toggle-webcam');
70
+
71
+    if(!button)
72
+        return;
73
+
74
+    button.innerHTML = usingWebcam ? '&#x1F39E' : '&#x1F3A5';
75
+    button.addEventListener('click', () => {
76
+        if(usingWebcam)
77
+            location.href = page;
78
+        else
79
+            location.href = page + '?webcam';
80
+    });
81
+});

+ 59
- 0
demos/hello-aframe/index.html Zobrazit soubor

@@ -0,0 +1,59 @@
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>MARTINS.js WebAR demo using A-Frame</title>
7
+        <link href="../assets/demo.css" rel="stylesheet">
8
+        <script src="../../dist/martins.js"></script>
9
+        <script src="https://cdn.jsdelivr.net/npm/aframe@1.3.0/dist/aframe-v1.3.0.min.js"></script>
10
+        <script src="../assets/aframe-particle-system-component.min.js"></script>
11
+        <script src="demo.js"></script>
12
+        <script src="../assets/aframe-with-martins.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
+                <button id="toggle-webcam"></button>
19
+            </div>
20
+        </div>
21
+        <img id="my-reference-image" src="../assets/my-reference-image.webp" hidden>
22
+        <video id="my-video" src="../assets/my-video.webm" hidden muted loop playsinline autoplay oncanplay="this.muted=true;this.play()"></video>
23
+
24
+        <!-- This is a scene -->
25
+        <a-scene ar-scene>
26
+            <a-camera ar-camera></a-camera>
27
+
28
+            <!-- Whatever you add to <ar-root> will appear in AR -->
29
+            <ar-root>
30
+
31
+                <!-- Ground plane -->
32
+                <a-plane position="0 -0.5 -0.5" rotation="-90 0 0" width="2" height="1" color="indigo">
33
+
34
+                    <!-- 3D model -->
35
+                    <a-entity gltf-model="#my-3d-model"></a-entity>
36
+
37
+                    <!-- Particles -->
38
+                    <a-entity rotation="90 0 0">
39
+                        <a-entity position="0.75 0 0" particle-system="texture: ../assets/particle.png; color: #03f; opacity: 0.33; size: 20; maxAge: 0.64; velocityValue: 0 6.5 0; velocitySpread: 0 0 0; accelerationSpread: 2 0 2; particleCount: 2000"></a-entity>
40
+                        <a-entity position="-0.75 0 0" particle-system="texture: ../assets/particle.png; color: #f70; opacity: 0.33; size: 20; maxAge: 0.64; velocityValue: 0 6.5 0; velocitySpread: 0 0 0; accelerationSpread: 2 0 2; particleCount: 2000"></a-entity>
41
+                    </a-entity>
42
+
43
+                    <!-- Rotating text -->
44
+                    <a-entity animation="property: rotation.z; from: 0; to: 360; dur: 2000; loop: true; easing: linear">
45
+                        <a-text value="It works!" font="mozillavr" color="#fe3" scale="-1 -1 1" rotation="-90 0 0" position="0 0.40 1" align="center"></a-text>
46
+                        <a-text value="Cool!" font="mozillavr" color="#8ef" scale="1 1 1" rotation="90 0 0" position="0 -0.40 1" align="center"></a-text>
47
+                    </a-entity>
48
+
49
+                </a-plane>
50
+
51
+            </ar-root>
52
+
53
+            <!-- Declare external media files here -->
54
+            <a-assets>
55
+                <a-asset-item id="my-3d-model" src="../assets/my-3d-model.glb"></a-asset-item>
56
+            </a-assets>
57
+        </a-scene>
58
+    </body>
59
+</html>

+ 181
- 0
demos/hello-three/demo.js Zobrazit soubor

@@ -0,0 +1,181 @@
1
+/**
2
+ * @file MARTINS.js WebAR demo using THREE.js
3
+ * @version 1.0.2
4
+ * @author Alexandre Martins (https://github.com/alemart)
5
+ * @license AGPL-3.0
6
+ */
7
+
8
+window.addEventListener('load', () => {
9
+
10
+    const my = { };
11
+
12
+    async function initialize(ar)
13
+    {
14
+        // add lights
15
+        const ambientLight = new THREE.AmbientLight(0xb7b7b7);
16
+        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.4);
17
+        directionalLight.position.set(0, 0, -1);
18
+        directionalLight.target.position.set(0, 0, 0);
19
+        ar.scene.add(directionalLight);
20
+        ar.scene.add(ambientLight);
21
+
22
+        // create a group of objects as a child of ar.root
23
+        const group = createGroup('in-front');
24
+        //const group = createGroup('on-top'); // try this option!
25
+        ar.root.add(group);
26
+
27
+        // create cubes
28
+        const cubeA = createCube(-0.75, 0, 0xffff00);
29
+        const cubeB = createCube(0.75, 0, 0x00ff00);
30
+        group.add(cubeA, cubeB);
31
+
32
+        // create the ground
33
+        const ground = createGround(0x3d5afe);
34
+        group.add(ground);
35
+
36
+        // load a 3D model
37
+        const modelURL = '../assets/my-3d-model.glb';
38
+        const model = await loadModel(modelURL);
39
+        group.add(model);
40
+
41
+        // export objects
42
+        my.cubes = [ cubeA, cubeB ];
43
+        my.group = group;
44
+        my.model = model;
45
+        my.ground = ground;
46
+    }
47
+
48
+    function animate(ar)
49
+    {
50
+        const ROTATION_CYCLES_PER_SECOND = 1.0;
51
+        const TWO_PI = 2.0 * Math.PI;
52
+        const delta = ar.session.time.delta;
53
+
54
+        // rotate the cubes
55
+        for(const cube of my.cubes)
56
+            cube.rotateY(TWO_PI * ROTATION_CYCLES_PER_SECOND * delta);
57
+    }
58
+
59
+    function createGroup(mode = 'in-front')
60
+    {
61
+        const group = new THREE.Group();
62
+
63
+        if(mode == 'in-front') {
64
+            group.rotation.set(-Math.PI/2, 0, 0);
65
+            group.position.set(0, -0.5, 0.5);
66
+        }
67
+        else if(mode == 'on-top') {
68
+            group.rotation.set(0, 0, 0);
69
+            group.position.set(0, 0, 0);
70
+        }
71
+
72
+        return group;
73
+    }
74
+
75
+    function createCube(x, y, color, length = 0.25)
76
+    {
77
+        const geometry = new THREE.BoxGeometry(length, length, length);
78
+        const material = new THREE.MeshPhongMaterial({ color });
79
+        const cube = new THREE.Mesh(geometry, material);
80
+
81
+        cube.position.set(x, y, 1.25);
82
+
83
+        return cube;
84
+    }
85
+
86
+    function createGround(color)
87
+    {
88
+        const geometry = new THREE.RingGeometry(0.001, 1, 8);
89
+        const material = new THREE.MeshPhongMaterial({ color: color, side: THREE.DoubleSide });
90
+        const ground = new THREE.Mesh(geometry, material);
91
+
92
+        material.transparent = true;
93
+        material.opacity = 0.75;
94
+
95
+        return ground;
96
+    }
97
+
98
+    async function loadModel(filepath)
99
+    {
100
+        const loader = new THREE.GLTFLoader();
101
+        const gltf = await loader.loadAsync(filepath);
102
+        const model = gltf.scene;
103
+
104
+        return model;
105
+    }
106
+
107
+    async function startARSession()
108
+    {
109
+        if(!Martins.isSupported()) {
110
+            throw new Error(
111
+                'Use a browser/device compatible with WebGL2 and WebAssembly. ' +
112
+                'Your user agent is ' + navigator.userAgent
113
+            );
114
+        }
115
+
116
+        //Martins.Settings.powerPreference = 'low-power';
117
+
118
+        const tracker = Martins.Tracker.ImageTracker();
119
+        await tracker.database.add([{
120
+            name: 'my-reference-image',
121
+            image: document.getElementById('my-reference-image')
122
+        }]);
123
+
124
+        const viewport = Martins.Viewport({
125
+            container: document.getElementById('ar-viewport'),
126
+            hudContainer: document.getElementById('ar-hud')
127
+        });
128
+
129
+        //const useWebcam = true;
130
+        const useWebcam = (location.search.substr(1) == 'webcam');
131
+        const video = document.getElementById('my-video');
132
+        const source = !useWebcam ? Martins.Source.Video(video) : Martins.Source.Camera();
133
+
134
+        const session = await Martins.startSession({
135
+            mode: 'immersive',
136
+            viewport: viewport,
137
+            trackers: [ tracker ],
138
+            sources: [ source ],
139
+            stats: true,
140
+            gizmos: true,
141
+        });
142
+
143
+        const scan = document.getElementById('scan');
144
+
145
+        tracker.addEventListener('targetfound', event => {
146
+            session.gizmos.visible = false;
147
+            if(scan)
148
+                scan.hidden = true;
149
+        });
150
+
151
+        tracker.addEventListener('targetlost', event => {
152
+            session.gizmos.visible = true;
153
+            if(scan)
154
+                scan.hidden = false;
155
+        });
156
+
157
+        return session;
158
+    }
159
+
160
+    // link MARTINS.js to THREE.js
161
+    linkMartinsToTHREE(startARSession, animate, initialize);
162
+
163
+});
164
+
165
+// Toggle webcam
166
+window.addEventListener('load', () => {
167
+    const page = location.href.replace(/\?.*$/, '');
168
+    const usingWebcam = (location.search.substr(1) == 'webcam');
169
+    const button = document.getElementById('toggle-webcam');
170
+
171
+    if(!button)
172
+        return;
173
+
174
+    button.innerHTML = usingWebcam ? '&#x1F39E' : '&#x1F3A5';
175
+    button.addEventListener('click', () => {
176
+        if(usingWebcam)
177
+            location.href = page;
178
+        else
179
+            location.href = page + '?webcam';
180
+    });
181
+});

+ 24
- 0
demos/hello-three/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>MARTINS.js WebAR demo using THREE.js</title>
7
+        <link href="../assets/demo.css" rel="stylesheet">
8
+        <script src="../../dist/martins.js"></script>
9
+        <script src="https://cdn.jsdelivr.net/npm/three@0.138.3/build/three.min.js"></script>
10
+        <script src="https://cdn.jsdelivr.net/npm/three@0.138.3/examples/js/loaders/GLTFLoader.js"></script>
11
+        <script src="../assets/three-with-martins.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
+                <button id="toggle-webcam"></button>
19
+            </div>
20
+        </div>
21
+        <img id="my-reference-image" src="../assets/my-reference-image.webp" hidden>
22
+        <video id="my-video" src="../assets/my-video.webm" hidden muted loop playsinline autoplay oncanplay="this.muted=true;this.play()"></video>
23
+    </body>
24
+</html>

docs_overrides/demo/demo.js → demos/hello-webgl/demo.js Zobrazit soubor

@@ -1,10 +1,10 @@
1
-/*
2
-
3
-This demo is rendered using WebGL code
1
+/**
2
+ * @file MARTINS.js WebAR demo using pure WebGL
3
+ * @version 1.0.2
4
+ * @author Alexandre Martins (https://github.com/alemart)
5
+ * @license AGPL-3.0
6
+ */
4 7
 
5
-Check the MARTINS.js code below!
6
-
7
-*/
8 8
 
9 9
 
10 10
 /*
@@ -936,7 +936,10 @@ window.addEventListener('load', async function() {
936 936
             hudContainer: document.getElementById('ar-hud')
937 937
         });
938 938
 
939
-        const source = Martins.Source.Camera({
939
+        //const useWebcam = true;
940
+        const useWebcam = (location.search.substr(1) == 'webcam');
941
+        const video = document.getElementById('my-video');
942
+        const source = !useWebcam ? Martins.Source.Video(video) : Martins.Source.Camera({
940 943
             resolution: 'md'
941 944
         });
942 945
 
@@ -965,4 +968,22 @@ window.addEventListener('load', async function() {
965 968
 
966 969
         return session;
967 970
     }
971
+});
972
+
973
+// Toggle webcam
974
+window.addEventListener('load', () => {
975
+    const page = location.href.replace(/\?.*$/, '');
976
+    const usingWebcam = (location.search.substr(1) == 'webcam');
977
+    const button = document.getElementById('toggle-webcam');
978
+
979
+    if(!button)
980
+        return;
981
+
982
+    button.innerHTML = usingWebcam ? '&#x1F39E' : '&#x1F3A5';
983
+    button.addEventListener('click', () => {
984
+        if(usingWebcam)
985
+            location.href = page;
986
+        else
987
+            location.href = page + '?webcam';
988
+    });
968 989
 });

+ 23
- 0
demos/hello-webgl/index.html Zobrazit soubor

@@ -0,0 +1,23 @@
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>MARTINS.js WebAR demo using pure WebGL</title>
7
+        <link href="../assets/demo.css" rel="stylesheet">
8
+        <script src="../../dist/martins.js"></script>
9
+        <script src="demo.js"></script>
10
+    </head>
11
+    <body>
12
+        <div id="ar-viewport">
13
+            <div id="ar-hud" hidden>
14
+                <img id="scan" src="../assets/scan.png">
15
+                <button id="toggle-webcam"></button>
16
+            </div>
17
+        </div>
18
+        <img id="it-works" src="../assets/it-works.png" hidden>
19
+        <img id="bird" src="../assets/bird.png" hidden>
20
+        <img id="my-reference-image" src="../assets/my-reference-image.webp" hidden>
21
+        <video id="my-video" src="../assets/my-video.webm" hidden muted loop autoplay playsinline oncanplay="this.muted=true;this.play()"></video>
22
+    </body>
23
+</html>

+ 93
- 0
demos/hello-world/demo.js Zobrazit soubor

@@ -0,0 +1,93 @@
1
+/**
2
+ * @file MARTINS.js WebAR: Hello World demo
3
+ * @version 1.0.2
4
+ * @author Alexandre Martins (https://github.com/alemart)
5
+ * @license AGPL-3.0
6
+ */
7
+
8
+window.addEventListener('load', async function() {
9
+    try {
10
+        const session = await startARSession();
11
+
12
+        function animate(time, frame)
13
+        {
14
+            session.requestAnimationFrame(animate);
15
+        }
16
+
17
+        session.requestAnimationFrame(animate);
18
+    }
19
+    catch(error) {
20
+        alert(error.message);
21
+    }
22
+
23
+    async function startARSession()
24
+    {
25
+        if(!Martins.isSupported()) {
26
+            throw new Error(
27
+                'Use a browser/device compatible with WebGL2 and WebAssembly. ' +
28
+                'Your user agent is ' + navigator.userAgent
29
+            );
30
+        }
31
+
32
+        //Martins.Settings.powerPreference = 'low-power';
33
+
34
+        const tracker = Martins.Tracker.ImageTracker();
35
+        await tracker.database.add([{
36
+            name: 'my-reference-image',
37
+            image: document.getElementById('my-reference-image')
38
+        }]);
39
+
40
+        const viewport = Martins.Viewport({
41
+            container: document.getElementById('ar-viewport'),
42
+            hudContainer: document.getElementById('ar-hud')
43
+        });
44
+
45
+        //const useWebcam = true;
46
+        const useWebcam = (location.search.substr(1) == 'webcam');
47
+        const video = document.getElementById('my-video');
48
+        const source = !useWebcam ? Martins.Source.Video(video) : Martins.Source.Camera({
49
+            resolution: 'md'
50
+        });
51
+
52
+        const session = await Martins.startSession({
53
+            mode: 'immersive',
54
+            viewport: viewport,
55
+            trackers: [ tracker ],
56
+            sources: [ source ],
57
+            stats: true,
58
+            gizmos: true,
59
+        });
60
+
61
+        const scan = document.getElementById('scan');
62
+
63
+        tracker.addEventListener('targetfound', event => {
64
+            if(scan)
65
+                scan.hidden = true;
66
+        });
67
+
68
+        tracker.addEventListener('targetlost', event => {
69
+            if(scan)
70
+                scan.hidden = false;
71
+        });
72
+
73
+        return session;
74
+    }
75
+});
76
+
77
+// Toggle webcam
78
+window.addEventListener('load', () => {
79
+    const page = location.href.replace(/\?.*$/, '');
80
+    const usingWebcam = (location.search.substr(1) == 'webcam');
81
+    const button = document.getElementById('toggle-webcam');
82
+
83
+    if(!button)
84
+        return;
85
+
86
+    button.innerHTML = usingWebcam ? '&#x1F39E' : '&#x1F3A5';
87
+    button.addEventListener('click', () => {
88
+        if(usingWebcam)
89
+            location.href = page;
90
+        else
91
+            location.href = page + '?webcam';
92
+    });
93
+});

+ 21
- 0
demos/hello-world/index.html Zobrazit soubor

@@ -0,0 +1,21 @@
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>MARTINS.js WebAR: Hello World demo</title>
7
+        <link href="../assets/demo.css" rel="stylesheet">
8
+        <script src="../../dist/martins.js"></script>
9
+        <script src="demo.js"></script>
10
+    </head>
11
+    <body>
12
+        <div id="ar-viewport">
13
+            <div id="ar-hud" hidden>
14
+                <img id="scan" src="../assets/scan.png">
15
+                <button id="toggle-webcam"></button>
16
+            </div>
17
+        </div>
18
+        <img id="my-reference-image" src="../assets/my-reference-image.webp" hidden>
19
+        <video id="my-video" src="../assets/my-video.webm" hidden muted loop playsinline autoplay oncanplay="this.muted=true;this.play()"></video>
20
+    </body>
21
+</html>

+ 72
- 0
demos/simple-webcam/demo.js Zobrazit soubor

@@ -0,0 +1,72 @@
1
+/**
2
+ * @file MARTINS.js WebAR: Simple Webcam demo
3
+ * @version 1.0.2
4
+ * @author Alexandre Martins (https://github.com/alemart)
5
+ * @license AGPL-3.0
6
+ */
7
+
8
+window.addEventListener('load', async function() {
9
+    try {
10
+        const session = await startARSession();
11
+
12
+        function animate(time, frame)
13
+        {
14
+            session.requestAnimationFrame(animate);
15
+        }
16
+
17
+        session.requestAnimationFrame(animate);
18
+    }
19
+    catch(error) {
20
+        alert(error.message);
21
+    }
22
+
23
+    async function startARSession()
24
+    {
25
+        if(!Martins.isSupported()) {
26
+            throw new Error(
27
+                'Use a browser/device compatible with WebGL2 and WebAssembly. ' +
28
+                'Your user agent is ' + navigator.userAgent
29
+            );
30
+        }
31
+
32
+        //Martins.Settings.powerPreference = 'low-power';
33
+
34
+        const tracker = Martins.Tracker.ImageTracker();
35
+        await tracker.database.add([{
36
+            name: 'my-reference-image',
37
+            image: document.getElementById('my-reference-image')
38
+        }]);
39
+
40
+        const viewport = Martins.Viewport({
41
+            container: document.getElementById('ar-viewport'),
42
+            hudContainer: document.getElementById('ar-hud')
43
+        });
44
+
45
+        const source = Martins.Source.Camera({
46
+            resolution: 'md'
47
+        });
48
+
49
+        const session = await Martins.startSession({
50
+            mode: 'immersive',
51
+            viewport: viewport,
52
+            trackers: [ tracker ],
53
+            sources: [ source ],
54
+            stats: true,
55
+            gizmos: true,
56
+        });
57
+
58
+        const scan = document.getElementById('scan');
59
+
60
+        tracker.addEventListener('targetfound', event => {
61
+            if(scan)
62
+                scan.hidden = true;
63
+        });
64
+
65
+        tracker.addEventListener('targetlost', event => {
66
+            if(scan)
67
+                scan.hidden = false;
68
+        });
69
+
70
+        return session;
71
+    }
72
+});

+ 20
- 0
demos/simple-webcam/index.html Zobrazit soubor

@@ -0,0 +1,20 @@
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>MARTINS.js WebAR: Simple Webcam demo</title>
7
+        <link href="../assets/demo.css" rel="stylesheet">
8
+        <script src="../../dist/martins.js"></script>
9
+        <script src="demo.js"></script>
10
+    </head>
11
+    <body>
12
+        <div id="ar-viewport">
13
+            <div id="ar-hud" hidden>
14
+                <img id="scan" src="../assets/scan.png">
15
+                <button id="toggle-webcam"></button>
16
+            </div>
17
+        </div>
18
+        <img id="my-reference-image" src="../assets/my-reference-image.webp" hidden>
19
+    </body>
20
+</html>

+ 211
- 0
demos/touch-interaction/demo.js Zobrazit soubor

@@ -0,0 +1,211 @@
1
+/**
2
+ * @file MARTINS.js WebAR demo with touch interaction using THREE.js
3
+ * @version 1.0.2
4
+ * @author Alexandre Martins (https://github.com/alemart)
5
+ * @license AGPL-3.0
6
+ */
7
+
8
+window.addEventListener('load', () => {
9
+
10
+    const my = { };
11
+
12
+    async function initialize(ar)
13
+    {
14
+        // add lights
15
+        const ambientLight = new THREE.AmbientLight(0x808080);
16
+        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.75);
17
+        directionalLight.position.set(0, 0, -1);
18
+        ar.scene.add(ambientLight);
19
+        ar.scene.add(directionalLight);
20
+
21
+        // create cubes
22
+        my.cubes = [
23
+            createCube(ar, 1.0, -0.5, 0x00ff00),
24
+            createCube(ar, -1.0, -0.5, 0xffff00),
25
+            createCube(ar, 0.0, -0.5, 0x0077ff),
26
+        ];
27
+
28
+        // create text
29
+        my.text = await createText(ar, 'Tap on any cube', 0x88ffee);
30
+        my.text.position.set(-1.5, 0.25, 0.5);
31
+
32
+        // setup interactivity
33
+        my.pointer = createPointer(ar);
34
+        my.raycaster = new THREE.Raycaster();
35
+    }
36
+
37
+    function createCube(ar, x, y, color, length = 0.7)
38
+    {
39
+        const geometry = new THREE.BoxGeometry(length, length, length);
40
+        const material = new THREE.MeshPhongMaterial({ color });
41
+        const cube = new THREE.Mesh(geometry, material);
42
+
43
+        cube.position.x = x;
44
+        cube.position.y = y;
45
+        cube.position.z = length / 2;
46
+        cube.userData.color = color;
47
+
48
+        material.opacity = 1.0;
49
+        material.transparent = true;
50
+
51
+        ar.root.add(cube);
52
+        return cube;
53
+    }
54
+
55
+    async function createText(ar, text, color = 0xffffff)
56
+    {
57
+        const loader = new THREE.FontLoader();
58
+        const fontURL = '../assets/helvetiker_bold.typeface.json';
59
+        const font = await loader.loadAsync(fontURL);
60
+
61
+        const material = new THREE.MeshPhongMaterial({ color });
62
+        const geometry = new THREE.TextGeometry(text, {
63
+            font: font,
64
+            size: 0.3,
65
+            height: 0.05,
66
+        });
67
+        const mesh = new THREE.Mesh(geometry, material);
68
+
69
+        ar.root.add(mesh);
70
+        return mesh;
71
+    }
72
+
73
+    function createPointer(ar)
74
+    {
75
+        const pointer = {
76
+            position: new THREE.Vector2(),
77
+            down: false,
78
+
79
+            get active()
80
+            {
81
+                return this.down && Math.max(Math.abs(this.position.x), Math.abs(this.position.y)) <= 1.0;
82
+            }
83
+        };
84
+
85
+        function updatePosition(event)
86
+        {
87
+            const canvas = ar.renderer.domElement;
88
+            const rect = canvas.getBoundingClientRect();
89
+            const x = event.pageX - (rect.left + window.scrollX);
90
+            const y = event.pageY - (rect.top + window.scrollY);
91
+
92
+            // normalize to [-1,1] x [-1,1]
93
+            pointer.position.x = 2.0 * x / rect.width - 1.0;
94
+            pointer.position.y = -2.0 * y / rect.height + 1.0;
95
+        }
96
+
97
+        // setup pointer interactivity
98
+        window.addEventListener('pointermove', event => {
99
+            updatePosition(event);
100
+        });
101
+        window.addEventListener('pointerdown', event => {
102
+            updatePosition(event);
103
+            pointer.down = true;
104
+        });
105
+        window.addEventListener('pointerup', event => {
106
+            pointer.down = false;
107
+        });
108
+
109
+        // done!
110
+        return pointer;
111
+    }
112
+
113
+    function animate(ar)
114
+    {
115
+        // reset all cubes
116
+        for(let i = 0; i < my.cubes.length; i++) {
117
+            my.cubes[i].material.color.setHex(my.cubes[i].userData.color);
118
+            my.cubes[i].scale.z = 1.0;
119
+        }
120
+
121
+        // interact with objects via raycasting
122
+        if(my.pointer.active) {
123
+            my.raycaster.setFromCamera(my.pointer.position, ar.camera);
124
+
125
+            const intersections = my.raycaster.intersectObjects(my.cubes);
126
+            for(let i = 0; i < intersections.length; i++) {
127
+
128
+                // create the appearance of a pushed button
129
+                const object = intersections[i].object;
130
+                object.material.color.setHex(0xff3333);
131
+                object.scale.z = 0.2;
132
+
133
+            }
134
+        }
135
+    }
136
+
137
+    async function startARSession()
138
+    {
139
+        if(!Martins.isSupported()) {
140
+            throw new Error(
141
+                'Use a browser/device compatible with WebGL2 and WebAssembly. ' +
142
+                'Your user agent is ' + navigator.userAgent
143
+            );
144
+        }
145
+
146
+        //Martins.Settings.powerPreference = 'low-power';
147
+
148
+        const tracker = Martins.Tracker.ImageTracker();
149
+        await tracker.database.add([{
150
+            name: 'my-reference-image',
151
+            image: document.getElementById('my-reference-image')
152
+        }]);
153
+
154
+        const viewport = Martins.Viewport({
155
+            container: document.getElementById('ar-viewport'),
156
+            hudContainer: document.getElementById('ar-hud')
157
+        });
158
+
159
+        //const useWebcam = true;
160
+        const useWebcam = (location.search.substr(1) == 'webcam');
161
+        const video = document.getElementById('my-video');
162
+        const source = !useWebcam ? Martins.Source.Video(video) : Martins.Source.Camera();
163
+
164
+        const session = await Martins.startSession({
165
+            mode: 'immersive',
166
+            viewport: viewport,
167
+            trackers: [ tracker ],
168
+            sources: [ source ],
169
+            stats: true,
170
+            gizmos: true,
171
+        });
172
+
173
+        const scan = document.getElementById('scan');
174
+
175
+        tracker.addEventListener('targetfound', event => {
176
+            session.gizmos.visible = false;
177
+            if(scan)
178
+                scan.hidden = true;
179
+        });
180
+
181
+        tracker.addEventListener('targetlost', event => {
182
+            session.gizmos.visible = true;
183
+            if(scan)
184
+                scan.hidden = false;
185
+        });
186
+
187
+        return session;
188
+    }
189
+
190
+    // link MARTINS.js to THREE.js
191
+    linkMartinsToTHREE(startARSession, animate, initialize);
192
+
193
+});
194
+
195
+// Toggle webcam
196
+window.addEventListener('load', () => {
197
+    const page = location.href.replace(/\?.*$/, '');
198
+    const usingWebcam = (location.search.substr(1) == 'webcam');
199
+    const button = document.getElementById('toggle-webcam');
200
+
201
+    if(!button)
202
+        return;
203
+
204
+    button.innerHTML = usingWebcam ? '&#x1F39E' : '&#x1F3A5';
205
+    button.addEventListener('click', () => {
206
+        if(usingWebcam)
207
+            location.href = page;
208
+        else
209
+            location.href = page + '?webcam';
210
+    });
211
+});

+ 25
- 0
demos/touch-interaction/index.html Zobrazit soubor

@@ -0,0 +1,25 @@
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>MARTINS.js WebAR demo with touch interaction using THREE.js</title>
7
+        <link href="../assets/demo.css" rel="stylesheet">
8
+        <script src="../../dist/martins.js"></script>
9
+        <script src="https://cdn.jsdelivr.net/npm/three@0.138.3/build/three.min.js"></script>
10
+        <script src="https://cdn.jsdelivr.net/npm/three@0.138.3/examples/js/loaders/FontLoader.js"></script>
11
+        <script src="https://cdn.jsdelivr.net/npm/three@0.138.3/examples/js/geometries/TextGeometry.js"></script>
12
+        <script src="../assets/three-with-martins.js"></script>
13
+        <script src="demo.js"></script>
14
+    </head>
15
+    <body>
16
+        <div id="ar-viewport">
17
+            <div id="ar-hud" hidden>
18
+                <img id="scan" src="../assets/scan.png">
19
+                <button id="toggle-webcam"></button>
20
+            </div>
21
+        </div>
22
+        <img id="my-reference-image" src="../assets/my-reference-image.webp" hidden>
23
+        <video id="my-video" src="../assets/my-video.webm" hidden muted loop playsinline autoplay oncanplay="this.muted=true;this.play()"></video>
24
+    </body>
25
+</html>

+ 1
- 1
docs/demo/index.md Zobrazit soubor

@@ -1,4 +1,4 @@
1 1
 ---
2
-template: demo/index.html
2
+template: basic_demo.html
3 3
 title: ""
4 4
 ---

+ 2
- 2
docs/demo/instructions.md Zobrazit soubor

@@ -19,8 +19,8 @@ title: Try WebAR right now!
19 19
     - The physical environment should be properly illuminated.
20 20
     - Avoid low-quality cameras (cameras of common smartphones are OK).
21 21
 
22
-[![WebAR demo](reference-image-with-qr-code.webp)](./index.md){ ._blank }
22
+[![WebAR demo](reference-image-with-qr-code.webp "Based on free image by ArtRose from https://pixabay.com/pt/vectors/bruxa-vassoura-gato-chap%c3%a9u-magia-5635225/")](./index.md){ ._blank }
23 23
 
24 24
 ## Wanna see more?
25 25
 
26
-[Check out my WebAR demos](../demos.md){ .md-button }
26
+[Check out my WebAR demos](../gallery.md){ .md-button }

+ 0
- 110
docs/demos.md Zobrazit soubor

@@ -1,110 +0,0 @@
1
----
2
-title: WebAR demos
3
----
4
-
5
-<style>
6
-.gallery-grid {
7
-    display: flex;
8
-    flex-direction: row;
9
-    flex-wrap: wrap;
10
-    align-items: flex-end;
11
-    justify-content: space-evenly;
12
-}
13
-
14
-.gallery-item {
15
-    text-align: center;
16
-    padding: 0;
17
-}
18
-
19
-.gallery-item:not(.gallery-item-3) img {
20
-    /*border-radius: 25px;*/
21
-}
22
-
23
-@media screen and (min-width: 600px) {
24
-    .gallery-item {
25
-        flex-basis: 80%;
26
-    }
27
-}
28
-
29
-@media screen and (min-width: 1220px) {
30
-    .gallery-item {
31
-        transition: transform 0.25s, opacity 0.25s;
32
-        opacity: 0.9;
33
-    }
34
-    .gallery-item:hover {
35
-        /*transform: scale(1.1);*/
36
-        opacity: 1.0;
37
-    }
38
-}
39
-</style>
40
-
41
-# WebAR demos
42
-
43
-Here you'll find some cool examples of what you can do with MARTINS.js. They are hosted on [Glitch](https://glitch.com){ ._blank }: it's easy to remix them. Simply click on a link or scan any of the QR codes below.
44
-
45
-**Important:** after opening the web pages, scan the [reference image below](#reference-image).
46
-
47
-## Basic demos
48
-
49
-The following demos will help you get started:
50
-
51
-<div class="gallery-grid" markdown>
52
-<div class="gallery-item" markdown>
53
-![QR code](./img/qr-demo-hello-aframe.png)
54
-
55
-**WebAR with MARTINS.js + AFRAME**
56
-
57
-[Launch demo](https://webar-martins-js-hello-aframe.glitch.me){ ._blank } | [View code](https://glitch.com/edit/#!/webar-martins-js-hello-aframe){ ._blank }
58
-</div>
59
-<div class="gallery-item" markdown>
60
-![QR code](./img/qr-demo-hello-three.png)
61
-
62
-**WebAR with MARTINS.js + THREE.js**
63
-
64
-[Launch demo](https://webar-martins-js-hello-three.glitch.me){ ._blank } | [View code](https://glitch.com/edit/#!/webar-martins-js-hello-three){ ._blank }
65
-</div>
66
-<div class="gallery-item" markdown>
67
-![QR code](./img/qr-demo-hello-webgl.png)
68
-
69
-**WebAR with MARTINS.js + pure WebGL**
70
-
71
-[Launch demo](https://webar-martins-js-hello-webgl.glitch.me){ ._blank } | [View code](https://glitch.com/edit/#!/webar-martins-js-hello-webgl){ ._blank }
72
-</div>
73
-<div class="gallery-item" markdown>
74
-![](./img/logo-babylonjs.png "Babylon.js logo by David Catuhe")
75
-
76
-**WebAR with MARTINS.js + BABYLON.js**
77
-
78
-Soon!
79
-</div>
80
-<div class="gallery-item" markdown>
81
-![QR code](./img/qr-demo-hello-world.png)
82
-
83
-**Hello, world: minimal example**
84
-
85
-[Launch demo](https://webar-martins-js-hello-world.glitch.me){ ._blank } | [View code](https://glitch.com/edit/#!/webar-martins-js-hello-world){ ._blank }
86
-</div>
87
-</div>
88
-
89
-!!! tip Tip
90
-
91
-    AFRAME is the easiest choice for non-coders. If you're a coder, all choices are good.
92
-
93
-## Fun & games
94
-
95
-WebAR can be a lot of fun. More demos coming soon!
96
-
97
-<div class="gallery-grid" markdown>
98
-<div class="gallery-item" markdown>
99
-![QR code](./img/qr-demo-interactivity-three.png)
100
-
101
-**Touch interaction with THREE.js**
102
-
103
-[Launch demo](https://webar-martins-js-interactivity-three.glitch.me){ ._blank } | [View code](https://glitch.com/edit/#!/webar-martins-js-interactivity-three){ ._blank }
104
-</div>
105
-</div>
106
-
107
-
108
-## Reference image
109
-
110
-[![Reference image](./assets/my-reference-image.webp)](./assets/my-reference-image.webp){ ._blank }

+ 115
- 0
docs/gallery.md Zobrazit soubor

@@ -0,0 +1,115 @@
1
+---
2
+title: WebAR demos
3
+---
4
+
5
+<style>
6
+.gallery-grid {
7
+    display: flex;
8
+    flex-direction: row;
9
+    flex-wrap: wrap;
10
+    align-items: flex-end;
11
+    justify-content: space-evenly;
12
+}
13
+
14
+.gallery-item {
15
+    text-align: center;
16
+    padding: 0;
17
+}
18
+
19
+.gallery-item img {
20
+    width: 100%;
21
+    image-rendering: pixelated;
22
+}
23
+
24
+@media screen and (min-width: 600px) {
25
+    .gallery-item {
26
+        flex-basis: 40%;
27
+    }
28
+}
29
+
30
+@media screen and (min-width: 1220px) {
31
+    .gallery-item img {
32
+        transition: transform 0.25s, opacity 0.25s;
33
+        opacity: 0.9;
34
+    }
35
+    .gallery-item img:hover {
36
+        transform: scale(1.125);
37
+        opacity: 1.0;
38
+    }
39
+}
40
+</style>
41
+
42
+# WebAR demos
43
+
44
+Here you'll find some cool examples of what you can do with MARTINS.js. Simply click on a link or scan any of the QR codes below. After opening the web pages, scan the [target image](#target-image). In addition, please read the [guidelines](#guidelines).
45
+
46
+## Basic demos
47
+
48
+The following demos will help you get started:
49
+
50
+<div class="gallery-grid" markdown>
51
+<div class="gallery-item" markdown>
52
+[![QR code](./img/qr-demo-hello-aframe.gif)](/martins-js/demos/hello-aframe){ ._blank }
53
+
54
+**MARTINS.js + AFRAME**
55
+
56
+[Launch demo](/martins-js/demos/hello-aframe){ ._blank } | [View the code](https://github.com/alemart/martins-js/tree/master/demos/hello-aframe){ ._blank }
57
+</div>
58
+<div class="gallery-item" markdown>
59
+[![QR code](./img/qr-demo-hello-three.gif)](/martins-js/demos/hello-three){ ._blank }
60
+
61
+**MARTINS.js + THREE.js**
62
+
63
+[Launch demo](/martins-js/demos/hello-three){ ._blank } | [View the code](https://github.com/alemart/martins-js/tree/master/demos/hello-three){ ._blank }
64
+</div>
65
+<div class="gallery-item" markdown>
66
+[![QR code](./img/qr-demo-hello-webgl.gif)](/martins-js/demos/hello-webgl){ ._blank }
67
+
68
+**MARTINS.js + pure WebGL**
69
+
70
+[Launch demo](/martins-js/demos/hello-webgl){ ._blank } | [View the code](https://github.com/alemart/martins-js/tree/master/demos/hello-webgl){ ._blank }
71
+</div>
72
+<div class="gallery-item" markdown>
73
+[![QR code](./img/qr-demo-touch-interaction.gif)](/martins-js/demos/touch-interaction){ ._blank }
74
+
75
+**Touch interaction with THREE.js**
76
+
77
+[Launch demo](/martins-js/demos/touch-interaction){ ._blank } | [View the code](https://github.com/alemart/martins-js/tree/master/demos/touch-interaction){ ._blank }
78
+</div>
79
+</div>
80
+
81
+## Minimal demos
82
+
83
+Explore the source code with these minimalistic demos:
84
+
85
+<div class="gallery-grid" markdown>
86
+<div class="gallery-item" markdown>
87
+[![QR code](./img/qr-demo-hello-world.gif)](/martins-js/demos/hello-world){ ._blank }
88
+
89
+**Hello, world!**
90
+
91
+[Launch demo](/martins-js/demos/hello-world){ ._blank } | [View the code](https://github.com/alemart/martins-js/tree/master/demos/hello-world){ ._blank }
92
+</div>
93
+<div class="gallery-item" markdown>
94
+[![QR code](./img/qr-demo-simple-webcam.gif)](/martins-js/demos/simple-webcam){ ._blank }
95
+
96
+**Simple Webcam demo**
97
+
98
+[Launch demo](/martins-js/demos/simple-webcam){ ._blank } | [View the code](https://github.com/alemart/martins-js/tree/master/demos/simple-webcam){ ._blank }
99
+</div>
100
+</div>
101
+
102
+## Guidelines
103
+
104
+You can use a webcam or a video file as input. Click on the 🎥 icon at the top-right corner of the screen to toggle webcam input. When using a webcam:
105
+
106
+* Avoid low-quality cameras. A camera of a typical smartphone is probably good enough.
107
+* Don't move the camera nor the target image too quickly. This produces motion blur.
108
+* Make sure that the physical environment is properly illuminated.
109
+* The target image should appear clearly in the video.
110
+* If you're scanning the image on a screen, make sure to adjust the brightness. If the screen is too bright (too dark), it will cause overexposure (underexposure) in the video and tracking difficulties - details of the images will be lost. Screen reflections are also undesirable.
111
+* If you print the image, avoid shiny materials (e.g., glossy paper). They may generate artifacts in the image and interfere with the tracking. Prefer non-reflective materials.
112
+
113
+## Target image
114
+
115
+[![Target image](./assets/my-reference-image.webp)](./assets/my-reference-image.webp "Based on free image by ArtRose from https://pixabay.com/pt/vectors/bruxa-vassoura-gato-chap%c3%a9u-magia-5635225/"){ ._blank }

+ 1
- 1
docs/getting-started/create-the-augmented-scene.md Zobrazit soubor

@@ -34,7 +34,7 @@ I provide easy-to-use glue codes that work with different 3D rendering technolog
34 34
 
35 35
 [:octocat: Get the glue codes on GitHub](https://github.com/alemart/martins-js/tree/master/dist){ .md-button ._blank }
36 36
 
37
-[Get the glue codes in my demos](../demos.md){ .md-button ._blank }
37
+[Get the glue codes in my demos](../gallery.md){ .md-button ._blank }
38 38
 
39 39
 ## Create the virtual scene
40 40
 

+ 21
- 0
docs/hooks.py Zobrazit soubor

@@ -0,0 +1,21 @@
1
+import os
2
+import shutil
3
+
4
+def copy_static_files(config, **kwargs):
5
+    site_dir = config['site_dir']
6
+    copy_directory('dist', site_dir)
7
+    copy_directory('demos', site_dir)
8
+
9
+def copy_directory(dir_path, site_dir):
10
+    d = os.path.join(site_dir, dir_path)
11
+    os.makedirs(d, exist_ok=True)
12
+    copy_tree(dir_path, d)
13
+
14
+def copy_tree(src, dst, symlinks=False, ignore=None):
15
+    for item in os.listdir(src):
16
+        s = os.path.join(src, item)
17
+        d = os.path.join(dst, item)
18
+        if os.path.isdir(s):
19
+            shutil.copytree(s, d, symlinks, ignore)
20
+        else:
21
+            shutil.copy2(s, d)

binární
docs/img/qr-demo-hello-aframe.gif Zobrazit soubor


binární
docs/img/qr-demo-hello-aframe.png Zobrazit soubor


binární
docs/img/qr-demo-hello-three.gif Zobrazit soubor


binární
docs/img/qr-demo-hello-three.png Zobrazit soubor


binární
docs/img/qr-demo-hello-webgl.gif Zobrazit soubor


binární
docs/img/qr-demo-hello-webgl.png Zobrazit soubor


binární
docs/img/qr-demo-hello-world.gif Zobrazit soubor


binární
docs/img/qr-demo-hello-world.png Zobrazit soubor


binární
docs/img/qr-demo-interactivity-three.png Zobrazit soubor


binární
docs/img/qr-demo-simple-webcam.gif Zobrazit soubor


binární
docs/img/qr-demo-touch-interaction.gif Zobrazit soubor


+ 0
- 129
docs/license/PolyForm-Perimeter-1.0.0-1.md Zobrazit soubor

@@ -1,129 +0,0 @@
1
-# PolyForm Perimeter License 1.0.0
2
-
3
-<https://polyformproject.org/licenses/perimeter/1.0.0>
4
-
5
-## Acceptance
6
-
7
-In order to get any license under these terms, you must agree
8
-to them as both strict obligations and conditions to all
9
-your licenses.
10
-
11
-## Copyright License
12
-
13
-The licensor grants you a copyright license for the
14
-software to do everything you might do with the software
15
-that would otherwise infringe the licensor's copyright
16
-in it for any permitted purpose.  However, you may
17
-only distribute the software according to [Distribution
18
-License](#distribution-license) and make changes or new works
19
-based on the software according to [Changes and New Works
20
-License](#changes-and-new-works-license).
21
-
22
-## Distribution License
23
-
24
-The licensor grants you an additional copyright license
25
-to distribute copies of the software.  Your license
26
-to distribute covers distributing the software with
27
-changes and new works permitted by [Changes and New Works
28
-License](#changes-and-new-works-license).
29
-
30
-## Notices
31
-
32
-You must ensure that anyone who gets a copy of any part of
33
-the software from you also gets a copy of these terms or the
34
-URL for them above, as well as copies of any plain-text lines
35
-beginning with `Required Notice:` that the licensor provided
36
-with the software.  For example:
37
-
38
-> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
39
-
40
-## Changes and New Works License
41
-
42
-The licensor grants you an additional copyright license to
43
-make changes and new works based on the software for any
44
-permitted purpose.
45
-
46
-## Patent License
47
-
48
-The licensor grants you a patent license for the software that
49
-covers patent claims the licensor can license, or becomes able
50
-to license, that you would infringe by using the software.
51
-
52
-## Noncompete
53
-
54
-Any purpose is a permitted purpose, except for providing to
55
-others any product that competes with the software.
56
-
57
-## Competition
58
-
59
-If you use this software to market a product as a substitute
60
-for the functionality or value of the software, it competes
61
-with the software. A product may compete regardless how it is
62
-designed or deployed. For example, a product may compete even
63
-if it provides its functionality via any kind of interface
64
-(including services, libraries or plug-ins), even if it is
65
-ported to a different platforms or programming languages,
66
-and even if it is provided free of charge.
67
-
68
-## Fair Use
69
-
70
-You may have "fair use" rights for the software under the
71
-law. These terms do not limit them.
72
-
73
-## No Other Rights
74
-
75
-These terms do not allow you to sublicense or transfer any of
76
-your licenses to anyone else, or prevent the licensor from
77
-granting licenses to anyone else.  These terms do not imply
78
-any other licenses.
79
-
80
-## Patent Defense
81
-
82
-If you make any written claim that the software infringes or
83
-contributes to infringement of any patent, your patent license
84
-for the software granted under these terms ends immediately. If
85
-your company makes such a claim, your patent license ends
86
-immediately for work on behalf of your company.
87
-
88
-## Violations
89
-
90
-The first time you are notified in writing that you have
91
-violated any of these terms, or done anything with the software
92
-not covered by your licenses, your licenses can nonetheless
93
-continue if you come into full compliance with these terms,
94
-and take practical steps to correct past violations, within
95
-32 days of receiving notice.  Otherwise, all your licenses
96
-end immediately.
97
-
98
-## No Liability
99
-
100
-***As far as the law allows, the software comes as is, without
101
-any warranty or condition, and the licensor will not be liable
102
-to you for any damages arising out of these terms or the use
103
-or nature of the software, under any kind of legal claim.***
104
-
105
-## Definitions
106
-
107
-The **licensor** is the individual or entity offering these
108
-terms, and the **software** is the software the licensor makes
109
-available under these terms.
110
-
111
-A **product** can be a good or service, or a combination
112
-of them.
113
-
114
-**You** refers to the individual or entity agreeing to these
115
-terms.
116
-
117
-**Your company** is any legal entity, sole proprietorship,
118
-or other kind of organization that you work for, plus all
119
-organizations that have control over, are under the control of,
120
-or are under common control with that organization.  **Control**
121
-means ownership of substantially all the assets of an entity,
122
-or the power to direct its management and policies by vote,
123
-contract, or otherwise.  Control can be direct or indirect.
124
-
125
-**Your licenses** are all the licenses granted to you for the
126
-software under these terms.
127
-
128
-**Use** means anything you do with the software requiring one
129
-of your licenses.

+ 11
- 0
docs_overrides/basic_demo.html Zobrazit soubor

@@ -0,0 +1,11 @@
1
+<!doctype html>
2
+<html>
3
+    <head>
4
+        <meta charset="utf-8">
5
+        <meta http-equiv="refresh" content="0; url='{{ 'demos/hello-webgl/?webcam' | url }}'">
6
+        <title>MARTINS.js WebAR demo</title>
7
+    </head>
8
+    <body>
9
+        <p>Loading the <a href="{{ 'demos/hello-webgl/?webcam' | url }}">WebAR demo</a>...</p>
10
+    </body>
11
+</html>

+ 0
- 10
docs_overrides/demo/demo.css Zobrazit soubor

@@ -1,10 +0,0 @@
1
-body {
2
-    background-color: #3d5afe;
3
-}
4
-
5
-#scan {
6
-    width: 100%;
7
-    height: 100%;
8
-    object-fit: contain;
9
-    opacity: 0.75;
10
-}

+ 0
- 21
docs_overrides/demo/index.html Zobrazit soubor

@@ -1,21 +0,0 @@
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>MARTINS.js WebAR demo</title>
7
-        <link href="{{ 'demo/demo.css' | url }}" rel="stylesheet">
8
-        <script src="{{ 'dist/martins.min.js' | url }}"></script>
9
-        <script src="{{ 'demo/demo.js' | url }}"></script>
10
-    </head>
11
-    <body>
12
-        <div id="ar-viewport">
13
-            <div id="ar-hud" hidden>
14
-                <img id="scan" src="{{ 'demo/scan.png' | url }}">
15
-            </div>
16
-        </div>
17
-        <img id="my-reference-image" src="{{ 'demo/my-reference-image.webp' | url }}" hidden>
18
-        <img id="it-works" src="{{ 'demo/it-works.png' | url }}" hidden>
19
-        <img id="bird" src="{{ 'demo/bird.png' | url }}" hidden>
20
-    </body>
21
-</html>

+ 0
- 1
docs_overrides/dist/aframe-with-martins.js Zobrazit soubor

@@ -1 +0,0 @@
1
-../../dist/aframe-with-martins.js

+ 0
- 1
docs_overrides/dist/martins.js Zobrazit soubor

@@ -1 +0,0 @@
1
-../../dist/martins.js

+ 0
- 1
docs_overrides/dist/martins.min.js Zobrazit soubor

@@ -1 +0,0 @@
1
-../../dist/martins.min.js

+ 0
- 1
docs_overrides/dist/three-with-martins.js Zobrazit soubor

@@ -1 +0,0 @@
1
-../../dist/three-with-martins.js

+ 7
- 2
mkdocs.yml Zobrazit soubor

@@ -14,7 +14,12 @@ theme:
14 14
   logo: img/martins-icon.png
15 15
 
16 16
 extra_css: [ 'style/extra.css' ]
17
-extra_javascript: [ 'js/extra.js', 'dist/martins.js', 'dist/martins.min.js' ]
17
+extra_javascript: [ 'js/extra.js' ]
18
+
19
+plugins:
20
+  - mkdocs-simple-hooks:
21
+      hooks:
22
+        on_post_build: 'docs.hooks:copy_static_files'
18 23
 
19 24
 markdown_extensions:
20 25
   - admonition
@@ -66,7 +71,7 @@ nav:
66 71
     - 'Questions & Answers': 'faq.md'
67 72
     - 'Contribute': 'CONTRIBUTING.md'
68 73
   - 'Demos':
69
-    - 'Demo gallery': 'demos.md'
74
+    - 'Demo gallery': 'gallery.md'
70 75
     - 'Try WebAR now!': 'demo/instructions.md'
71 76
   - 'API':
72 77
     - 'General':

+ 1
- 1
webpack.config.js Zobrazit soubor

@@ -69,7 +69,7 @@ module.exports = (env, argv) => ({
69 69
         https: true,
70 70
         host: env.HOST || '0.0.0.0',
71 71
         port: env.PORT || 8000,
72
-        static: ['assets', 'demos', 'tests'].map(dir => ({
72
+        static: ['demos', 'tests'].map(dir => ({
73 73
             directory: path.resolve(__dirname, dir),
74 74
             publicPath: `/${dir}/`,
75 75
         })),

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