|
@@ -9470,6 +9470,10 @@ var BABYLON;
|
|
|
* @param fileName defines the name of the downloaded file
|
|
|
*/
|
|
|
Tools.Download = function (blob, fileName) {
|
|
|
+ if (navigator && navigator.msSaveBlob) {
|
|
|
+ navigator.msSaveBlob(blob, fileName);
|
|
|
+ return;
|
|
|
+ }
|
|
|
var url = window.URL.createObjectURL(blob);
|
|
|
var a = document.createElement("a");
|
|
|
document.body.appendChild(a);
|
|
@@ -11693,7 +11697,7 @@ var BABYLON;
|
|
|
* Returns the current version of the framework
|
|
|
*/
|
|
|
get: function () {
|
|
|
- return "3.3.0-alpha.11";
|
|
|
+ return "3.3.0-alpha.12";
|
|
|
},
|
|
|
enumerable: true,
|
|
|
configurable: true
|
|
@@ -22838,12 +22842,16 @@ var BABYLON;
|
|
|
(function (BABYLON) {
|
|
|
var RenderingManager = /** @class */ (function () {
|
|
|
function RenderingManager(scene) {
|
|
|
+ /**
|
|
|
+ * Hidden
|
|
|
+ */
|
|
|
+ this._useSceneAutoClearSetup = false;
|
|
|
this._renderingGroups = new Array();
|
|
|
this._autoClearDepthStencil = {};
|
|
|
this._customOpaqueSortCompareFn = {};
|
|
|
this._customAlphaTestSortCompareFn = {};
|
|
|
this._customTransparentSortCompareFn = {};
|
|
|
- this._renderinGroupInfo = null;
|
|
|
+ this._renderingGroupInfo = new BABYLON.RenderingGroupInfo();
|
|
|
this._scene = scene;
|
|
|
for (var i = RenderingManager.MIN_RENDERINGGROUPS; i < RenderingManager.MAX_RENDERINGGROUPS; i++) {
|
|
|
this._autoClearDepthStencil[i] = { autoClear: true, depth: true, stencil: true };
|
|
@@ -22859,17 +22867,10 @@ var BABYLON;
|
|
|
this._depthStencilBufferAlreadyCleaned = true;
|
|
|
};
|
|
|
RenderingManager.prototype.render = function (customRenderFunction, activeMeshes, renderParticles, renderSprites) {
|
|
|
- // Check if there's at least on observer on the onRenderingGroupObservable and initialize things to fire it
|
|
|
- var observable = this._scene.onRenderingGroupObservable.hasObservers() ? this._scene.onRenderingGroupObservable : null;
|
|
|
- var info = null;
|
|
|
- if (observable) {
|
|
|
- if (!this._renderinGroupInfo) {
|
|
|
- this._renderinGroupInfo = new BABYLON.RenderingGroupInfo();
|
|
|
- }
|
|
|
- info = this._renderinGroupInfo;
|
|
|
- info.scene = this._scene;
|
|
|
- info.camera = this._scene.activeCamera;
|
|
|
- }
|
|
|
+ // Update the observable context (not null as it only goes away on dispose)
|
|
|
+ var info = this._renderingGroupInfo;
|
|
|
+ info.scene = this._scene;
|
|
|
+ info.camera = this._scene.activeCamera;
|
|
|
// Dispatch sprites
|
|
|
if (renderSprites) {
|
|
|
for (var index = 0; index < this._scene.spriteManagers.length; index++) {
|
|
@@ -22881,47 +22882,33 @@ var BABYLON;
|
|
|
for (var index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {
|
|
|
this._depthStencilBufferAlreadyCleaned = index === RenderingManager.MIN_RENDERINGGROUPS;
|
|
|
var renderingGroup = this._renderingGroups[index];
|
|
|
- if (!renderingGroup && !observable)
|
|
|
+ if (!renderingGroup)
|
|
|
continue;
|
|
|
- var renderingGroupMask = 0;
|
|
|
- // Fire PRECLEAR stage
|
|
|
- if (observable && info) {
|
|
|
- renderingGroupMask = Math.pow(2, index);
|
|
|
- info.renderStage = BABYLON.RenderingGroupInfo.STAGE_PRECLEAR;
|
|
|
- info.renderingGroupId = index;
|
|
|
- observable.notifyObservers(info, renderingGroupMask);
|
|
|
- }
|
|
|
+ var renderingGroupMask = Math.pow(2, index);
|
|
|
+ info.renderingGroupId = index;
|
|
|
+ // Before Observable
|
|
|
+ this._scene.onBeforeRenderingGroupObservable.notifyObservers(info, renderingGroupMask);
|
|
|
// Clear depth/stencil if needed
|
|
|
if (RenderingManager.AUTOCLEAR) {
|
|
|
- var autoClear = this._autoClearDepthStencil[index];
|
|
|
+ var autoClear = this._useSceneAutoClearSetup ?
|
|
|
+ this._scene.getAutoClearDepthStencilSetup(index) :
|
|
|
+ this._autoClearDepthStencil[index];
|
|
|
if (autoClear && autoClear.autoClear) {
|
|
|
this._clearDepthStencilBuffer(autoClear.depth, autoClear.stencil);
|
|
|
}
|
|
|
}
|
|
|
- if (observable && info) {
|
|
|
- // Fire PREOPAQUE stage
|
|
|
- info.renderStage = BABYLON.RenderingGroupInfo.STAGE_PREOPAQUE;
|
|
|
- observable.notifyObservers(info, renderingGroupMask);
|
|
|
- // Fire PRETRANSPARENT stage
|
|
|
- info.renderStage = BABYLON.RenderingGroupInfo.STAGE_PRETRANSPARENT;
|
|
|
- observable.notifyObservers(info, renderingGroupMask);
|
|
|
- }
|
|
|
- if (renderingGroup) {
|
|
|
- for (var _i = 0, _a = this._scene._beforeRenderingGroupDrawStage; _i < _a.length; _i++) {
|
|
|
- var step = _a[_i];
|
|
|
- step.action(index);
|
|
|
- }
|
|
|
- renderingGroup.render(customRenderFunction, renderSprites, renderParticles, activeMeshes);
|
|
|
- for (var _b = 0, _c = this._scene._afterRenderingGroupDrawStage; _b < _c.length; _b++) {
|
|
|
- var step = _c[_b];
|
|
|
- step.action(index);
|
|
|
- }
|
|
|
+ // Render
|
|
|
+ for (var _i = 0, _a = this._scene._beforeRenderingGroupDrawStage; _i < _a.length; _i++) {
|
|
|
+ var step = _a[_i];
|
|
|
+ step.action(index);
|
|
|
}
|
|
|
- // Fire POSTTRANSPARENT stage
|
|
|
- if (observable && info) {
|
|
|
- info.renderStage = BABYLON.RenderingGroupInfo.STAGE_POSTTRANSPARENT;
|
|
|
- observable.notifyObservers(info, renderingGroupMask);
|
|
|
+ renderingGroup.render(customRenderFunction, renderSprites, renderParticles, activeMeshes);
|
|
|
+ for (var _b = 0, _c = this._scene._afterRenderingGroupDrawStage; _b < _c.length; _b++) {
|
|
|
+ var step = _c[_b];
|
|
|
+ step.action(index);
|
|
|
}
|
|
|
+ // After Observable
|
|
|
+ this._scene.onAfterRenderingGroupObservable.notifyObservers(info, renderingGroupMask);
|
|
|
}
|
|
|
};
|
|
|
RenderingManager.prototype.reset = function () {
|
|
@@ -22935,6 +22922,7 @@ var BABYLON;
|
|
|
RenderingManager.prototype.dispose = function () {
|
|
|
this.freeRenderingGroups();
|
|
|
this._renderingGroups.length = 0;
|
|
|
+ this._renderingGroupInfo = null;
|
|
|
};
|
|
|
/**
|
|
|
* Clear the info related to rendering groups preventing retention points during dispose.
|
|
@@ -23016,6 +23004,15 @@ var BABYLON;
|
|
|
};
|
|
|
};
|
|
|
/**
|
|
|
+ * Gets the current auto clear configuration for one rendering group of the rendering
|
|
|
+ * manager.
|
|
|
+ * @param index the rendering group index to get the information for
|
|
|
+ * @returns The auto clear setup for the requested rendering group
|
|
|
+ */
|
|
|
+ RenderingManager.prototype.getAutoClearDepthStencilSetup = function (index) {
|
|
|
+ return this._autoClearDepthStencil[index];
|
|
|
+ };
|
|
|
+ /**
|
|
|
* The max id used for rendering groups (not included)
|
|
|
*/
|
|
|
RenderingManager.MAX_RENDERINGGROUPS = 4;
|
|
@@ -23674,26 +23671,6 @@ var BABYLON;
|
|
|
var RenderingGroupInfo = /** @class */ (function () {
|
|
|
function RenderingGroupInfo() {
|
|
|
}
|
|
|
- /**
|
|
|
- * Stage corresponding to the very first hook in the renderingGroup phase: before the render buffer may be cleared
|
|
|
- * This stage will be fired no matter what
|
|
|
- */
|
|
|
- RenderingGroupInfo.STAGE_PRECLEAR = 1;
|
|
|
- /**
|
|
|
- * Called before opaque object are rendered.
|
|
|
- * This stage will be fired only if there's 3D Opaque content to render
|
|
|
- */
|
|
|
- RenderingGroupInfo.STAGE_PREOPAQUE = 2;
|
|
|
- /**
|
|
|
- * Called after the opaque objects are rendered and before the transparent ones
|
|
|
- * This stage will be fired only if there's 3D transparent content to render
|
|
|
- */
|
|
|
- RenderingGroupInfo.STAGE_PRETRANSPARENT = 3;
|
|
|
- /**
|
|
|
- * Called after the transparent object are rendered, last hook of the renderingGroup phase
|
|
|
- * This stage will be fired no matter what
|
|
|
- */
|
|
|
- RenderingGroupInfo.STAGE_POSTTRANSPARENT = 4;
|
|
|
return RenderingGroupInfo;
|
|
|
}());
|
|
|
BABYLON.RenderingGroupInfo = RenderingGroupInfo;
|
|
@@ -23909,11 +23886,17 @@ var BABYLON;
|
|
|
*/
|
|
|
_this.onAfterStepObservable = new BABYLON.Observable();
|
|
|
/**
|
|
|
- * This Observable will be triggered for each stage of each renderingGroup of each rendered camera.
|
|
|
+ * This Observable will be triggered before rendering each renderingGroup of each rendered camera.
|
|
|
* The RenderinGroupInfo class contains all the information about the context in which the observable is called
|
|
|
* If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3)
|
|
|
*/
|
|
|
- _this.onRenderingGroupObservable = new BABYLON.Observable();
|
|
|
+ _this.onBeforeRenderingGroupObservable = new BABYLON.Observable();
|
|
|
+ /**
|
|
|
+ * This Observable will be triggered after rendering each renderingGroup of each rendered camera.
|
|
|
+ * The RenderinGroupInfo class contains all the information about the context in which the observable is called
|
|
|
+ * If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3)
|
|
|
+ */
|
|
|
+ _this.onAfterRenderingGroupObservable = new BABYLON.Observable();
|
|
|
// Animations
|
|
|
_this._registeredForLateAnimationBindings = new BABYLON.SmartArrayNoDuplicate(256);
|
|
|
/**
|
|
@@ -24175,6 +24158,8 @@ var BABYLON;
|
|
|
*/
|
|
|
_this._afterCameraDrawStage = BABYLON.Stage.Create();
|
|
|
_this._activeMeshesFrozen = false;
|
|
|
+ /** @hidden */
|
|
|
+ _this._allowPostProcessClear = true;
|
|
|
_this._tempPickingRay = BABYLON.Ray ? BABYLON.Ray.Zero() : null;
|
|
|
_this._engine = engine || BABYLON.Engine.LastCreatedEngine;
|
|
|
_this._engine.scenes.push(_this);
|
|
@@ -28035,6 +28020,8 @@ var BABYLON;
|
|
|
this.onBeforeAnimationsObservable.clear();
|
|
|
this.onAfterAnimationsObservable.clear();
|
|
|
this.onDataLoadedObservable.clear();
|
|
|
+ this.onBeforeRenderingGroupObservable.clear();
|
|
|
+ this.onAfterRenderingGroupObservable.clear();
|
|
|
this.detachControl();
|
|
|
// Release sounds & sounds tracks
|
|
|
if (BABYLON.AudioEngine) {
|
|
@@ -28849,6 +28836,15 @@ var BABYLON;
|
|
|
this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil, depth, stencil);
|
|
|
};
|
|
|
/**
|
|
|
+ * Gets the current auto clear configuration for one rendering group of the rendering
|
|
|
+ * manager.
|
|
|
+ * @param index the rendering group index to get the information for
|
|
|
+ * @returns The auto clear setup for the requested rendering group
|
|
|
+ */
|
|
|
+ Scene.prototype.getAutoClearDepthStencilSetup = function (index) {
|
|
|
+ return this._renderingManager.getAutoClearDepthStencilSetup(index);
|
|
|
+ };
|
|
|
+ /**
|
|
|
* Will flag all materials as dirty to trigger new shader compilation
|
|
|
* @param flag defines the flag used to specify which material part must be marked as dirty
|
|
|
* @param predicate If not null, it will be used to specifiy if a material has to be marked as dirty
|
|
@@ -58186,9 +58182,15 @@ var BABYLON;
|
|
|
return "LinesMesh";
|
|
|
};
|
|
|
Object.defineProperty(LinesMesh.prototype, "material", {
|
|
|
+ /**
|
|
|
+ * @hidden
|
|
|
+ */
|
|
|
get: function () {
|
|
|
return this._colorShader;
|
|
|
},
|
|
|
+ /**
|
|
|
+ * @hidden
|
|
|
+ */
|
|
|
set: function (value) {
|
|
|
// Do nothing
|
|
|
},
|
|
@@ -58196,6 +58198,9 @@ var BABYLON;
|
|
|
configurable: true
|
|
|
});
|
|
|
Object.defineProperty(LinesMesh.prototype, "checkCollisions", {
|
|
|
+ /**
|
|
|
+ * @hidden
|
|
|
+ */
|
|
|
get: function () {
|
|
|
return false;
|
|
|
},
|
|
@@ -64975,6 +64980,7 @@ var BABYLON;
|
|
|
_this._doNotChangeAspectRatio = doNotChangeAspectRatio;
|
|
|
// Rendering groups
|
|
|
_this._renderingManager = new BABYLON.RenderingManager(scene);
|
|
|
+ _this._renderingManager._useSceneAutoClearSetup = true;
|
|
|
if (isMulti) {
|
|
|
return _this;
|
|
|
}
|
|
@@ -65475,6 +65481,7 @@ var BABYLON;
|
|
|
*/
|
|
|
RenderTargetTexture.prototype.setRenderingAutoClearDepthStencil = function (renderingGroupId, autoClearDepthStencil) {
|
|
|
this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);
|
|
|
+ this._renderingManager._useSceneAutoClearSetup = false;
|
|
|
};
|
|
|
RenderTargetTexture.prototype.clone = function () {
|
|
|
var textureSize = this.getSize();
|
|
@@ -67162,7 +67169,7 @@ var BABYLON;
|
|
|
}
|
|
|
this.onActivateObservable.notifyObservers(camera);
|
|
|
// Clear
|
|
|
- if (this.autoClear && this.alphaMode === BABYLON.Engine.ALPHA_DISABLE) {
|
|
|
+ if (scene._allowPostProcessClear && this.autoClear && this.alphaMode === BABYLON.Engine.ALPHA_DISABLE) {
|
|
|
this._engine.clear(this.clearColor ? this.clearColor : scene.clearColor, true, true, true);
|
|
|
}
|
|
|
if (this._reusable) {
|
|
@@ -89282,6 +89289,7 @@ var BABYLON;
|
|
|
this.onPointerOutObservable = new BABYLON.Observable();
|
|
|
// Create scene which will be rendered in the foreground and remove it from being referenced by engine to avoid interfering with existing app
|
|
|
this.utilityLayerScene = new BABYLON.Scene(originalScene.getEngine());
|
|
|
+ this.utilityLayerScene._allowPostProcessClear = false;
|
|
|
originalScene.getEngine().scenes.pop();
|
|
|
// Detach controls on utility scene, events will be fired by logic below to handle picking priority
|
|
|
this.utilityLayerScene.detachControl();
|
|
@@ -89399,7 +89407,27 @@ var BABYLON;
|
|
|
*/
|
|
|
UtilityLayerRenderer.prototype.render = function () {
|
|
|
this._updateCamera();
|
|
|
- this.utilityLayerScene.render(false);
|
|
|
+ if (this.utilityLayerScene.activeCamera) {
|
|
|
+ // Set the camera's scene to utility layers scene
|
|
|
+ var oldScene = this.utilityLayerScene.activeCamera.getScene();
|
|
|
+ var camera = this.utilityLayerScene.activeCamera;
|
|
|
+ camera._scene = this.utilityLayerScene;
|
|
|
+ if (camera.leftCamera) {
|
|
|
+ camera.leftCamera._scene = this.utilityLayerScene;
|
|
|
+ }
|
|
|
+ if (camera.rightCamera) {
|
|
|
+ camera.rightCamera._scene = this.utilityLayerScene;
|
|
|
+ }
|
|
|
+ this.utilityLayerScene.render(false);
|
|
|
+ // Reset camera's scene back to original
|
|
|
+ camera._scene = oldScene;
|
|
|
+ if (camera.leftCamera) {
|
|
|
+ camera.leftCamera._scene = oldScene;
|
|
|
+ }
|
|
|
+ if (camera.rightCamera) {
|
|
|
+ camera.rightCamera._scene = oldScene;
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
/**
|
|
|
* Disposes of the renderer
|
|
@@ -89495,6 +89523,10 @@ var BABYLON;
|
|
|
*/
|
|
|
this.enabled = true;
|
|
|
/**
|
|
|
+ * If camera controls should be detached during the drag
|
|
|
+ */
|
|
|
+ this.detachCameraControls = true;
|
|
|
+ /**
|
|
|
* If set, the drag plane/axis will be rotated based on the attached mesh's world rotation (Default: true)
|
|
|
*/
|
|
|
this.useObjectOrienationForDragging = true;
|
|
@@ -89552,6 +89584,10 @@ var BABYLON;
|
|
|
PointerDragBehavior._planeScene = new BABYLON.Scene(this._scene.getEngine());
|
|
|
PointerDragBehavior._planeScene.detachControl();
|
|
|
this._scene.getEngine().scenes.pop();
|
|
|
+ this._scene.onDisposeObservable.addOnce(function () {
|
|
|
+ PointerDragBehavior._planeScene.dispose();
|
|
|
+ PointerDragBehavior._planeScene = null;
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
this._dragPlane = BABYLON.Mesh.CreatePlane("pointerDragPlane", this._debugMode ? 1 : 10000, PointerDragBehavior._planeScene, false, BABYLON.Mesh.DOUBLESIDE);
|
|
@@ -89563,6 +89599,7 @@ var BABYLON;
|
|
|
var pickPredicate = function (m) {
|
|
|
return _this._attachedNode == m || m.isDescendantOf(_this._attachedNode);
|
|
|
};
|
|
|
+ var attachedElement = null;
|
|
|
this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
|
|
|
if (!_this.enabled) {
|
|
|
return;
|
|
@@ -89577,12 +89614,26 @@ var BABYLON;
|
|
|
_this.lastDragPosition.copyFrom(pickedPoint);
|
|
|
_this.onDragStartObservable.notifyObservers({ dragPlanePoint: pickedPoint, pointerId: _this.currentDraggingPointerID });
|
|
|
targetPosition.copyFrom(_this._attachedNode.absolutePosition);
|
|
|
+ // Detatch camera controls
|
|
|
+ if (_this.detachCameraControls && _this._scene.activeCamera) {
|
|
|
+ if (_this._scene.activeCamera.inputs.attachedElement) {
|
|
|
+ attachedElement = _this._scene.activeCamera.inputs.attachedElement;
|
|
|
+ _this._scene.activeCamera.detachControl(_this._scene.activeCamera.inputs.attachedElement);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ attachedElement = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERUP) {
|
|
|
if (_this.currentDraggingPointerID == pointerInfo.event.pointerId) {
|
|
|
_this.releaseDrag();
|
|
|
+ // Reattach camera controls
|
|
|
+ if (_this.detachCameraControls && attachedElement && _this._scene.activeCamera) {
|
|
|
+ _this._scene.activeCamera.attachControl(attachedElement, true);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
|
|
@@ -89848,6 +89899,10 @@ var BABYLON;
|
|
|
* The id of the pointer that is currently interacting with the behavior (-1 when no pointer is active)
|
|
|
*/
|
|
|
this.currentDraggingPointerID = -1;
|
|
|
+ /**
|
|
|
+ * If camera controls should be detached during the drag
|
|
|
+ */
|
|
|
+ this.detachCameraControls = true;
|
|
|
}
|
|
|
Object.defineProperty(SixDofDragBehavior.prototype, "name", {
|
|
|
/**
|
|
@@ -89885,6 +89940,7 @@ var BABYLON;
|
|
|
var pickPredicate = function (m) {
|
|
|
return _this._ownerNode == m || m.isDescendantOf(_this._ownerNode);
|
|
|
};
|
|
|
+ var attachedElement = null;
|
|
|
this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
|
|
|
if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
|
|
|
if (!_this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)) {
|
|
@@ -89911,6 +89967,16 @@ var BABYLON;
|
|
|
_this._targetPosition.copyFrom(_this._virtualDragMesh.absolutePosition);
|
|
|
_this.dragging = true;
|
|
|
_this.currentDraggingPointerID = pointerInfo.event.pointerId;
|
|
|
+ // Detatch camera controls
|
|
|
+ if (_this.detachCameraControls && _this._scene.activeCamera) {
|
|
|
+ if (_this._scene.activeCamera.inputs.attachedElement) {
|
|
|
+ attachedElement = _this._scene.activeCamera.inputs.attachedElement;
|
|
|
+ _this._scene.activeCamera.detachControl(_this._scene.activeCamera.inputs.attachedElement);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ attachedElement = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERUP) {
|
|
@@ -89920,6 +89986,10 @@ var BABYLON;
|
|
|
_this.currentDraggingPointerID = -1;
|
|
|
pickedMesh = null;
|
|
|
_this._virtualOriginMesh.removeChild(_this._virtualDragMesh);
|
|
|
+ // Reattach camera controls
|
|
|
+ if (_this.detachCameraControls && attachedElement && _this._scene.activeCamera) {
|
|
|
+ _this._scene.activeCamera.attachControl(attachedElement, true);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
|
|
@@ -90005,6 +90075,178 @@ var BABYLON;
|
|
|
var BABYLON;
|
|
|
(function (BABYLON) {
|
|
|
/**
|
|
|
+ * @hidden
|
|
|
+ */
|
|
|
+ var FaceDirectionInfo = /** @class */ (function () {
|
|
|
+ function FaceDirectionInfo(direction, rotatedDirection, diff, ignore) {
|
|
|
+ if (rotatedDirection === void 0) { rotatedDirection = new BABYLON.Vector3(); }
|
|
|
+ if (diff === void 0) { diff = 0; }
|
|
|
+ if (ignore === void 0) { ignore = false; }
|
|
|
+ this.direction = direction;
|
|
|
+ this.rotatedDirection = rotatedDirection;
|
|
|
+ this.diff = diff;
|
|
|
+ this.ignore = ignore;
|
|
|
+ }
|
|
|
+ return FaceDirectionInfo;
|
|
|
+ }());
|
|
|
+ /**
|
|
|
+ * A behavior that when attached to a mesh will will place a specified node on the meshes face pointing towards the camera
|
|
|
+ */
|
|
|
+ var AttachToBoxBehavior = /** @class */ (function () {
|
|
|
+ /**
|
|
|
+ * Creates the AttachToBoxBehavior, used to attach UI to the closest face of the box to a camera
|
|
|
+ * @param ui The transform node that should be attched to the mesh
|
|
|
+ */
|
|
|
+ function AttachToBoxBehavior(ui) {
|
|
|
+ this.ui = ui;
|
|
|
+ /**
|
|
|
+ * The name of the behavior
|
|
|
+ */
|
|
|
+ this.name = "AttachToBoxBehavior";
|
|
|
+ /**
|
|
|
+ * The distance away from the face of the mesh that the UI should be attached to (default: 0.15)
|
|
|
+ */
|
|
|
+ this.distanceAwayFromFace = 0.15;
|
|
|
+ /**
|
|
|
+ * The distance from the bottom of the face that the UI should be attached to (default: 0.15)
|
|
|
+ */
|
|
|
+ this.distanceAwayFromBottomOfFace = 0.15;
|
|
|
+ this._faceVectors = [new FaceDirectionInfo(BABYLON.Vector3.Up()), new FaceDirectionInfo(BABYLON.Vector3.Down()), new FaceDirectionInfo(BABYLON.Vector3.Left()), new FaceDirectionInfo(BABYLON.Vector3.Right()), new FaceDirectionInfo(BABYLON.Vector3.Forward()), new FaceDirectionInfo(BABYLON.Vector3.Forward().scaleInPlace(-1))];
|
|
|
+ this._tmpMatrix = new BABYLON.Matrix();
|
|
|
+ this._tmpVector = new BABYLON.Vector3();
|
|
|
+ this._zeroVector = BABYLON.Vector3.Zero();
|
|
|
+ this._lookAtTmpMatrix = new BABYLON.Matrix();
|
|
|
+ /* Does nothing */
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Initializes the behavior
|
|
|
+ */
|
|
|
+ AttachToBoxBehavior.prototype.init = function () {
|
|
|
+ /* Does nothing */
|
|
|
+ };
|
|
|
+ AttachToBoxBehavior.prototype._closestFace = function (targetDirection) {
|
|
|
+ var _this = this;
|
|
|
+ // Go over each face and calculate the angle between the face's normal and targetDirection
|
|
|
+ this._faceVectors.forEach(function (v) {
|
|
|
+ if (!_this._target.rotationQuaternion) {
|
|
|
+ _this._target.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this._target.rotation.y, _this._target.rotation.x, _this._target.rotation.z);
|
|
|
+ }
|
|
|
+ _this._target.rotationQuaternion.toRotationMatrix(_this._tmpMatrix);
|
|
|
+ BABYLON.Vector3.TransformCoordinatesToRef(v.direction, _this._tmpMatrix, v.rotatedDirection);
|
|
|
+ v.diff = BABYLON.Vector3.GetAngleBetweenVectors(v.rotatedDirection, targetDirection, BABYLON.Vector3.Cross(v.rotatedDirection, targetDirection));
|
|
|
+ });
|
|
|
+ // Return the face information of the one with the normal closeset to target direction
|
|
|
+ return this._faceVectors.reduce(function (min, p) {
|
|
|
+ if (min.ignore) {
|
|
|
+ return p;
|
|
|
+ }
|
|
|
+ else if (p.ignore) {
|
|
|
+ return min;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return min.diff < p.diff ? min : p;
|
|
|
+ }
|
|
|
+ }, this._faceVectors[0]);
|
|
|
+ };
|
|
|
+ AttachToBoxBehavior.prototype._lookAtToRef = function (pos, up, ref) {
|
|
|
+ if (up === void 0) { up = new BABYLON.Vector3(0, 1, 0); }
|
|
|
+ BABYLON.Matrix.LookAtLHToRef(this._zeroVector, pos, up, this._lookAtTmpMatrix);
|
|
|
+ this._lookAtTmpMatrix.invert();
|
|
|
+ BABYLON.Quaternion.FromRotationMatrixToRef(this._lookAtTmpMatrix, ref);
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * Attaches the AttachToBoxBehavior to the passed in mesh
|
|
|
+ * @param target The mesh that the specified node will be attached to
|
|
|
+ */
|
|
|
+ AttachToBoxBehavior.prototype.attach = function (target) {
|
|
|
+ var _this = this;
|
|
|
+ this._target = target;
|
|
|
+ this._scene = this._target.getScene();
|
|
|
+ // Every frame, update the app bars position
|
|
|
+ this._onRenderObserver = this._scene.onBeforeRenderObservable.add(function () {
|
|
|
+ if (!_this._scene.activeCamera) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // Find the face closest to the cameras position
|
|
|
+ var cameraPos = _this._scene.activeCamera.position;
|
|
|
+ if (_this._scene.activeCamera.devicePosition) {
|
|
|
+ cameraPos = _this._scene.activeCamera.devicePosition;
|
|
|
+ }
|
|
|
+ var facing = _this._closestFace(cameraPos.subtract(target.position));
|
|
|
+ if (_this._scene.activeCamera.leftCamera) {
|
|
|
+ _this._scene.activeCamera.leftCamera.computeWorldMatrix().getRotationMatrixToRef(_this._tmpMatrix);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _this._scene.activeCamera.computeWorldMatrix().getRotationMatrixToRef(_this._tmpMatrix);
|
|
|
+ }
|
|
|
+ // Get camera up direction
|
|
|
+ BABYLON.Vector3.TransformCoordinatesToRef(BABYLON.Vector3.Up(), _this._tmpMatrix, _this._tmpVector);
|
|
|
+ // Ignore faces to not select a parrelel face for the up vector of the UI
|
|
|
+ _this._faceVectors.forEach(function (v) {
|
|
|
+ if (facing.direction.x && v.direction.x) {
|
|
|
+ v.ignore = true;
|
|
|
+ }
|
|
|
+ if (facing.direction.y && v.direction.y) {
|
|
|
+ v.ignore = true;
|
|
|
+ }
|
|
|
+ if (facing.direction.z && v.direction.z) {
|
|
|
+ v.ignore = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ var facingUp = _this._closestFace(_this._tmpVector);
|
|
|
+ // Unignore faces
|
|
|
+ _this._faceVectors.forEach(function (v) {
|
|
|
+ v.ignore = false;
|
|
|
+ });
|
|
|
+ // Position the app bar on that face
|
|
|
+ _this.ui.position.copyFrom(target.position);
|
|
|
+ if (facing.direction.x) {
|
|
|
+ facing.rotatedDirection.scaleToRef((target.scaling.x / 2) + _this.distanceAwayFromFace, _this._tmpVector);
|
|
|
+ _this.ui.position.addInPlace(_this._tmpVector);
|
|
|
+ }
|
|
|
+ if (facing.direction.y) {
|
|
|
+ facing.rotatedDirection.scaleToRef((target.scaling.y / 2) + _this.distanceAwayFromFace, _this._tmpVector);
|
|
|
+ _this.ui.position.addInPlace(_this._tmpVector);
|
|
|
+ }
|
|
|
+ if (facing.direction.z) {
|
|
|
+ facing.rotatedDirection.scaleToRef((target.scaling.z / 2) + _this.distanceAwayFromFace, _this._tmpVector);
|
|
|
+ _this.ui.position.addInPlace(_this._tmpVector);
|
|
|
+ }
|
|
|
+ // Rotate to be oriented properly to the camera
|
|
|
+ if (!_this.ui.rotationQuaternion) {
|
|
|
+ _this.ui.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this.ui.rotation.y, _this.ui.rotation.x, _this.ui.rotation.z);
|
|
|
+ }
|
|
|
+ facing.rotatedDirection.scaleToRef(-1, _this._tmpVector);
|
|
|
+ _this._lookAtToRef(_this._tmpVector, facingUp.rotatedDirection, _this.ui.rotationQuaternion);
|
|
|
+ // Place ui the correct distance from the bottom of the mesh
|
|
|
+ if (facingUp.direction.x) {
|
|
|
+ _this.ui.up.scaleToRef(_this.distanceAwayFromBottomOfFace - target.scaling.x / 2, _this._tmpVector);
|
|
|
+ }
|
|
|
+ if (facingUp.direction.y) {
|
|
|
+ _this.ui.up.scaleToRef(_this.distanceAwayFromBottomOfFace - target.scaling.y / 2, _this._tmpVector);
|
|
|
+ }
|
|
|
+ if (facingUp.direction.z) {
|
|
|
+ _this.ui.up.scaleToRef(_this.distanceAwayFromBottomOfFace - target.scaling.z / 2, _this._tmpVector);
|
|
|
+ }
|
|
|
+ _this.ui.position.addInPlace(_this._tmpVector);
|
|
|
+ });
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * Detaches the behavior from the mesh
|
|
|
+ */
|
|
|
+ AttachToBoxBehavior.prototype.detach = function () {
|
|
|
+ this._scene.onBeforeRenderObservable.remove(this._onRenderObserver);
|
|
|
+ };
|
|
|
+ return AttachToBoxBehavior;
|
|
|
+ }());
|
|
|
+ BABYLON.AttachToBoxBehavior = AttachToBoxBehavior;
|
|
|
+})(BABYLON || (BABYLON = {}));
|
|
|
+
|
|
|
+//# sourceMappingURL=babylon.attachToBoxBehavior.js.map
|
|
|
+
|
|
|
+var BABYLON;
|
|
|
+(function (BABYLON) {
|
|
|
+ /**
|
|
|
* Renders gizmos on top of an existing scene which provide controls for position, rotation, etc.
|
|
|
*/
|
|
|
var Gizmo = /** @class */ (function () {
|
|
@@ -104206,11 +104448,15 @@ var BABYLON;
|
|
|
else {
|
|
|
_this._useDirectMapping = options.useDirectMapping;
|
|
|
}
|
|
|
+ _this._setReady(false);
|
|
|
// create
|
|
|
var tempOptions = { loop: options.loop, autoPlay: options.autoPlay, autoUpdateTexture: true, poster: options.poster };
|
|
|
var material = _this._material = new BABYLON.BackgroundMaterial(name + "_material", scene);
|
|
|
var texture = _this._videoTexture = new BABYLON.VideoTexture(name + "_texture", urlsOrVideo, scene, false, _this._useDirectMapping, BABYLON.Texture.TRILINEAR_SAMPLINGMODE, tempOptions);
|
|
|
_this._mesh = BABYLON.Mesh.CreateSphere(name + "_mesh", options.resolution, options.size, scene, false, BABYLON.Mesh.BACKSIDE);
|
|
|
+ texture.onLoadObservable.addOnce(function () {
|
|
|
+ _this._setReady(true);
|
|
|
+ });
|
|
|
// configure material
|
|
|
material.useEquirectangularFOV = true;
|
|
|
material.fovMultiplier = 1.0;
|
|
@@ -104309,6 +104555,7 @@ var BABYLON;
|
|
|
else {
|
|
|
_this._useDirectMapping = options.useDirectMapping;
|
|
|
}
|
|
|
+ _this._setReady(false);
|
|
|
// create
|
|
|
var material = _this._material = new BABYLON.BackgroundMaterial(name + "_material", scene);
|
|
|
_this._mesh = BABYLON.Mesh.CreateSphere(name + "_mesh", options.resolution, options.size, scene, false, BABYLON.Mesh.BACKSIDE);
|
|
@@ -104317,6 +104564,9 @@ var BABYLON;
|
|
|
material.useEquirectangularFOV = true;
|
|
|
material.fovMultiplier = 1.0;
|
|
|
_this.photoTexture = new BABYLON.Texture(urlOfPhoto, scene, true, !_this._useDirectMapping);
|
|
|
+ _this.photoTexture.onLoadObservable.addOnce(function () {
|
|
|
+ _this._setReady(true);
|
|
|
+ });
|
|
|
// configure mesh
|
|
|
_this._mesh.material = material;
|
|
|
_this._mesh.parent = _this;
|