Skip to content

Commit

Permalink
Add click handler and two more examples
Browse files Browse the repository at this point in the history
  • Loading branch information
nickw1 committed Nov 3, 2024
1 parent 44e22fa commit 3a5a99d
Show file tree
Hide file tree
Showing 21 changed files with 410 additions and 177 deletions.
4 changes: 2 additions & 2 deletions docs/01-helloworld/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<html>
<head>
<title>three.js</title>
<script type="module" crossorigin src="/locar.js/assets/01-helloworld-B_XJysGc.js"></script>
<link rel="modulepreload" crossorigin href="/locar.js/assets/locar.es-K2XRG_mr.js">
<script type="module" crossorigin src="/locar.js/assets/01-helloworld-BK54cGeW.js"></script>
<link rel="modulepreload" crossorigin href="/locar.js/assets/locar.es-D2pHxP8J.js">
</head>
<body>
</body>
Expand Down
4 changes: 2 additions & 2 deletions docs/02-gps-and-sensors/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<html>
<head>
<title>three.js</title>
<script type="module" crossorigin src="/locar.js/assets/02-gps-and-sensors-Bz5hD0d7.js"></script>
<link rel="modulepreload" crossorigin href="/locar.js/assets/locar.es-K2XRG_mr.js">
<script type="module" crossorigin src="/locar.js/assets/02-gps-and-sensors-La4_GML4.js"></script>
<link rel="modulepreload" crossorigin href="/locar.js/assets/locar.es-D2pHxP8J.js">
</head>
<body>
</body>
Expand Down
10 changes: 10 additions & 0 deletions docs/03-ar-objects/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>three.js</title>
<script type="module" crossorigin src="/locar.js/assets/03-ar-objects-D3M74PcG.js"></script>
<link rel="modulepreload" crossorigin href="/locar.js/assets/locar.es-D2pHxP8J.js">
</head>
<body>
</body>
</html>
10 changes: 10 additions & 0 deletions docs/04-api-communication/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>three.js</title>
<script type="module" crossorigin src="/locar.js/assets/04-api-communication-B3laukjY.js"></script>
<link rel="modulepreload" crossorigin href="/locar.js/assets/locar.es-D2pHxP8J.js">
</head>
<body>
</body>
</html>

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

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

1 change: 1 addition & 0 deletions docs/assets/03-ar-objects-D3M74PcG.js

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

1 change: 1 addition & 0 deletions docs/assets/04-api-communication-B3laukjY.js

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

332 changes: 166 additions & 166 deletions docs/assets/locar.es-K2XRG_mr.js → docs/assets/locar.es-D2pHxP8J.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ <h1>LocAR.js examples</h1>
<ol>
<li><a href='01-helloworld/index.html'>Hello World</a>: Display a red cube just to the north of a fake GPS location. Can be tested on a desktop or laptop.</li>
<li><a href='02-gps-and-sensors/index.html'>GPS and Sensors</a>: Requires a mobile device wih GPS and sensors. Demonstrates use of the GPS and the device sensors to show real AR. Gets your initial location and displays four coloured boxes to the north (red), south (yellow), west (blue) and east (green) of your initial location. Can be used as a test to check whether your device sensors are accurate; if the red box does not appear to the North, your device sensors may be mis-calibrated.</li>
<li><a href='03-ar-objects/index.html'>AR Objects</a>: shows how you can add real AR objects with a given latitude and longitude and properties. Also shows how you can detect clicks on objects. Uses a hard-coded "fake" location and hard-coded objects, and you can rotate the three.js camera using the mouse, so will work on a desktop or laptop.</li>
</ol>
</body>
</html>
9 changes: 9 additions & 0 deletions examples/03-ar-objects/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>three.js</title>
<script type='module' src='src/main.js'></script>
</head>
<body>
</body>
</html>
92 changes: 92 additions & 0 deletions examples/03-ar-objects/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as THREE from 'three';
import * as LocAR from 'locar';

const camera = new THREE.PerspectiveCamera(80, window.innerWidth/window.innerHeight, 0.001, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
const scene = new THREE.Scene();


document.body.appendChild(renderer.domElement);


window.addEventListener("resize", e => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});

