-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #406 from AR-js-org/new-aframe-location-based
New A-Frame location based
- Loading branch information
Showing
15 changed files
with
359 additions
and
4 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 } ); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
aframe/src/new-location-based/arjs-device-orientation-controls.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] | ||
); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"; |
Oops, something went wrong.