Created
February 14, 2023 20:42
-
-
Save miqmago/e1430405b34d384dec5fd393d6ee3ded to your computer and use it in GitHub Desktop.
Threejs + AR in stencil
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
import { Component, h } from '@stencil/core/internal'; | |
import { | |
Scene, | |
PerspectiveCamera, | |
WebGLRenderer, | |
BoxGeometry, | |
MeshBasicMaterial, | |
Mesh, | |
} from 'three'; | |
import * as THREEx from '@ar-js-org/ar.js/three.js/build/ar-threex-location-only.js'; | |
@Component({ | |
tag: 'app-root-threejs', | |
styleUrl: 'app-root-threejs.css', | |
}) | |
export class AppComponentThreeJS { | |
canvas: HTMLCanvasElement; | |
renderer: WebGLRenderer; | |
camera: PerspectiveCamera; | |
webCam: THREEx.WebcamRenderer; | |
scene: Scene; | |
deviceOrientationControls: THREEx.DeviceOrientationControls; | |
arjs: THREEx.LocationBased; | |
componentDidLoad() { | |
this.scene = new Scene(); | |
this.camera = new PerspectiveCamera(60, 1.33, 0.1, 10000); | |
this.renderer = new WebGLRenderer({ canvas: this.canvas }); | |
this.arjs = new THREEx.LocationBased(this.scene, this.camera); | |
this.webCam = new THREEx.WebcamRenderer(this.renderer); | |
const geom = new BoxGeometry(20, 20, 20); | |
const mtl = new MeshBasicMaterial({ color: 0xff0000 }); | |
const box = new Mesh(geom, mtl); | |
// Create the device orientation tracker | |
this.deviceOrientationControls = new THREEx.DeviceOrientationControls(this.camera); | |
this.arjs.on('gpsupdate', async (pos) => { | |
// https://ar-js-org.github.io/AR.js-Docs/location-based-three/part3/ | |
console.log('pos', pos); | |
}); | |
// https://stackoverflow.com/questions/60330263/ar-js-is-it-possible-to-update-the-location-of-a-gps-entity-place | |
if (navigator.geolocation) { | |
navigator.geolocation.getCurrentPosition((position) => { | |
// let gps = document.createAttribute('gps-entity-place'), | |
// this.arjs = document.createAttribute('arjs'); | |
// arjs.value = 'sourceType: webcam; sourceWidth: 1280; sourceHeight: 960; trackingMethod: best; debugUIEnabled: false;'; | |
// gps.value = `latitude: ${position.coords.latitude - 0.001}; longitude: ${position.coords.longitude + 0.001}`; | |
// console.log(gps.value); | |
// https://stackoverflow.com/questions/7477003/calculating-new-longitude-latitude-from-old-n-meters | |
const { longitude, latitude } = position.coords; | |
const earthRadius = 6371000.0; // meters | |
const dx = 15; // meters: > 0 => east; < 0 => west | |
const dy = 0; // meters: > 0 => north; < 0 => south | |
const new_latitude = latitude + (dy / earthRadius) * (180 / Math.PI); | |
const new_longitude = longitude + (dx / earthRadius) * (180 / Math.PI) / Math.cos(latitude * Math.PI / 180); | |
// const new_longitude = longitude + (dx / earthRadius) * (180 / Math.PI) / cos(NEW_LATITUDE * Math.PI/180); | |
console.log(`longitude: ${position.coords.longitude}, latitude: ${position.coords.latitude}`); | |
console.log(`longitude: ${new_longitude}, latitude: ${new_latitude}`); | |
// arjs.add(box, -0.72, 51.051); | |
// longitude: 2.2505232, latitude: 41.452908400000005; | |
this.arjs.add(box, new_longitude, new_latitude); | |
// Longitude, latitude | |
// Change this to a location 0.001 degrees of latitude north of you, so that you will face it | |
// arjs.fakeGps(-0.72, 51.05); | |
// Start the GPS | |
this.arjs.startGps(); | |
// scene.setAttributeNode(gps); /* Apply to whole scene */ | |
// scene.setAttributeNode(arjs); | |
}); | |
} | |
requestAnimationFrame(this.animationFrameCb.bind(this)); | |
} | |
animationFrameCb() { | |
if (this.canvas && (this.canvas.width != this.canvas.clientWidth || this.canvas.height != this.canvas.clientHeight)) { | |
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight, false); | |
const aspect = this.canvas.clientWidth / this.canvas.clientHeight; | |
this.camera.aspect = aspect; | |
this.camera.updateProjectionMatrix(); | |
} | |
try { | |
// Update the scene using the latest sensor readings | |
this.deviceOrientationControls.update(); | |
} catch (e) { | |
// console.log(e); | |
} | |
this.webCam.update(); | |
this.renderer.render(this.scene, this.camera); | |
requestAnimationFrame(this.animationFrameCb.bind(this)); | |
} | |
render() { | |
return ( | |
<canvas ref={e => (this.canvas = e)} class='webcam-canvas' /> | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment