Pārlūkot izejas kodu

New version of the three.js plugin

customisations
alemart 11 mēnešus atpakaļ
vecāks
revīzija
c45cdd6b74
1 mainītis faili ar 164 papildinājumiem un 67 dzēšanām
  1. 164
    67
      plugins/three-with-encantar.js

+ 164
- 67
plugins/three-with-encantar.js Parādīt failu

@@ -11,40 +11,142 @@ __THIS_PLUGIN_HAS_BEEN_TESTED_WITH__({
11 11
 });
12 12
 
13 13
 /**
14
- * Use this object to create your augmented scene
15
- * @typedef {object} ARSystem
16
- * @property {Session} session AR Session
17
- * @property {Frame} frame current Frame
18
- * @property {ReferenceImage | null} referenceImage corresponds to the target being tracked (if any)
19
- * @property {THREE.Scene} scene three.js Scene
20
- * @property {THREE.Group} root a 3D object that is automatically aligned to the physical target
21
- * @property {THREE.Camera} camera a camera adjusted for AR
22
- * @property {THREE.WebGLRenderer} renderer three.js renderer
14
+ * Base class for augmented scenes
23 15
  */
16
+class ARScene
17
+{
18
+    /**
19
+     * Start the AR session
20
+     * @abstract
21
+     * @returns {Promise<Session> | SpeedyPromise<Session>}
22
+     */
23
+    startSession()
24
+    {
25
+        throw new Error('Abstract method');
26
+    }
27
+
28
+    /**
29
+     * Initialize the augmented scene
30
+     * @abstract
31
+     * @param {ARPluginSystem} ar
32
+     * @returns {void | Promise<void> | SpeedyPromise<void>}
33
+     */
34
+    init(ar)
35
+    {
36
+        throw new Error('Abstract method');
37
+    }
38
+
39
+    /**
40
+     * Update / animate the augmented scene
41
+     * @abstract
42
+     * @param {ARPluginSystem} ar
43
+     * @returns {void}
44
+     */
45
+    update(ar)
46
+    {
47
+        throw new Error('Abstract method');
48
+    }
49
+
50
+    /**
51
+     * Release the augmented scene
52
+     * @param {ARPluginSystem} ar
53
+     * @returns {void}
54
+     */
55
+    release(ar)
56
+    {
57
+        // optional implementation
58
+    }
59
+}
60
+
61
+/**
62
+ * Helper for augmenting the scenes with three.js
63
+ */
64
+class ARPluginSystem
65
+{
66
+    /**
67
+     * AR Session
68
+     * @returns {Session}
69
+     */
70
+    get session()
71
+    {
72
+        return this._session;
73
+    }
74
+
75
+    /**
76
+     * Current frame: an object holding data to augment the physical scene.
77
+     * If the AR scene is not initialized, this will be null.
78
+     * @returns {Frame | null}
79
+     */
80
+    get frame()
81
+    {
82
+        return this._frame;
83
+    }
84
+
85
+    /**
86
+     * The root is a 3D object that is automatically aligned to the physical
87
+     * scene. Objects of your virtual scene should be descendants of this node.
88
+     * The root is only visible if something is being tracked.
89
+     * @returns {THREE.Group}
90
+     */
91
+    get root()
92
+    {
93
+        return this._root;
94
+    }
95
+
96
+    /**
97
+     * The three.js scene
98
+     * @returns {THREE.Scene}
99
+     */
100
+    get scene()
101
+    {
102
+        return this._scene;
103
+    }
104
+
105
+    /**
106
+     * A camera that is automatically adjusted for AR
107
+     * @returns {THREE.Camera}
108
+     */
109
+    get camera()
110
+    {
111
+        return this._camera;
112
+    }
113
+
114
+    /**
115
+     * The three.js renderer
116
+     * @returns {THREE.WebGLRenderer}
117
+     */
118
+    get renderer()
119
+    {
120
+        return this._renderer;
121
+    }
122
+
123
+    /**
124
+     * Constructor
125
+     */
126
+    constructor()
127
+    {
128
+        this._session = null;
129
+        this._frame = null;
130
+        this._origin = null;
131
+        this._root = null;
132
+        this._scene = null;
133
+        this._camera = null;
134
+        this._renderer = null;
135
+    }
136
+}
24 137
 
25 138
 /**
26 139
  * Do magic to connect encantar.js to three.js
27
- * @param {() => Promise<Session> | SpeedyPromise<Session>} startARSession
28
- * @param {(ar: ARSystem, deltaSeconds?: number) => void} [animateVirtualScene] animation callback
29
- * @param {(ar: ARSystem) => void | Promise<void> | SpeedyPromise<Session>} [initializeVirtualScene] initialization callback
30
- * @returns {Promise<ARSystem> | SpeedyPromise<ARSystem>}
140
+ * @param {ARScene} scene
141
+ * @returns {Promise<ARPluginSystem> | SpeedyPromise<ARPluginSystem>}
31 142
  */
32
-function encantar(startARSession, animateVirtualScene, initializeVirtualScene)
143
+function encantar(scene)
33 144
 {
34
-    const ar = /** @type {ARSystem} */ ({
35
-        session: null,
36
-        frame: null,
37
-        referenceImage: null,
38
-        scene: null,
39
-        root: null,
40
-        camera: null,
41
-        renderer: null,
42
-    });
145
+    const ar = new ARPluginSystem();
43 146
 
44 147
     function mix(frame)
45 148
     {
46
-        ar.root.visible = false;
47
-        ar.referenceImage = null;
149
+        ar._root.visible = false;
48 150
 
49 151
         for(const result of frame.results) {
50 152
             if(result.tracker.type == 'image-tracker') {
@@ -54,10 +156,10 @@ function encantar(startARSession, animateVirtualScene, initializeVirtualScene)
54 156
                     const viewMatrixInverse = result.viewer.pose.transform.matrix;
55 157
                     const modelMatrix = trackable.pose.transform.matrix;
56 158
 
57
-                    ar.root.visible = true;
58
-                    ar.referenceImage = trackable.referenceImage;
59
-
60 159
                     align(projectionMatrix, viewMatrixInverse, modelMatrix);
160
+                    ar._root.visible = true;
161
+
162
+                    return;
61 163
                 }
62 164
             }
63 165
         }
@@ -65,64 +167,59 @@ function encantar(startARSession, animateVirtualScene, initializeVirtualScene)
65 167
 
66 168
     function align(projectionMatrix, viewMatrixInverse, modelMatrix)
67 169
     {
68
-        ar.camera.projectionMatrix.fromArray(projectionMatrix.read());
69
-        ar.camera.projectionMatrixInverse.copy(ar.camera.projectionMatrix).invert();
70
-        ar.camera.matrix.fromArray(viewMatrixInverse.read());
71
-        ar.camera.updateMatrixWorld(true);
72
-        ar.root.matrix.fromArray(modelMatrix.read());
73
-        ar.root.updateMatrixWorld(true);
170
+        ar._camera.projectionMatrix.fromArray(projectionMatrix.read());
171
+        ar._camera.projectionMatrixInverse.copy(ar._camera.projectionMatrix).invert();
172
+        ar._camera.matrix.fromArray(viewMatrixInverse.read());
173
+        ar._camera.updateMatrixWorld(true);
174
+        ar._origin.matrix.fromArray(modelMatrix.read());
175
+        ar._origin.updateMatrixWorld(true);
74 176
     }
75 177
 
76 178
     function animate(time, frame)
77 179
     {
78
-        ar.frame = frame;
79
-        mix(ar.frame);
180
+        ar._frame = frame;
181
+        mix(frame);
80 182
 
81
-        animateVirtualScene.call(undefined, ar, ar.session.time.delta);
183
+        scene.update(ar);
82 184
 
83
-        ar.renderer.render(ar.scene, ar.camera);
84
-        ar.session.requestAnimationFrame(animate);
185
+        ar._renderer.render(ar._scene, ar._camera);
186
+        ar._session.requestAnimationFrame(animate);
85 187
     }
86 188
 
189
+    return scene.startSession().then(session => {
87 190
 
191
+        ar._session = session;
88 192
 
193
+        ar._scene = new THREE.Scene();
89 194
 
90
-    if(typeof animateVirtualScene !== 'function')
91
-        animateVirtualScene = (ar => void 0);
92
-
93
-    if(typeof initializeVirtualScene !== 'function')
94
-        initializeVirtualScene = (ar => void 0);
95
-
96
-    return startARSession().then(session => {
195
+        ar._origin = new THREE.Group();
196
+        ar._origin.matrixAutoUpdate = false;
197
+        ar._scene.add(ar._origin);
97 198
 
98
-        ar.session = session;
199
+        ar._root = new THREE.Group();
200
+        ar._origin.add(ar._root);
99 201
 
100
-        ar.scene = new THREE.Scene();
101
-        ar.camera = new THREE.PerspectiveCamera();
102
-        ar.camera.matrixAutoUpdate = false;
202
+        ar._camera = new THREE.PerspectiveCamera();
203
+        ar._camera.matrixAutoUpdate = false;
103 204
 
104
-        ar.root = new THREE.Group();
105
-        ar.root.matrixAutoUpdate = false;
106
-        ar.scene.add(ar.root);
107
-
108
-        ar.renderer = new THREE.WebGLRenderer({
109
-            canvas: ar.session.viewport.canvas,
205
+        ar._renderer = new THREE.WebGLRenderer({
206
+            canvas: session.viewport.canvas,
110 207
             alpha: true,
111 208
         });
112 209
 
113
-        ar.session.addEventListener('end', event => {
114
-            ar.root.visible = false;
115
-            ar.frame = null;
116
-            ar.referenceImage = null;
210
+        session.addEventListener('end', event => {
211
+            ar._root.visible = false;
212
+            scene.release(ar);
213
+            ar._frame = null;
117 214
         });
118 215
 
119
-        ar.session.viewport.addEventListener('resize', event => {
120
-            const size = ar.session.viewport.virtualSize;
121
-            ar.renderer.setPixelRatio(1.0);
122
-            ar.renderer.setSize(size.width, size.height, false);
216
+        session.viewport.addEventListener('resize', event => {
217
+            const size = session.viewport.virtualSize;
218
+            ar._renderer.setPixelRatio(1.0);
219
+            ar._renderer.setSize(size.width, size.height, false);
123 220
         });
124 221
 
125
-        let init = initializeVirtualScene.call(undefined, ar);
222
+        let init = scene.init(ar);
126 223
         if(!(typeof init === 'object' && 'then' in init))
127 224
             init = Promise.resolve();
128 225
 
@@ -135,7 +232,7 @@ function encantar(startARSession, animateVirtualScene, initializeVirtualScene)
135 232
         
136 233
         console.error(error);
137 234
         alert(error.message);
138
-        return ar;
235
+        throw error;
139 236
    
140 237
     });
141 238
 }
@@ -157,4 +254,4 @@ function __THIS_PLUGIN_HAS_BEEN_TESTED_WITH__(json)
157 254
             alert(e.message);
158 255
         }
159 256
     });
160
-}
257
+}

Notiek ielāde…
Atcelt
Saglabāt