const locar = new LocAR.LocationBased(scene, camera);

const cam = new LocAR.WebcamRenderer(renderer);


let firstPosition = true;
const oneDegAsRad = THREE.MathUtils.degToRad(1.0);

const indexedObjects = { };

const cube = new THREE.BoxGeometry(20, 20, 20);

let mouseDown = false, initX;
let curRotation = 0.0;

const clickHandler = new LocAR.ClickHandler(renderer);

renderer.domElement.addEventListener("mousedown", e=> {
mouseDown = true;
initX = e.clientX;
});

renderer.domElement.addEventListener("mousemove", e=> {
if(mouseDown) {
curRotation += e.clientX > initX ? oneDegAsRad*10: -oneDegAsRad*10;
if(curRotation > Math.PI) {
curRotation -= 2*Math.PI;
} else if(curRotation < -Math.PI) {
curRotation += 2*Math.PI;
}
camera.rotation.set(0, curRotation, 0);
}
});

renderer.domElement.addEventListener("mouseup", e=> {
mouseDown = false;

});

locar.on("gpsupdate", async(pos, distMoved) => {

// Even if you have static AR objects, as opposed to objects from an
// API, you must wait until the first GPS update before adding the
// objects. This is because the internal x, y and z coordinates of each
// object are relative to the initial position, and if we do not yet
// have a GPS position, the initial position will be unknown.
if(firstPosition) {
firstPosition = false;
const guildhall = new THREE.Mesh(
cube,
new THREE.MeshBasicMaterial({color: 0x00ffff})
);
const oneills = new THREE.Mesh(
cube,
new THREE.MeshBasicMaterial({color: 0xff0000})
);

locar.add(guildhall, -1.406392, 50.908042, 0, { "name": "Guildhall"} );
locar.add(oneills, -1.404340, 50.907330, 0, { "name": "O'Neills"} );
}

});
locar.fakeGps(-1.404555, 50.908015);

renderer.setAnimationLoop(animate);

function animate() {
cam.update();
const objects = clickHandler.raycast(camera, scene);
if(objects.length) {
alert(`This is ${objects[0].object.properties.name}`);
}
renderer.render(scene, camera);
}
9 changes: 9 additions & 0 deletions examples/04-api-communication/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>three.js</title>
<script type='module' src='src/main.js'></script>
</head>
<body>
</body>
</html>
68 changes: 68 additions & 0 deletions examples/04-api-communication/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as THREE from 'three';
import * as LocAR from 'locar';

const camera = new THREE.PerspectiveCamera(80, window.innerWidth/window.innerHeight, 0.001, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
const scene = new THREE.Scene();


document.body.appendChild(renderer.domElement);


window.addEventListener("resize", e => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});

const locar = new LocAR.LocationBased(scene, camera);

const deviceControls = new LocAR.DeviceOrientationControls(camera);

const cam = new LocAR.WebcamRenderer(renderer);


let firstPosition = true;

const indexedObjects = { };

const cube = new THREE.BoxGeometry(20, 20, 20);

const clickHandler = new LocAR.ClickHandler(renderer);

locar.on("gpsupdate", async(pos, distMoved) => {

if(firstPosition || distMoved > 100) {

const response = await fetch(`https://hikar.org/webapp/map?bbox=${pos.coords.longitude-0.02},${pos.coords.latitude-0.02},${pos.coords.longitude+0.02},${pos.coords.latitude+0.02}&layers=poi&outProj=4326`);
const pois = await response.json();

pois.features.forEach ( poi => {
if(!indexedObjects[poi.properties.osm_id]) {
const mesh = new THREE.Mesh(
cube,
new THREE.MeshBasicMaterial({color: 0xff0000})
);

locar.add(mesh, poi.geometry.coordinates[0], poi.geometry.coordinates[1], 0, poi.properties);
indexedObjects[poi.osm_id] = mesh;
}
});
firstPosition = false;
}

});
locar.startGps();

renderer.setAnimationLoop(animate);

