Skip to content

Commit

Permalink
Merge pull request #406 from AR-js-org/new-aframe-location-based
Browse files Browse the repository at this point in the history
New A-Frame location based
  • Loading branch information
nickw1 authored Apr 17, 2022
2 parents 3fdc52a + 25a4b40 commit 867be54
Show file tree
Hide file tree
Showing 15 changed files with 359 additions and 4 deletions.
1 change: 1 addition & 0 deletions aframe/build/aframe-ar-new-location-only.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion aframe/build/aframe-ar-nft.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion aframe/build/aframe-ar.js

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions aframe/examples/new-location-based/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<title>AR.js A-Frame</title>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<!-- Assumes AR.js build is in the 'AR.js' directory -->
<script type='text/javascript' src='../../../three.js/build/ar-threex-location-only.js'></script>
<script type='text/javascript' src='../../build/aframe-ar.js'></script>
<script src='index.js'></script>
</head>
<body>
<a-scene vr-mode-ui='enabled: false' arjs='sourceType: webcam; videoTexture: true; debugUIEnabled: false' renderer='antialias: true; alpha: true'>
<!--
<a-camera gps-new-camera='gpsMinDistance: 5' look-controls-enabled='false' arjs-device-orientation-controls></a-camera>
-->
<a-camera gps-new-camera='gpsMinDistance: 5'></a-camera>
</a-scene>
<div id='setloc' style='position:absolute; left: 10px; bottom: 2%; z-index:999; background-color: blue; color: white; padding: 10px'>
Lat:<input id="lat" value="51.049" />
Lon: <input id="lon" value="-0.723"/>
Min Acc: <input id='minacc' value='1000' /> <input type='button' id='go' value='go' />
</div>
</body>
</html>
54 changes: 54 additions & 0 deletions aframe/examples/new-location-based/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
window.onload = () => {
let testEntitiesAdded = false;
alert('If testing the lat/lon manual input on a mobile device, please turn off your GPS to avoid the real location being detected.');
const el = document.querySelector("[gps-new-camera]");
el.addEventListener("gps-camera-update-position", e => {
if(!testEntitiesAdded) {
alert(`Got first GPS position: lon ${e.detail.position.longitude} lat ${e.detail.position.latitude}`);
// Add four boxes to the north (red), south (yellow), west (blue)
// and east (red) of the initial GPS position
const properties = [{
color: 'red',
latDis: 0.001,
lonDis: 0
},{
color: 'yellow',
latDis: -0.001,
lonDis: 0
},{
color: 'blue',
latDis: 0,
lonDis: -0.001
},{
color: 'green',
latDis: 0,
lonDis: 0.001
}
];
for(const prop of properties) {
const entity = document.createElement("a-box");
entity.setAttribute("scale", {
x: 20,
y: 20,
z: 20
});
entity.setAttribute('material', { color: prop.color } );
entity.setAttribute('gps-new-entity-place', {
latitude: e.detail.position.latitude + prop.latDis,
longitude: e.detail.position.longitude + prop.lonDis
});

document.querySelector("a-scene").appendChild(entity);
}
testEntitiesAdded = true;
}
});

document.getElementById("go").addEventListener("click", e=> {
const lat = document.getElementById('lat').value;
const lon = document.getElementById('lon').value;
const minacc = document.getElementById('minacc').value;

el.setAttribute('gps-new-camera', { simulateLatitude: lat, simulateLongitude: lon, positionMinAccuracy: minacc } );
});
};
3 changes: 3 additions & 0 deletions aframe/src/index-nft.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import "./location-based/gps-camera";
import "./location-based/gps-entity-place";
import "./location-based/gps-projected-camera";
import "./location-based/gps-projected-entity-place";
import "./new-location-based/gps-new-camera";
import "./new-location-based/gps-new-entity-place";
import "./new-location-based/arjs-device-orientation-controls";

// System
import "./system-arjs-nft";
3 changes: 3 additions & 0 deletions aframe/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import "./location-based/gps-camera";
import "./location-based/gps-entity-place";
import "./location-based/gps-projected-camera";
import "./location-based/gps-projected-entity-place";
import "./new-location-based/gps-new-camera";
import "./new-location-based/gps-new-entity-place";
import "./new-location-based/arjs-device-orientation-controls";

// System
import "./system-arjs";
36 changes: 36 additions & 0 deletions aframe/src/new-location-based/arjs-device-orientation-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* arjs-device-orientation-controls
*
* Replaces the standard look-controls component to provide mobile device
* orientation controls.
*
* A lightweight A-Frame wrapper round the modified three.js
* DeviceOrientationControls used in the three.js location-based API.
*
* Creates the THREE object using using the three.js camera, and allows update
* of the smoothing factor.
*/

import * as AFRAME from "aframe";
AFRAME.registerComponent("arjs-device-orientation-controls", {
schema: {
smoothingFactor: {
type: "number",
default: 1,
},
},

init: function () {
this._orientationControls = new THREEx.DeviceOrientationControls(
this.el.object3D
);
},

update: function () {
this._orientationControls.smoothingFactor = this.data.smoothingFactor;
},

tick: function () {
this._orientationControls.update();
},
});
174 changes: 174 additions & 0 deletions aframe/src/new-location-based/gps-new-camera.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import * as AFRAME from "aframe";

