|
@@ -108859,6 +108859,14 @@ var BABYLON;
|
|
|
});
|
|
|
};
|
|
|
/**
|
|
|
+ * 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
|
|
|
+ */
|
|
|
+ WebXRExperienceHelper.prototype.environmentPointHitTest = function (ray) {
|
|
|
+ return this._sessionManager.environmentPointHitTest(ray);
|
|
|
+ };
|
|
|
+ /**
|
|
|
* Checks if the creation options are supported by the xr session
|
|
|
* @param options creation options
|
|
|
* @returns true if supported
|
|
@@ -108923,6 +108931,32 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
var BABYLON;
|
|
|
(function (BABYLON) {
|
|
|
/**
|
|
|
+ * Button which can be used to enter a different mode of XR
|
|
|
+ */
|
|
|
+ var WebXREnterExitUIButton = /** @class */ (function () {
|
|
|
+ /**
|
|
|
+ * Creates a WebXREnterExitUIButton
|
|
|
+ * @param element button element
|
|
|
+ * @param initializationOptions XR initialization options for the button
|
|
|
+ */
|
|
|
+ function WebXREnterExitUIButton(
|
|
|
+ /** button element */
|
|
|
+ element,
|
|
|
+ /** XR initialization options for the button */
|
|
|
+ initializationOptions) {
|
|
|
+ this.element = element;
|
|
|
+ this.initializationOptions = initializationOptions;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Overwritable function which can be used to update the button's visuals when the state changes
|
|
|
+ * @param activeButton the current active button in the UI
|
|
|
+ */
|
|
|
+ WebXREnterExitUIButton.prototype.update = function (activeButton) {
|
|
|
+ };
|
|
|
+ return WebXREnterExitUIButton;
|
|
|
+ }());
|
|
|
+ BABYLON.WebXREnterExitUIButton = WebXREnterExitUIButton;
|
|
|
+ /**
|
|
|
* Options to create the webXR UI
|
|
|
*/
|
|
|
var WebXREnterExitUIOptions = /** @class */ (function () {
|
|
@@ -108939,6 +108973,7 @@ var BABYLON;
|
|
|
var _this = this;
|
|
|
this.scene = scene;
|
|
|
this._buttons = [];
|
|
|
+ this._activeButton = null;
|
|
|
this._overlay = document.createElement("div");
|
|
|
this._overlay.style.cssText = "z-index:11;position: absolute; right: 20px;bottom: 50px;";
|
|
|
if (options.customButtons) {
|
|
@@ -108948,11 +108983,20 @@ var BABYLON;
|
|
|
var hmdBtn = document.createElement("button");
|
|
|
hmdBtn.style.cssText = "color: #868686; border-color: #868686; border-style: solid; margin-left: 10px; height: 50px; width: 80px; background-color: rgba(51,51,51,0.7); background-repeat:no-repeat; background-position: center; outline: none;";
|
|
|
hmdBtn.innerText = "HMD";
|
|
|
- this._buttons.push({ element: hmdBtn, initializationOptions: { immersive: true } });
|
|
|
+ this._buttons.push(new WebXREnterExitUIButton(hmdBtn, { immersive: true, outputContext: options.outputCanvasContext }));
|
|
|
+ this._buttons[this._buttons.length - 1].update = function (activeButton) {
|
|
|
+ this.element.style.display = (activeButton === null || activeButton === this) ? "" : "none";
|
|
|
+ this.element.innerText = activeButton === this ? "EXIT" : "HMD";
|
|
|
+ };
|
|
|
var windowBtn = document.createElement("button");
|
|
|
windowBtn.style.cssText = hmdBtn.style.cssText;
|
|
|
windowBtn.innerText = "Window";
|
|
|
- this._buttons.push({ element: windowBtn, initializationOptions: { immersive: false, environmentIntegration: true, outputContext: options.outputCanvasContext } });
|
|
|
+ this._buttons.push(new WebXREnterExitUIButton(windowBtn, { immersive: false, environmentIntegration: true, outputContext: options.outputCanvasContext }));
|
|
|
+ this._buttons[this._buttons.length - 1].update = function (activeButton) {
|
|
|
+ this.element.style.display = (activeButton === null || activeButton === this) ? "" : "none";
|
|
|
+ this.element.innerText = activeButton === this ? "EXIT" : "Window";
|
|
|
+ };
|
|
|
+ this._updateButtons(null);
|
|
|
}
|
|
|
var renderCanvas = scene.getEngine().getRenderingCanvas();
|
|
|
if (renderCanvas && renderCanvas.parentNode) {
|
|
@@ -108975,6 +109019,11 @@ var BABYLON;
|
|
|
var supportedPromises = ui._buttons.map(function (btn) {
|
|
|
return helper.supportsSession(btn.initializationOptions);
|
|
|
});
|
|
|
+ helper.onStateChangedObservable.add(function (state) {
|
|
|
+ if (state == BABYLON.WebXRState.NOT_IN_XR) {
|
|
|
+ ui._updateButtons(null);
|
|
|
+ }
|
|
|
+ });
|
|
|
return Promise.all(supportedPromises).then(function (results) {
|
|
|
results.forEach(function (supported, i) {
|
|
|
if (supported) {
|
|
@@ -108984,12 +109033,14 @@ var BABYLON;
|
|
|
switch (_a.label) {
|
|
|
case 0:
|
|
|
if (!(helper.state == BABYLON.WebXRState.IN_XR)) return [3 /*break*/, 2];
|
|
|
+ ui._updateButtons(null);
|
|
|
return [4 /*yield*/, helper.exitXR()];
|
|
|
case 1:
|
|
|
_a.sent();
|
|
|
return [2 /*return*/];
|
|
|
case 2:
|
|
|
if (!(helper.state == BABYLON.WebXRState.NOT_IN_XR)) return [3 /*break*/, 4];
|
|
|
+ ui._updateButtons(ui._buttons[i]);
|
|
|
return [4 /*yield*/, helper.enterXR(ui._buttons[i].initializationOptions, "eye-level")];
|
|
|
case 3:
|
|
|
_a.sent();
|
|
@@ -109002,6 +109053,13 @@ var BABYLON;
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
+ WebXREnterExitUI.prototype._updateButtons = function (activeButton) {
|
|
|
+ var _this = this;
|
|
|
+ this._activeButton = activeButton;
|
|
|
+ this._buttons.forEach(function (b) {
|
|
|
+ b.update(_this._activeButton);
|
|
|
+ });
|
|
|
+ };
|
|
|
/**
|
|
|
* Disposes of the object
|
|
|
*/
|
|
@@ -109038,7 +109096,7 @@ var BABYLON;
|
|
|
this.canvasContext = null;
|
|
|
if (!canvas) {
|
|
|
canvas = document.createElement('canvas');
|
|
|
- canvas.style.cssText = "position:absolute; bottom:0px;right:0px;z-index:10;width:100%;height:100%;background-color: #48989e;";
|
|
|
+ canvas.style.cssText = "position:absolute; bottom:0px;right:0px;z-index:10;width:100%;height:100%;background-color: #000000;";
|
|
|
}
|
|
|
this._setManagedOutputCanvas(canvas);
|
|
|
helper.onStateChangedObservable.add(function (stateInfo) {
|
|
@@ -109086,6 +109144,104 @@ var BABYLON;
|
|
|
|
|
|
//# sourceMappingURL=babylon.webXRManagedOutputCanvas.js.map
|
|
|
|
|
|
+var BABYLON;
|
|
|
+(function (BABYLON) {
|
|
|
+ /**
|
|
|
+ * Represents an XR input
|
|
|
+ */
|
|
|
+ var WebXRController = /** @class */ (function () {
|
|
|
+ /**
|
|
|
+ * Creates the controller
|
|
|
+ * @see https://doc.babylonjs.com/how_to/webxr
|
|
|
+ * @param scene the scene which the controller should be associated to
|
|
|
+ */
|
|
|
+ function WebXRController(scene) {
|
|
|
+ this.pointer = new BABYLON.AbstractMesh("controllerPointer", scene);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Disposes of the object
|
|
|
+ */
|
|
|
+ WebXRController.prototype.dispose = function () {
|
|
|
+ if (this.grip) {
|
|
|
+ this.grip.dispose();
|
|
|
+ }
|
|
|
+ this.pointer.dispose();
|
|
|
+ };
|
|
|
+ return WebXRController;
|
|
|
+ }());
|
|
|
+ BABYLON.WebXRController = WebXRController;
|
|
|
+ /**
|
|
|
+ * XR input used to track XR inputs such as controllers/rays
|
|
|
+ */
|
|
|
+ var WebXRInput = /** @class */ (function () {
|
|
|
+ /**
|
|
|
+ * Initializes the WebXRInput
|
|
|
+ * @param helper experience helper which the input should be created for
|
|
|
+ */
|
|
|
+ function WebXRInput(helper) {
|
|
|
+ var _this = this;
|
|
|
+ this.helper = helper;
|
|
|
+ /**
|
|
|
+ * XR controllers being tracked
|
|
|
+ */
|
|
|
+ this.controllers = [];
|
|
|
+ this._tmpMatrix = new BABYLON.Matrix();
|
|
|
+ this._frameObserver = helper._sessionManager.onXRFrameObservable.add(function () {
|
|
|
+ if (!helper._sessionManager._currentXRFrame || !helper._sessionManager._currentXRFrame.getDevicePose) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ var xrFrame = helper._sessionManager._currentXRFrame;
|
|
|
+ var inputSources = helper._sessionManager._xrSession.getInputSources();
|
|
|
+ inputSources.forEach(function (input, i) {
|
|
|
+ var inputPose = xrFrame.getInputPose(input, helper._sessionManager._frameOfReference);
|
|
|
+ if (inputPose) {
|
|
|
+ if (_this.controllers.length <= i) {
|
|
|
+ _this.controllers.push(new WebXRController(helper.container.getScene()));
|
|
|
+ }
|
|
|
+ var controller = _this.controllers[i];
|
|
|
+ // Manage the grip if it exists
|
|
|
+ if (inputPose.gripMatrix) {
|
|
|
+ if (!controller.grip) {
|
|
|
+ controller.grip = new BABYLON.AbstractMesh("controllerGrip", helper.container.getScene());
|
|
|
+ }
|
|
|
+ BABYLON.Matrix.FromFloat32ArrayToRefScaled(inputPose.gripMatrix, 0, 1, _this._tmpMatrix);
|
|
|
+ if (!controller.grip.getScene().useRightHandedSystem) {
|
|
|
+ _this._tmpMatrix.toggleModelMatrixHandInPlace();
|
|
|
+ }
|
|
|
+ if (!controller.grip.rotationQuaternion) {
|
|
|
+ controller.grip.rotationQuaternion = new BABYLON.Quaternion();
|
|
|
+ }
|
|
|
+ _this._tmpMatrix.decompose(controller.grip.scaling, controller.grip.rotationQuaternion, controller.grip.position);
|
|
|
+ }
|
|
|
+ // Manager pointer of controller
|
|
|
+ BABYLON.Matrix.FromFloat32ArrayToRefScaled(inputPose.targetRay.transformMatrix, 0, 1, _this._tmpMatrix);
|
|
|
+ if (!controller.pointer.getScene().useRightHandedSystem) {
|
|
|
+ _this._tmpMatrix.toggleModelMatrixHandInPlace();
|
|
|
+ }
|
|
|
+ if (!controller.pointer.rotationQuaternion) {
|
|
|
+ controller.pointer.rotationQuaternion = new BABYLON.Quaternion();
|
|
|
+ }
|
|
|
+ _this._tmpMatrix.decompose(controller.pointer.scaling, controller.pointer.rotationQuaternion, controller.pointer.position);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Disposes of the object
|
|
|
+ */
|
|
|
+ WebXRInput.prototype.dispose = function () {
|
|
|
+ this.controllers.forEach(function (c) {
|
|
|
+ c.dispose();
|
|
|
+ });
|
|
|
+ this.helper._sessionManager.onXRFrameObservable.remove(this._frameObserver);
|
|
|
+ };
|
|
|
+ return WebXRInput;
|
|
|
+ }());
|
|
|
+ BABYLON.WebXRInput = WebXRInput;
|
|
|
+})(BABYLON || (BABYLON = {}));
|
|
|
+
|
|
|
+//# sourceMappingURL=babylon.webXRInput.js.map
|
|
|
+
|
|
|
// 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
|
|
|
// & on Seb Lee-Delisle original work: http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/
|
|
@@ -119986,7 +120142,9 @@ var BABYLON;
|
|
|
var _this = this;
|
|
|
return BABYLON.WebXRExperienceHelper.CreateAsync(this).then(function (helper) {
|
|
|
var outputCanvas = new BABYLON.WebXRManagedOutputCanvas(helper);
|
|
|
- return BABYLON.WebXREnterExitUI.CreateAsync(_this, helper, { outputCanvasContext: outputCanvas.canvasContext }).then(function (ui) {
|
|
|
+ return BABYLON.WebXREnterExitUI.CreateAsync(_this, helper, { outputCanvasContext: outputCanvas.canvasContext })
|
|
|
+ .then(function (ui) {
|
|
|
+ new BABYLON.WebXRInput(helper);
|
|
|
return helper;
|
|
|
});
|
|
|
});
|