|
@@ -7997,6 +7997,24 @@ var BABYLON;
|
|
}
|
|
}
|
|
return this;
|
|
return this;
|
|
};
|
|
};
|
|
|
|
+ /**
|
|
|
|
+ * Toggles model matrix from being right handed to left handed in place and vice versa
|
|
|
|
+ */
|
|
|
|
+ Matrix.prototype.toggleModelMatrixHandInPlace = function () {
|
|
|
|
+ var _this = this;
|
|
|
|
+ [2, 6, 8, 9, 14].forEach(function (num) {
|
|
|
|
+ _this.m[num] *= -1;
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Toggles projection matrix from being right handed to left handed in place and vice versa
|
|
|
|
+ */
|
|
|
|
+ Matrix.prototype.toggleProjectionMatrixHandInPlace = function () {
|
|
|
|
+ var _this = this;
|
|
|
|
+ [8, 9, 10, 11].forEach(function (num) {
|
|
|
|
+ _this.m[num] *= -1;
|
|
|
|
+ });
|
|
|
|
+ };
|
|
// Statics
|
|
// Statics
|
|
/**
|
|
/**
|
|
* Creates a matrix from an array
|
|
* Creates a matrix from an array
|
|
@@ -10355,7 +10373,12 @@ var BABYLON;
|
|
|
|
|
|
//# sourceMappingURL=babylon.math.scalar.js.map
|
|
//# sourceMappingURL=babylon.math.scalar.js.map
|
|
|
|
|
|
-
|
|
|
|
|
|
+var XRFrameOfReferenceType;
|
|
|
|
+(function (XRFrameOfReferenceType) {
|
|
|
|
+ XRFrameOfReferenceType[XRFrameOfReferenceType["head-model"] = 0] = "head-model";
|
|
|
|
+ XRFrameOfReferenceType[XRFrameOfReferenceType["eye-level"] = 1] = "eye-level";
|
|
|
|
+ XRFrameOfReferenceType[XRFrameOfReferenceType["stage"] = 2] = "stage";
|
|
|
|
+})(XRFrameOfReferenceType || (XRFrameOfReferenceType = {}));
|
|
|
|
|
|
//# sourceMappingURL=babylon.mixins.js.map
|
|
//# sourceMappingURL=babylon.mixins.js.map
|
|
|
|
|
|
@@ -23480,7 +23503,7 @@ var BABYLON;
|
|
*/
|
|
*/
|
|
_this.cameraRigMode = Camera.RIG_MODE_NONE;
|
|
_this.cameraRigMode = Camera.RIG_MODE_NONE;
|
|
/**
|
|
/**
|
|
- * Defines the list of custom render target the camera should render to.
|
|
|
|
|
|
+ * Defines the list of custom render target which are rendered to and then used as the input to this camera's render. Eg. display another camera view on a TV in the main scene
|
|
* This is pretty helpfull if you wish to make a camera render to a texture you could reuse somewhere
|
|
* This is pretty helpfull if you wish to make a camera render to a texture you could reuse somewhere
|
|
* else in the scene.
|
|
* else in the scene.
|
|
*/
|
|
*/
|
|
@@ -23488,7 +23511,7 @@ var BABYLON;
|
|
/**
|
|
/**
|
|
* When set, the camera will render to this render target instead of the default canvas
|
|
* When set, the camera will render to this render target instead of the default canvas
|
|
*/
|
|
*/
|
|
- _this.customDefaultRenderTarget = null;
|
|
|
|
|
|
+ _this.outputRenderTarget = null;
|
|
/**
|
|
/**
|
|
* Observable triggered when the camera view matrix has changed.
|
|
* Observable triggered when the camera view matrix has changed.
|
|
*/
|
|
*/
|
|
@@ -23517,6 +23540,7 @@ var BABYLON;
|
|
/** @hidden */
|
|
/** @hidden */
|
|
_this._activeMeshes = new BABYLON.SmartArray(256);
|
|
_this._activeMeshes = new BABYLON.SmartArray(256);
|
|
_this._globalPosition = BABYLON.Vector3.Zero();
|
|
_this._globalPosition = BABYLON.Vector3.Zero();
|
|
|
|
+ /** hidden */
|
|
_this._computedViewMatrix = BABYLON.Matrix.Identity();
|
|
_this._computedViewMatrix = BABYLON.Matrix.Identity();
|
|
_this._doNotComputeProjectionMatrix = false;
|
|
_this._doNotComputeProjectionMatrix = false;
|
|
_this._transformMatrix = BABYLON.Matrix.Zero();
|
|
_this._transformMatrix = BABYLON.Matrix.Zero();
|
|
@@ -26822,8 +26846,6 @@ var BABYLON;
|
|
Scene.prototype.simulatePointerUp = function (pickResult, pointerEventInit) {
|
|
Scene.prototype.simulatePointerUp = function (pickResult, pointerEventInit) {
|
|
var evt = new PointerEvent("pointerup", pointerEventInit);
|
|
var evt = new PointerEvent("pointerup", pointerEventInit);
|
|
var clickInfo = new ClickInfo();
|
|
var clickInfo = new ClickInfo();
|
|
- clickInfo.singleClick = true;
|
|
|
|
- clickInfo.ignore = true;
|
|
|
|
if (this._checkPrePointerObservable(pickResult, evt, BABYLON.PointerEventTypes.POINTERUP)) {
|
|
if (this._checkPrePointerObservable(pickResult, evt, BABYLON.PointerEventTypes.POINTERUP)) {
|
|
return this;
|
|
return this;
|
|
}
|
|
}
|
|
@@ -26871,27 +26893,17 @@ var BABYLON;
|
|
}
|
|
}
|
|
var type = BABYLON.PointerEventTypes.POINTERUP;
|
|
var type = BABYLON.PointerEventTypes.POINTERUP;
|
|
if (this.onPointerObservable.hasObservers()) {
|
|
if (this.onPointerObservable.hasObservers()) {
|
|
- if (!clickInfo.ignore) {
|
|
|
|
- if (!clickInfo.hasSwiped) {
|
|
|
|
- if (clickInfo.singleClick && this.onPointerObservable.hasSpecificMask(BABYLON.PointerEventTypes.POINTERTAP)) {
|
|
|
|
- var type_2 = BABYLON.PointerEventTypes.POINTERTAP;
|
|
|
|
- var pi = new BABYLON.PointerInfo(type_2, evt, pickResult);
|
|
|
|
- this._setRayOnPointerInfo(pi);
|
|
|
|
- this.onPointerObservable.notifyObservers(pi, type_2);
|
|
|
|
- }
|
|
|
|
- if (clickInfo.doubleClick && this.onPointerObservable.hasSpecificMask(BABYLON.PointerEventTypes.POINTERDOUBLETAP)) {
|
|
|
|
- var type_3 = BABYLON.PointerEventTypes.POINTERDOUBLETAP;
|
|
|
|
- var pi = new BABYLON.PointerInfo(type_3, evt, pickResult);
|
|
|
|
- this._setRayOnPointerInfo(pi);
|
|
|
|
- this.onPointerObservable.notifyObservers(pi, type_3);
|
|
|
|
- }
|
|
|
|
|
|
+ if (!clickInfo.ignore && !clickInfo.hasSwiped) {
|
|
|
|
+ if (clickInfo.singleClick && this.onPointerObservable.hasSpecificMask(BABYLON.PointerEventTypes.POINTERTAP)) {
|
|
|
|
+ type = BABYLON.PointerEventTypes.POINTERTAP;
|
|
|
|
+ }
|
|
|
|
+ else if (clickInfo.doubleClick && this.onPointerObservable.hasSpecificMask(BABYLON.PointerEventTypes.POINTERDOUBLETAP)) {
|
|
|
|
+ type = BABYLON.PointerEventTypes.POINTERDOUBLETAP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- else {
|
|
|
|
- var pi = new BABYLON.PointerInfo(type, evt, pickResult);
|
|
|
|
- this._setRayOnPointerInfo(pi);
|
|
|
|
- this.onPointerObservable.notifyObservers(pi, type);
|
|
|
|
- }
|
|
|
|
|
|
+ var pi = new BABYLON.PointerInfo(type, evt, pickResult);
|
|
|
|
+ this._setRayOnPointerInfo(pi);
|
|
|
|
+ this.onPointerObservable.notifyObservers(pi, type);
|
|
}
|
|
}
|
|
if (this.onPointerUp && !clickInfo.ignore) {
|
|
if (this.onPointerUp && !clickInfo.ignore) {
|
|
this.onPointerUp(evt, pickResult, type);
|
|
this.onPointerUp(evt, pickResult, type);
|
|
@@ -29113,8 +29125,8 @@ var BABYLON;
|
|
step.action(this.activeCamera);
|
|
step.action(this.activeCamera);
|
|
}
|
|
}
|
|
this._intermediateRendering = false;
|
|
this._intermediateRendering = false;
|
|
- if (this.activeCamera.customDefaultRenderTarget) {
|
|
|
|
- var internalTexture = this.activeCamera.customDefaultRenderTarget.getInternalTexture();
|
|
|
|
|
|
+ if (this.activeCamera.outputRenderTarget) {
|
|
|
|
+ var internalTexture = this.activeCamera.outputRenderTarget.getInternalTexture();
|
|
if (internalTexture) {
|
|
if (internalTexture) {
|
|
engine.bindFramebuffer(internalTexture);
|
|
engine.bindFramebuffer(internalTexture);
|
|
}
|
|
}
|
|
@@ -30110,6 +30122,11 @@ var BABYLON;
|
|
function AssetContainer(scene) {
|
|
function AssetContainer(scene) {
|
|
var _this = _super.call(this) || this;
|
|
var _this = _super.call(this) || this;
|
|
_this.scene = scene;
|
|
_this.scene = scene;
|
|
|
|
+ _this["sounds"] = [];
|
|
|
|
+ _this["effectLayers"] = [];
|
|
|
|
+ _this["layers"] = [];
|
|
|
|
+ _this["lensFlareSystems"] = [];
|
|
|
|
+ _this["proceduralTextures"] = [];
|
|
return _this;
|
|
return _this;
|
|
}
|
|
}
|
|
/**
|
|
/**
|
|
@@ -30158,7 +30175,7 @@ var BABYLON;
|
|
});
|
|
});
|
|
for (var _i = 0, _a = this.scene._serializableComponents; _i < _a.length; _i++) {
|
|
for (var _i = 0, _a = this.scene._serializableComponents; _i < _a.length; _i++) {
|
|
var component = _a[_i];
|
|
var component = _a[_i];
|
|
- component.addFromContainer(this.scene);
|
|
|
|
|
|
+ component.addFromContainer(this);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
/**
|
|
/**
|
|
@@ -30207,7 +30224,7 @@ var BABYLON;
|
|
});
|
|
});
|
|
for (var _i = 0, _a = this.scene._serializableComponents; _i < _a.length; _i++) {
|
|
for (var _i = 0, _a = this.scene._serializableComponents; _i < _a.length; _i++) {
|
|
var component = _a[_i];
|
|
var component = _a[_i];
|
|
- component.removeFromContainer(this.scene);
|
|
|
|
|
|
+ component.removeFromContainer(this);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
|
|
AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
|
|
@@ -30887,8 +30904,10 @@ var BABYLON;
|
|
* Creates a new InternalTexture
|
|
* Creates a new InternalTexture
|
|
* @param engine defines the engine to use
|
|
* @param engine defines the engine to use
|
|
* @param dataSource defines the type of data that will be used
|
|
* @param dataSource defines the type of data that will be used
|
|
|
|
+ * @param delayAllocation if the texture allocation should be delayed (default: false)
|
|
*/
|
|
*/
|
|
- function InternalTexture(engine, dataSource) {
|
|
|
|
|
|
+ function InternalTexture(engine, dataSource, delayAllocation) {
|
|
|
|
+ if (delayAllocation === void 0) { delayAllocation = false; }
|
|
/**
|
|
/**
|
|
* Observable called when the texture is loaded
|
|
* Observable called when the texture is loaded
|
|
*/
|
|
*/
|
|
@@ -30922,7 +30941,9 @@ var BABYLON;
|
|
this._references = 1;
|
|
this._references = 1;
|
|
this._engine = engine;
|
|
this._engine = engine;
|
|
this._dataSource = dataSource;
|
|
this._dataSource = dataSource;
|
|
- this._webGLTexture = engine._createTexture();
|
|
|
|
|
|
+ if (!delayAllocation) {
|
|
|
|
+ this._webGLTexture = engine._createTexture();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
/**
|
|
/**
|
|
* Gets the Engine the texture belongs to.
|
|
* Gets the Engine the texture belongs to.
|
|
@@ -73400,8 +73421,9 @@ var BABYLON;
|
|
* @param generateStencilBuffer True to generate a stencil buffer
|
|
* @param generateStencilBuffer True to generate a stencil buffer
|
|
* @param isMulti True if multiple textures need to be created (Draw Buffers)
|
|
* @param isMulti True if multiple textures need to be created (Draw Buffers)
|
|
* @param format The internal format of the buffer in the RTT (RED, RG, RGB, RGBA, ALPHA...)
|
|
* @param format The internal format of the buffer in the RTT (RED, RG, RGB, RGBA, ALPHA...)
|
|
|
|
+ * @param delayAllocation if the texture allocation should be delayed (default: false)
|
|
*/
|
|
*/
|
|
- function RenderTargetTexture(name, size, scene, generateMipMaps, doNotChangeAspectRatio, type, isCube, samplingMode, generateDepthBuffer, generateStencilBuffer, isMulti, format) {
|
|
|
|
|
|
+ function RenderTargetTexture(name, size, scene, generateMipMaps, doNotChangeAspectRatio, type, isCube, samplingMode, generateDepthBuffer, generateStencilBuffer, isMulti, format, delayAllocation) {
|
|
if (doNotChangeAspectRatio === void 0) { doNotChangeAspectRatio = true; }
|
|
if (doNotChangeAspectRatio === void 0) { doNotChangeAspectRatio = true; }
|
|
if (type === void 0) { type = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
|
|
if (type === void 0) { type = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
|
|
if (isCube === void 0) { isCube = false; }
|
|
if (isCube === void 0) { isCube = false; }
|
|
@@ -73410,6 +73432,7 @@ var BABYLON;
|
|
if (generateStencilBuffer === void 0) { generateStencilBuffer = false; }
|
|
if (generateStencilBuffer === void 0) { generateStencilBuffer = false; }
|
|
if (isMulti === void 0) { isMulti = false; }
|
|
if (isMulti === void 0) { isMulti = false; }
|
|
if (format === void 0) { format = BABYLON.Engine.TEXTUREFORMAT_RGBA; }
|
|
if (format === void 0) { format = BABYLON.Engine.TEXTUREFORMAT_RGBA; }
|
|
|
|
+ if (delayAllocation === void 0) { delayAllocation = false; }
|
|
var _this = _super.call(this, null, scene, !generateMipMaps) || this;
|
|
var _this = _super.call(this, null, scene, !generateMipMaps) || this;
|
|
_this.isCube = isCube;
|
|
_this.isCube = isCube;
|
|
/**
|
|
/**
|
|
@@ -73488,13 +73511,15 @@ var BABYLON;
|
|
_this.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
|
|
_this.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
|
|
_this.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
|
|
_this.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
|
|
}
|
|
}
|
|
- if (isCube) {
|
|
|
|
- _this._texture = scene.getEngine().createRenderTargetCubeTexture(_this.getRenderSize(), _this._renderTargetOptions);
|
|
|
|
- _this.coordinatesMode = BABYLON.Texture.INVCUBIC_MODE;
|
|
|
|
- _this._textureMatrix = BABYLON.Matrix.Identity();
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- _this._texture = scene.getEngine().createRenderTargetTexture(_this._size, _this._renderTargetOptions);
|
|
|
|
|
|
+ if (!delayAllocation) {
|
|
|
|
+ if (isCube) {
|
|
|
|
+ _this._texture = scene.getEngine().createRenderTargetCubeTexture(_this.getRenderSize(), _this._renderTargetOptions);
|
|
|
|
+ _this.coordinatesMode = BABYLON.Texture.INVCUBIC_MODE;
|
|
|
|
+ _this._textureMatrix = BABYLON.Matrix.Identity();
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ _this._texture = scene.getEngine().createRenderTargetTexture(_this._size, _this._renderTargetOptions);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return _this;
|
|
return _this;
|
|
}
|
|
}
|
|
@@ -73884,7 +73909,7 @@ var BABYLON;
|
|
// Is predicate defined?
|
|
// Is predicate defined?
|
|
if (this.renderListPredicate) {
|
|
if (this.renderListPredicate) {
|
|
if (this.renderList) {
|
|
if (this.renderList) {
|
|
- this.renderList.splice(0); // Clear previous renderList
|
|
|
|
|
|
+ this.renderList.length = 0; // Clear previous renderList
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
this.renderList = [];
|
|
this.renderList = [];
|
|
@@ -108408,11 +108433,57 @@ var BABYLON;
|
|
this._updateNumberOfRigCameras(2);
|
|
this._updateNumberOfRigCameras(2);
|
|
this.rigCameras[0].viewport = new BABYLON.Viewport(0, 0, 0.5, 1.0);
|
|
this.rigCameras[0].viewport = new BABYLON.Viewport(0, 0, 0.5, 1.0);
|
|
this.rigCameras[0].position.x = -pupilDistance / 2;
|
|
this.rigCameras[0].position.x = -pupilDistance / 2;
|
|
- this.rigCameras[0].customDefaultRenderTarget = null;
|
|
|
|
|
|
+ this.rigCameras[0].outputRenderTarget = null;
|
|
this.rigCameras[1].viewport = new BABYLON.Viewport(0.5, 0, 0.5, 1.0);
|
|
this.rigCameras[1].viewport = new BABYLON.Viewport(0.5, 0, 0.5, 1.0);
|
|
this.rigCameras[1].position.x = pupilDistance / 2;
|
|
this.rigCameras[1].position.x = pupilDistance / 2;
|
|
- this.rigCameras[1].customDefaultRenderTarget = null;
|
|
|
|
|
|
+ this.rigCameras[1].outputRenderTarget = null;
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Updates the cameras position from the current pose information of the XR session
|
|
|
|
+ * @param xrSessionManager the session containing pose information
|
|
|
|
+ */
|
|
|
|
+ WebXRCamera.prototype.updateFromXRSessionManager = function (xrSessionManager) {
|
|
|
|
+ var _this = this;
|
|
|
|
+ // Ensure all frame data is available
|
|
|
|
+ if (!xrSessionManager._currentXRFrame || !xrSessionManager._currentXRFrame.getDevicePose) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ var pose = xrSessionManager._currentXRFrame.getDevicePose(xrSessionManager._frameOfReference);
|
|
|
|
+ if (!pose || !pose.poseModelMatrix) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ // Update the parent cameras matrix
|
|
|
|
+ BABYLON.Matrix.FromFloat32ArrayToRefScaled(pose.poseModelMatrix, 0, 1, WebXRCamera._TmpMatrix);
|
|
|
|
+ if (!this._scene.useRightHandedSystem) {
|
|
|
|
+ WebXRCamera._TmpMatrix.toggleModelMatrixHandInPlace();
|
|
|
|
+ }
|
|
|
|
+ WebXRCamera._TmpMatrix.getTranslationToRef(this.position);
|
|
|
|
+ WebXRCamera._TmpMatrix.getRotationMatrixToRef(WebXRCamera._TmpMatrix);
|
|
|
|
+ BABYLON.Quaternion.FromRotationMatrixToRef(WebXRCamera._TmpMatrix, this.rotationQuaternion);
|
|
|
|
+ this.computeWorldMatrix();
|
|
|
|
+ // Update camera rigs
|
|
|
|
+ this._updateNumberOfRigCameras(xrSessionManager._currentXRFrame.views.length);
|
|
|
|
+ xrSessionManager._currentXRFrame.views.forEach(function (view, i) {
|
|
|
|
+ // Update view/projection matrix
|
|
|
|
+ BABYLON.Matrix.FromFloat32ArrayToRefScaled(pose.getViewMatrix(view), 0, 1, _this.rigCameras[i]._computedViewMatrix);
|
|
|
|
+ BABYLON.Matrix.FromFloat32ArrayToRefScaled(view.projectionMatrix, 0, 1, _this.rigCameras[i]._projectionMatrix);
|
|
|
|
+ if (!_this._scene.useRightHandedSystem) {
|
|
|
|
+ _this.rigCameras[i]._computedViewMatrix.toggleModelMatrixHandInPlace();
|
|
|
|
+ _this.rigCameras[i]._projectionMatrix.toggleProjectionMatrixHandInPlace();
|
|
|
|
+ }
|
|
|
|
+ // Update viewport
|
|
|
|
+ var viewport = xrSessionManager._xrSession.baseLayer.getViewport(view);
|
|
|
|
+ var width = xrSessionManager._xrSession.baseLayer.framebufferWidth;
|
|
|
|
+ var height = xrSessionManager._xrSession.baseLayer.framebufferHeight;
|
|
|
|
+ _this.rigCameras[i].viewport.width = viewport.width / width;
|
|
|
|
+ _this.rigCameras[i].viewport.height = viewport.height / height;
|
|
|
|
+ _this.rigCameras[i].viewport.x = viewport.x / width;
|
|
|
|
+ _this.rigCameras[i].viewport.y = viewport.y / height;
|
|
|
|
+ // Set cameras to render to the session's render target
|
|
|
|
+ _this.rigCameras[i].outputRenderTarget = xrSessionManager._sessionRenderTargetTexture;
|
|
|
|
+ });
|
|
};
|
|
};
|
|
|
|
+ WebXRCamera._TmpMatrix = new BABYLON.Matrix();
|
|
return WebXRCamera;
|
|
return WebXRCamera;
|
|
}(BABYLON.FreeCamera));
|
|
}(BABYLON.FreeCamera));
|
|
BABYLON.WebXRCamera = WebXRCamera;
|
|
BABYLON.WebXRCamera = WebXRCamera;
|
|
@@ -108420,6 +108491,141 @@ var BABYLON;
|
|
|
|
|
|
//# sourceMappingURL=babylon.webXRCamera.js.map
|
|
//# sourceMappingURL=babylon.webXRCamera.js.map
|
|
|
|
|
|
|
|
+var BABYLON;
|
|
|
|
+(function (BABYLON) {
|
|
|
|
+ /**
|
|
|
|
+ * Manages an XRSession
|
|
|
|
+ * @see https://doc.babylonjs.com/how_to/webxr
|
|
|
|
+ */
|
|
|
|
+ var WebXRSessionManager = /** @class */ (function () {
|
|
|
|
+ /**
|
|
|
|
+ * Constructs a WebXRSessionManager, this must be initialized within a user action before usage
|
|
|
|
+ * @param scene The scene which the session should be created for
|
|
|
|
+ */
|
|
|
|
+ function WebXRSessionManager(scene) {
|
|
|
|
+ this.scene = scene;
|
|
|
|
+ this._tmpMatrix = new BABYLON.Matrix();
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * Initializes the manager, this must be done with a user action (eg. button click event)
|
|
|
|
+ * After initialization enterXR can be called to start an XR session
|
|
|
|
+ * @returns Promise which resolves after it is initialized
|
|
|
|
+ */
|
|
|
|
+ WebXRSessionManager.prototype.initialize = function () {
|
|
|
|
+ var _this = this;
|
|
|
|
+ // Check if the browser supports webXR
|
|
|
|
+ this._xrNavigator = navigator;
|
|
|
|
+ if (!this._xrNavigator.xr) {
|
|
|
|
+ return Promise.reject("webXR not supported by this browser");
|
|
|
|
+ }
|
|
|
|
+ // Request the webXR device
|
|
|
|
+ return this._xrNavigator.xr.requestDevice().then(function (device) {
|
|
|
|
+ _this._xrDevice = device;
|
|
|
|
+ return _this.scene.getEngine()._gl.setCompatibleXRDevice(_this._xrDevice);
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Enters XR with the desired XR session options
|
|
|
|
+ * @param sessionCreationOptions xr options to create the session with
|
|
|
|
+ * @param frameOfReferenceType option to configure how the xr pose is expressed
|
|
|
|
+ * @returns Promise which resolves after it enters XR
|
|
|
|
+ */
|
|
|
|
+ WebXRSessionManager.prototype.enterXR = function (sessionCreationOptions, frameOfReferenceType) {
|
|
|
|
+ var _this = this;
|
|
|
|
+ // initialize session
|
|
|
|
+ return this._xrDevice.requestSession(sessionCreationOptions).then(function (session) {
|
|
|
|
+ _this._xrSession = session;
|
|
|
|
+ _this._xrSession.baseLayer = new XRWebGLLayer(_this._xrSession, _this.scene.getEngine()._gl);
|
|
|
|
+ return _this._xrSession.requestFrameOfReference(frameOfReferenceType);
|
|
|
|
+ }).then(function (frameOfRef) {
|
|
|
|
+ _this._frameOfReference = frameOfRef;
|
|
|
|
+ // Tell the engine's render loop to be driven by the xr session's refresh rate and provide xr pose information
|
|
|
|
+ _this.scene.getEngine().customAnimationFrameRequester = {
|
|
|
|
+ requestAnimationFrame: _this._xrSession.requestAnimationFrame.bind(_this._xrSession),
|
|
|
|
+ renderFunction: function (timestamp, xrFrame) {
|
|
|
|
+ // Store the XR frame in the manager to be consumed by the XR camera to update pose
|
|
|
|
+ _this._currentXRFrame = xrFrame;
|
|
|
|
+ _this.scene.getEngine()._renderLoop();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ // Create render target texture from xr's webgl render target
|
|
|
|
+ _this._sessionRenderTargetTexture = WebXRSessionManager._CreateRenderTargetTextureFromSession(_this._xrSession, _this.scene);
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Stops the xrSession and restores the renderloop
|
|
|
|
+ * @returns Promise which resolves after it exits XR
|
|
|
|
+ */
|
|
|
|
+ WebXRSessionManager.prototype.exitXR = function () {
|
|
|
|
+ var _this = this;
|
|
|
|
+ return new Promise(function (res) {
|
|
|
|
+ _this.scene.getEngine().customAnimationFrameRequester = null;
|
|
|
|
+ _this._xrSession.end();
|
|
|
|
+ // Restore frame buffer to avoid clear on xr framebuffer after session end
|
|
|
|
+ _this.scene.getEngine().restoreDefaultFramebuffer();
|
|
|
|
+ // Need to restart render loop as after calling session.end the last request for new frame will never call callback
|
|
|
|
+ _this.scene.getEngine()._renderLoop();
|
|
|
|
+ res();
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Fires a ray and returns the closest hit in the xr sessions enviornment, useful to place objects in AR
|
|
|
|
+ * @param ray ray to cast into the environment
|
|
|
|
+ * @returns Promise which resolves with a collision point in the environment if it exists
|
|
|
|
+ */
|
|
|
|
+ WebXRSessionManager.prototype.environmentPointHitTest = function (ray) {
|
|
|
|
+ var _this = this;
|
|
|
|
+ return new Promise(function (res, rej) {
|
|
|
|
+ // Compute left handed inputs to request hit test
|
|
|
|
+ var origin = new Float32Array([ray.origin.x, ray.origin.y, ray.origin.z]);
|
|
|
|
+ var direction = new Float32Array([ray.direction.x, ray.direction.y, ray.direction.z]);
|
|
|
|
+ if (!_this.scene.useRightHandedSystem) {
|
|
|
|
+ origin[2] *= -1;
|
|
|
|
+ direction[2] *= -1;
|
|
|
|
+ }
|
|
|
|
+ // Fire hittest
|
|
|
|
+ _this._xrSession.requestHitTest(origin, direction, _this._frameOfReference)
|
|
|
|
+ .then(function (hits) {
|
|
|
|
+ if (hits.length > 0) {
|
|
|
|
+ BABYLON.Matrix.FromFloat32ArrayToRefScaled(hits[0].hitMatrix, 0, 1.0, _this._tmpMatrix);
|
|
|
|
+ var hitPoint = _this._tmpMatrix.getTranslation();
|
|
|
|
+ if (!_this.scene.useRightHandedSystem) {
|
|
|
|
+ hitPoint.z *= -1;
|
|
|
|
+ }
|
|
|
|
+ res(hitPoint);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ res(null);
|
|
|
|
+ }
|
|
|
|
+ }).catch(function (e) {
|
|
|
|
+ res(null);
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * @hidden
|
|
|
|
+ * Converts the render layer of xrSession to a render target
|
|
|
|
+ * @param session session to create render target for
|
|
|
|
+ * @param scene scene the new render target should be created for
|
|
|
|
+ */
|
|
|
|
+ WebXRSessionManager._CreateRenderTargetTextureFromSession = function (session, scene) {
|
|
|
|
+ // Create internal texture
|
|
|
|
+ var internalTexture = new BABYLON.InternalTexture(scene.getEngine(), BABYLON.InternalTexture.DATASOURCE_UNKNOWN, true);
|
|
|
|
+ internalTexture.width = session.baseLayer.framebufferWidth;
|
|
|
|
+ internalTexture.height = session.baseLayer.framebufferHeight;
|
|
|
|
+ internalTexture._framebuffer = session.baseLayer.framebuffer;
|
|
|
|
+ // Create render target texture from the internal texture
|
|
|
|
+ var renderTargetTexture = new BABYLON.RenderTargetTexture("XR renderTargetTexture", { width: internalTexture.width, height: internalTexture.height }, scene, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, true);
|
|
|
|
+ renderTargetTexture._texture = internalTexture;
|
|
|
|
+ return renderTargetTexture;
|
|
|
|
+ };
|
|
|
|
+ return WebXRSessionManager;
|
|
|
|
+ }());
|
|
|
|
+ BABYLON.WebXRSessionManager = WebXRSessionManager;
|
|
|
|
+})(BABYLON || (BABYLON = {}));
|
|
|
|
+
|
|
|
|
+//# sourceMappingURL=babylon.webXRSessionManager.js.map
|
|
|
|
+
|
|
// Mainly based on these 2 articles :
|
|
// Mainly based on these 2 articles :
|
|
// Creating an universal virtual touch joystick working for all Touch models thanks to Hand.JS : http://blogs.msdn.com/b/davrous/archive/2013/02/22/creating-an-universal-virtual-touch-joystick-working-for-all-touch-models-thanks-to-hand-js.aspx
|
|
// Creating an universal virtual touch joystick working for all Touch models thanks to Hand.JS : http://blogs.msdn.com/b/davrous/archive/2013/02/22/creating-an-universal-virtual-touch-joystick-working-for-all-touch-models-thanks-to-hand-js.aspx
|
|
// & on Seb Lee-Delisle original work: http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/
|
|
// & on Seb Lee-Delisle original work: http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/
|