提交 3ecb176e 编写于 作者: J Jerome Etienne

working on aframe tango

上级 20c4edae
......@@ -10,6 +10,11 @@
- ```arglCameraFrustum(&((arc->paramLT)->param), arc->nearPlane, arc->farPlane, arc->cameraLens);```
- this should be called in setNearPlane
- do test with a special webrtc emulation layer
- so i can download video and/or image - better for testing
- handle pwa stuff - useful for phone
- https://twitter.com/jerome_etienne/status/888008537984708608
# aframe-ar.js new
- there is a resize every 1/60 seconds ??
- test on mobile
......
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
// to keep backward compatibility with deprecated code
// AFRAME.registerComponent('arjs', buildSystemParameter())
// AFRAME.registerComponent('artoolkit', buildSystemParameter())
// function buildSystemParameter(){ return {
// AFRAME.registerSystem('arjs', {
AFRAME.registerSystem('arjs', {
schema: {
trackingBackend : {
type: 'string',
default: 'artoolkit',
},
areaLearningButton : {
type: 'boolean',
default: true,
},
performanceProfile : {
type: 'string',
default: 'default',
},
// old parameters
debug : {
type: 'boolean',
default: false
},
detectionMode : {
type: 'string',
default: '',
},
matrixCodeType : {
type: 'string',
default: '',
},
cameraParametersUrl : {
type: 'string',
default: '',
},
maxDetectionRate : {
type: 'number',
default: -1
},
sourceType : {
type: 'string',
default: '',
},
sourceUrl : {
type: 'string',
default: '',
},
sourceWidth : {
type: 'number',
default: -1
},
sourceHeight : {
type: 'number',
default: -1
},
displayWidth : {
type: 'number',
default: -1
},
displayHeight : {
type: 'number',
default: -1
},
canvasWidth : {
type: 'number',
default: -1
},
canvasHeight : {
type: 'number',
default: -1
},
},
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
init: function () {
var _this = this
// setup artoolkitProfile
var artoolkitProfile = new THREEx.ArToolkitProfile()
artoolkitProfile.sourceWebcam()
artoolkitProfile.trackingBackend(this.data.trackingBackend)
artoolkitProfile.performance(this.data.performanceProfile)
//////////////////////////////////////////////////////////////////////////////
// honor this.data
//////////////////////////////////////////////////////////////////////////////
// honor this.data and push what has been modified into artoolkitProfile
if( this.data.debug !== false ) artoolkitProfile.contextParameters.debug = this.data.debug
if( this.data.detectionMode !== '' ) artoolkitProfile.contextParameters.detectionMode = this.data.detectionMode
if( this.data.matrixCodeType !== '' ) artoolkitProfile.contextParameters.matrixCodeType = this.data.matrixCodeType
if( this.data.cameraParametersUrl !== '' ) artoolkitProfile.contextParameters.cameraParametersUrl = this.data.cameraParametersUrl
if( this.data.maxDetectionRate !== -1 ) artoolkitProfile.contextParameters.maxDetectionRate = this.data.maxDetectionRate
if( this.data.sourceType !== '' ) artoolkitProfile.contextParameters.sourceType = this.data.sourceType
if( this.data.sourceUrl !== '' ) artoolkitProfile.contextParameters.sourceUrl = this.data.sourceUrl
if( this.data.sourceWidth !== -1 ) artoolkitProfile.contextParameters.sourceWidth = this.data.sourceWidth
if( this.data.sourceHeight !== -1 ) artoolkitProfile.contextParameters.sourceHeight = this.data.sourceHeight
if( this.data.displayWidth !== -1 ) artoolkitProfile.contextParameters.displayWidth = this.data.displayWidth
if( this.data.displayHeight !== -1 ) artoolkitProfile.contextParameters.displayHeight = this.data.displayHeight
if( this.data.canvasWidth !== -1 ) artoolkitProfile.contextParameters.canvasWidth = this.data.canvasWidth
if( this.data.canvasHeight !== -1 ) artoolkitProfile.contextParameters.canvasHeight = this.data.canvasHeight
////////////////////////////////////////////////////////////////////////////////
// handle arToolkitSource
////////////////////////////////////////////////////////////////////////////////
var arToolkitSource = new THREEx.ArToolkitSource(artoolkitProfile.sourceParameters)
this.arToolkitSource = arToolkitSource
arToolkitSource.init(function onReady(){
// handle resize of renderer
onResize()
// kludge to write a 'resize' event - use exponentialBackoff delay
var startedAt = Date.now()
var exponentialBackoffDelay = 1000/60
setTimeout(function callback(){
if( Date.now() - startedAt > 5*1000 ) return
// update delay
exponentialBackoffDelay *= 1.2;
exponentialBackoffDelay = Math.min(exponentialBackoffDelay, 1*1000)
setTimeout(callback, exponentialBackoffDelay)
// trigger a resize
window.dispatchEvent(new Event('resize'));
console.log('trigger a resize', exponentialBackoffDelay)
}, exponentialBackoffDelay)
})
// handle resize
window.addEventListener('resize', onResize)
function onResize(){
// ugly kludge to get resize on aframe... not even sure it works
arToolkitSource.onResizeElement()
arToolkitSource.copyElementSizeTo(document.body)
var buttonElement = document.querySelector('.a-enter-vr')
if( buttonElement ){
buttonElement.style.position = 'fixed'
}
}
////////////////////////////////////////////////////////////////////////////////
// initialize arToolkitContext
////////////////////////////////////////////////////////////////////////////////
// create atToolkitContext
var arToolkitContext = new THREEx.ArToolkitContext(artoolkitProfile.contextParameters)
this.arToolkitContext = arToolkitContext
// initialize it
arToolkitContext.init(function onCompleted(){
// // copy projection matrix to camera
// var projectionMatrixArr = arToolkitContext.arController.getCameraMatrix();
// _this.sceneEl.camera.projectionMatrix.fromArray(projprojectionMatrixArrectionMatrix);
})
//////////////////////////////////////////////////////////////////////////////
// area learning
//////////////////////////////////////////////////////////////////////////////
// export function to navigateToLearnerPage
this.navigateToLearnerPage = function(){
var learnerURL = THREEx.ArToolkitContext.baseURL + 'examples/multi-markers/examples/learner.html'
THREEx.ArMultiMarkerUtils.navigateToLearnerPage(learnerURL, _this.data.trackingBackend)
}
// export function to initAreaLearningButton
this.initAreaLearningButton = function(){
// honor arjsSystem.data.areaLearningButton
if( this.data.areaLearningButton === false ) return
// if there is already a button, do nothing
if( document.querySelector('#arjsAreaLearningButton') !== null ) return
// create the img
var imgElement = document.createElement('img')
imgElement.id = 'arjsAreaLearningButton'
imgElement.style.position = 'fixed'
imgElement.style.bottom = '16px'
imgElement.style.left = '16px'
imgElement.style.width = '48px'
imgElement.style.height = '48px'
imgElement.style.zIndex = 1
imgElement.src = THREEx.ArToolkitContext.baseURL + "examples/multi-markers/examples/images/record-start.png"
document.body.appendChild(imgElement)
imgElement.addEventListener('click', function(){
_this.navigateToLearnerPage()
})
}
},
tick : function(now, delta){
if( this.arToolkitSource.ready === false ) return
// copy projection matrix to camera
if( this.arToolkitContext.arController !== null ){
this.el.sceneEl.camera.projectionMatrix.copy( this.arToolkitContext.getProjectionMatrix() );
}
this.arToolkitContext.update( this.arToolkitSource.domElement )
},
})
//////////////////////////////////////////////////////////////////////////////
// arjsmarker
//////////////////////////////////////////////////////////////////////////////
AFRAME.registerComponent('arjsmarker', {
dependencies: ['arjs', 'artoolkit'],
schema: {
preset: {
type: 'string',
},
markerhelpers : { // IIF preset === 'area'
type: 'boolean',
default: false,
},
// controls parameters
size: {
type: 'number',
default: 1
},
type: {
type: 'string',
},
patternUrl: {
type: 'string',
},
barcodeValue: {
type: 'number'
},
changeMatrixMode: {
type: 'string',
default : 'modelViewMatrix',
},
minConfidence: {
type: 'number',
default: 0.6,
},
},
init: function () {
var _this = this
// actually init arMarkerControls
var arjsSystem = this.el.sceneEl.systems.arjs || this.el.sceneEl.systems.artoolkit
var artoolkitContext = arjsSystem.arToolkitContext
var scene = this.el.sceneEl.object3D
// honor this.data.preset
if( this.data.preset === 'hiro' ){
this.data.type = 'pattern'
this.data.patternUrl = THREEx.ArToolkitContext.baseURL+'examples/marker-training/examples/pattern-files/pattern-hiro.patt'
}else if( this.data.preset === 'kanji' ){
this.data.type = 'pattern'
this.data.patternUrl = THREEx.ArToolkitContext.baseURL+'examples/marker-training/examples/pattern-files/pattern-kanji.patt'
}else if( this.data.preset === 'area' ){
this.data.type = 'area'
}else {
console.assert( this.data.preset === '', 'illegal preset value '+this.data.preset)
}
// build a smoothedControls
this._markerRoot = new THREE.Group()
scene.add(this._markerRoot)
this._arMarkerControls = null
this._multiMarkerControls = null
// create the controls
if( this.data.type === 'area' ){
// if no localStorage.ARjsMultiMarkerFile, then write one with default marker
if( localStorage.getItem('ARjsMultiMarkerFile') === null ){
THREEx.ArMultiMarkerUtils.storeDefaultMultiMarkerFile(arjsSystem.data.trackingBackend)
}
// get multiMarkerFile from localStorage
console.assert( localStorage.getItem('ARjsMultiMarkerFile') !== null )
var multiMarkerFile = localStorage.getItem('ARjsMultiMarkerFile')
// create ArMultiMarkerControls
this._multiMarkerControls = THREEx.ArMultiMarkerControls.fromJSON(artoolkitContext, scene, this._markerRoot, multiMarkerFile, {
changeMatrixMode : this.data.changeMatrixMode
})
console.log('this.data.markerhelpers', this.data.markerhelpers)
// display THREEx.ArMarkerHelper if needed - useful to debug
if( this.data.markerhelpers === true ){
this._multiMarkerControls.subMarkersControls.forEach(function(subMarkerControls){
// add an helper to visuable each sub-marker
var markerHelper = new THREEx.ArMarkerHelper(subMarkerControls)
scene.add( markerHelper.object3d )
})
}
}else if( this.data.type === 'pattern' || this.data.type === 'barcode' || this.data.type === 'unknown' ){
this._arMarkerControls = new THREEx.ArMarkerControls(artoolkitContext, this._markerRoot, this.data)
}else console.assert(false)
// build a smoothedControls
this.arSmoothedControls = new THREEx.ArSmoothedControls(this.el.object3D)
// honor arjsSystem.data.areaLearningButton
if( this.data.type === 'area' ) arjsSystem.initAreaLearningButton()
},
remove : function(){
// this._arMarkerControls.dispose()
},
update: function () {
// FIXME this mean to change the recode in trackBarcodeMarkerId ?
// var markerRoot = this.el.object3D;
// markerRoot.userData.size = this.data.size;
},
tick: function(){
if( this.data.changeMatrixMode === 'cameraTransformMatrix' ){
this.el.sceneEl.object3D.visible = this.el.object3D.visible;
}
if( this._multiMarkerControls !== null ){
// update smoothedControls parameters depending on how many markers are visible in multiMarkerControls
this._multiMarkerControls.updateSmoothedControls(this.arSmoothedControls)
}
// update smoothedControls position
this.arSmoothedControls.update(this._markerRoot)
}
});
//////////////////////////////////////////////////////////////////////////////
// define some primitives shortcuts
//////////////////////////////////////////////////////////////////////////////
AFRAME.registerPrimitive('a-marker', AFRAME.utils.extendDeep({}, AFRAME.primitives.getMeshMixin(), {
defaultComponents: {
'arjsmarker': {},
},
mappings: {
'type': 'arjsmarker.type',
'size': 'arjsmarker.size',
'url': 'arjsmarker.patternUrl',
'value': 'arjsmarker.barcodeValue',
'preset': 'arjsmarker.preset',
'minConfidence': 'arjsmarker.minConfidence',
'markerhelpers': 'arjsmarker.markerhelpers',
}
}));
AFRAME.registerPrimitive('a-marker-camera', AFRAME.utils.extendDeep({}, AFRAME.primitives.getMeshMixin(), {
defaultComponents: {
'arjsmarker': {
changeMatrixMode: 'cameraTransformMatrix'
},
'camera': true,
},
mappings: {
'type': 'arjsmarker.type',
'size': 'arjsmarker.size',
'url': 'arjsmarker.patternUrl',
'value': 'arjsmarker.barcodeValue',
'preset': 'arjsmarker.preset',
'minConfidence': 'arjsmarker.minConfidence',
'markerhelpers': 'arjsmarker.markerhelpers',
}
}));
......@@ -123,7 +123,7 @@ AFRAME.registerSystem('arjs', {
// handle resize of renderer
onResize()
// TODO this is crappy
// TODO this is crappy - code an exponential backoff - max 1 seconds
// kludge to write a 'resize' event
var startedAt = Date.now()
var timerId = setInterval(function(){
......@@ -140,7 +140,8 @@ AFRAME.registerSystem('arjs', {
window.addEventListener('resize', onResize)
function onResize(){
// ugly kludge to get resize on aframe... not even sure it works
arToolkitSource.onResize(document.body)
arToolkitSource.onResizeElement()
arToolkitSource.copyElementSizeTo(document.body)
var buttonElement = document.querySelector('.a-enter-vr')
if( buttonElement ){
......@@ -263,7 +264,6 @@ AFRAME.registerComponent('arjsmarker', {
this.data.patternUrl = THREEx.ArToolkitContext.baseURL+'examples/marker-training/examples/pattern-files/pattern-kanji.patt'
}else if( this.data.preset === 'area' ){
this.data.type = 'area'
// fall through
}else {
console.assert( this.data.preset === '', 'illegal preset value '+this.data.preset)
}
......
......@@ -41,7 +41,6 @@ var THREEx = THREEx || {}
* - seems an easy light layer for clickable object
* - up to
*/
THREEx.ARClickability = function(sourceElement){
this._sourceElement = sourceElement
// Create cameraPicking
......@@ -80,6 +79,39 @@ THREEx.ARClickability.prototype.computeIntersects = function(domEvent, objects){
THREEx.ARClickability.prototype.update = function(){
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ARClickability.tangoPickingPointCloud = function(artoolkitContext, mouseX, mouseY){
var vrDisplay = artoolkitContext._tangoContext.vrDisplay
if (vrDisplay === null ) return
var pointAndPlane = vrDisplay.getPickingPointAndPlaneInPointCloud(mouseX, mouseY)
if( pointAndPlane == null ) {
console.warn('Could not retrieve the correct point and plane.')
return null
}
// FIXME not sure what this is
var boundingSphereRadius = 0.01
// the bigger the number the likeliest it crash chromium-webar
// Orient and position the model in the picking point according
// to the picking plane. The offset is half of the model size.
var object3d = new THREE.Object3D
THREE.WebAR.positionAndRotateObject3DWithPickingPointAndPlaneInPointCloud(
pointAndPlane, object3d, boundingSphereRadius
)
object3d.rotateZ(-Math.PI/2)
// return the result
var result = {}
result.position = object3d.position
result.quaternion = object3d.quaternion
return result
}
var THREEx = THREEx || {}
/**
* - videoTexture
......@@ -478,7 +510,6 @@ THREEx.ArMarkerControls.prototype._initArtoolkit = function(){
}else{
console.log(false, 'invalid marker type', _this.parameters.type)
}
// listen to the event
arController.addEventListener('getMarker', function(event){
......@@ -612,136 +643,6 @@ THREEx.ArSmoothedControls.prototype.update = function(targetObject3d){
var present = performance.now()/1000
//////////////////////////////////////////////////////////////////////////////
// handle object3d.visible with minVisibleDelay/minUnvisibleDelay
//////////////////////////////////////////////////////////////////////////////
if( targetObject3d.visible === false ) this._visibleStartedAt = null
if( targetObject3d.visible === true ) this._unvisibleStartedAt = null
if( wasVisible === false && targetObject3d.visible === true ){
if( this._visibleStartedAt === null ) this._visibleStartedAt = present
var visibleFor = present - this._visibleStartedAt
if( visibleFor >= this.parameters.minVisibleDelay ){
object3d.visible = true
this._visibleStartedAt = null
}
console.log('visibleFor', visibleFor)
}
if( wasVisible === true && targetObject3d.visible === false ){
if( this._unvisibleStartedAt === null ) this._unvisibleStartedAt = present
var unvisibleFor = present - this._unvisibleStartedAt
if( unvisibleFor >= this.parameters.minUnvisibleDelay ){
object3d.visible = false
}
// console.log('unvisibleFor', unvisibleFor)
}
// disabled minVisibleDelay+minUnvisibleDelay
// if( true ){
// object3d.visible = targetObject3d.visible
// }
//////////////////////////////////////////////////////////////////////////////
// apply lerp on positon/quaternion/scale
//////////////////////////////////////////////////////////////////////////////
// apply lerp steps - require fix time steps to behave the same no matter the fps
if( this._lastLerpStepAt === null ){
applyOneSlepStep()
this._lastLerpStepAt = present
}else{
var nStepsToDo = Math.floor( (present - this._lastLerpStepAt)/this.parameters.lerpStepDelay )
for(var i = 0; i < nStepsToDo; i++){
applyOneSlepStep()
this._lastLerpStepAt += this.parameters.lerpStepDelay
}
}
// update the matrix
this.object3d.updateMatrix()
// disable the lerp by directly copying targetObject3d position/quaternion/scale
if( false ){
this.object3d.position.copy( targetObject3d.position )
this.object3d.quaternion.copy( targetObject3d.quaternion )
this.object3d.scale.copy( targetObject3d.scale )
this.object3d.updateMatrix()
}
//////////////////////////////////////////////////////////////////////////////
// honor becameVisible/becameUnVisible event
//////////////////////////////////////////////////////////////////////////////
// honor becameVisible event
if( wasVisible === false && object3d.visible === true ){
this.dispatchEvent({ type: 'becameVisible' })
}
// honor becameUnVisible event
if( wasVisible === true && object3d.visible === false ){
this.dispatchEvent({ type: 'becameUnVisible' })
}
return
function applyOneSlepStep(){
object3d.position.lerp(targetObject3d.position, parameters.lerpPosition)
object3d.quaternion.slerp(targetObject3d.quaternion, parameters.lerpQuaternion)
object3d.scale.lerp(targetObject3d.scale, parameters.lerpScale)
}
}
var THREEx = THREEx || {}
/**
* - lerp position/quaternino/scale
* - minDelayDetected
* - minDelayUndetected
* @param {[type]} object3d [description]
* @param {[type]} parameters [description]
*/
THREEx.ArSmoothedControls = function(object3d, parameters){
var _this = this
THREEx.ArBaseControls.call(this, object3d)
// copy parameters
this.object3d.visible = false
this._lastLerpStepAt = null
this._visibleStartedAt = null
this._unvisibleStartedAt = null
// handle default parameters
parameters = parameters || {}
this.parameters = {
// lerp coeficient for the position - between [0,1] - default to 1
lerpPosition: parameters.lerpPosition !== undefined ? parameters.lerpPosition : 0.8,
// lerp coeficient for the quaternion - between [0,1] - default to 1
lerpQuaternion: parameters.lerpQuaternion !== undefined ? parameters.lerpQuaternion : 0.2,
// lerp coeficient for the scale - between [0,1] - default to 1
lerpScale: parameters.lerpScale !== undefined ? parameters.lerpScale : 0.7,
// delay for lerp fixed steps - in seconds - default to 1/120
lerpStepDelay: parameters.fixStepDelay !== undefined ? parameters.fixStepDelay : 1/60,
// minimum delay the sub-control must be visible before this controls become visible - default to 0 seconds
minVisibleDelay: parameters.minVisibleDelay !== undefined ? parameters.minVisibleDelay : 0.0,
// minimum delay the sub-control must be unvisible before this controls become unvisible - default to 0 seconds
minUnvisibleDelay: parameters.minUnvisibleDelay !== undefined ? parameters.minUnvisibleDelay : 0.2,
}
}
THREEx.ArSmoothedControls.prototype = Object.create( THREEx.ArBaseControls.prototype );
THREEx.ArSmoothedControls.prototype.constructor = THREEx.ArSmoothedControls;
//////////////////////////////////////////////////////////////////////////////
// update function
//////////////////////////////////////////////////////////////////////////////
THREEx.ArSmoothedControls.prototype.update = function(targetObject3d){
var object3d = this.object3d
var parameters = this.parameters
var wasVisible = object3d.visible
var present = performance.now()/1000
//////////////////////////////////////////////////////////////////////////////
// handle object3d.visible with minVisibleDelay/minUnvisibleDelay
//////////////////////////////////////////////////////////////////////////////
......@@ -830,7 +731,7 @@ THREEx.ArToolkitContext = function(parameters){
// debug - true if one should display artoolkit debug canvas, false otherwise
debug: parameters.debug !== undefined ? parameters.debug : false,
// the mode of detection - ['color', 'color_and_matrix', 'mono', 'mono_and_matrix']
detectionMode: parameters.detectionMode !== undefined ? parameters.detectionMode : 'color_and_matrix',
detectionMode: parameters.detectionMode !== undefined ? parameters.detectionMode : 'mono',
// type of matrix code - valid iif detectionMode end with 'matrix' - [3x3, 3x3_HAMMING63, 3x3_PARITY65, 4x4, 4x4_BCH_13_9_3, 4x4_BCH_13_5_5]
matrixCodeType: parameters.matrixCodeType !== undefined ? parameters.matrixCodeType : '3x3',
......@@ -865,17 +766,48 @@ THREEx.ArToolkitContext.baseURL = 'https://jeromeetienne.github.io/AR.js/three.j
THREEx.ArToolkitContext.REVISION = '1.0.1-dev'
/**
* Create a default camera for this trackingBackend
* @param {string} trackingBackend - the tracking to user
* @return {THREE.Camera} the created camera
*/
THREEx.ArToolkitContext.createDefaultCamera = function( trackingBackend ){
console.assert(false, 'use ARjs.Utils.createDefaultCamera instead')
// Create a camera
if( trackingBackend === 'artoolkit' ){
var camera = new THREE.Camera();
}else if( trackingBackend === 'aruco' ){
var camera = new THREE.PerspectiveCamera(42, renderer.domElement.width / renderer.domElement.height, 0.01, 100);
}else if( trackingBackend === 'tango' ){
var camera = new THREE.PerspectiveCamera(42, renderer.domElement.width / renderer.domElement.height, 0.01, 100);
}else console.assert(false)
return camera
}
//////////////////////////////////////////////////////////////////////////////
// init functions
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitContext.prototype.init = function(onCompleted){
var _this = this
if( this.parameters.trackingBackend === 'artoolkit' ){
this._initArtoolkit(onCompleted)
this._initArtoolkit(done)
}else if( this.parameters.trackingBackend === 'aruco' ){
this._initAruco(onCompleted)
this._initAruco(done)
}else if( this.parameters.trackingBackend === 'tango' ){
this._initTango(onCompleted)
this._initTango(done)
}else console.assert(false)
return
function done(){
// dispatch event
_this.dispatchEvent({
type: 'initialized'
});
onCompleted && onCompleted()
}
}
////////////////////////////////////////////////////////////////////////////////
// update function
......@@ -918,8 +850,6 @@ THREEx.ArToolkitContext.prototype.update = function(srcElement){
return true;
}
////////////////////////////////////////////////////////////////////////////////
// Add/Remove markerControls
////////////////////////////////////////////////////////////////////////////////
......@@ -1002,7 +932,7 @@ THREEx.ArToolkitContext.prototype._initArtoolkit = function(onCompleted){
// arController.setThresholdMode(artoolkit.AR_LABELING_THRESH_MODE_AUTO_OTSU)
// notify
onCompleted && onCompleted()
onCompleted()
})
return this
}
......@@ -1056,7 +986,7 @@ THREEx.ArToolkitContext.prototype._initAruco = function(onCompleted){
setTimeout(function(){
onCompleted && onCompleted()
onCompleted()
}, 0)
}
......@@ -1093,6 +1023,7 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
var _this = this
// check webvr is available
if (navigator.getVRDisplays) {
// do nothing
} else if (navigator.getVRDevices) {
alert("Your browser supports WebVR but not the latest version. See <a href='http://webvr.info'>webvr.info</a> for more info.");
} else {
......@@ -1102,6 +1033,7 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
this._tangoContext = {
vrDisplay: null,
vrPointCloud: null,
frameData: new VRFrameData(),
}
......@@ -1109,20 +1041,23 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
// get vrDisplay
navigator.getVRDisplays().then(function (vrDisplays) {
if( vrDisplays.length === 0 ) alert('no vrDisplays available')
var vrDisplay = vrDisplays[0]
_this._tangoContext.vrDisplay = vrDisplay
var vrDisplay = _this._tangoContext.vrDisplay = vrDisplays[0]
console.log('vrDisplays.displayName :', vrDisplay.displayName)
// init vrPointCloud
if( vrDisplay.displayName === "Tango VR Device" ){
_this._tangoContext.vrPointCloud = new THREE.WebAR.VRPointCloud(vrDisplay, true)
}
var canvasElement = document.createElement('canvas')
document.body.appendChild(canvasElement)
var layers = [{ source: canvasElement }]
// vrDisplay.requestPresent(layers).then(function() {
// console.log('vrdisplay request accepted')
// });
// window.vrDisplay = vrDisplay
// NOTE it doesnt seem necessary and it fails on tango
// var canvasElement = document.createElement('canvas')
// document.body.appendChild(canvasElement)
// _this._tangoContext.requestPresent([{ source: canvasElement }]).then(function() {
// console.log('vrdisplay request accepted')
// });
onCompleted && onCompleted()
onCompleted()
});
}
......@@ -1132,9 +1067,19 @@ THREEx.ArToolkitContext.prototype._updateTango = function(srcElement){
var _this = this
var arMarkersControls = this._arMarkersControls
var tangoContext= this._tangoContext
var vrDisplay = this._tangoContext.vrDisplay
// check vrDisplay is already initialized
if( tangoContext.vrDisplay === null ) return
if( vrDisplay === null ) return
// Update the point cloud. Only if the point cloud will be shown the geometry is also updated.
if( vrDisplay.displayName === "Tango VR Device" ){
var showPointCloud = true
var pointsToSkip = 0
_this._tangoContext.vrPointCloud.update(showPointCloud, pointsToSkip, true)
}
if( this._arMarkersControls.length === 0 ) return
......@@ -1145,20 +1090,29 @@ THREEx.ArToolkitContext.prototype._updateTango = function(srcElement){
var frameData = this._tangoContext.frameData
// read frameData
tangoContext.vrDisplay.getFrameData(frameData);
vrDisplay.getFrameData(frameData);
if( frameData.pose.position === null ) return
if( frameData.pose.orientation === null ) return
// create cameraTransformMatrix
var position = new THREE.Vector3().fromArray(frameData.pose.position)
var quaternion = new THREE.Quaternion().fromArray(frameData.pose.orientation)
var scale = new THREE.Vector3(1,1,1)
var scale = new THREE.Vector3(1,1,1)
var cameraTransformMatrix = new THREE.Matrix4().compose(position, quaternion, scale)
// compute modelViewMatrix from cameraTransformMatrix
var modelViewMatrix = new THREE.Matrix4()
modelViewMatrix.getInverse( cameraTransformMatrix )
console.log('position', position)
foundControls.updateWithModelViewMatrix(modelViewMatrix)
// console.log('position', position)
// if( position.x !== 0 || position.y !== 0 || position.z !== 0 ){
// console.log('vrDisplay tracking')
// }else{
// console.log('vrDisplay NOT tracking')
// }
}
var THREEx = THREEx || {}
......@@ -1254,22 +1208,27 @@ THREEx.ArToolkitProfile.prototype.performance = function(label) {
//////////////////////////////////////////////////////////////////////////////
// Marker
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitProfile.prototype.kanjiMarker = function () {
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.kanji'
return this
}
THREEx.ArToolkitProfile.prototype.hiroMarker = function () {
this.contextParameters.detectionMode = 'mono'
THREEx.ArToolkitProfile.prototype.defaultMarker = function (trackingBackend) {
trackingBackend = trackingBackend || this.contextParameters.trackingBackend
if( trackingBackend === 'artoolkit' ){
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro'
}else if( trackingBackend === 'aruco' ){
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'barcode'
this.defaultMarkerParameters.barcodeValue = 1001
}else if( trackingBackend === 'tango' ){
// FIXME temporary placeholder - to reevaluate later
this.defaultMarkerParameters.type = 'barcode'
this.defaultMarkerParameters.barcodeValue = 1001
}else console.assert(false)
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro'
return this
}
//////////////////////////////////////////////////////////////////////////////
// Source
//////////////////////////////////////////////////////////////////////////////
......@@ -1297,6 +1256,7 @@ THREEx.ArToolkitProfile.prototype.sourceImage = function (url) {
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitProfile.prototype.trackingBackend = function (trackingBackend) {
this.contextParameters.trackingBackend = trackingBackend
return this
}
var THREEx = THREEx || {}
......@@ -1534,7 +1494,7 @@ THREEx.ArToolkitSource.prototype.toggleMobileTorch = function(){
// handle resize
////////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
THREEx.ArToolkitSource.prototype.onResizeElement = function(mirrorDomElements){
var _this = this
var screenWidth = window.innerWidth
var screenHeight = window.innerHeight
......@@ -1576,6 +1536,11 @@ THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
this.domElement.style.marginLeft = '0px'
}
if( arguments.length !== 0 ){
debugger
console.warn('use bad signature for arToolkitSource.copyElementSizeTo')
}
// honor default parameters
// if( mirrorDomElements !== undefined ) console.warn('still use the old resize. fix it')
if( mirrorDomElements === undefined ) mirrorDomElements = []
......@@ -1583,16 +1548,68 @@ THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
// Mirror _this.domElement.style to mirrorDomElements
mirrorDomElements.forEach(function(domElement){
_this.copySizeTo(domElement)
_this.copyElementSizeTo(domElement)
})
}
THREEx.ArToolkitSource.prototype.copySizeTo = function(otherElement){
THREEx.ArToolkitSource.prototype.copyElementSizeTo = function(otherElement){
otherElement.style.width = this.domElement.style.width
otherElement.style.height = this.domElement.style.height
otherElement.style.marginLeft = this.domElement.style.marginLeft
otherElement.style.marginTop = this.domElement.style.marginTop
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.copySizeTo = function(){
console.warn('obsolete function arToolkitSource.copySizeTo. Use arToolkitSource.copyElementSizeTo' )
this.copyElementSizeTo.apply(this, arguments)
}
THREEx.ArToolkitSource.prototype.onResize = function(){
console.warn('obsolete function arToolkitSource.onResize. Use arToolkitSource.onResizeElement' )
this.onResizeElement.apply(this, arguments)
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.onResize2 = function(arToolkitContext, renderer, camera){
var trackingBackend = arToolkitContext.parameters.trackingBackend
// RESIZE DOMELEMENT
if( trackingBackend === 'artoolkit' ){
this.onResizeElement()
this.copyElementSizeTo(renderer.domElement)
if( arToolkitContext.arController !== null ){
this.copyElementSizeTo(arToolkitContext.arController.canvas)
}
}else if( trackingBackend === 'aruco' ){
this.onResizeElement()
this.copyElementSizeTo(renderer.domElement)
this.copyElementSizeTo(arToolkitContext.arucoContext.canvas)
}else if( trackingBackend === 'tango' ){
renderer.setSize( window.innerWidth, window.innerHeight )
}else console.assert(false, 'unhandled trackingBackend '+trackingBackend)
// RESIZE CAMERA
if( trackingBackend === 'artoolkit' ){
camera.projectionMatrix.copy( arToolkitContext.getProjectionMatrix() );
}else if( trackingBackend === 'aruco' ){
camera.aspect = renderer.domElement.width / renderer.domElement.height;
camera.updateProjectionMatrix();
}else if( trackingBackend === 'tango' ){
var vrDisplay = arToolkitContext._tangoContext.vrDisplay
// make camera fit vrDisplay
if( vrDisplay && vrDisplay.displayName === "Tango VR Device" ) THREE.WebAR.resizeVRSeeThroughCamera(vrDisplay, camera)
}else console.assert(false, 'unhandled trackingBackend '+trackingBackend)
}
var THREEx = THREEx || {}
THREEx.ArVideoInWebgl = function(videoTexture){
......@@ -2355,6 +2372,13 @@ THREEx.ArMultiMarkerUtils = {}
//////////////////////////////////////////////////////////////////////////////
// navigateToLearnerPage
//////////////////////////////////////////////////////////////////////////////
/**
* Navigate to the multi-marker learner page
*
* @param {String} learnerBaseURL - the base url for the learner
* @param {String} trackingBackend - the tracking backend to use
*/
THREEx.ArMultiMarkerUtils.navigateToLearnerPage = function(learnerBaseURL, trackingBackend){
var learnerParameters = {
backURL : location.href,
......@@ -2367,6 +2391,12 @@ THREEx.ArMultiMarkerUtils.navigateToLearnerPage = function(learnerBaseURL, track
//////////////////////////////////////////////////////////////////////////////
// DefaultMultiMarkerFile
//////////////////////////////////////////////////////////////////////////////
/**
* Create and store a default multi-marker file
*
* @param {String} trackingBackend - the tracking backend to use
*/
THREEx.ArMultiMarkerUtils.storeDefaultMultiMarkerFile = function(trackingBackend){
var file = THREEx.ArMultiMarkerUtils.createDefaultMultiMarkerFile(trackingBackend)
// json.strinfy the value and store it in localStorage
......@@ -2374,7 +2404,15 @@ THREEx.ArMultiMarkerUtils.storeDefaultMultiMarkerFile = function(trackingBackend
}
/**
* Create a default multi-marker file
* @param {String} trackingBackend - the tracking backend to use
* @return {Object} - json object of the multi-marker file
*/
THREEx.ArMultiMarkerUtils.createDefaultMultiMarkerFile = function(trackingBackend){
console.assert(trackingBackend)
if( trackingBackend === undefined ) debugger
// create the base file
var file = {
meta : {
......@@ -2383,7 +2421,7 @@ THREEx.ArMultiMarkerUtils.createDefaultMultiMarkerFile = function(trackingBacken
},
trackingBackend : trackingBackend,
subMarkersControls : [
// empty for now...
// empty for now... being filled
]
}
// add a subMarkersControls
......@@ -2407,6 +2445,12 @@ THREEx.ArMultiMarkerUtils.createDefaultMultiMarkerFile = function(trackingBacken
// createDefaultMarkersControlsParameters
//////////////////////////////////////////////////////////////////////////////
/**
* Create a default controls parameters for the multi-marker learner
*
* @param {String} trackingBackend - the tracking backend to use
* @return {Object} - json object containing the controls parameters
*/
THREEx.ArMultiMarkerUtils.createDefaultMarkersControlsParameters = function(trackingBackend){
var link = document.createElement('a')
link.href = THREEx.ArToolkitContext.baseURL
......@@ -2594,7 +2638,7 @@ AFRAME.registerSystem('arjs', {
// handle resize of renderer
onResize()
// TODO this is crappy
// TODO this is crappy - code an exponential backoff - max 1 seconds
// kludge to write a 'resize' event
var startedAt = Date.now()
var timerId = setInterval(function(){
......@@ -2611,7 +2655,8 @@ AFRAME.registerSystem('arjs', {
window.addEventListener('resize', onResize)
function onResize(){
// ugly kludge to get resize on aframe... not even sure it works
arToolkitSource.onResize(document.body)
arToolkitSource.onResizeElement()
arToolkitSource.copyElementSizeTo(document.body)
var buttonElement = document.querySelector('.a-enter-vr')
if( buttonElement ){
......@@ -2734,7 +2779,6 @@ AFRAME.registerComponent('arjsmarker', {
this.data.patternUrl = THREEx.ArToolkitContext.baseURL+'examples/marker-training/examples/pattern-files/pattern-kanji.patt'
}else if( this.data.preset === 'area' ){
this.data.type = 'area'
// fall through
}else {
console.assert( this.data.preset === '', 'illegal preset value '+this.data.preset)
}
......
......@@ -16,7 +16,7 @@
<a-marker preset='hiro'>
<!-- define the object which gonna be put on this marker -->
<a-box position='0 0.5 0' material='opacity: 0.5; side: double'>
<a-torus-knot radius='0.27' radius-tubular='0.05'>
<a-torus-knot radius='0.26' radius-tubular='0.05'>
<a-animation attribute="rotation" to="360 0 0" dur="5000" easing='linear' repeat="indefinite"></a-animation>
</a-torus-knot>
</a-box>
......
......@@ -2,7 +2,7 @@
<script src="https://aframe.io/releases/0.6.0/aframe.min.js"></script>
<script src="https://rawgit.com/jeromeetienne/ar.js/master/aframe/build/aframe-ar.js"></script>
<body style='margin : 0px; overflow: hidden;'>
<a-scene embedded artoolkit='sourceType: webcam;'>
<a-scene embedded arjs='sourceType: webcam;'>
<a-box position='0 0.5 0' material='opacity: 0.5;'></a-box>
<a-marker-camera preset='hiro'></a-marker-camera>
</a-scene>
......
......@@ -14,7 +14,7 @@
<!-- define the object which gonna be put on this marker -->
<a-box position='0 0.5 0' material='opacity: 0.5; side: double'>
<a-torus-knot radius='0.27' radius-tubular='0.05'>
<a-torus-knot radius='0.26' radius-tubular='0.05'>
<a-animation attribute="rotation" to="360 0 0" dur="3000" easing='linear' repeat="indefinite"></a-animation>
</a-torus-knot>
</a-box>
......
......@@ -17,7 +17,7 @@
<!-- handle hiro marker -->
<a-marker preset='hiro'>
<a-box position='0 0.5 0' material='opacity: 0.5; side: double;color:red;'>
<a-torus-knot radius='0.27' radius-tubular='0.05'>
<a-torus-knot radius='0.26' radius-tubular='0.05'>
<a-animation attribute="rotation" to="360 0 0" dur="5000" easing='linear' repeat="indefinite"></a-animation>
</a-torus-knot>
</a-box>
......@@ -26,7 +26,7 @@
<!-- handle hiro marker -->
<a-marker type='barcode' barcodeValue='5'>
<a-box position='0 0.5 0' material='opacity: 0.5; side: double;color:pink;'>
<a-torus-knot radius='0.27' radius-tubular='0.05'>
<a-torus-knot radius='0.26' radius-tubular='0.05'>
<a-animation attribute="rotation" to="360 0 0" dur="5000" easing='linear' repeat="indefinite"></a-animation>
</a-torus-knot>
</a-box>
......@@ -35,7 +35,7 @@
<!-- handle kanji marker -->
<a-marker preset='kanji'>
<a-box position='0 0.5 0' material='opacity: 0.5; side: double;color:green;'>
<a-torus-knot radius='0.27' radius-tubular='0.05'>
<a-torus-knot radius='0.26' radius-tubular='0.05'>
<a-animation attribute="rotation" to="360 0 0" dur="5000" easing='linear' repeat="indefinite"></a-animation>
</a-torus-knot>
</a-box>
......
......@@ -14,7 +14,7 @@
<a-marker preset='hiro'>
<!-- define the object which gonna be put on this marker -->
<a-box position='0 0.5 0' material='opacity: 0.5; side: double'>
<a-torus-knot radius='0.27' radius-tubular='0.05'>
<a-torus-knot radius='0.26' radius-tubular='0.05'>
</a-torus-knot>
</a-box>
</a-marker>
......
<!DOCTYPE html>
<!-- include a-frame -->
<script src="vendor/aframe.min.js"></script>
<!-- include aframe-ar.js -->
<script src="../aframe-ar-new.js"></script>
<!-- jsartookit -->
<script src="../../three.js/vendor/jsartoolkit5/build/artoolkit.min.js"></script>
<script src="../../three.js/vendor/jsartoolkit5/js/artoolkit.api.js"></script>
<!-- include ar.js -->
<script src="../../three.js/threex-artoolkitcontext.js"></script>
<script src="../../three.js/threex-artoolkitsource.js"></script>
<script src='../../three.js/threex-artoolkitprofile.js'></script>
<script src="../../three.js/threex-arbasecontrols.js"></script>
<script src="../../three.js/threex-armarkercontrols.js"></script>
<script src="../../three.js/threex-armarkerhelper.js"></script>
<script src="../../three.js/threex-arsmoothedcontrols.js"></script>
<!-- include for tango trackingBackend -->
<script src='../../three.js/vendor/chromium-tango/THREE.WebAR.js'></script>
<body style='margin : 0px; overflow: hidden; font-family: Monospace;'><div style='position: fixed; top: 10px; width:inherit; text-align: center; z-index: 1;'>
<a href="https://github.com/jeromeetienne/AR.js/" target="_blank">AR.js</a> - tango example for a-frame by <a href='https://twitter.com/jerome_etienne' target='_blank'>@jerome_etienne</a>
</div>
<a-scene embedded arjs='sourceType: webcam; trackingBackend: artoolkit;'>
<a-box position='0 0.5 0' material='opacity: 0.5; side: double; color: blue;'>
<a-torus-knot radius='0.26' radius-tubular='0.05'>
<a-animation attribute="rotation" to="360 0 0" dur="3000" easing='linear' repeat="indefinite"></a-animation>
</a-torus-knot>
</a-box>
<a-marker-camera preset='hiro'></a-marker-camera>
</a-scene>
<!-- <a-scene embedded arjs='sourceType: webcam; trackingBackend: tango;'>
<a-box position='0 0.5 0' material='opacity: 0.5; side: double;color:pink;'>
<a-torus-knot radius='0.26' radius-tubular='0.05'>
<a-animation attribute="rotation" to="360 0 0" dur="5000" easing='linear' repeat="indefinite"></a-animation>
</a-torus-knot>
</a-box>
<a-marker-camera preset='tango'></a-marker-camera>
</a-scene> -->
</body>
</html>
......@@ -1662,7 +1662,6 @@ var THREEx = THREEx || {}
* - seems an easy light layer for clickable object
* - up to
*/
THREEx.ARClickability = function(sourceElement){
this._sourceElement = sourceElement
// Create cameraPicking
......@@ -1701,6 +1700,39 @@ THREEx.ARClickability.prototype.computeIntersects = function(domEvent, objects){
THREEx.ARClickability.prototype.update = function(){
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ARClickability.tangoPickingPointCloud = function(artoolkitContext, mouseX, mouseY){
var vrDisplay = artoolkitContext._tangoContext.vrDisplay
if (vrDisplay === null ) return
var pointAndPlane = vrDisplay.getPickingPointAndPlaneInPointCloud(mouseX, mouseY)
if( pointAndPlane == null ) {
console.warn('Could not retrieve the correct point and plane.')
return null
}
// FIXME not sure what this is
var boundingSphereRadius = 0.01
// the bigger the number the likeliest it crash chromium-webar
// Orient and position the model in the picking point according
// to the picking plane. The offset is half of the model size.
var object3d = new THREE.Object3D
THREE.WebAR.positionAndRotateObject3DWithPickingPointAndPlaneInPointCloud(
pointAndPlane, object3d, boundingSphereRadius
)
object3d.rotateZ(-Math.PI/2)
// return the result
var result = {}
result.position = object3d.position
result.quaternion = object3d.quaternion
return result
}
var THREEx = THREEx || {}
/**
* - videoTexture
......@@ -2099,7 +2131,6 @@ THREEx.ArMarkerControls.prototype._initArtoolkit = function(){
}else{
console.log(false, 'invalid marker type', _this.parameters.type)
}
// listen to the event
arController.addEventListener('getMarker', function(event){
......@@ -2233,136 +2264,6 @@ THREEx.ArSmoothedControls.prototype.update = function(targetObject3d){
var present = performance.now()/1000
//////////////////////////////////////////////////////////////////////////////
// handle object3d.visible with minVisibleDelay/minUnvisibleDelay
//////////////////////////////////////////////////////////////////////////////
if( targetObject3d.visible === false ) this._visibleStartedAt = null
if( targetObject3d.visible === true ) this._unvisibleStartedAt = null
if( wasVisible === false && targetObject3d.visible === true ){
if( this._visibleStartedAt === null ) this._visibleStartedAt = present
var visibleFor = present - this._visibleStartedAt
if( visibleFor >= this.parameters.minVisibleDelay ){
object3d.visible = true
this._visibleStartedAt = null
}
console.log('visibleFor', visibleFor)
}
if( wasVisible === true && targetObject3d.visible === false ){
if( this._unvisibleStartedAt === null ) this._unvisibleStartedAt = present
var unvisibleFor = present - this._unvisibleStartedAt
if( unvisibleFor >= this.parameters.minUnvisibleDelay ){
object3d.visible = false
}
// console.log('unvisibleFor', unvisibleFor)
}
// disabled minVisibleDelay+minUnvisibleDelay
// if( true ){
// object3d.visible = targetObject3d.visible
// }
//////////////////////////////////////////////////////////////////////////////
// apply lerp on positon/quaternion/scale
//////////////////////////////////////////////////////////////////////////////
// apply lerp steps - require fix time steps to behave the same no matter the fps
if( this._lastLerpStepAt === null ){
applyOneSlepStep()
this._lastLerpStepAt = present
}else{
var nStepsToDo = Math.floor( (present - this._lastLerpStepAt)/this.parameters.lerpStepDelay )
for(var i = 0; i < nStepsToDo; i++){
applyOneSlepStep()
this._lastLerpStepAt += this.parameters.lerpStepDelay
}
}
// update the matrix
this.object3d.updateMatrix()
// disable the lerp by directly copying targetObject3d position/quaternion/scale
if( false ){
this.object3d.position.copy( targetObject3d.position )
this.object3d.quaternion.copy( targetObject3d.quaternion )
this.object3d.scale.copy( targetObject3d.scale )
this.object3d.updateMatrix()
}
//////////////////////////////////////////////////////////////////////////////
// honor becameVisible/becameUnVisible event
//////////////////////////////////////////////////////////////////////////////
// honor becameVisible event
if( wasVisible === false && object3d.visible === true ){
this.dispatchEvent({ type: 'becameVisible' })
}
// honor becameUnVisible event
if( wasVisible === true && object3d.visible === false ){
this.dispatchEvent({ type: 'becameUnVisible' })
}
return
function applyOneSlepStep(){
object3d.position.lerp(targetObject3d.position, parameters.lerpPosition)
object3d.quaternion.slerp(targetObject3d.quaternion, parameters.lerpQuaternion)
object3d.scale.lerp(targetObject3d.scale, parameters.lerpScale)
}
}
var THREEx = THREEx || {}
/**
* - lerp position/quaternino/scale
* - minDelayDetected
* - minDelayUndetected
* @param {[type]} object3d [description]
* @param {[type]} parameters [description]
*/
THREEx.ArSmoothedControls = function(object3d, parameters){
var _this = this
THREEx.ArBaseControls.call(this, object3d)
// copy parameters
this.object3d.visible = false
this._lastLerpStepAt = null
this._visibleStartedAt = null
this._unvisibleStartedAt = null
// handle default parameters
parameters = parameters || {}
this.parameters = {
// lerp coeficient for the position - between [0,1] - default to 1
lerpPosition: parameters.lerpPosition !== undefined ? parameters.lerpPosition : 0.8,
// lerp coeficient for the quaternion - between [0,1] - default to 1
lerpQuaternion: parameters.lerpQuaternion !== undefined ? parameters.lerpQuaternion : 0.2,
// lerp coeficient for the scale - between [0,1] - default to 1
lerpScale: parameters.lerpScale !== undefined ? parameters.lerpScale : 0.7,
// delay for lerp fixed steps - in seconds - default to 1/120
lerpStepDelay: parameters.fixStepDelay !== undefined ? parameters.fixStepDelay : 1/60,
// minimum delay the sub-control must be visible before this controls become visible - default to 0 seconds
minVisibleDelay: parameters.minVisibleDelay !== undefined ? parameters.minVisibleDelay : 0.0,
// minimum delay the sub-control must be unvisible before this controls become unvisible - default to 0 seconds
minUnvisibleDelay: parameters.minUnvisibleDelay !== undefined ? parameters.minUnvisibleDelay : 0.2,
}
}
THREEx.ArSmoothedControls.prototype = Object.create( THREEx.ArBaseControls.prototype );
THREEx.ArSmoothedControls.prototype.constructor = THREEx.ArSmoothedControls;
//////////////////////////////////////////////////////////////////////////////
// update function
//////////////////////////////////////////////////////////////////////////////
THREEx.ArSmoothedControls.prototype.update = function(targetObject3d){
var object3d = this.object3d
var parameters = this.parameters
var wasVisible = object3d.visible
var present = performance.now()/1000
//////////////////////////////////////////////////////////////////////////////
// handle object3d.visible with minVisibleDelay/minUnvisibleDelay
//////////////////////////////////////////////////////////////////////////////
......@@ -2451,7 +2352,7 @@ THREEx.ArToolkitContext = function(parameters){
// debug - true if one should display artoolkit debug canvas, false otherwise
debug: parameters.debug !== undefined ? parameters.debug : false,
// the mode of detection - ['color', 'color_and_matrix', 'mono', 'mono_and_matrix']
detectionMode: parameters.detectionMode !== undefined ? parameters.detectionMode : 'color_and_matrix',
detectionMode: parameters.detectionMode !== undefined ? parameters.detectionMode : 'mono',
// type of matrix code - valid iif detectionMode end with 'matrix' - [3x3, 3x3_HAMMING63, 3x3_PARITY65, 4x4, 4x4_BCH_13_9_3, 4x4_BCH_13_5_5]
matrixCodeType: parameters.matrixCodeType !== undefined ? parameters.matrixCodeType : '3x3',
......@@ -2486,17 +2387,48 @@ THREEx.ArToolkitContext.baseURL = 'https://jeromeetienne.github.io/AR.js/three.j
THREEx.ArToolkitContext.REVISION = '1.0.1-dev'
/**
* Create a default camera for this trackingBackend
* @param {string} trackingBackend - the tracking to user
* @return {THREE.Camera} the created camera
*/
THREEx.ArToolkitContext.createDefaultCamera = function( trackingBackend ){
console.assert(false, 'use ARjs.Utils.createDefaultCamera instead')
// Create a camera
if( trackingBackend === 'artoolkit' ){
var camera = new THREE.Camera();
}else if( trackingBackend === 'aruco' ){
var camera = new THREE.PerspectiveCamera(42, renderer.domElement.width / renderer.domElement.height, 0.01, 100);
}else if( trackingBackend === 'tango' ){
var camera = new THREE.PerspectiveCamera(42, renderer.domElement.width / renderer.domElement.height, 0.01, 100);
}else console.assert(false)
return camera
}
//////////////////////////////////////////////////////////////////////////////
// init functions
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitContext.prototype.init = function(onCompleted){
var _this = this
if( this.parameters.trackingBackend === 'artoolkit' ){
this._initArtoolkit(onCompleted)
this._initArtoolkit(done)
}else if( this.parameters.trackingBackend === 'aruco' ){
this._initAruco(onCompleted)
this._initAruco(done)
}else if( this.parameters.trackingBackend === 'tango' ){
this._initTango(onCompleted)
this._initTango(done)
}else console.assert(false)
return
function done(){
// dispatch event
_this.dispatchEvent({
type: 'initialized'
});
onCompleted && onCompleted()
}
}
////////////////////////////////////////////////////////////////////////////////
// update function
......@@ -2539,8 +2471,6 @@ THREEx.ArToolkitContext.prototype.update = function(srcElement){
return true;
}
////////////////////////////////////////////////////////////////////////////////
// Add/Remove markerControls
////////////////////////////////////////////////////////////////////////////////
......@@ -2623,7 +2553,7 @@ THREEx.ArToolkitContext.prototype._initArtoolkit = function(onCompleted){
// arController.setThresholdMode(artoolkit.AR_LABELING_THRESH_MODE_AUTO_OTSU)
// notify
onCompleted && onCompleted()
onCompleted()
})
return this
}
......@@ -2677,7 +2607,7 @@ THREEx.ArToolkitContext.prototype._initAruco = function(onCompleted){
setTimeout(function(){
onCompleted && onCompleted()
onCompleted()
}, 0)
}
......@@ -2714,6 +2644,7 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
var _this = this
// check webvr is available
if (navigator.getVRDisplays) {
// do nothing
} else if (navigator.getVRDevices) {
alert("Your browser supports WebVR but not the latest version. See <a href='http://webvr.info'>webvr.info</a> for more info.");
} else {
......@@ -2723,6 +2654,7 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
this._tangoContext = {
vrDisplay: null,
vrPointCloud: null,
frameData: new VRFrameData(),
}
......@@ -2730,20 +2662,23 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
// get vrDisplay
navigator.getVRDisplays().then(function (vrDisplays) {
if( vrDisplays.length === 0 ) alert('no vrDisplays available')
var vrDisplay = vrDisplays[0]
_this._tangoContext.vrDisplay = vrDisplay
var vrDisplay = _this._tangoContext.vrDisplay = vrDisplays[0]
console.log('vrDisplays.displayName :', vrDisplay.displayName)
// init vrPointCloud
if( vrDisplay.displayName === "Tango VR Device" ){
_this._tangoContext.vrPointCloud = new THREE.WebAR.VRPointCloud(vrDisplay, true)
}
var canvasElement = document.createElement('canvas')
document.body.appendChild(canvasElement)
var layers = [{ source: canvasElement }]
// vrDisplay.requestPresent(layers).then(function() {
// console.log('vrdisplay request accepted')
// });
// window.vrDisplay = vrDisplay
// NOTE it doesnt seem necessary and it fails on tango
// var canvasElement = document.createElement('canvas')
// document.body.appendChild(canvasElement)
// _this._tangoContext.requestPresent([{ source: canvasElement }]).then(function() {
// console.log('vrdisplay request accepted')
// });
onCompleted && onCompleted()
onCompleted()
});
}
......@@ -2753,9 +2688,19 @@ THREEx.ArToolkitContext.prototype._updateTango = function(srcElement){
var _this = this
var arMarkersControls = this._arMarkersControls
var tangoContext= this._tangoContext
var vrDisplay = this._tangoContext.vrDisplay
// check vrDisplay is already initialized
if( tangoContext.vrDisplay === null ) return
if( vrDisplay === null ) return
// Update the point cloud. Only if the point cloud will be shown the geometry is also updated.
if( vrDisplay.displayName === "Tango VR Device" ){
var showPointCloud = true
var pointsToSkip = 0
_this._tangoContext.vrPointCloud.update(showPointCloud, pointsToSkip, true)
}
if( this._arMarkersControls.length === 0 ) return
......@@ -2766,20 +2711,29 @@ THREEx.ArToolkitContext.prototype._updateTango = function(srcElement){
var frameData = this._tangoContext.frameData
// read frameData
tangoContext.vrDisplay.getFrameData(frameData);
vrDisplay.getFrameData(frameData);
if( frameData.pose.position === null ) return
if( frameData.pose.orientation === null ) return
// create cameraTransformMatrix
var position = new THREE.Vector3().fromArray(frameData.pose.position)
var quaternion = new THREE.Quaternion().fromArray(frameData.pose.orientation)
var scale = new THREE.Vector3(1,1,1)
var scale = new THREE.Vector3(1,1,1)
var cameraTransformMatrix = new THREE.Matrix4().compose(position, quaternion, scale)
// compute modelViewMatrix from cameraTransformMatrix
var modelViewMatrix = new THREE.Matrix4()
modelViewMatrix.getInverse( cameraTransformMatrix )
console.log('position', position)
foundControls.updateWithModelViewMatrix(modelViewMatrix)
// console.log('position', position)
// if( position.x !== 0 || position.y !== 0 || position.z !== 0 ){
// console.log('vrDisplay tracking')
// }else{
// console.log('vrDisplay NOT tracking')
// }
}
var THREEx = THREEx || {}
......@@ -2875,22 +2829,27 @@ THREEx.ArToolkitProfile.prototype.performance = function(label) {
//////////////////////////////////////////////////////////////////////////////
// Marker
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitProfile.prototype.kanjiMarker = function () {
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.kanji'
return this
}
THREEx.ArToolkitProfile.prototype.hiroMarker = function () {
this.contextParameters.detectionMode = 'mono'
THREEx.ArToolkitProfile.prototype.defaultMarker = function (trackingBackend) {
trackingBackend = trackingBackend || this.contextParameters.trackingBackend
if( trackingBackend === 'artoolkit' ){
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro'
}else if( trackingBackend === 'aruco' ){
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'barcode'
this.defaultMarkerParameters.barcodeValue = 1001
}else if( trackingBackend === 'tango' ){
// FIXME temporary placeholder - to reevaluate later
this.defaultMarkerParameters.type = 'barcode'
this.defaultMarkerParameters.barcodeValue = 1001
}else console.assert(false)
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro'
return this
}
//////////////////////////////////////////////////////////////////////////////
// Source
//////////////////////////////////////////////////////////////////////////////
......@@ -2918,6 +2877,7 @@ THREEx.ArToolkitProfile.prototype.sourceImage = function (url) {
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitProfile.prototype.trackingBackend = function (trackingBackend) {
this.contextParameters.trackingBackend = trackingBackend
return this
}
var THREEx = THREEx || {}
......@@ -3155,7 +3115,7 @@ THREEx.ArToolkitSource.prototype.toggleMobileTorch = function(){
// handle resize
////////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
THREEx.ArToolkitSource.prototype.onResizeElement = function(mirrorDomElements){
var _this = this
var screenWidth = window.innerWidth
var screenHeight = window.innerHeight
......@@ -3197,6 +3157,8 @@ THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
this.domElement.style.marginLeft = '0px'
}
if( arguments.length !== 0 ) console.warn('use bad signature for arToolkitSource.copyElementSizeTo')
// honor default parameters
// if( mirrorDomElements !== undefined ) console.warn('still use the old resize. fix it')
if( mirrorDomElements === undefined ) mirrorDomElements = []
......@@ -3208,12 +3170,64 @@ THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
})
}
THREEx.ArToolkitSource.prototype.copySizeTo = function(otherElement){
THREEx.ArToolkitSource.prototype.copyElementSizeTo = function(otherElement){
otherElement.style.width = this.domElement.style.width
otherElement.style.height = this.domElement.style.height
otherElement.style.marginLeft = this.domElement.style.marginLeft
otherElement.style.marginTop = this.domElement.style.marginTop
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.copySizeTo = function(){
console.warn('obsolete function arToolkitSource.copySizeTo. Use arToolkitSource.copyElementSizeTo' )
this.copyElementSizeTo.apply(this, arguments)
}
THREEx.ArToolkitSource.prototype.onResize = function(){
console.warn('obsolete function arToolkitSource.onResize. Use arToolkitSource.onResizeElement' )
this.onResizeElement.apply(this, arguments)
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.onResize2 = function(arToolkitContext, renderer, camera){
var trackingBackend = arToolkitContext.parameters.trackingBackend
// RESIZE DOMELEMENT
if( trackingBackend === 'artoolkit' ){
this.onResizeElement()
this.copyElementSizeTo(renderer.domElement)
if( arToolkitContext.arController !== null ){
this.copyElementSizeTo(arToolkitContext.arController.canvas)
}
}else if( trackingBackend === 'aruco' ){
this.onResizeElement()
this.copyElementSizeTo(renderer.domElement)
this.copyElementSizeTo(arToolkitContext.arucoContext.canvas)
}else if( trackingBackend === 'tango' ){
renderer.setSize( window.innerWidth, window.innerHeight )
}else console.assert(false, 'unhandled trackingBackend '+trackingBackend)
// RESIZE CAMERA
if( trackingBackend === 'artoolkit' ){
camera.projectionMatrix.copy( arToolkitContext.getProjectionMatrix() );
}else if( trackingBackend === 'aruco' ){
camera.aspect = renderer.domElement.width / renderer.domElement.height;
camera.updateProjectionMatrix();
}else if( trackingBackend === 'tango' ){
var vrDisplay = arToolkitContext._tangoContext.vrDisplay
// make camera fit vrDisplay
if( vrDisplay && vrDisplay.displayName === "Tango VR Device" ) THREE.WebAR.resizeVRSeeThroughCamera(vrDisplay, camera)
}else console.assert(false, 'unhandled trackingBackend '+trackingBackend)
}
var THREEx = THREEx || {}
THREEx.ArVideoInWebgl = function(videoTexture){
......@@ -3976,6 +3990,13 @@ THREEx.ArMultiMarkerUtils = {}
//////////////////////////////////////////////////////////////////////////////
// navigateToLearnerPage
//////////////////////////////////////////////////////////////////////////////
/**
* Navigate to the multi-marker learner page
*
* @param {String} learnerBaseURL - the base url for the learner
* @param {String} trackingBackend - the tracking backend to use
*/
THREEx.ArMultiMarkerUtils.navigateToLearnerPage = function(learnerBaseURL, trackingBackend){
var learnerParameters = {
backURL : location.href,
......@@ -3988,6 +4009,12 @@ THREEx.ArMultiMarkerUtils.navigateToLearnerPage = function(learnerBaseURL, track
//////////////////////////////////////////////////////////////////////////////
// DefaultMultiMarkerFile
//////////////////////////////////////////////////////////////////////////////
/**
* Create and store a default multi-marker file
*
* @param {String} trackingBackend - the tracking backend to use
*/
THREEx.ArMultiMarkerUtils.storeDefaultMultiMarkerFile = function(trackingBackend){
var file = THREEx.ArMultiMarkerUtils.createDefaultMultiMarkerFile(trackingBackend)
// json.strinfy the value and store it in localStorage
......@@ -3995,7 +4022,15 @@ THREEx.ArMultiMarkerUtils.storeDefaultMultiMarkerFile = function(trackingBackend
}
/**
* Create a default multi-marker file
* @param {String} trackingBackend - the tracking backend to use
* @return {Object} - json object of the multi-marker file
*/
THREEx.ArMultiMarkerUtils.createDefaultMultiMarkerFile = function(trackingBackend){
console.assert(trackingBackend)
if( trackingBackend === undefined ) debugger
// create the base file
var file = {
meta : {
......@@ -4004,7 +4039,7 @@ THREEx.ArMultiMarkerUtils.createDefaultMultiMarkerFile = function(trackingBacken
},
trackingBackend : trackingBackend,
subMarkersControls : [
// empty for now...
// empty for now... being filled
]
}
// add a subMarkersControls
......@@ -4028,6 +4063,12 @@ THREEx.ArMultiMarkerUtils.createDefaultMultiMarkerFile = function(trackingBacken
// createDefaultMarkersControlsParameters
//////////////////////////////////////////////////////////////////////////////
/**
* Create a default controls parameters for the multi-marker learner
*
* @param {String} trackingBackend - the tracking backend to use
* @return {Object} - json object containing the controls parameters
*/
THREEx.ArMultiMarkerUtils.createDefaultMarkersControlsParameters = function(trackingBackend){
var link = document.createElement('a')
link.href = THREEx.ArToolkitContext.baseURL
......
......@@ -85,10 +85,10 @@
onResize()
})
function onResize(){
arToolkitSource.onResize()
arToolkitSource.copySizeTo(renderer.domElement)
arToolkitSource.onResizeElement()
arToolkitSource.copyElementSizeTo(renderer.domElement)
if( arToolkitContext.arController !== null ){
arToolkitSource.copySizeTo(arToolkitContext.arController.canvas)
arToolkitSource.copyElementSizeTo(arToolkitContext.arController.canvas)
}
}
......
......@@ -277,7 +277,10 @@ THREEx.ArToolkitSource.prototype.onResizeElement = function(mirrorDomElements){
}
if( arguments.length !== 0 ) console.warn('use bad signature for arToolkitSource.copyElementSizeTo')
if( arguments.length !== 0 ){
debugger
console.warn('use bad signature for arToolkitSource.copyElementSizeTo')
}
// honor default parameters
// if( mirrorDomElements !== undefined ) console.warn('still use the old resize. fix it')
if( mirrorDomElements === undefined ) mirrorDomElements = []
......@@ -285,7 +288,7 @@ THREEx.ArToolkitSource.prototype.onResizeElement = function(mirrorDomElements){
// Mirror _this.domElement.style to mirrorDomElements
mirrorDomElements.forEach(function(domElement){
_this.copySizeTo(domElement)
_this.copyElementSizeTo(domElement)
})
}
......
......@@ -1662,7 +1662,6 @@ var THREEx = THREEx || {}
* - seems an easy light layer for clickable object
* - up to
*/
THREEx.ARClickability = function(sourceElement){
this._sourceElement = sourceElement
// Create cameraPicking
......@@ -1701,6 +1700,39 @@ THREEx.ARClickability.prototype.computeIntersects = function(domEvent, objects){
THREEx.ARClickability.prototype.update = function(){
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ARClickability.tangoPickingPointCloud = function(artoolkitContext, mouseX, mouseY){
var vrDisplay = artoolkitContext._tangoContext.vrDisplay
if (vrDisplay === null ) return
var pointAndPlane = vrDisplay.getPickingPointAndPlaneInPointCloud(mouseX, mouseY)
if( pointAndPlane == null ) {
console.warn('Could not retrieve the correct point and plane.')
return null
}
// FIXME not sure what this is
var boundingSphereRadius = 0.01
// the bigger the number the likeliest it crash chromium-webar
// Orient and position the model in the picking point according
// to the picking plane. The offset is half of the model size.
var object3d = new THREE.Object3D
THREE.WebAR.positionAndRotateObject3DWithPickingPointAndPlaneInPointCloud(
pointAndPlane, object3d, boundingSphereRadius
)
object3d.rotateZ(-Math.PI/2)
// return the result
var result = {}
result.position = object3d.position
result.quaternion = object3d.quaternion
return result
}
var THREEx = THREEx || {}
/**
* - videoTexture
......@@ -2099,7 +2131,6 @@ THREEx.ArMarkerControls.prototype._initArtoolkit = function(){
}else{
console.log(false, 'invalid marker type', _this.parameters.type)
}
// listen to the event
arController.addEventListener('getMarker', function(event){
......@@ -2233,136 +2264,6 @@ THREEx.ArSmoothedControls.prototype.update = function(targetObject3d){
var present = performance.now()/1000
//////////////////////////////////////////////////////////////////////////////
// handle object3d.visible with minVisibleDelay/minUnvisibleDelay
//////////////////////////////////////////////////////////////////////////////
if( targetObject3d.visible === false ) this._visibleStartedAt = null
if( targetObject3d.visible === true ) this._unvisibleStartedAt = null
if( wasVisible === false && targetObject3d.visible === true ){
if( this._visibleStartedAt === null ) this._visibleStartedAt = present
var visibleFor = present - this._visibleStartedAt
if( visibleFor >= this.parameters.minVisibleDelay ){
object3d.visible = true
this._visibleStartedAt = null
}
console.log('visibleFor', visibleFor)
}
if( wasVisible === true && targetObject3d.visible === false ){
if( this._unvisibleStartedAt === null ) this._unvisibleStartedAt = present
var unvisibleFor = present - this._unvisibleStartedAt
if( unvisibleFor >= this.parameters.minUnvisibleDelay ){
object3d.visible = false
}
// console.log('unvisibleFor', unvisibleFor)
}
// disabled minVisibleDelay+minUnvisibleDelay
// if( true ){
// object3d.visible = targetObject3d.visible
// }
//////////////////////////////////////////////////////////////////////////////
// apply lerp on positon/quaternion/scale
//////////////////////////////////////////////////////////////////////////////
// apply lerp steps - require fix time steps to behave the same no matter the fps
if( this._lastLerpStepAt === null ){
applyOneSlepStep()
this._lastLerpStepAt = present
}else{
var nStepsToDo = Math.floor( (present - this._lastLerpStepAt)/this.parameters.lerpStepDelay )
for(var i = 0; i < nStepsToDo; i++){
applyOneSlepStep()
this._lastLerpStepAt += this.parameters.lerpStepDelay
}
}
// update the matrix
this.object3d.updateMatrix()
// disable the lerp by directly copying targetObject3d position/quaternion/scale
if( false ){
this.object3d.position.copy( targetObject3d.position )
this.object3d.quaternion.copy( targetObject3d.quaternion )
this.object3d.scale.copy( targetObject3d.scale )
this.object3d.updateMatrix()
}
//////////////////////////////////////////////////////////////////////////////
// honor becameVisible/becameUnVisible event
//////////////////////////////////////////////////////////////////////////////
// honor becameVisible event
if( wasVisible === false && object3d.visible === true ){
this.dispatchEvent({ type: 'becameVisible' })
}
// honor becameUnVisible event
if( wasVisible === true && object3d.visible === false ){
this.dispatchEvent({ type: 'becameUnVisible' })
}
return
function applyOneSlepStep(){
object3d.position.lerp(targetObject3d.position, parameters.lerpPosition)
object3d.quaternion.slerp(targetObject3d.quaternion, parameters.lerpQuaternion)
object3d.scale.lerp(targetObject3d.scale, parameters.lerpScale)
}
}
var THREEx = THREEx || {}
/**
* - lerp position/quaternino/scale
* - minDelayDetected
* - minDelayUndetected
* @param {[type]} object3d [description]
* @param {[type]} parameters [description]
*/
THREEx.ArSmoothedControls = function(object3d, parameters){
var _this = this
THREEx.ArBaseControls.call(this, object3d)
// copy parameters
this.object3d.visible = false
this._lastLerpStepAt = null
this._visibleStartedAt = null
this._unvisibleStartedAt = null
// handle default parameters
parameters = parameters || {}
this.parameters = {
// lerp coeficient for the position - between [0,1] - default to 1
lerpPosition: parameters.lerpPosition !== undefined ? parameters.lerpPosition : 0.8,
// lerp coeficient for the quaternion - between [0,1] - default to 1
lerpQuaternion: parameters.lerpQuaternion !== undefined ? parameters.lerpQuaternion : 0.2,
// lerp coeficient for the scale - between [0,1] - default to 1
lerpScale: parameters.lerpScale !== undefined ? parameters.lerpScale : 0.7,
// delay for lerp fixed steps - in seconds - default to 1/120
lerpStepDelay: parameters.fixStepDelay !== undefined ? parameters.fixStepDelay : 1/60,
// minimum delay the sub-control must be visible before this controls become visible - default to 0 seconds
minVisibleDelay: parameters.minVisibleDelay !== undefined ? parameters.minVisibleDelay : 0.0,
// minimum delay the sub-control must be unvisible before this controls become unvisible - default to 0 seconds
minUnvisibleDelay: parameters.minUnvisibleDelay !== undefined ? parameters.minUnvisibleDelay : 0.2,
}
}
THREEx.ArSmoothedControls.prototype = Object.create( THREEx.ArBaseControls.prototype );
THREEx.ArSmoothedControls.prototype.constructor = THREEx.ArSmoothedControls;
//////////////////////////////////////////////////////////////////////////////
// update function
//////////////////////////////////////////////////////////////////////////////
THREEx.ArSmoothedControls.prototype.update = function(targetObject3d){
var object3d = this.object3d
var parameters = this.parameters
var wasVisible = object3d.visible
var present = performance.now()/1000
//////////////////////////////////////////////////////////////////////////////
// handle object3d.visible with minVisibleDelay/minUnvisibleDelay
//////////////////////////////////////////////////////////////////////////////
......@@ -2451,7 +2352,7 @@ THREEx.ArToolkitContext = function(parameters){
// debug - true if one should display artoolkit debug canvas, false otherwise
debug: parameters.debug !== undefined ? parameters.debug : false,
// the mode of detection - ['color', 'color_and_matrix', 'mono', 'mono_and_matrix']
detectionMode: parameters.detectionMode !== undefined ? parameters.detectionMode : 'color_and_matrix',
detectionMode: parameters.detectionMode !== undefined ? parameters.detectionMode : 'mono',
// type of matrix code - valid iif detectionMode end with 'matrix' - [3x3, 3x3_HAMMING63, 3x3_PARITY65, 4x4, 4x4_BCH_13_9_3, 4x4_BCH_13_5_5]
matrixCodeType: parameters.matrixCodeType !== undefined ? parameters.matrixCodeType : '3x3',
......@@ -2486,17 +2387,48 @@ THREEx.ArToolkitContext.baseURL = 'https://jeromeetienne.github.io/AR.js/three.j
THREEx.ArToolkitContext.REVISION = '1.0.1-dev'
/**
* Create a default camera for this trackingBackend
* @param {string} trackingBackend - the tracking to user
* @return {THREE.Camera} the created camera
*/
THREEx.ArToolkitContext.createDefaultCamera = function( trackingBackend ){
console.assert(false, 'use ARjs.Utils.createDefaultCamera instead')
// Create a camera
if( trackingBackend === 'artoolkit' ){
var camera = new THREE.Camera();
}else if( trackingBackend === 'aruco' ){
var camera = new THREE.PerspectiveCamera(42, renderer.domElement.width / renderer.domElement.height, 0.01, 100);
}else if( trackingBackend === 'tango' ){
var camera = new THREE.PerspectiveCamera(42, renderer.domElement.width / renderer.domElement.height, 0.01, 100);
}else console.assert(false)
return camera
}
//////////////////////////////////////////////////////////////////////////////
// init functions
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitContext.prototype.init = function(onCompleted){
var _this = this
if( this.parameters.trackingBackend === 'artoolkit' ){
this._initArtoolkit(onCompleted)
this._initArtoolkit(done)
}else if( this.parameters.trackingBackend === 'aruco' ){
this._initAruco(onCompleted)
this._initAruco(done)
}else if( this.parameters.trackingBackend === 'tango' ){
this._initTango(onCompleted)
this._initTango(done)
}else console.assert(false)
return
function done(){
// dispatch event
_this.dispatchEvent({
type: 'initialized'
});
onCompleted && onCompleted()
}
}
////////////////////////////////////////////////////////////////////////////////
// update function
......@@ -2539,8 +2471,6 @@ THREEx.ArToolkitContext.prototype.update = function(srcElement){
return true;
}
////////////////////////////////////////////////////////////////////////////////
// Add/Remove markerControls
////////////////////////////////////////////////////////////////////////////////
......@@ -2623,7 +2553,7 @@ THREEx.ArToolkitContext.prototype._initArtoolkit = function(onCompleted){
// arController.setThresholdMode(artoolkit.AR_LABELING_THRESH_MODE_AUTO_OTSU)
// notify
onCompleted && onCompleted()
onCompleted()
})
return this
}
......@@ -2677,7 +2607,7 @@ THREEx.ArToolkitContext.prototype._initAruco = function(onCompleted){
setTimeout(function(){
onCompleted && onCompleted()
onCompleted()
}, 0)
}
......@@ -2714,6 +2644,7 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
var _this = this
// check webvr is available
if (navigator.getVRDisplays) {
// do nothing
} else if (navigator.getVRDevices) {
alert("Your browser supports WebVR but not the latest version. See <a href='http://webvr.info'>webvr.info</a> for more info.");
} else {
......@@ -2723,6 +2654,7 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
this._tangoContext = {
vrDisplay: null,
vrPointCloud: null,
frameData: new VRFrameData(),
}
......@@ -2730,20 +2662,23 @@ THREEx.ArToolkitContext.prototype._initTango = function(onCompleted){
// get vrDisplay
navigator.getVRDisplays().then(function (vrDisplays) {
if( vrDisplays.length === 0 ) alert('no vrDisplays available')
var vrDisplay = vrDisplays[0]
_this._tangoContext.vrDisplay = vrDisplay
var vrDisplay = _this._tangoContext.vrDisplay = vrDisplays[0]
console.log('vrDisplays.displayName :', vrDisplay.displayName)
// init vrPointCloud
if( vrDisplay.displayName === "Tango VR Device" ){
_this._tangoContext.vrPointCloud = new THREE.WebAR.VRPointCloud(vrDisplay, true)
}
var canvasElement = document.createElement('canvas')
document.body.appendChild(canvasElement)
var layers = [{ source: canvasElement }]
// vrDisplay.requestPresent(layers).then(function() {
// console.log('vrdisplay request accepted')
// });
// window.vrDisplay = vrDisplay
// NOTE it doesnt seem necessary and it fails on tango
// var canvasElement = document.createElement('canvas')
// document.body.appendChild(canvasElement)
// _this._tangoContext.requestPresent([{ source: canvasElement }]).then(function() {
// console.log('vrdisplay request accepted')
// });
onCompleted && onCompleted()
onCompleted()
});
}
......@@ -2753,9 +2688,19 @@ THREEx.ArToolkitContext.prototype._updateTango = function(srcElement){
var _this = this
var arMarkersControls = this._arMarkersControls
var tangoContext= this._tangoContext
var vrDisplay = this._tangoContext.vrDisplay
// check vrDisplay is already initialized
if( tangoContext.vrDisplay === null ) return
if( vrDisplay === null ) return
// Update the point cloud. Only if the point cloud will be shown the geometry is also updated.
if( vrDisplay.displayName === "Tango VR Device" ){
var showPointCloud = true
var pointsToSkip = 0
_this._tangoContext.vrPointCloud.update(showPointCloud, pointsToSkip, true)
}
if( this._arMarkersControls.length === 0 ) return
......@@ -2766,20 +2711,29 @@ THREEx.ArToolkitContext.prototype._updateTango = function(srcElement){
var frameData = this._tangoContext.frameData
// read frameData
tangoContext.vrDisplay.getFrameData(frameData);
vrDisplay.getFrameData(frameData);
if( frameData.pose.position === null ) return
if( frameData.pose.orientation === null ) return
// create cameraTransformMatrix
var position = new THREE.Vector3().fromArray(frameData.pose.position)
var quaternion = new THREE.Quaternion().fromArray(frameData.pose.orientation)
var scale = new THREE.Vector3(1,1,1)
var scale = new THREE.Vector3(1,1,1)
var cameraTransformMatrix = new THREE.Matrix4().compose(position, quaternion, scale)
// compute modelViewMatrix from cameraTransformMatrix
var modelViewMatrix = new THREE.Matrix4()
modelViewMatrix.getInverse( cameraTransformMatrix )
console.log('position', position)
foundControls.updateWithModelViewMatrix(modelViewMatrix)
// console.log('position', position)
// if( position.x !== 0 || position.y !== 0 || position.z !== 0 ){
// console.log('vrDisplay tracking')
// }else{
// console.log('vrDisplay NOT tracking')
// }
}
var THREEx = THREEx || {}
......@@ -2875,22 +2829,27 @@ THREEx.ArToolkitProfile.prototype.performance = function(label) {
//////////////////////////////////////////////////////////////////////////////
// Marker
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitProfile.prototype.kanjiMarker = function () {
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.kanji'
return this
}
THREEx.ArToolkitProfile.prototype.hiroMarker = function () {
this.contextParameters.detectionMode = 'mono'
THREEx.ArToolkitProfile.prototype.defaultMarker = function (trackingBackend) {
trackingBackend = trackingBackend || this.contextParameters.trackingBackend
if( trackingBackend === 'artoolkit' ){
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro'
}else if( trackingBackend === 'aruco' ){
this.contextParameters.detectionMode = 'mono'
this.defaultMarkerParameters.type = 'barcode'
this.defaultMarkerParameters.barcodeValue = 1001
}else if( trackingBackend === 'tango' ){
// FIXME temporary placeholder - to reevaluate later
this.defaultMarkerParameters.type = 'barcode'
this.defaultMarkerParameters.barcodeValue = 1001
}else console.assert(false)
this.defaultMarkerParameters.type = 'pattern'
this.defaultMarkerParameters.patternUrl = THREEx.ArToolkitContext.baseURL + '../data/data/patt.hiro'
return this
}
//////////////////////////////////////////////////////////////////////////////
// Source
//////////////////////////////////////////////////////////////////////////////
......@@ -2918,6 +2877,7 @@ THREEx.ArToolkitProfile.prototype.sourceImage = function (url) {
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitProfile.prototype.trackingBackend = function (trackingBackend) {
this.contextParameters.trackingBackend = trackingBackend
return this
}
var THREEx = THREEx || {}
......@@ -3155,7 +3115,7 @@ THREEx.ArToolkitSource.prototype.toggleMobileTorch = function(){
// handle resize
////////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
THREEx.ArToolkitSource.prototype.onResizeElement = function(mirrorDomElements){
var _this = this
var screenWidth = window.innerWidth
var screenHeight = window.innerHeight
......@@ -3197,6 +3157,8 @@ THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
this.domElement.style.marginLeft = '0px'
}
if( arguments.length !== 0 ) console.warn('use bad signature for arToolkitSource.copyElementSizeTo')
// honor default parameters
// if( mirrorDomElements !== undefined ) console.warn('still use the old resize. fix it')
if( mirrorDomElements === undefined ) mirrorDomElements = []
......@@ -3208,12 +3170,64 @@ THREEx.ArToolkitSource.prototype.onResize = function(mirrorDomElements){
})
}
THREEx.ArToolkitSource.prototype.copySizeTo = function(otherElement){
THREEx.ArToolkitSource.prototype.copyElementSizeTo = function(otherElement){
otherElement.style.width = this.domElement.style.width
otherElement.style.height = this.domElement.style.height
otherElement.style.marginLeft = this.domElement.style.marginLeft
otherElement.style.marginTop = this.domElement.style.marginTop
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.copySizeTo = function(){
console.warn('obsolete function arToolkitSource.copySizeTo. Use arToolkitSource.copyElementSizeTo' )
this.copyElementSizeTo.apply(this, arguments)
}
THREEx.ArToolkitSource.prototype.onResize = function(){
console.warn('obsolete function arToolkitSource.onResize. Use arToolkitSource.onResizeElement' )
this.onResizeElement.apply(this, arguments)
}
//////////////////////////////////////////////////////////////////////////////
// Code Separator
//////////////////////////////////////////////////////////////////////////////
THREEx.ArToolkitSource.prototype.onResize2 = function(arToolkitContext, renderer, camera){
var trackingBackend = arToolkitContext.parameters.trackingBackend
// RESIZE DOMELEMENT
if( trackingBackend === 'artoolkit' ){
this.onResizeElement()
this.copyElementSizeTo(renderer.domElement)
if( arToolkitContext.arController !== null ){
this.copyElementSizeTo(arToolkitContext.arController.canvas)
}
}else if( trackingBackend === 'aruco' ){
this.onResizeElement()
this.copyElementSizeTo(renderer.domElement)
this.copyElementSizeTo(arToolkitContext.arucoContext.canvas)
}else if( trackingBackend === 'tango' ){
renderer.setSize( window.innerWidth, window.innerHeight )
}else console.assert(false, 'unhandled trackingBackend '+trackingBackend)
// RESIZE CAMERA
if( trackingBackend === 'artoolkit' ){
camera.projectionMatrix.copy( arToolkitContext.getProjectionMatrix() );
}else if( trackingBackend === 'aruco' ){
camera.aspect = renderer.domElement.width / renderer.domElement.height;
camera.updateProjectionMatrix();
}else if( trackingBackend === 'tango' ){
var vrDisplay = arToolkitContext._tangoContext.vrDisplay
// make camera fit vrDisplay
if( vrDisplay && vrDisplay.displayName === "Tango VR Device" ) THREE.WebAR.resizeVRSeeThroughCamera(vrDisplay, camera)
}else console.assert(false, 'unhandled trackingBackend '+trackingBackend)
}
var THREEx = THREEx || {}
THREEx.ArVideoInWebgl = function(videoTexture){
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册