locar 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/locar.d.ts +49 -4
- package/dist/locar.es.js +35 -22
- package/dist/locar.umd.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
package/dist/locar.d.ts
CHANGED
|
@@ -20,8 +20,10 @@ export declare class App extends EventEmitter {
|
|
|
20
20
|
/**
|
|
21
21
|
* Create an App object.
|
|
22
22
|
* @param {AppOptions} - Startup options.
|
|
23
|
+
* Note that you can only specify ONE of cameraOptions and threeObjects, as cameraOptions is intended to configure a new three.js camera,
|
|
24
|
+
* while threeObjects allows you to specify an existing camera, renderer and scene.
|
|
23
25
|
*/
|
|
24
|
-
constructor({ cameraOptions, canvas, gpsOptions, videoConstraints, deviceOrientationOptions, serverLogger, projection }: AppOptions);
|
|
26
|
+
constructor({ cameraOptions, canvas, gpsOptions, videoConstraints, deviceOrientationOptions, serverLogger, projection, threeObjects }: AppOptions);
|
|
25
27
|
/**
|
|
26
28
|
* Start the app.
|
|
27
29
|
* Must be called after construction.
|
|
@@ -29,10 +31,17 @@ export declare class App extends EventEmitter {
|
|
|
29
31
|
* Promise resolving with LocAR object. Rejects with object containing code and message.
|
|
30
32
|
*/
|
|
31
33
|
start(): Promise<LocAR>;
|
|
34
|
+
/**
|
|
35
|
+
* Add an event handler.
|
|
36
|
+
* Overridden from EventEmitter to create a ClickHandler for objectsIntersected event.
|
|
37
|
+
* @param {string} eventName - the event to handle.
|
|
38
|
+
* @param {Function} eventHandler - the event handler function.
|
|
39
|
+
*/
|
|
40
|
+
on(eventName: string, eventHandler: (...args: any[]) => void): void;
|
|
32
41
|
}
|
|
33
42
|
|
|
34
|
-
/**
|
|
35
|
-
export declare interface AppOptions {
|
|
43
|
+
/** Full options including three.js configuration options. */
|
|
44
|
+
export declare interface AppOptions extends BasicAppOptions {
|
|
36
45
|
/** the three.js camera options to use - note however we specify horizontal, not vertical, field of view */
|
|
37
46
|
cameraOptions?: {
|
|
38
47
|
hFov: number;
|
|
@@ -41,6 +50,13 @@ export declare interface AppOptions {
|
|
|
41
50
|
};
|
|
42
51
|
/** the canvas to render the AR scene into (one will be created if omitted) */
|
|
43
52
|
canvas?: HTMLCanvasElement;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Basic options to pass into the App object, excluding options specific to configuring three.js.
|
|
56
|
+
* If you already have three.js camera, scene and renderer objects set up (e.g. via react-three-fiber), you can just pass
|
|
57
|
+
* in BasicAppOptions to App.
|
|
58
|
+
*/
|
|
59
|
+
export declare interface BasicAppOptions {
|
|
44
60
|
/** GPS options, see GpsOptions documentation for details */
|
|
45
61
|
gpsOptions?: GpsOptions;
|
|
46
62
|
/** Video constraints for Media Devices API */
|
|
@@ -57,6 +73,8 @@ export declare interface AppOptions {
|
|
|
57
73
|
projection?: Projection;
|
|
58
74
|
/** Server logger to use - ensure you gain consent from the user if you are doing this, it's usually a Data Protection legal requirement */
|
|
59
75
|
serverLogger?: ServerLogger;
|
|
76
|
+
/** Existing three.js objects, set up elsewhere - e.g. react-three-fiber */
|
|
77
|
+
threeObjects?: ThreeObjects;
|
|
60
78
|
}
|
|
61
79
|
|
|
62
80
|
/**
|
|
@@ -169,7 +187,7 @@ export declare class EventEmitter {
|
|
|
169
187
|
* @param {string} eventName - the event to handle.
|
|
170
188
|
* @param {Function} eventHandler - the event handler function.
|
|
171
189
|
*/
|
|
172
|
-
on
|
|
190
|
+
on(eventName: string, eventHandler: (...args: any[]) => void): void;
|
|
173
191
|
/**
|
|
174
192
|
* Emit an event.
|
|
175
193
|
* @param {string} eventName - the event to emit.
|
|
@@ -287,7 +305,24 @@ export declare class LocAR extends EventEmitter {
|
|
|
287
305
|
* the contents of the GeoJSON properties field).
|
|
288
306
|
*/
|
|
289
307
|
add(object: THREE.Object3D, lon: number, lat: number, elev?: number | undefined, properties?: Record<string, any>): void;
|
|
308
|
+
/**
|
|
309
|
+
* Add a new triangle-strip based polyline to LocAR, defined by an array of points.
|
|
310
|
+
* Each point is a three-member array contaning longitude, latitude and optional altitude.
|
|
311
|
+
* @param {Array<[number, number, number?]>} points - the array of points
|
|
312
|
+
* @param {THREE.Material} material - the material to use
|
|
313
|
+
* @param {number} lineWidth - line width in world units (default 1)
|
|
314
|
+
* @return {THREE.Mesh} - mesh containing the polyline
|
|
315
|
+
*/
|
|
290
316
|
addGeoLine(points: Array<[number, number, number?]>, material: THREE.Material, lineWidth?: number): THREE.Mesh;
|
|
317
|
+
/**
|
|
318
|
+
* Create a new triangle-strip based polyline geometry, defined by an array of points.
|
|
319
|
+
* Each point is a three-member array contaning longitude, latitude and optional altitude.
|
|
320
|
+
* This method simply projects the coordinates and creates the geometry, it does not create a mesh.
|
|
321
|
+
* @param {Array<[number, number, number?]>} points - the array of points
|
|
322
|
+
* @param {number} lineWidth - line width in world units (default 1)
|
|
323
|
+
* @return {THREE.BufferGeometry} - the created geometry
|
|
324
|
+
*/
|
|
325
|
+
createGeoLine(points: Array<[number, number, number?]>, lineWidth?: number): THREE.BufferGeometry;
|
|
291
326
|
/**
|
|
292
327
|
* Set the elevation (y coordinate) of the camera.
|
|
293
328
|
* @param {number} elev - the elevation in metres.
|
|
@@ -352,6 +387,16 @@ export declare class SphMercProjection implements Projection {
|
|
|
352
387
|
getID: () => string;
|
|
353
388
|
}
|
|
354
389
|
|
|
390
|
+
/** Interface representing existing three.js objects if you want to pass them in from elsewhere (e.g. react-three-fiber) */
|
|
391
|
+
export declare interface ThreeObjects {
|
|
392
|
+
/** the three.js camera */
|
|
393
|
+
camera: THREE.PerspectiveCamera;
|
|
394
|
+
/** the three.js renderer */
|
|
395
|
+
renderer: THREE.WebGLRenderer;
|
|
396
|
+
/** the three.js scene */
|
|
397
|
+
scene: THREE.Scene;
|
|
398
|
+
}
|
|
399
|
+
|
|
355
400
|
/** Class to setup the webcam. */
|
|
356
401
|
export declare class Webcam extends EventEmitter {
|
|
357
402
|
#private;
|
package/dist/locar.es.js
CHANGED
|
@@ -3,9 +3,7 @@ import { Euler as t, EventDispatcher as n, MathUtils as r, Quaternion as i, Vect
|
|
|
3
3
|
//#region lib/three/event-emitter.ts
|
|
4
4
|
var o = class {
|
|
5
5
|
constructor() {
|
|
6
|
-
this.
|
|
7
|
-
this.eventHandlers[e] === void 0 && (this.eventHandlers[e] = []), this.eventHandlers[e].push(t);
|
|
8
|
-
}, this.emit = (e, ...t) => {
|
|
6
|
+
this.emit = (e, ...t) => {
|
|
9
7
|
this.eventHandlers[e]?.forEach((e) => {
|
|
10
8
|
e(...t);
|
|
11
9
|
});
|
|
@@ -16,26 +14,33 @@ var o = class {
|
|
|
16
14
|
}
|
|
17
15
|
}, this.eventHandlers = {};
|
|
18
16
|
}
|
|
17
|
+
on(e, t) {
|
|
18
|
+
this.eventHandlers[e] === void 0 && (this.eventHandlers[e] = []), this.eventHandlers[e].push(t);
|
|
19
|
+
}
|
|
19
20
|
}, s = class extends o {
|
|
20
|
-
|
|
21
|
+
#e;
|
|
22
|
+
constructor({ cameraOptions: t, canvas: n, gpsOptions: r, videoConstraints: i, deviceOrientationOptions: a, serverLogger: o, projection: s, threeObjects: c }) {
|
|
23
|
+
if (c && t) throw Error("LocAR.App: ERROR: can only specify one of cameraOptions and threeObjects");
|
|
21
24
|
super(), this.origHfov = t?.hFov || 80, this.cameraFeedDimensions = null;
|
|
22
|
-
let
|
|
23
|
-
this.camera = new e.PerspectiveCamera(this.origHfov /
|
|
25
|
+
let u = window.innerWidth / window.innerHeight;
|
|
26
|
+
this.camera = c?.camera || new e.PerspectiveCamera(this.origHfov / u, u, t?.near || .001, t?.far || 1e3), this.scene = c?.scene || new e.Scene(), c ? this.renderer = c.renderer : (n ? (this.renderer = new e.WebGLRenderer({
|
|
24
27
|
canvas: n,
|
|
25
28
|
alpha: !0
|
|
26
|
-
}), this.renderer.setClearColor(65280, 0)) : (this.renderer = new e.WebGLRenderer({ alpha: !0 }), this.renderer.setClearColor(65280, 0), document.body.appendChild(this.renderer.domElement)), this.renderer.setSize(window.innerWidth, window.innerHeight), this.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
}), this.renderer.setClearColor(65280, 0)) : (this.renderer = new e.WebGLRenderer({ alpha: !0 }), this.renderer.setClearColor(65280, 0), this.renderer.domElement.style.position = "relative", this.renderer.domElement.style.zIndex = "999", document.body.appendChild(this.renderer.domElement)), this.renderer.setSize(window.innerWidth, window.innerHeight), this.renderer.setAnimationLoop(() => {
|
|
30
|
+
this.deviceOrientationControls?.update(), this.renderer.render(this.scene, this.camera);
|
|
31
|
+
let e = this.#e?.raycast(this.camera, this.scene) ?? [];
|
|
32
|
+
e.length > 0 && this.emit("objectsIntersected", { intersections: e });
|
|
33
|
+
}), window.addEventListener("resize", () => {
|
|
29
34
|
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
|
30
35
|
let e = window.innerWidth / window.innerHeight;
|
|
31
36
|
if (this.camera.aspect = e, this.cameraFeedDimensions !== null) {
|
|
32
37
|
let t = e > 1 ? this.cameraFeedDimensions.landWidth : this.cameraFeedDimensions.landHeight, n = e > 1 ? this.cameraFeedDimensions.landHeight : this.cameraFeedDimensions.landWidth;
|
|
33
|
-
this.#
|
|
38
|
+
this.#t(t, n, e);
|
|
34
39
|
}
|
|
35
40
|
this.camera.updateProjectionMatrix();
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
}));
|
|
42
|
+
let d = a || { enabled: !0 };
|
|
43
|
+
this.locar = new l(this.scene, this.camera, r, o, s), this.webcam = new w(i), this.deviceOrientationControls = d.enabled === !0 ? new S(this.camera, d) : null, this.#e = null;
|
|
39
44
|
}
|
|
40
45
|
start() {
|
|
41
46
|
return new Promise((e, t) => {
|
|
@@ -44,7 +49,7 @@ var o = class {
|
|
|
44
49
|
this.cameraFeedDimensions = {
|
|
45
50
|
landWidth: t ? e.videoWidth : e.videoHeight,
|
|
46
51
|
landHeight: t ? e.videoHeight : e.videoWidth
|
|
47
|
-
}, this.#
|
|
52
|
+
}, this.#t(e.videoWidth, e.videoHeight, window.innerWidth / window.innerHeight), this.camera.updateProjectionMatrix();
|
|
48
53
|
}), this.webcam.on("webcamerror", (e) => {
|
|
49
54
|
t({
|
|
50
55
|
code: e.code,
|
|
@@ -60,12 +65,15 @@ var o = class {
|
|
|
60
65
|
}), this.deviceOrientationControls.init());
|
|
61
66
|
});
|
|
62
67
|
}
|
|
63
|
-
#
|
|
68
|
+
#t(e, t, n) {
|
|
64
69
|
if (n < e / t) {
|
|
65
70
|
let r = e * (window.innerHeight / t), i = this.origHfov * (window.innerWidth / r);
|
|
66
71
|
this.camera.fov = i / n;
|
|
67
72
|
} else this.camera.fov = this.origHfov / n;
|
|
68
73
|
}
|
|
74
|
+
on(e, t) {
|
|
75
|
+
e == "objectsIntersected" && this.#e === null && (this.#e = new C(this.renderer)), super.on(e, t);
|
|
76
|
+
}
|
|
69
77
|
}, c = class {
|
|
70
78
|
constructor() {
|
|
71
79
|
this.project = (e, t) => [this.#e(e), this.#t(t)], this.unproject = (e) => [this.#n(e[0]), this.#r(e[1])], this.#e = (e) => e / 180 * this.HALF_EARTH, this.#t = (e) => Math.log(Math.tan((90 + e) * Math.PI / 360)) / (Math.PI / 180) * this.HALF_EARTH / 180, this.#n = (e) => e / this.HALF_EARTH * 180, this.#r = (e) => {
|
|
@@ -139,13 +147,17 @@ var o = class {
|
|
|
139
147
|
});
|
|
140
148
|
}
|
|
141
149
|
addGeoLine(t, n, r = 1) {
|
|
142
|
-
let i =
|
|
150
|
+
let i = this.createGeoLine(t, r);
|
|
151
|
+
n.setValues({ side: e.DoubleSide });
|
|
152
|
+
let a = new e.Mesh(i, n);
|
|
153
|
+
return this.scene.add(a), a;
|
|
154
|
+
}
|
|
155
|
+
createGeoLine(t, n = 1) {
|
|
156
|
+
let r = t.map(((t) => {
|
|
143
157
|
let [n, r] = this.lonLatToWorldCoords(t[0], t[1]);
|
|
144
158
|
return new e.Vector3(n, t[2] || 0, r);
|
|
145
|
-
}))
|
|
146
|
-
|
|
147
|
-
let o = new e.Mesh(a, n);
|
|
148
|
-
return this.scene.add(o), o;
|
|
159
|
+
}));
|
|
160
|
+
return this.#l(r, n);
|
|
149
161
|
}
|
|
150
162
|
#l(t, n) {
|
|
151
163
|
let r, i, a, o, s = 0, c = 0, l = [], u, d = t.length - 1, f = [];
|
|
@@ -331,13 +343,14 @@ var x = .5 * Math.PI, S = class extends n {
|
|
|
331
343
|
}, C = class {
|
|
332
344
|
constructor(t) {
|
|
333
345
|
this.raycaster = new e.Raycaster(), this.normalisedMousePosition = null, t.domElement.addEventListener("click", (n) => {
|
|
334
|
-
|
|
346
|
+
let r = t.domElement.getBoundingClientRect();
|
|
347
|
+
this.normalisedMousePosition = new e.Vector2((n.clientX - r.left) / t.domElement.clientWidth * 2 - 1, -((n.clientY - r.top) / t.domElement.clientHeight * 2) + 1);
|
|
335
348
|
});
|
|
336
349
|
}
|
|
337
350
|
raycast(e, t) {
|
|
338
351
|
if (this.normalisedMousePosition !== null) {
|
|
339
352
|
this.raycaster.setFromCamera(this.normalisedMousePosition, e);
|
|
340
|
-
let n = this.raycaster.intersectObjects(t.children, !
|
|
353
|
+
let n = this.raycaster.intersectObjects(t.children, !0);
|
|
341
354
|
return this.normalisedMousePosition = null, n;
|
|
342
355
|
}
|
|
343
356
|
return [];
|
package/dist/locar.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("three")):typeof define==`function`&&define.amd?define([`exports`,`three`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.locar={},e.THREE))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,c=(e,t,n,o)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=a(t),l=0,u=c.length,d;l<u;l++)d=c[l],!s.call(e,d)&&d!==n&&r(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(o=i(t,d))||o.enumerable});return e};t=((e,t,i)=>(i=e==null?{}:n(o(e)),c(t||!e||!e.__esModule?r(i,`default`,{value:e,enumerable:!0}):i,e)))(t);var l=class{constructor(){this.on=(e,t)=>{this.eventHandlers[e]===void 0&&(this.eventHandlers[e]=[]),this.eventHandlers[e].push(t)},this.emit=(e,...t)=>{this.eventHandlers[e]?.forEach(e=>{e(...t)})},this.off=(e,t)=>{if(this.eventHandlers[e]){let n=this.eventHandlers[e].indexOf(t);n>-1&&this.eventHandlers[e].splice(n,1)}},this.eventHandlers={}}},u=class extends l{constructor({cameraOptions:e,canvas:n,gpsOptions:r,videoConstraints:i,deviceOrientationOptions:a,serverLogger:o,projection:s}){super(),this.origHfov=e?.hFov||80,this.cameraFeedDimensions=null;let c=window.innerWidth/window.innerHeight;this.camera=new t.PerspectiveCamera(this.origHfov/c,c,e?.near||.001,e?.far||1e3),n?(this.renderer=new t.WebGLRenderer({canvas:n,alpha:!0}),this.renderer.setClearColor(65280,0)):(this.renderer=new t.WebGLRenderer({alpha:!0}),this.renderer.setClearColor(65280,0),document.body.appendChild(this.renderer.domElement)),this.renderer.setSize(window.innerWidth,window.innerHeight),this.scene=new t.Scene;let l=a||{enabled:!0};window.addEventListener(`resize`,()=>{this.renderer.setSize(window.innerWidth,window.innerHeight);let e=window.innerWidth/window.innerHeight;if(this.camera.aspect=e,this.cameraFeedDimensions!==null){let t=e>1?this.cameraFeedDimensions.landWidth:this.cameraFeedDimensions.landHeight,n=e>1?this.cameraFeedDimensions.landHeight:this.cameraFeedDimensions.landWidth;this.#e(t,n,e)}this.camera.updateProjectionMatrix()}),this.locar=new f(this.scene,this.camera,r,o,s),this.webcam=new D(i),this.deviceOrientationControls=l.enabled===!0?new T(this.camera,l):null,this.renderer.setAnimationLoop(()=>{this.deviceOrientationControls?.update(),this.renderer.render(this.scene,this.camera)})}start(){return new Promise((e,t)=>{this.webcam.on(`webcamstarted`,e=>{let t=e.videoWidth>e.videoHeight;this.cameraFeedDimensions={landWidth:t?e.videoWidth:e.videoHeight,landHeight:t?e.videoHeight:e.videoWidth},this.#e(e.videoWidth,e.videoHeight,window.innerWidth/window.innerHeight),this.camera.updateProjectionMatrix()}),this.webcam.on(`webcamerror`,e=>{t({code:e.code,message:e.message})}),this.deviceOrientationControls===null?e(this.locar):(this.deviceOrientationControls?.on(`deviceorientationgranted`,t=>{t.target.connect(),e(this.locar)}),this.deviceOrientationControls.on(`deviceorientationerror`,e=>{t({code:e.code,message:e.message})}),this.deviceOrientationControls.init())})}#e(e,t,n){if(n<e/t){let r=e*(window.innerHeight/t),i=this.origHfov*(window.innerWidth/r);this.camera.fov=i/n}else this.camera.fov=this.origHfov/n}},d=class{constructor(){this.project=(e,t)=>[this.#e(e),this.#t(t)],this.unproject=e=>[this.#n(e[0]),this.#r(e[1])],this.#e=e=>e/180*this.HALF_EARTH,this.#t=e=>Math.log(Math.tan((90+e)*Math.PI/360))/(Math.PI/180)*this.HALF_EARTH/180,this.#n=e=>e/this.HALF_EARTH*180,this.#r=e=>{var t=e/this.HALF_EARTH*180;return t=180/Math.PI*(2*Math.atan(Math.exp(t*Math.PI/180))-Math.PI/2),t},this.getID=()=>`epsg:3857`,this.EARTH=40075016.68,this.HALF_EARTH=20037508.34}#e;#t;#n;#r},f=class e extends l{#e;#t;#n;#r;#i;#a;#o;#s;#c;constructor(e,t,n={},r=null,i=new d){super(),this.scene=e,this.camera=t,this.#e=i,this.#t=null,this.#n=0,this.#r=100,this.#i=null,this.setGpsOptions(n),this.#a=null,this.#o=0,this.#s=0,this.#c=r}setProjection(e){this.#e=e}setGpsOptions(e={}){e.gpsMinDistance!==void 0&&(this.#n=e.gpsMinDistance),e.gpsMinAccuracy!==void 0&&(this.#r=e.gpsMinAccuracy)}async startGps(){if(this.#c){let e=await(await this.#c.sendData(`/gps/start`,{gpsMinDistance:this.#n,gpsMinAccuracy:this.#r})).json();this.#s=e.session}return this.#i===null?(this.#i=navigator.geolocation.watchPosition(e=>{this.#f(e)},e=>{this.emit(`gpserror`,e)},{enableHighAccuracy:!0}),!0):!1}stopGps(){return this.#i===null?!1:(navigator.geolocation.clearWatch(this.#i),this.#i=null,!0)}fakeGps(e,t,n=null,r=0){n!==null&&this.setElevation(n),this.#f({coords:{longitude:e,latitude:t,accuracy:r}})}lonLatToWorldCoords(e,t){let n=this.#e.project(e,t);return this.eastNorthToWorldCoords(n)}eastNorthToWorldCoords(e){if(this.#a)e[0]-=this.#a[0],e[1]-=this.#a[1];else throw`No initial position determined`;return[e[0],-e[1]]}add(e,t,n,r,i={}){e.properties=i,this.#u(e,t,n,r||0),this.scene.add(e),this.#c?.sendData(`/object/new`,{position:e.position,x:e.position.x,z:e.position.z,session:this.#s,properties:i})}addGeoLine(e,n,r=1){let i=e.map((e=>{let[n,r]=this.lonLatToWorldCoords(e[0],e[1]);return new t.Vector3(n,e[2]||0,r)})),a=this.#l(i,r);n.setValues({side:t.DoubleSide});let o=new t.Mesh(a,n);return this.scene.add(o),o}#l(e,n){let r,i,a,o,s=0,c=0,l=[],u,d=e.length-1,f=[];for(let t=0;t<d;t++)r=e[t+1].x-e[t].x,i=e[t+1].z-e[t].z,a=e[t+1].y-e[t].y,o=Math.sqrt(r*r+a*a+i*i),s=-(n/2*i)/o,c=n/2*r/o,u=[e[t].x-s,e[t].y,e[t].z-c,e[t].x+s,e[t].y,e[t].z+c],t>0&&u.forEach((e,t)=>{e=(e+l[t])/2}),f.push(...u),l=[e[t+1].x-s,e[t+1].y,e[t+1].z-c,e[t+1].x+s,e[t+1].y,e[t+1].z+c];f.push(e[d].x-s),f.push(e[d].y),f.push(e[d].z-c),f.push(e[d].x+s),f.push(e[d].y),f.push(e[d].z+c);let p=[];for(let e=0;e<d;e++)p.push(e*2,e*2+1,e*2+2),p.push(e*2+1,e*2+3,e*2+2);let m=new t.BufferGeometry,h=new Float32Array(f);return m.setIndex(p),m.setAttribute(`position`,new t.BufferAttribute(h,3)),m.computeBoundingBox(),m}#u(e,t,n,r){let i=this.lonLatToWorldCoords(t,n);r!==void 0&&(e.position.y=r),[e.position.x,e.position.z]=i}setElevation(e){this.camera.position.y=e}#d(e,t){this.#a=this.#e.project(e,t)}#f(t){let n=Number.MAX_VALUE;this.#o++,this.#c?.sendData(`/gps/new`,{gpsCount:this.#o,lat:t.coords.latitude,lon:t.coords.longitude,acc:t.coords.accuracy,session:this.#s}),t.coords.accuracy<=this.#r&&(this.#t===null?this.#t={latitude:t.coords.latitude,longitude:t.coords.longitude}:n=e.haversineDist(this.#t,t.coords),n>=this.#n&&(this.#t.longitude=t.coords.longitude,this.#t.latitude=t.coords.latitude,this.#a||(this.#d(t.coords.longitude,t.coords.latitude),this.#c?.sendData(`/worldorigin/new`,{gpsCount:this.#o,lat:t.coords.latitude,lon:t.coords.longitude,session:this.#s,initialPosition:this.#a})),this.#u(this.camera,t.coords.longitude,t.coords.latitude),this.#c?.sendData(`/gps/accepted`,{gpsCount:this.#o,cameraX:this.camera.position.x,cameraZ:this.camera.position.z,session:this.#s,distMoved:n}),this.emit(`gpsupdate`,{position:t,distMoved:n})))}static haversineDist(e,n){let r=t.MathUtils.degToRad(n.longitude-e.longitude),i=t.MathUtils.degToRad(n.latitude-e.latitude),a=Math.sin(i/2)*Math.sin(i/2)+Math.cos(t.MathUtils.degToRad(e.latitude))*Math.cos(t.MathUtils.degToRad(n.latitude))*(Math.sin(r/2)*Math.sin(r/2));return 2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a))*6371e3}getLastKnownLocation(){return this.#t}},p=`locar-device-orientation-permission-modal`,m=`locar-device-orientation-permission-button`,h=`locar-device-orientation-permission-message`,g=`locar-device-orientation-permission-inner`,_=`locar-device-orientation-permission-button-inner`,v=`This immersive website requires access to your device motion sensors.`,y=navigator.userAgent.match(/iPhone|iPad|iPod/i)||/Macintosh/i.test(navigator.userAgent)&&navigator.maxTouchPoints!=null&&navigator.maxTouchPoints>1,b=new t.Vector3(0,0,1),x=new t.Euler,S=new t.Quaternion,C=new t.Quaternion(-Math.sqrt(.5),0,0,Math.sqrt(.5));2*Math.PI;var w=.5*Math.PI,T=class extends t.EventDispatcher{constructor(e,n={}){super(),this.init=()=>{window.DeviceOrientationEvent===void 0?this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_NOT_SUPPORTED`,message:`Device orientation API not supported`}):window.isSecureContext===!1?this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_NO_HTTPS`,message:`DeviceOrientationEvent is only available in secure contexts (https)`}):typeof window.DeviceOrientationEvent.requestPermission==`function`&&this.enablePermissionDialog?this.obtainPermissionGesture():this.eventEmitter.emit(`deviceorientationgranted`,{target:this})},this.eventEmitter=new l;let r=this;this.object=e,this.object.rotation.reorder(`YXZ`),this.enabled=!0,this.deviceOrientation=null,this.screenOrientation=0,this.alphaOffset=0,this.orientationOffset=0,this.initialOffset=null,this.lastQuaternion=null,this.orientationChangeEventName=`ondeviceorientationabsolute`in window?`deviceorientationabsolute`:`deviceorientation`,this.smoothingFactor=n.smoothingFactor||.2,this.enablePermissionDialog=n.enablePermissionDialog??!0,this.enableInlineStyling=n.enableStyling??!0,this.preferConfirmDialog=n.preferConfirmDialog??!1,this.orientationChangeThreshold=n.orientationChangeThreshold??0;let i=n=>{let{alpha:i,beta:a,gamma:o,webkitCompassHeading:s}=n;if(i??=0,a??=0,o??=0,s??=0,y){let e=360-s;r.alphaOffset=t.MathUtils.degToRad(e-i),r.deviceOrientation={alpha:i,beta:a,gamma:o,webkitCompassHeading:s}}else i<0&&(i+=360),r.deviceOrientation={alpha:i,beta:a,gamma:o};window.dispatchEvent(new CustomEvent(`camera-rotation-change`,{detail:{cameraRotation:e.rotation}}))},a=()=>{r.screenOrientation=window.screen.orientation?.angle??0,y&&(r.screenOrientation===90?r.orientationOffset=-w:r.screenOrientation===-90?r.orientationOffset=w:r.orientationOffset=0)},o=(e,t,n,r,i)=>{x.set(n,t,-r,`YXZ`),e.setFromEuler(x),e.multiply(C),e.multiply(S.setFromAxisAngle(b,-i))};this.connect=()=>{a(),window.addEventListener(`orientationchange`,a),window.addEventListener(r.orientationChangeEventName,i),r.enabled=!0},this.disconnect=()=>{window.removeEventListener(`orientationchange`,a),window.removeEventListener(r.orientationChangeEventName,i),r.enabled=!1,r.initialOffset=!1,r.deviceOrientation=null,r.lastQuaternion=null},this.requestOrientationPermissions=()=>{window.DeviceOrientationEvent!==void 0&&typeof window.DeviceOrientationEvent.requestPermission==`function`?window.DeviceOrientationEvent.requestPermission().then(e=>{e===`granted`?this.eventEmitter.emit(`deviceorientationgranted`,{target:this}):this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_PERMISSION_DENIED`,message:`Permission for device orientation denied - AR will not work correctly`})}).catch(e=>{this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_PERMISSION_FAILED`,message:`Permission request for device orientation failed - AR will not work correctly`,error:JSON.stringify(e,null,2)})}):this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_INTERNAL_ERROR`,message:`Internal error: no requestPermission() found although requestOrientationPermissions() was called - please raise an issue on GitHub`})},this.update=()=>{if(r.enabled===!1)return;let e=r.deviceOrientation;if(e){let n=e.alpha?t.MathUtils.degToRad(e.alpha)+r.alphaOffset:0,i=e.beta?t.MathUtils.degToRad(e.beta):0,a=e.gamma?t.MathUtils.degToRad(e.gamma):0,s=r.screenOrientation?t.MathUtils.degToRad(r.screenOrientation):0,c=new t.Quaternion;if(y){o(c,n,i,a,s);let l=new t.Euler().setFromQuaternion(c,`YXZ`);l.y=t.MathUtils.degToRad(360-(e.webkitCompassHeading??0))+(r.orientationOffset||0),c.setFromEuler(l)}else o(c,n,i,a,s);if(r.lastQuaternion&&r.orientationChangeThreshold>0&&c.angleTo(r.lastQuaternion)<r.orientationChangeThreshold)return;if(r.smoothingFactor<1&&r.lastQuaternion){let e=1-r.smoothingFactor;r.object.quaternion.slerp(c,e)}else r.object.quaternion.copy(c);r.lastQuaternion=r.object.quaternion.clone(),window.dispatchEvent(new CustomEvent(`camera-rotation-change`,{detail:{cameraRotation:r.object.rotation}}))}},this.getCorrectedHeading=()=>{let{deviceOrientation:e}=r;if(!e)return 0;let t=0;return y?(t=360-(e.webkitCompassHeading??0),r.orientationOffset&&(t+=r.orientationOffset*(180/Math.PI),t=(t+360)%360)):(e.absolute===!0||r.orientationChangeEventName,t=e.alpha?e.alpha:0,t=(360-t)%360,t<0&&(t+=360)),t},this.updateAlphaOffset=()=>{r.initialOffset=!1},this.dispose=()=>{r.disconnect()},this.getAlpha=()=>{let{deviceOrientation:e}=r;return e&&e.alpha?t.MathUtils.degToRad(e.alpha)+r.alphaOffset:0},this.getBeta=()=>{let{deviceOrientation:e}=r;return e&&e.beta?t.MathUtils.degToRad(e.beta):0},this.getGamma=()=>{let{deviceOrientation:e}=r;return e&&e.gamma?t.MathUtils.degToRad(e.gamma):0},this.createObtainPermissionGestureDialog=()=>{let e=document.createElement(`div`);e.classList.add(p);let t=document.createElement(`div`);t.classList.add(g);let n=document.createElement(`div`);n.classList.add(h);let r=document.createElement(`div`);r.classList.add(_);let i=document.createElement(`button`);i.classList.add(m),document.body.appendChild(e),this.enableInlineStyling===!0&&(e.style.fontFamily=`-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'`,e.style.display=`flex`,e.style.position=`fixed`,e.style.zIndex=`100000`,e.style.justifyContent=`center`,e.style.alignItems=`center`,e.style.backgroundColor=`rgba(0,0,0,0.2)`,e.style.inset=`0`,e.style.padding=`20px`,t.style.backgroundColor=`rgba(220, 220, 220, 0.85)`,t.style.padding=`6px 0`,t.style.borderRadius=`10px`,t.style.width=`100%`,t.style.maxWidth=`400px`,n.style.padding=`10px 12px`,n.style.textAlign=`center`,n.style.fontWeight=`400`,n.style.fontSize=`13px`,n.style.display=`flex`,n.style.justifyContent=`center`,n.style.alignItems=`center`,r.style.display=`block`,r.style.textAlign=`center`,r.style.textDecoration=`none`,r.style.borderTop=`rgb(180,180,180) solid 1px`,i.style.display=`block`,i.style.width=`100%`,i.style.textAlign=`center`,i.style.appearance=`none`,i.style.background=`none`,i.style.border=`none`,i.style.outline=`none`,i.style.padding=`10px`,i.style.fontWeight=`400`,i.style.fontSize=`16px`,i.style.color=`#2e7cf1`,i.style.cursor=`pointer`),e.appendChild(t),t.appendChild(n),t.appendChild(r),n.appendChild(document.createTextNode(v)),i.addEventListener(`click`,()=>{this.requestOrientationPermissions(),e.style.display=`none`}),i.appendChild(document.createTextNode(`OK`)),r.appendChild(i),document.body.appendChild(e)},this.obtainPermissionGesture=()=>{this.preferConfirmDialog===!0?window.confirm(v)&&this.requestOrientationPermissions():this.createObtainPermissionGestureDialog()}}on(e,t){this.eventEmitter.on(e,t)}},E=class{constructor(e){this.raycaster=new t.Raycaster,this.normalisedMousePosition=null,e.domElement.addEventListener(`click`,n=>{this.normalisedMousePosition=new t.Vector2(n.clientX/e.domElement.clientWidth*2-1,-(n.clientY/e.domElement.clientHeight*2)+1)})}raycast(e,t){if(this.normalisedMousePosition!==null){this.raycaster.setFromCamera(this.normalisedMousePosition,e);let n=this.raycaster.intersectObjects(t.children,!1);return this.normalisedMousePosition=null,n}return[]}},D=class extends l{#e;#t;constructor(e={video:{facingMode:`environment`}},n){super(),this.sceneWebcam=new t.Scene,n?this.#e=document.querySelector(n):(this.#e=document.createElement(`video`),this.#e.setAttribute(`autoplay`,`true`),this.#e.setAttribute(`playsinline`,`true`),this.#e.style.cssText+=`
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("three")):typeof define==`function`&&define.amd?define([`exports`,`three`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.locar={},e.THREE))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,c=(e,t,n,o)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=a(t),l=0,u=c.length,d;l<u;l++)d=c[l],!s.call(e,d)&&d!==n&&r(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(o=i(t,d))||o.enumerable});return e};t=((e,t,i)=>(i=e==null?{}:n(o(e)),c(t||!e||!e.__esModule?r(i,`default`,{value:e,enumerable:!0}):i,e)))(t);var l=class{constructor(){this.emit=(e,...t)=>{this.eventHandlers[e]?.forEach(e=>{e(...t)})},this.off=(e,t)=>{if(this.eventHandlers[e]){let n=this.eventHandlers[e].indexOf(t);n>-1&&this.eventHandlers[e].splice(n,1)}},this.eventHandlers={}}on(e,t){this.eventHandlers[e]===void 0&&(this.eventHandlers[e]=[]),this.eventHandlers[e].push(t)}},u=class extends l{#e;constructor({cameraOptions:e,canvas:n,gpsOptions:r,videoConstraints:i,deviceOrientationOptions:a,serverLogger:o,projection:s,threeObjects:c}){if(c&&e)throw Error(`LocAR.App: ERROR: can only specify one of cameraOptions and threeObjects`);super(),this.origHfov=e?.hFov||80,this.cameraFeedDimensions=null;let l=window.innerWidth/window.innerHeight;this.camera=c?.camera||new t.PerspectiveCamera(this.origHfov/l,l,e?.near||.001,e?.far||1e3),this.scene=c?.scene||new t.Scene,c?this.renderer=c.renderer:(n?(this.renderer=new t.WebGLRenderer({canvas:n,alpha:!0}),this.renderer.setClearColor(65280,0)):(this.renderer=new t.WebGLRenderer({alpha:!0}),this.renderer.setClearColor(65280,0),this.renderer.domElement.style.position=`relative`,this.renderer.domElement.style.zIndex=`999`,document.body.appendChild(this.renderer.domElement)),this.renderer.setSize(window.innerWidth,window.innerHeight),this.renderer.setAnimationLoop(()=>{this.deviceOrientationControls?.update(),this.renderer.render(this.scene,this.camera);let e=this.#e?.raycast(this.camera,this.scene)??[];e.length>0&&this.emit(`objectsIntersected`,{intersections:e})}),window.addEventListener(`resize`,()=>{this.renderer.setSize(window.innerWidth,window.innerHeight);let e=window.innerWidth/window.innerHeight;if(this.camera.aspect=e,this.cameraFeedDimensions!==null){let t=e>1?this.cameraFeedDimensions.landWidth:this.cameraFeedDimensions.landHeight,n=e>1?this.cameraFeedDimensions.landHeight:this.cameraFeedDimensions.landWidth;this.#t(t,n,e)}this.camera.updateProjectionMatrix()}));let u=a||{enabled:!0};this.locar=new f(this.scene,this.camera,r,o,s),this.webcam=new D(i),this.deviceOrientationControls=u.enabled===!0?new T(this.camera,u):null,this.#e=null}start(){return new Promise((e,t)=>{this.webcam.on(`webcamstarted`,e=>{let t=e.videoWidth>e.videoHeight;this.cameraFeedDimensions={landWidth:t?e.videoWidth:e.videoHeight,landHeight:t?e.videoHeight:e.videoWidth},this.#t(e.videoWidth,e.videoHeight,window.innerWidth/window.innerHeight),this.camera.updateProjectionMatrix()}),this.webcam.on(`webcamerror`,e=>{t({code:e.code,message:e.message})}),this.deviceOrientationControls===null?e(this.locar):(this.deviceOrientationControls?.on(`deviceorientationgranted`,t=>{t.target.connect(),e(this.locar)}),this.deviceOrientationControls.on(`deviceorientationerror`,e=>{t({code:e.code,message:e.message})}),this.deviceOrientationControls.init())})}#t(e,t,n){if(n<e/t){let r=e*(window.innerHeight/t),i=this.origHfov*(window.innerWidth/r);this.camera.fov=i/n}else this.camera.fov=this.origHfov/n}on(e,t){e==`objectsIntersected`&&this.#e===null&&(this.#e=new E(this.renderer)),super.on(e,t)}},d=class{constructor(){this.project=(e,t)=>[this.#e(e),this.#t(t)],this.unproject=e=>[this.#n(e[0]),this.#r(e[1])],this.#e=e=>e/180*this.HALF_EARTH,this.#t=e=>Math.log(Math.tan((90+e)*Math.PI/360))/(Math.PI/180)*this.HALF_EARTH/180,this.#n=e=>e/this.HALF_EARTH*180,this.#r=e=>{var t=e/this.HALF_EARTH*180;return t=180/Math.PI*(2*Math.atan(Math.exp(t*Math.PI/180))-Math.PI/2),t},this.getID=()=>`epsg:3857`,this.EARTH=40075016.68,this.HALF_EARTH=20037508.34}#e;#t;#n;#r},f=class e extends l{#e;#t;#n;#r;#i;#a;#o;#s;#c;constructor(e,t,n={},r=null,i=new d){super(),this.scene=e,this.camera=t,this.#e=i,this.#t=null,this.#n=0,this.#r=100,this.#i=null,this.setGpsOptions(n),this.#a=null,this.#o=0,this.#s=0,this.#c=r}setProjection(e){this.#e=e}setGpsOptions(e={}){e.gpsMinDistance!==void 0&&(this.#n=e.gpsMinDistance),e.gpsMinAccuracy!==void 0&&(this.#r=e.gpsMinAccuracy)}async startGps(){if(this.#c){let e=await(await this.#c.sendData(`/gps/start`,{gpsMinDistance:this.#n,gpsMinAccuracy:this.#r})).json();this.#s=e.session}return this.#i===null?(this.#i=navigator.geolocation.watchPosition(e=>{this.#f(e)},e=>{this.emit(`gpserror`,e)},{enableHighAccuracy:!0}),!0):!1}stopGps(){return this.#i===null?!1:(navigator.geolocation.clearWatch(this.#i),this.#i=null,!0)}fakeGps(e,t,n=null,r=0){n!==null&&this.setElevation(n),this.#f({coords:{longitude:e,latitude:t,accuracy:r}})}lonLatToWorldCoords(e,t){let n=this.#e.project(e,t);return this.eastNorthToWorldCoords(n)}eastNorthToWorldCoords(e){if(this.#a)e[0]-=this.#a[0],e[1]-=this.#a[1];else throw`No initial position determined`;return[e[0],-e[1]]}add(e,t,n,r,i={}){e.properties=i,this.#u(e,t,n,r||0),this.scene.add(e),this.#c?.sendData(`/object/new`,{position:e.position,x:e.position.x,z:e.position.z,session:this.#s,properties:i})}addGeoLine(e,n,r=1){let i=this.createGeoLine(e,r);n.setValues({side:t.DoubleSide});let a=new t.Mesh(i,n);return this.scene.add(a),a}createGeoLine(e,n=1){let r=e.map((e=>{let[n,r]=this.lonLatToWorldCoords(e[0],e[1]);return new t.Vector3(n,e[2]||0,r)}));return this.#l(r,n)}#l(e,n){let r,i,a,o,s=0,c=0,l=[],u,d=e.length-1,f=[];for(let t=0;t<d;t++)r=e[t+1].x-e[t].x,i=e[t+1].z-e[t].z,a=e[t+1].y-e[t].y,o=Math.sqrt(r*r+a*a+i*i),s=-(n/2*i)/o,c=n/2*r/o,u=[e[t].x-s,e[t].y,e[t].z-c,e[t].x+s,e[t].y,e[t].z+c],t>0&&u.forEach((e,t)=>{e=(e+l[t])/2}),f.push(...u),l=[e[t+1].x-s,e[t+1].y,e[t+1].z-c,e[t+1].x+s,e[t+1].y,e[t+1].z+c];f.push(e[d].x-s),f.push(e[d].y),f.push(e[d].z-c),f.push(e[d].x+s),f.push(e[d].y),f.push(e[d].z+c);let p=[];for(let e=0;e<d;e++)p.push(e*2,e*2+1,e*2+2),p.push(e*2+1,e*2+3,e*2+2);let m=new t.BufferGeometry,h=new Float32Array(f);return m.setIndex(p),m.setAttribute(`position`,new t.BufferAttribute(h,3)),m.computeBoundingBox(),m}#u(e,t,n,r){let i=this.lonLatToWorldCoords(t,n);r!==void 0&&(e.position.y=r),[e.position.x,e.position.z]=i}setElevation(e){this.camera.position.y=e}#d(e,t){this.#a=this.#e.project(e,t)}#f(t){let n=Number.MAX_VALUE;this.#o++,this.#c?.sendData(`/gps/new`,{gpsCount:this.#o,lat:t.coords.latitude,lon:t.coords.longitude,acc:t.coords.accuracy,session:this.#s}),t.coords.accuracy<=this.#r&&(this.#t===null?this.#t={latitude:t.coords.latitude,longitude:t.coords.longitude}:n=e.haversineDist(this.#t,t.coords),n>=this.#n&&(this.#t.longitude=t.coords.longitude,this.#t.latitude=t.coords.latitude,this.#a||(this.#d(t.coords.longitude,t.coords.latitude),this.#c?.sendData(`/worldorigin/new`,{gpsCount:this.#o,lat:t.coords.latitude,lon:t.coords.longitude,session:this.#s,initialPosition:this.#a})),this.#u(this.camera,t.coords.longitude,t.coords.latitude),this.#c?.sendData(`/gps/accepted`,{gpsCount:this.#o,cameraX:this.camera.position.x,cameraZ:this.camera.position.z,session:this.#s,distMoved:n}),this.emit(`gpsupdate`,{position:t,distMoved:n})))}static haversineDist(e,n){let r=t.MathUtils.degToRad(n.longitude-e.longitude),i=t.MathUtils.degToRad(n.latitude-e.latitude),a=Math.sin(i/2)*Math.sin(i/2)+Math.cos(t.MathUtils.degToRad(e.latitude))*Math.cos(t.MathUtils.degToRad(n.latitude))*(Math.sin(r/2)*Math.sin(r/2));return 2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a))*6371e3}getLastKnownLocation(){return this.#t}},p=`locar-device-orientation-permission-modal`,m=`locar-device-orientation-permission-button`,h=`locar-device-orientation-permission-message`,g=`locar-device-orientation-permission-inner`,_=`locar-device-orientation-permission-button-inner`,v=`This immersive website requires access to your device motion sensors.`,y=navigator.userAgent.match(/iPhone|iPad|iPod/i)||/Macintosh/i.test(navigator.userAgent)&&navigator.maxTouchPoints!=null&&navigator.maxTouchPoints>1,b=new t.Vector3(0,0,1),x=new t.Euler,S=new t.Quaternion,C=new t.Quaternion(-Math.sqrt(.5),0,0,Math.sqrt(.5));2*Math.PI;var w=.5*Math.PI,T=class extends t.EventDispatcher{constructor(e,n={}){super(),this.init=()=>{window.DeviceOrientationEvent===void 0?this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_NOT_SUPPORTED`,message:`Device orientation API not supported`}):window.isSecureContext===!1?this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_NO_HTTPS`,message:`DeviceOrientationEvent is only available in secure contexts (https)`}):typeof window.DeviceOrientationEvent.requestPermission==`function`&&this.enablePermissionDialog?this.obtainPermissionGesture():this.eventEmitter.emit(`deviceorientationgranted`,{target:this})},this.eventEmitter=new l;let r=this;this.object=e,this.object.rotation.reorder(`YXZ`),this.enabled=!0,this.deviceOrientation=null,this.screenOrientation=0,this.alphaOffset=0,this.orientationOffset=0,this.initialOffset=null,this.lastQuaternion=null,this.orientationChangeEventName=`ondeviceorientationabsolute`in window?`deviceorientationabsolute`:`deviceorientation`,this.smoothingFactor=n.smoothingFactor||.2,this.enablePermissionDialog=n.enablePermissionDialog??!0,this.enableInlineStyling=n.enableStyling??!0,this.preferConfirmDialog=n.preferConfirmDialog??!1,this.orientationChangeThreshold=n.orientationChangeThreshold??0;let i=n=>{let{alpha:i,beta:a,gamma:o,webkitCompassHeading:s}=n;if(i??=0,a??=0,o??=0,s??=0,y){let e=360-s;r.alphaOffset=t.MathUtils.degToRad(e-i),r.deviceOrientation={alpha:i,beta:a,gamma:o,webkitCompassHeading:s}}else i<0&&(i+=360),r.deviceOrientation={alpha:i,beta:a,gamma:o};window.dispatchEvent(new CustomEvent(`camera-rotation-change`,{detail:{cameraRotation:e.rotation}}))},a=()=>{r.screenOrientation=window.screen.orientation?.angle??0,y&&(r.screenOrientation===90?r.orientationOffset=-w:r.screenOrientation===-90?r.orientationOffset=w:r.orientationOffset=0)},o=(e,t,n,r,i)=>{x.set(n,t,-r,`YXZ`),e.setFromEuler(x),e.multiply(C),e.multiply(S.setFromAxisAngle(b,-i))};this.connect=()=>{a(),window.addEventListener(`orientationchange`,a),window.addEventListener(r.orientationChangeEventName,i),r.enabled=!0},this.disconnect=()=>{window.removeEventListener(`orientationchange`,a),window.removeEventListener(r.orientationChangeEventName,i),r.enabled=!1,r.initialOffset=!1,r.deviceOrientation=null,r.lastQuaternion=null},this.requestOrientationPermissions=()=>{window.DeviceOrientationEvent!==void 0&&typeof window.DeviceOrientationEvent.requestPermission==`function`?window.DeviceOrientationEvent.requestPermission().then(e=>{e===`granted`?this.eventEmitter.emit(`deviceorientationgranted`,{target:this}):this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_PERMISSION_DENIED`,message:`Permission for device orientation denied - AR will not work correctly`})}).catch(e=>{this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_PERMISSION_FAILED`,message:`Permission request for device orientation failed - AR will not work correctly`,error:JSON.stringify(e,null,2)})}):this.eventEmitter.emit(`deviceorientationerror`,{code:`LOCAR_DEVICE_ORIENTATION_INTERNAL_ERROR`,message:`Internal error: no requestPermission() found although requestOrientationPermissions() was called - please raise an issue on GitHub`})},this.update=()=>{if(r.enabled===!1)return;let e=r.deviceOrientation;if(e){let n=e.alpha?t.MathUtils.degToRad(e.alpha)+r.alphaOffset:0,i=e.beta?t.MathUtils.degToRad(e.beta):0,a=e.gamma?t.MathUtils.degToRad(e.gamma):0,s=r.screenOrientation?t.MathUtils.degToRad(r.screenOrientation):0,c=new t.Quaternion;if(y){o(c,n,i,a,s);let l=new t.Euler().setFromQuaternion(c,`YXZ`);l.y=t.MathUtils.degToRad(360-(e.webkitCompassHeading??0))+(r.orientationOffset||0),c.setFromEuler(l)}else o(c,n,i,a,s);if(r.lastQuaternion&&r.orientationChangeThreshold>0&&c.angleTo(r.lastQuaternion)<r.orientationChangeThreshold)return;if(r.smoothingFactor<1&&r.lastQuaternion){let e=1-r.smoothingFactor;r.object.quaternion.slerp(c,e)}else r.object.quaternion.copy(c);r.lastQuaternion=r.object.quaternion.clone(),window.dispatchEvent(new CustomEvent(`camera-rotation-change`,{detail:{cameraRotation:r.object.rotation}}))}},this.getCorrectedHeading=()=>{let{deviceOrientation:e}=r;if(!e)return 0;let t=0;return y?(t=360-(e.webkitCompassHeading??0),r.orientationOffset&&(t+=r.orientationOffset*(180/Math.PI),t=(t+360)%360)):(e.absolute===!0||r.orientationChangeEventName,t=e.alpha?e.alpha:0,t=(360-t)%360,t<0&&(t+=360)),t},this.updateAlphaOffset=()=>{r.initialOffset=!1},this.dispose=()=>{r.disconnect()},this.getAlpha=()=>{let{deviceOrientation:e}=r;return e&&e.alpha?t.MathUtils.degToRad(e.alpha)+r.alphaOffset:0},this.getBeta=()=>{let{deviceOrientation:e}=r;return e&&e.beta?t.MathUtils.degToRad(e.beta):0},this.getGamma=()=>{let{deviceOrientation:e}=r;return e&&e.gamma?t.MathUtils.degToRad(e.gamma):0},this.createObtainPermissionGestureDialog=()=>{let e=document.createElement(`div`);e.classList.add(p);let t=document.createElement(`div`);t.classList.add(g);let n=document.createElement(`div`);n.classList.add(h);let r=document.createElement(`div`);r.classList.add(_);let i=document.createElement(`button`);i.classList.add(m),document.body.appendChild(e),this.enableInlineStyling===!0&&(e.style.fontFamily=`-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'`,e.style.display=`flex`,e.style.position=`fixed`,e.style.zIndex=`100000`,e.style.justifyContent=`center`,e.style.alignItems=`center`,e.style.backgroundColor=`rgba(0,0,0,0.2)`,e.style.inset=`0`,e.style.padding=`20px`,t.style.backgroundColor=`rgba(220, 220, 220, 0.85)`,t.style.padding=`6px 0`,t.style.borderRadius=`10px`,t.style.width=`100%`,t.style.maxWidth=`400px`,n.style.padding=`10px 12px`,n.style.textAlign=`center`,n.style.fontWeight=`400`,n.style.fontSize=`13px`,n.style.display=`flex`,n.style.justifyContent=`center`,n.style.alignItems=`center`,r.style.display=`block`,r.style.textAlign=`center`,r.style.textDecoration=`none`,r.style.borderTop=`rgb(180,180,180) solid 1px`,i.style.display=`block`,i.style.width=`100%`,i.style.textAlign=`center`,i.style.appearance=`none`,i.style.background=`none`,i.style.border=`none`,i.style.outline=`none`,i.style.padding=`10px`,i.style.fontWeight=`400`,i.style.fontSize=`16px`,i.style.color=`#2e7cf1`,i.style.cursor=`pointer`),e.appendChild(t),t.appendChild(n),t.appendChild(r),n.appendChild(document.createTextNode(v)),i.addEventListener(`click`,()=>{this.requestOrientationPermissions(),e.style.display=`none`}),i.appendChild(document.createTextNode(`OK`)),r.appendChild(i),document.body.appendChild(e)},this.obtainPermissionGesture=()=>{this.preferConfirmDialog===!0?window.confirm(v)&&this.requestOrientationPermissions():this.createObtainPermissionGestureDialog()}}on(e,t){this.eventEmitter.on(e,t)}},E=class{constructor(e){this.raycaster=new t.Raycaster,this.normalisedMousePosition=null,e.domElement.addEventListener(`click`,n=>{let r=e.domElement.getBoundingClientRect();this.normalisedMousePosition=new t.Vector2((n.clientX-r.left)/e.domElement.clientWidth*2-1,-((n.clientY-r.top)/e.domElement.clientHeight*2)+1)})}raycast(e,t){if(this.normalisedMousePosition!==null){this.raycaster.setFromCamera(this.normalisedMousePosition,e);let n=this.raycaster.intersectObjects(t.children,!0);return this.normalisedMousePosition=null,n}return[]}},D=class extends l{#e;#t;constructor(e={video:{facingMode:`environment`}},n){super(),this.sceneWebcam=new t.Scene,n?this.#e=document.querySelector(n):(this.#e=document.createElement(`video`),this.#e.setAttribute(`autoplay`,`true`),this.#e.setAttribute(`playsinline`,`true`),this.#e.style.cssText+=`
|
|
2
2
|
width: 100%;
|
|
3
3
|
height: 100%;
|
|
4
4
|
object-fit: cover;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "locar",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Location-based AR from AR.js.",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"vite-plugin-dts": "^4.5.4"
|
|
38
38
|
},
|
|
39
39
|
"overrides": {
|
|
40
|
-
"brace-expansion" : "^5.0.
|
|
40
|
+
"brace-expansion" : "^5.0.9"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"three": "^0.181.0"
|