482 lines
14 KiB
JavaScript
482 lines
14 KiB
JavaScript
|
/**
|
||
|
* AR object
|
||
|
* @param augmented
|
||
|
* @param apiAR
|
||
|
* @returns {R3.AR}
|
||
|
* @constructor
|
||
|
*/
|
||
|
R3.AR = function(
|
||
|
augmented,
|
||
|
apiAR
|
||
|
) {
|
||
|
this.augmented = augmented;
|
||
|
|
||
|
if (R3.Utils.UndefinedOrNull(apiAR)) {
|
||
|
apiAR = {};
|
||
|
}
|
||
|
|
||
|
R3.API.AR.call(
|
||
|
this,
|
||
|
apiAR.id,
|
||
|
apiAR.name,
|
||
|
apiAR.parent,
|
||
|
apiAR.video,
|
||
|
apiAR.pathCamera,
|
||
|
apiAR.pathMarker,
|
||
|
apiAR.scene,
|
||
|
apiAR.camera,
|
||
|
apiAR.videoScene,
|
||
|
apiAR.videoCamera
|
||
|
);
|
||
|
|
||
|
if (
|
||
|
R3.Utils.Defined(this.video) &&
|
||
|
R3.Utils.Defined(this.video.componentType) &&
|
||
|
!(this.video instanceof R3.Video)
|
||
|
) {
|
||
|
this.video = R3.Component.ConstructFromObject(this.video);
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
R3.Utils.Defined(this.scene) &&
|
||
|
R3.Utils.Defined(this.scene.componentType) &&
|
||
|
!(this.scene instanceof R3.D3.Scene)
|
||
|
) {
|
||
|
this.scene = R3.Component.ConstructFromObject(this.scene);
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
R3.Utils.Defined(this.camera) &&
|
||
|
R3.Utils.Defined(this.camera.componentType) &&
|
||
|
!(this.camera instanceof R3.D3.Camera.Orthographic)
|
||
|
) {
|
||
|
this.camera = R3.Component.ConstructFromObject(this.camera);
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
R3.Utils.Defined(this.videoScene) &&
|
||
|
R3.Utils.Defined(this.videoScene.componentType) &&
|
||
|
!(this.videoScene instanceof R3.D3.Scene)
|
||
|
) {
|
||
|
this.videoScene = R3.Component.ConstructFromObject(this.videoScene);
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
R3.Utils.Defined(this.videoCamera) &&
|
||
|
R3.Utils.Defined(this.videoCamera.componentType) &&
|
||
|
!(this.videoCamera instanceof R3.D3.Camera.Orthographic)
|
||
|
) {
|
||
|
this.videoCamera = R3.Component.ConstructFromObject(this.videoCamera);
|
||
|
}
|
||
|
|
||
|
R3.Component.call(
|
||
|
this,
|
||
|
{
|
||
|
'video' : R3.Video,
|
||
|
'scene' : R3.D3.Scene,
|
||
|
'camera' : R3.D3.Camera,
|
||
|
'videoScene' : R3.D3.Scene,
|
||
|
'videoCamera' : R3.D3.Camera
|
||
|
}
|
||
|
);
|
||
|
|
||
|
};
|
||
|
|
||
|
R3.AR.prototype = Object.create(R3.Component.prototype);
|
||
|
R3.AR.prototype.constructor = R3.AR;
|
||
|
|
||
|
/**
|
||
|
* Creates a light instance
|
||
|
* @returns {*}
|
||
|
*/
|
||
|
R3.AR.prototype.createInstance = function() {
|
||
|
|
||
|
ARController.prototype.setupThree = function(arComponent) {
|
||
|
|
||
|
return function() {
|
||
|
|
||
|
if (this.THREE_JS_ENABLED) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this.THREE_JS_ENABLED = true;
|
||
|
|
||
|
/*
|
||
|
Listen to getMarker events to keep track of Three.js markers.
|
||
|
*/
|
||
|
this.addEventListener(
|
||
|
'getMarker',
|
||
|
function (event) {
|
||
|
|
||
|
if (event.data.type === artoolkit.PATTERN_MARKER) {
|
||
|
|
||
|
// console.log('found marker');
|
||
|
|
||
|
/**
|
||
|
* We want to update the camera
|
||
|
*/
|
||
|
var modelViewMatrix = new THREE.Matrix4().fromArray(event.data.matrix);
|
||
|
|
||
|
/**
|
||
|
* Apply context._axisTransformMatrix - change artoolkit axis to match usual webgl one
|
||
|
*/
|
||
|
var tmpMatrix = new THREE.Matrix4().copy(this._artoolkitProjectionAxisTransformMatrix);
|
||
|
|
||
|
tmpMatrix.multiply(modelViewMatrix);
|
||
|
|
||
|
modelViewMatrix.copy(tmpMatrix);
|
||
|
|
||
|
/**
|
||
|
* Change axis orientation on marker - artoolkit say Z is normal to the marker - ar.js say Y is normal to the marker
|
||
|
*/
|
||
|
var markerAxisTransformMatrix = new THREE.Matrix4().makeRotationX(Math.PI / 2);
|
||
|
modelViewMatrix.multiply(markerAxisTransformMatrix);
|
||
|
arComponent.camera.instance.matrix.getInverse(modelViewMatrix);
|
||
|
|
||
|
/**
|
||
|
* Decompose - the matrix into .position, .quaternion, .scale
|
||
|
*/
|
||
|
arComponent.camera.instance.matrix.decompose(
|
||
|
arComponent.camera.instance.position,
|
||
|
arComponent.camera.instance.quaternion,
|
||
|
arComponent.camera.instance.scale
|
||
|
);
|
||
|
|
||
|
// get projectionMatrixArr from artoolkit
|
||
|
var projectionMatrixArr = this.camera_mat;
|
||
|
|
||
|
var projectionMatrix = new THREE.Matrix4().fromArray(projectionMatrixArr);
|
||
|
|
||
|
// apply context._axisTransformMatrix - change artoolkit axis to match usual webgl one
|
||
|
projectionMatrix.multiply(this._artoolkitProjectionAxisTransformMatrix);
|
||
|
|
||
|
arComponent.camera.instance.projectionMatrix.copy(projectionMatrix);
|
||
|
|
||
|
arComponent.camera.updateFromInstance();
|
||
|
|
||
|
arComponent.camera.instance.fov = arComponent.camera.fov;
|
||
|
arComponent.camera.instance.near = arComponent.camera.near;
|
||
|
arComponent.camera.instance.far = arComponent.camera.far;
|
||
|
arComponent.camera.instance.filmGauge = arComponent.camera.filmGauge;
|
||
|
arComponent.camera.instance.filmOffset = arComponent.camera.filmOffset;
|
||
|
arComponent.camera.instance.focus = arComponent.camera.focus;
|
||
|
arComponent.camera.instance.zoom = arComponent.camera.zoom;
|
||
|
arComponent.camera.instance.aspect = arComponent.camera.aspect;
|
||
|
arComponent.camera.instance.updateProjectionMatrix();
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
);
|
||
|
|
||
|
this.threePatternMarkers = {};
|
||
|
|
||
|
this._artoolkitProjectionAxisTransformMatrix = new THREE.Matrix4();
|
||
|
this._artoolkitProjectionAxisTransformMatrix.multiply(new THREE.Matrix4().makeRotationY(Math.PI));
|
||
|
this._artoolkitProjectionAxisTransformMatrix.multiply(new THREE.Matrix4().makeRotationZ(Math.PI));
|
||
|
}
|
||
|
}(this);
|
||
|
|
||
|
R3.Event.Emit(
|
||
|
R3.Event.GET_RENDER_CONFIGURATION,
|
||
|
null,
|
||
|
function (renderConfiguration) {
|
||
|
|
||
|
if (this.scene === null) {
|
||
|
this.scene = renderConfiguration.activeScene;
|
||
|
}
|
||
|
|
||
|
if (this.camera === null) {
|
||
|
this.camera = renderConfiguration.activeCamera;
|
||
|
}
|
||
|
|
||
|
if (this.renderer === null) {
|
||
|
this.renderer = renderConfiguration.activeRenderer;
|
||
|
}
|
||
|
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
if (this.augmented.augmentedType === R3.AugmentedRuntime.JS_AR_TOOLKIT_5) {
|
||
|
|
||
|
console.warn('Using js artoolkit 5');
|
||
|
|
||
|
if (this.scene === null) {
|
||
|
console.warn('there is no default scene to create an AR component with');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (this.camera === null) {
|
||
|
console.warn('there is no default camera to create an AR component with');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ARController.getUserMediaThreeScene(
|
||
|
{
|
||
|
maxARVideoSize: 320,
|
||
|
cameraParam: this.pathCamera,
|
||
|
|
||
|
onSuccess: function (arScene,
|
||
|
arController,
|
||
|
arCamera) {
|
||
|
|
||
|
R3.Event.Emit(
|
||
|
R3.Event.GET_RENDER_CONFIGURATION,
|
||
|
null,
|
||
|
function(renderConfiguration) {
|
||
|
|
||
|
this.videoCamera.instance = arScene.videoCamera;
|
||
|
|
||
|
this.videoScene.instance = arScene.videoScene;
|
||
|
|
||
|
this.videoScene.camera = this.videoCamera;
|
||
|
|
||
|
//arScene.videoScene.children[0].material.map.flipY = true;
|
||
|
|
||
|
/**
|
||
|
* Also update the video texture before render
|
||
|
*/
|
||
|
this.subscribe(
|
||
|
R3.Event.BEFORE_RENDER,
|
||
|
function() {
|
||
|
arScene.videoScene.children[0].material.map.needsUpdate = true;
|
||
|
}
|
||
|
);
|
||
|
|
||
|
if (renderConfiguration.activeScenes.indexOf(this.videoScene) === -1) {
|
||
|
console.log('not adding video scene to default active scenes');
|
||
|
//renderConfiguration.activeScenes.unshift(this.videoScene);
|
||
|
}
|
||
|
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
arController.loadMarker(
|
||
|
this.pathMarker,
|
||
|
function (markerId) {
|
||
|
|
||
|
var markerRoot = arController.createThreeMarker(markerId);
|
||
|
|
||
|
markerRoot.add(this.scene.instance);
|
||
|
|
||
|
this.instance = {
|
||
|
arScene: arScene,
|
||
|
arController: arController,
|
||
|
arCamera: arCamera
|
||
|
};
|
||
|
|
||
|
R3.Component.prototype.createInstance.call(this);
|
||
|
|
||
|
}.bind(this)
|
||
|
);
|
||
|
|
||
|
}.bind(this)
|
||
|
}
|
||
|
);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (this.augmented.augmentedType === R3.AugmentedRuntime.AR_JS) {
|
||
|
|
||
|
console.log('using ar.js');
|
||
|
|
||
|
var size = R3.Utils.GetWindowSize();
|
||
|
|
||
|
this.arToolkitSource = new THREEx.ArToolkitSource(
|
||
|
{
|
||
|
sourceType: 'webcam',
|
||
|
sourceWidth: size.width,
|
||
|
sourceHeight: size.height,
|
||
|
displayWidth: size.width,
|
||
|
displayHeight: size.height
|
||
|
}
|
||
|
);
|
||
|
|
||
|
this.arToolkitSource.init(
|
||
|
|
||
|
function initialized() {
|
||
|
|
||
|
this.arToolkitSource.domElement.setAttribute('muted', '');
|
||
|
|
||
|
this.video.instance = this.arToolkitSource.domElement;
|
||
|
|
||
|
this.arToolkitContext = new THREEx.ArToolkitContext(
|
||
|
{
|
||
|
cameraParametersUrl: this.pathCamera,
|
||
|
detectionMode: 'mono',
|
||
|
maxDetectionRate: 30,
|
||
|
canvasWidth: 80*3,
|
||
|
canvasHeight: 60*3
|
||
|
}
|
||
|
);
|
||
|
|
||
|
this.arToolkitContext.init(
|
||
|
|
||
|
function initialized() {
|
||
|
|
||
|
this.controls = new THREEx.ArMarkerControls(
|
||
|
this.arToolkitContext,
|
||
|
this.camera.instance,
|
||
|
{
|
||
|
type: 'pattern',
|
||
|
patternUrl: this.pathMarker,
|
||
|
changeMatrixMode: 'cameraTransformMatrix'
|
||
|
}
|
||
|
);
|
||
|
|
||
|
this.instance = {
|
||
|
arToolkitContext: this.arToolkitContext,
|
||
|
arToolkitSource: this.arToolkitSource
|
||
|
};
|
||
|
|
||
|
this.scene.instance.add(this.camera.instance);
|
||
|
|
||
|
this.resize();
|
||
|
|
||
|
/**
|
||
|
* Copy the projectionmatrix of the context to our camera
|
||
|
* UPDATE - don't do this cause it messes up the projection matrix
|
||
|
*/
|
||
|
// this.camera.instance.projectionMatrix.copy(
|
||
|
// this.arToolkitContext.getProjectionMatrix()
|
||
|
// );
|
||
|
|
||
|
|
||
|
R3.Component.prototype.createInstance.call(this);
|
||
|
|
||
|
}.bind(this)
|
||
|
)
|
||
|
|
||
|
}.bind(this)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Updates the instance with the current state
|
||
|
*/
|
||
|
R3.AR.prototype.updateInstance = function(property) {
|
||
|
|
||
|
if (R3.Utils.UndefinedOrNull(property)) {
|
||
|
console.warn('unknown property update for AR: ' + property);
|
||
|
}
|
||
|
|
||
|
if (property === 'id') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (property === 'name') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (property === 'video') {
|
||
|
console.warn('todo: update video');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (property === 'pathCamera') {
|
||
|
console.warn('todo: update pathCamera');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (property === 'pathMarker') {
|
||
|
console.warn('todo: update pathMarker');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (property === 'scene') {
|
||
|
console.warn('todo: update scene');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (property === 'camera') {
|
||
|
console.warn('todo: update camera');
|
||
|
//
|
||
|
// if (this.augmented.augmentedType === R3.AugmentedRuntime.AR_JS) {
|
||
|
//
|
||
|
// if (this.camera) {
|
||
|
// this.controls = new THREEx.ArMarkerControls(
|
||
|
// this.arToolkitContext,
|
||
|
// this.camera.instance,
|
||
|
// {
|
||
|
// type: 'pattern',
|
||
|
// patternUrl: this.pathMarker,
|
||
|
// changeMatrixMode: 'cameraTransformMatrix'
|
||
|
// }
|
||
|
// );
|
||
|
// }
|
||
|
// }
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (property === 'videoScene') {
|
||
|
console.warn('todo: update videoScene');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (property === 'videoCamera') {
|
||
|
console.warn('todo: update videoCamera');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
R3.Component.prototype.updateInstance.call(this, property);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Converts a R3.AR to a R3.API.AR
|
||
|
* @returns {R3.API.AR}
|
||
|
*/
|
||
|
R3.AR.prototype.toApiObject = function() {
|
||
|
|
||
|
return new R3.API.AR(
|
||
|
this.id,
|
||
|
this.name,
|
||
|
R3.Utils.IdOrNull(this.parent),
|
||
|
R3.Utils.IdOrNull(this.video),
|
||
|
this.pathCamera,
|
||
|
this.pathMarker,
|
||
|
R3.Utils.IdOrNull(this.scene),
|
||
|
R3.Utils.IdOrNull(this.camera),
|
||
|
R3.Utils.IdOrNull(this.videoScene),
|
||
|
R3.Utils.IdOrNull(this.videoCamera)
|
||
|
);
|
||
|
};
|
||
|
|
||
|
R3.AR.prototype.beforeRender = function() {
|
||
|
|
||
|
if (this.augmented.augmentedType === R3.AugmentedRuntime.JS_AR_TOOLKIT_5) {
|
||
|
this.instance.arScene.process();
|
||
|
this.instance.arScene.renderOn(renderer.instance);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (this.augmented.augmentedType === R3.AugmentedRuntime.AR_JS) {
|
||
|
this.arToolkitContext.update(
|
||
|
this.arToolkitSource.domElement
|
||
|
);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
R3.AR.prototype.resize = function() {
|
||
|
|
||
|
if (this.augmented.augmentedType === R3.AugmentedRuntime.AR_JS) {
|
||
|
|
||
|
console.log('updating AR size');
|
||
|
|
||
|
this.arToolkitSource.onResizeElement();
|
||
|
|
||
|
if (this.arToolkitContext.arController !== null){
|
||
|
this.arToolkitSource.copyElementSizeTo(
|
||
|
this.arToolkitContext.arController.canvas
|
||
|
)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
};
|