AFRAME.registerComponent("gps-new-camera", {
schema: {
simulateLatitude: {
type: "number",
default: 0,
},
simulateLongitude: {
type: "number",
default: 0,
},
simulateAltitude: {
type: "number",
default: -Number.MAX_VALUE,
},
gpsMinDistance: {
type: "number",
default: 0,
},
positionMinAccuracy: {
type: "number",
default: 1000,
},
},

init: function () {
this._testForOrientationControls();

this.threeLoc = new THREEx.LocationBased(
this.el.sceneEl.object3D,
this.el.object3D
);

this.threeLoc.on("gpsupdate", (gpspos) => {
this._sendGpsUpdateEvent(gpspos.coords.longitude, gpspos.coords.latitude);
});

this.threeLoc.on("gpserror", (code) => {
const msg = [
"User denied access to GPS.",
"GPS satellites not available.",
"Timeout communicating with GPS satellites - try moving to a more open area.",
];
if (code >= 1 && code <= 3) {
this._displayError(msg[code - 1]);
} else {
this._displayError(`Unknown geolocation error code ${code}.`);
}
});

// Use arjs-device-orientation-controls on mobile only, with standard
// look-controls disabled (this interferes with the readings from the
// sensors). On desktop, use standard look-controls instead.

const mobile = this._isMobile();
this.el.setAttribute("look-controls-enabled", !mobile);
if (mobile) {
this.el.setAttribute("arjs-device-orientation-controls", true);
}

// from original gps-camera component
// if Safari
if (!!navigator.userAgent.match(/Version\/[\d.]+.*Safari/)) {
this._setupSafariOrientationPermissions();
}
},

update: function (oldData) {
this.threeLoc.setGpsOptions({
gpsMinAccuracy: this.data.positionMinAccuracy,
gpsMinDistance: this.data.gpsMinDistance,
});
if (
(this.data.simulateLatitude !== 0 || this.data.simulateLongitude !== 0) &&
(this.data.simulateLatitude != oldData.simulateLatitude ||
this.data.simulateLongitude != oldData.simulateLongitude)
) {
this.threeLoc.fakeGps(
this.data.simulateLongitude,
this.data.simulateLatitude
);
this.data.simulateLatitude = 0;
this.data.simulateLongitude = 0;
}
if (this.data.simulateAltitude > -Number.MAX_VALUE) {
this.threeLoc.setElevation(this.data.simulateAltitude + 1.6);
}
},

play: function () {
if (this.data.simulateLatitude === 0 && this.data.simulateLongitude === 0) {
this.threeLoc.startGps();
}
},

pause: function () {
this.threeLoc.stopGps();
},

_sendGpsUpdateEvent: function (lon, lat) {
this.el.emit("gps-camera-update-position", {
position: {
longitude: lon,
latitude: lat,
},
});
},

_testForOrientationControls: function () {
const msg =
"WARNING - No orientation controls component, app will not respond to device rotation.";
if (
!this.el.components["arjs-device-orientation-controls"] &&
!this.el.components["look-controls"]
) {
this._displayError(msg);
}
},

_displayError: function (error) {
const arjs = this.el.sceneEl.systems["arjs"];
if (arjs) {
arjs._displayErrorPopup(msg);
} else {
alert(msg);
}
},

// from original gps-camera component
_setupSafariOrientationPermissions: function () {
// iOS 13+
if (typeof DeviceOrientationEvent.requestPermission === "function") {
var handler = function () {
console.log("Requesting device orientation permissions...");
DeviceOrientationEvent.requestPermission();
document.removeEventListener("touchend", handler);
};

document.addEventListener(
"touchend",
function () {
handler();
},
false
);

this.el.sceneEl.systems["arjs"]._displayErrorPopup(
"After camera permission prompt, please tap the screen to activate geolocation."
);
} else {
var timeout = setTimeout(function () {
this.el.sceneEl.systems["arjs"]._displayErrorPopup(
"Please enable device orientation in Settings > Safari > Motion & Orientation Access."
);
}, 750);
window.addEventListener(eventName, function () {
clearTimeout(timeout);
});
}
},

_isMobile: function () {
if (
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
)
) {
// true for mobile device
return true;
}
return false;
},
});
35 changes: 35 additions & 0 deletions aframe/src/new-location-based/gps-new-entity-place.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as AFRAME from "aframe";

AFRAME.registerComponent("gps-new-entity-place", {
schema: {
longitude: {
type: "number",
default: 0,
},
latitude: {
type: "number",
default: 0,
},
},

init: function () {
const camera = document.querySelector("[gps-new-camera]");
if (!camera.components["gps-new-camera"]) {
console.error("gps-new-camera not initialised");
return;
}
this._cameraGps = camera.components["gps-new-camera"];
},

update: function () {
const projCoords = this._cameraGps.threeLoc.lonLatToWorldCoords(
this.data.longitude,
this.data.latitude
);
this.el.object3D.position.set(
projCoords[0],
this.el.object3D.position.y,
projCoords[1]
);
},
});
4 changes: 4 additions & 0 deletions aframe/src/new-location-based/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import "../location-based/arjs-webcam-texture";
import "./gps-new-camera";
import "./gps-new-entity-place";
import "./arjs-device-orientation-controls";
Loading

0 comments on commit 867be54

Please sign in to comment.