function animate() {
cam.update();
deviceControls.update();
const objects = clickHandler.raycast(scene, camera);
if(objects.length) {
alert(`This is ${objects[0].object.properties.name}`);
}
renderer.render(scene, camera);
}
1 change: 1 addition & 0 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ <h1>LocAR.js examples</h1>
<ol>
<li><a href='01-helloworld/index.html'>Hello World</a>: Display a red cube just to the north of a fake GPS location. Can be tested on a desktop or laptop.</li>
<li><a href='02-gps-and-sensors/index.html'>GPS and Sensors</a>: Requires a mobile device wih GPS and sensors. Demonstrates use of the GPS and the device sensors to show real AR. Gets your initial location and displays four coloured boxes to the north (red), south (yellow), west (blue) and east (green) of your initial location. Can be used as a test to check whether your device sensors are accurate; if the red box does not appear to the North, your device sensors may be mis-calibrated.</li>
<li><a href='03-ar-objects/index.html'>AR Objects</a>: shows how you can add real AR objects with a given latitude and longitude and properties. Also shows how you can detect clicks on objects. Uses a hard-coded "fake" location and hard-coded objects, and you can rotate the three.js camera using the mouse, so will work on a desktop or laptop.</li>
</ol>
</body>
</html>
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": {
"three": "^0.169.0",
"locar": "file:../locar-0.0.1.tgz"
"locar": "file:../locar-0.0.2.tgz"
},
"devDependencies": {
"vite": "^5.4.8"
Expand Down
2 changes: 1 addition & 1 deletion examples/vite.config.js → examples/vite.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { defineConfig } from 'vite';
import { resolve } from 'path';

const entries = { main: 'index.html' };
['01-helloworld', '02-gps-and-sensors'].forEach ( example => {
['01-helloworld', '02-gps-and-sensors', '03-ar-objects', '04-api-communication'].forEach ( example => {
entries[example] = resolve(__dirname, `${example}/index.html`);
});

Expand Down
3 changes: 2 additions & 1 deletion lib/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LocationBased } from "./src/location-based.js";
import { WebcamRenderer } from "./src/webcam-renderer.js";
import { DeviceOrientationControls } from "./src/device-orientation-controls.js";
import { ClickHandler } from './src/click-handler.js';

export { LocationBased, WebcamRenderer, DeviceOrientationControls };
export { LocationBased, WebcamRenderer, DeviceOrientationControls, ClickHandler };
28 changes: 28 additions & 0 deletions lib/src/click-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as THREE from 'three';

class ClickHandler {

constructor(renderer) {
this.raycaster = new THREE.Raycaster();
this.normalisedMousePosition = new THREE.Vector2(null, null);
renderer.domElement.addEventListener("click", e => {
this.normalisedMousePosition.set (
((e.clientX / renderer.domElement.clientWidth) * 2) - 1,
-((e.clientY / renderer.domElement.clientHeight) * 2) + 1
);
});
}


raycast(camera, scene) {
if(this.normalisedMousePosition.x !== null && this.normalisedMousePosition.y !== null) {
this.raycaster.setFromCamera(this.normalisedMousePosition, camera);
const objects = this.raycaster.intersectObjects(scene.children, false);
this.normalisedMousePosition.set(null, null);
return objects;
}
return [];
}
}

export { ClickHandler };
4 changes: 3 additions & 1 deletion lib/src/location-based.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SphMercProjection } from "./sphmerc-projection.js";
import * as THREE from "three";


class LocationBased {
constructor(scene, camera, options = {}) {
this._scene = scene;
Expand Down Expand Up @@ -84,7 +85,8 @@ class LocationBased {
return [projectedPos[0], -projectedPos[1]];
}

add(object, lon, lat, elev) {
add(object, lon, lat, elev, properties = { }) {
object.properties = properties;
this.setWorldPosition(object, lon, lat, elev);
this._scene.add(object);
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "locar",
"version": "0.0.1",
"version": "0.0.2",
"description": "Location-based AR from AR.js.",
"files": [
"dist"
Expand Down

0 comments on commit 3a5a99d

Please sign in to comment.