|
@@ -5781,7 +5781,6 @@ var BABYLON;
|
|
|
var Tools = /** @class */ (function () {
|
|
|
function Tools() {
|
|
|
}
|
|
|
- ;
|
|
|
/**
|
|
|
* Interpolates between a and b via alpha
|
|
|
* @param a The lower value (returned when alpha = 0)
|
|
@@ -6135,10 +6134,7 @@ var BABYLON;
|
|
|
database.openAsync(loadFromIndexedDB, noIndexedDB);
|
|
|
}
|
|
|
else {
|
|
|
- if (url.indexOf("file:") !== 0) {
|
|
|
- noIndexedDB();
|
|
|
- }
|
|
|
- else {
|
|
|
+ if (url.indexOf("file:") !== -1) {
|
|
|
var textureName = decodeURIComponent(url.substring(5).toLowerCase());
|
|
|
if (BABYLON.FilesInput.FilesToLoad[textureName]) {
|
|
|
try {
|
|
@@ -6155,16 +6151,13 @@ var BABYLON;
|
|
|
catch (e) {
|
|
|
img.src = "";
|
|
|
}
|
|
|
- }
|
|
|
- else {
|
|
|
- Tools.Error("Image: " + textureName + " not found. Did you forget to provide it?");
|
|
|
- img.src = Tools.fallbackTexture;
|
|
|
+ return img;
|
|
|
}
|
|
|
}
|
|
|
+ noIndexedDB();
|
|
|
}
|
|
|
return img;
|
|
|
};
|
|
|
- //ANY
|
|
|
Tools.LoadFile = function (url, callback, progressCallBack, database, useArrayBuffer, onError) {
|
|
|
url = Tools.CleanUrl(url);
|
|
|
url = Tools.PreprocessUrl(url);
|
|
@@ -6205,30 +6198,20 @@ var BABYLON;
|
|
|
database.loadFileFromDB(url, callback, progressCallBack, noIndexedDB, useArrayBuffer);
|
|
|
}
|
|
|
};
|
|
|
+ // If file and file input are set
|
|
|
if (url.indexOf("file:") !== -1) {
|
|
|
var fileName = decodeURIComponent(url.substring(5).toLowerCase());
|
|
|
if (BABYLON.FilesInput.FilesToLoad[fileName]) {
|
|
|
Tools.ReadFile(BABYLON.FilesInput.FilesToLoad[fileName], callback, progressCallBack, useArrayBuffer);
|
|
|
+ return request;
|
|
|
}
|
|
|
- else {
|
|
|
- var errorMessage = "File: " + fileName + " not found. Did you forget to provide it?";
|
|
|
- if (onError) {
|
|
|
- var e = new Error(errorMessage);
|
|
|
- onError(undefined, e);
|
|
|
- }
|
|
|
- else {
|
|
|
- Tools.Error(errorMessage);
|
|
|
- }
|
|
|
- }
|
|
|
+ }
|
|
|
+ // Caching all files
|
|
|
+ if (database && database.enableSceneOffline) {
|
|
|
+ database.openAsync(loadFromIndexedDB, noIndexedDB);
|
|
|
}
|
|
|
else {
|
|
|
- // Caching all files
|
|
|
- if (database && database.enableSceneOffline) {
|
|
|
- database.openAsync(loadFromIndexedDB, noIndexedDB);
|
|
|
- }
|
|
|
- else {
|
|
|
- noIndexedDB();
|
|
|
- }
|
|
|
+ noIndexedDB();
|
|
|
}
|
|
|
return request;
|
|
|
};
|
|
@@ -6384,7 +6367,7 @@ var BABYLON;
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
- Tools.DumpFramebuffer = function (width, height, engine, successCallback, mimeType) {
|
|
|
+ Tools.DumpFramebuffer = function (width, height, engine, successCallback, mimeType, fileName) {
|
|
|
if (mimeType === void 0) { mimeType = "image/png"; }
|
|
|
// Read the contents of the framebuffer
|
|
|
var numberOfChannelsByLine = width * 4;
|
|
@@ -6415,38 +6398,63 @@ var BABYLON;
|
|
|
var castData = (imageData.data);
|
|
|
castData.set(data);
|
|
|
context.putImageData(imageData, 0, 0);
|
|
|
- Tools.EncodeScreenshotCanvasData(successCallback, mimeType);
|
|
|
+ Tools.EncodeScreenshotCanvasData(successCallback, mimeType, fileName);
|
|
|
}
|
|
|
};
|
|
|
- Tools.EncodeScreenshotCanvasData = function (successCallback, mimeType) {
|
|
|
+ Tools.EncodeScreenshotCanvasData = function (successCallback, mimeType, fileName) {
|
|
|
if (mimeType === void 0) { mimeType = "image/png"; }
|
|
|
var base64Image = screenshotCanvas.toDataURL(mimeType);
|
|
|
if (successCallback) {
|
|
|
successCallback(base64Image);
|
|
|
}
|
|
|
else {
|
|
|
- //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.
|
|
|
- if (("download" in document.createElement("a"))) {
|
|
|
- var a = window.document.createElement("a");
|
|
|
- a.href = base64Image;
|
|
|
- var date = new Date();
|
|
|
- var stringDate = (date.getFullYear() + "-" + (date.getMonth() + 1)).slice(-2) + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
|
|
|
- a.setAttribute("download", "screenshot_" + stringDate + ".png");
|
|
|
- window.document.body.appendChild(a);
|
|
|
- a.addEventListener("click", function () {
|
|
|
- if (a.parentElement) {
|
|
|
- a.parentElement.removeChild(a);
|
|
|
- }
|
|
|
- });
|
|
|
- a.click();
|
|
|
- //Or opening a new tab with the image if it is not possible to automatically start download.
|
|
|
- }
|
|
|
- else {
|
|
|
- var newWindow = window.open("");
|
|
|
- var img = newWindow.document.createElement("img");
|
|
|
- img.src = base64Image;
|
|
|
- newWindow.document.body.appendChild(img);
|
|
|
+ // We need HTMLCanvasElement.toBlob for HD screenshots
|
|
|
+ if (!screenshotCanvas.toBlob) {
|
|
|
+ // low performance polyfill based on toDataURL (https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob)
|
|
|
+ screenshotCanvas.toBlob = function (callback, type, quality) {
|
|
|
+ var canvas = this;
|
|
|
+ setTimeout(function () {
|
|
|
+ var binStr = atob(canvas.toDataURL(type, quality).split(',')[1]), len = binStr.length, arr = new Uint8Array(len);
|
|
|
+ for (var i = 0; i < len; i++) {
|
|
|
+ arr[i] = binStr.charCodeAt(i);
|
|
|
+ }
|
|
|
+ callback(new Blob([arr], { type: type || 'image/png' }));
|
|
|
+ });
|
|
|
+ };
|
|
|
}
|
|
|
+ screenshotCanvas.toBlob(function (blob) {
|
|
|
+ var url = URL.createObjectURL(blob);
|
|
|
+ //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.
|
|
|
+ if (("download" in document.createElement("a"))) {
|
|
|
+ var a = window.document.createElement("a");
|
|
|
+ a.href = url;
|
|
|
+ if (fileName) {
|
|
|
+ a.setAttribute("download", fileName);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ var date = new Date();
|
|
|
+ var stringDate = (date.getFullYear() + "-" + (date.getMonth() + 1)).slice(-2) + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
|
|
|
+ a.setAttribute("download", "screenshot_" + stringDate + ".png");
|
|
|
+ }
|
|
|
+ window.document.body.appendChild(a);
|
|
|
+ a.addEventListener("click", function () {
|
|
|
+ if (a.parentElement) {
|
|
|
+ a.parentElement.removeChild(a);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ a.click();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ var newWindow = window.open("");
|
|
|
+ var img = newWindow.document.createElement("img");
|
|
|
+ img.onload = function () {
|
|
|
+ // no longer need to read the blob so it's revoked
|
|
|
+ URL.revokeObjectURL(url);
|
|
|
+ };
|
|
|
+ img.src = url;
|
|
|
+ newWindow.document.body.appendChild(img);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
};
|
|
|
Tools.CreateScreenshot = function (engine, camera, size, successCallback, mimeType) {
|
|
@@ -6499,9 +6507,10 @@ var BABYLON;
|
|
|
}
|
|
|
Tools.EncodeScreenshotCanvasData(successCallback, mimeType);
|
|
|
};
|
|
|
- Tools.CreateScreenshotUsingRenderTarget = function (engine, camera, size, successCallback, mimeType, samples) {
|
|
|
+ Tools.CreateScreenshotUsingRenderTarget = function (engine, camera, size, successCallback, mimeType, samples, antialiasing, fileName) {
|
|
|
if (mimeType === void 0) { mimeType = "image/png"; }
|
|
|
if (samples === void 0) { samples = 1; }
|
|
|
+ if (antialiasing === void 0) { antialiasing = false; }
|
|
|
var width;
|
|
|
var height;
|
|
|
//If a precision value is specified
|
|
@@ -6542,8 +6551,11 @@ var BABYLON;
|
|
|
var texture = new BABYLON.RenderTargetTexture("screenShot", size, scene, false, false, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, false, BABYLON.Texture.NEAREST_SAMPLINGMODE);
|
|
|
texture.renderList = null;
|
|
|
texture.samples = samples;
|
|
|
+ if (antialiasing) {
|
|
|
+ texture.addPostProcess(new BABYLON.FxaaPostProcess('antialiasing', 1.0, scene.activeCamera));
|
|
|
+ }
|
|
|
texture.onAfterRenderObservable.add(function () {
|
|
|
- Tools.DumpFramebuffer(width, height, engine, successCallback, mimeType);
|
|
|
+ Tools.DumpFramebuffer(width, height, engine, successCallback, mimeType, fileName);
|
|
|
});
|
|
|
scene.incrementRenderId();
|
|
|
scene.resetCachedMaterial();
|
|
@@ -8522,7 +8534,7 @@ var BABYLON;
|
|
|
});
|
|
|
Object.defineProperty(Engine, "Version", {
|
|
|
get: function () {
|
|
|
- return "3.1-beta-4";
|
|
|
+ return "3.1-beta-5";
|
|
|
},
|
|
|
enumerable: true,
|
|
|
configurable: true
|
|
@@ -20477,35 +20489,37 @@ var BABYLON;
|
|
|
this.simplificationQueue.executeNext();
|
|
|
}
|
|
|
if (this._engine.isDeterministicLockStep()) {
|
|
|
- var deltaTime = Math.max(Scene.MinDeltaTime, Math.min(this._engine.getDeltaTime(), Scene.MaxDeltaTime)) / 1000;
|
|
|
- var defaultTimeStep = (60.0 / 1000.0);
|
|
|
+ var deltaTime = Math.max(Scene.MinDeltaTime, Math.min(this._engine.getDeltaTime(), Scene.MaxDeltaTime)) + this._timeAccumulator;
|
|
|
+ var defaultFPS = (60.0 / 1000.0);
|
|
|
+ var defaultFrameTime = 1000 / 60; // frame time in MS
|
|
|
if (this._physicsEngine) {
|
|
|
- defaultTimeStep = this._physicsEngine.getTimeStep();
|
|
|
+ defaultFrameTime = this._physicsEngine.getTimeStep() / 1000; //timestep in physics engine is in seconds
|
|
|
}
|
|
|
+ var stepsTaken = 0;
|
|
|
var maxSubSteps = this._engine.getLockstepMaxSteps();
|
|
|
- this._timeAccumulator += deltaTime;
|
|
|
- // compute the amount of fixed steps we should have taken since the last step
|
|
|
- var internalSteps = Math.floor(this._timeAccumulator / defaultTimeStep);
|
|
|
+ var internalSteps = Math.floor(deltaTime / (1000 * defaultFPS));
|
|
|
internalSteps = Math.min(internalSteps, maxSubSteps);
|
|
|
- for (this._currentInternalStep = 0; this._currentInternalStep < internalSteps; this._currentInternalStep++) {
|
|
|
+ do {
|
|
|
this.onBeforeStepObservable.notifyObservers(this);
|
|
|
// Animations
|
|
|
- this._animationRatio = defaultTimeStep * (60.0 / 1000.0);
|
|
|
+ this._animationRatio = defaultFrameTime * defaultFPS;
|
|
|
this._animate();
|
|
|
this.onAfterAnimationsObservable.notifyObservers(this);
|
|
|
// Physics
|
|
|
if (this._physicsEngine) {
|
|
|
this.onBeforePhysicsObservable.notifyObservers(this);
|
|
|
- this._physicsEngine._step(defaultTimeStep);
|
|
|
+ this._physicsEngine._step(defaultFPS);
|
|
|
this.onAfterPhysicsObservable.notifyObservers(this);
|
|
|
}
|
|
|
- this._timeAccumulator -= defaultTimeStep;
|
|
|
this.onAfterStepObservable.notifyObservers(this);
|
|
|
this._currentStepId++;
|
|
|
- if ((internalSteps > 1) && (this._currentInternalStep != internalSteps - 1)) {
|
|
|
+ if ((internalSteps > 1) && (stepsTaken != internalSteps - 1)) {
|
|
|
this._evaluateActiveMeshes();
|
|
|
}
|
|
|
- }
|
|
|
+ stepsTaken++;
|
|
|
+ deltaTime -= defaultFrameTime;
|
|
|
+ } while (deltaTime > 0 && stepsTaken > maxSubSteps);
|
|
|
+ this._timeAccumulator = deltaTime;
|
|
|
}
|
|
|
else {
|
|
|
// Animations
|
|
@@ -29677,11 +29691,17 @@ var BABYLON;
|
|
|
var indices = [];
|
|
|
var positions = [];
|
|
|
var lines = options.lines;
|
|
|
+ var colors = options.colors;
|
|
|
+ var vertexColors = [];
|
|
|
var idx = 0;
|
|
|
for (var l = 0; l < lines.length; l++) {
|
|
|
var points = lines[l];
|
|
|
for (var index = 0; index < points.length; index++) {
|
|
|
positions.push(points[index].x, points[index].y, points[index].z);
|
|
|
+ if (colors) {
|
|
|
+ var color = colors[l];
|
|
|
+ vertexColors.push(color[index].r, color[index].g, color[index].b, color[index].a);
|
|
|
+ }
|
|
|
if (index > 0) {
|
|
|
indices.push(idx - 1);
|
|
|
indices.push(idx);
|
|
@@ -29692,6 +29712,9 @@ var BABYLON;
|
|
|
var vertexData = new VertexData();
|
|
|
vertexData.indices = indices;
|
|
|
vertexData.positions = positions;
|
|
|
+ if (colors) {
|
|
|
+ vertexData.colors = vertexColors;
|
|
|
+ }
|
|
|
return vertexData;
|
|
|
};
|
|
|
/**
|
|
@@ -47198,27 +47221,35 @@ var BABYLON;
|
|
|
(function (BABYLON) {
|
|
|
var LinesMesh = /** @class */ (function (_super) {
|
|
|
__extends(LinesMesh, _super);
|
|
|
- function LinesMesh(name, scene, parent, source, doNotCloneChildren, useVertexColor) {
|
|
|
+ function LinesMesh(name, scene, parent, source, doNotCloneChildren, useVertexColor, useVertexAlpha) {
|
|
|
if (scene === void 0) { scene = null; }
|
|
|
if (parent === void 0) { parent = null; }
|
|
|
var _this = _super.call(this, name, scene, parent, source, doNotCloneChildren) || this;
|
|
|
_this.useVertexColor = useVertexColor;
|
|
|
+ _this.useVertexAlpha = useVertexAlpha;
|
|
|
_this.color = new BABYLON.Color3(1, 1, 1);
|
|
|
_this.alpha = 1;
|
|
|
if (source) {
|
|
|
_this.color = source.color.clone();
|
|
|
_this.alpha = source.alpha;
|
|
|
_this.useVertexColor = source.useVertexColor;
|
|
|
+ _this.useVertexAlpha = source.useVertexAlpha;
|
|
|
}
|
|
|
_this._intersectionThreshold = 0.1;
|
|
|
+ var defines = [];
|
|
|
var options = {
|
|
|
attributes: [BABYLON.VertexBuffer.PositionKind],
|
|
|
uniforms: ["world", "viewProjection"],
|
|
|
needAlphaBlending: false,
|
|
|
+ defines: defines
|
|
|
};
|
|
|
if (!useVertexColor) {
|
|
|
options.uniforms.push("color");
|
|
|
- options.needAlphaBlending = true;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ options.needAlphaBlending = (useVertexAlpha) ? true : false;
|
|
|
+ options.defines.push("#define VERTEXCOLOR");
|
|
|
+ options.attributes.push(BABYLON.VertexBuffer.ColorKind);
|
|
|
}
|
|
|
_this._colorShader = new BABYLON.ShaderMaterial("colorShader", _this.getScene(), "color", options);
|
|
|
return _this;
|
|
@@ -48152,6 +48183,8 @@ var BABYLON;
|
|
|
* Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineSystem to this static function.
|
|
|
* The parameter `lines` is an array of lines, each line being an array of successive Vector3.
|
|
|
* The optional parameter `instance` is an instance of an existing LineSystem object to be updated with the passed `lines` parameter. The way to update it is the same than for
|
|
|
+ * The optional parameter `colors` is an array of line colors, each line colors being an array of successive Color4, one per line point.
|
|
|
+ * The optional parameter `useVertexAlpha' is to be set to `true` (default `false`) when the alpha value from the former `Color4` array must be used.
|
|
|
* updating a simple Line mesh, you just need to update every line in the `lines` array : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#lines-and-dashedlines
|
|
|
* When updating an instance, remember that only line point positions can change, not the number of points, neither the number of lines.
|
|
|
* The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
|
|
@@ -48159,24 +48192,42 @@ var BABYLON;
|
|
|
MeshBuilder.CreateLineSystem = function (name, options, scene) {
|
|
|
var instance = options.instance;
|
|
|
var lines = options.lines;
|
|
|
+ var colors = options.colors;
|
|
|
if (instance) {
|
|
|
- var positionFunction = function (positions) {
|
|
|
- var i = 0;
|
|
|
- for (var l = 0; l < lines.length; l++) {
|
|
|
- var points = lines[l];
|
|
|
- for (var p = 0; p < points.length; p++) {
|
|
|
- positions[i] = points[p].x;
|
|
|
- positions[i + 1] = points[p].y;
|
|
|
- positions[i + 2] = points[p].z;
|
|
|
- i += 3;
|
|
|
+ var positions = instance.getVerticesData(BABYLON.VertexBuffer.PositionKind);
|
|
|
+ var vertexColor;
|
|
|
+ var lineColors;
|
|
|
+ if (colors) {
|
|
|
+ vertexColor = instance.getVerticesData(BABYLON.VertexBuffer.ColorKind);
|
|
|
+ }
|
|
|
+ var i = 0;
|
|
|
+ var c = 0;
|
|
|
+ for (var l = 0; l < lines.length; l++) {
|
|
|
+ var points = lines[l];
|
|
|
+ for (var p = 0; p < points.length; p++) {
|
|
|
+ positions[i] = points[p].x;
|
|
|
+ positions[i + 1] = points[p].y;
|
|
|
+ positions[i + 2] = points[p].z;
|
|
|
+ if (colors && vertexColor) {
|
|
|
+ lineColors = colors[l];
|
|
|
+ vertexColor[c] = lineColors[p].r;
|
|
|
+ vertexColor[c + 1] = lineColors[p].g;
|
|
|
+ vertexColor[c + 2] = lineColors[p].b;
|
|
|
+ vertexColor[c + 3] = lineColors[p].a;
|
|
|
+ c += 4;
|
|
|
}
|
|
|
+ i += 3;
|
|
|
}
|
|
|
- };
|
|
|
- instance.updateMeshPositions(positionFunction, false);
|
|
|
+ }
|
|
|
+ instance.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positions, false, false);
|
|
|
+ if (colors && vertexColor) {
|
|
|
+ instance.updateVerticesData(BABYLON.VertexBuffer.ColorKind, vertexColor, false, false);
|
|
|
+ }
|
|
|
return instance;
|
|
|
}
|
|
|
// line system creation
|
|
|
- var lineSystem = new BABYLON.LinesMesh(name, scene);
|
|
|
+ var useVertexColor = (colors) ? true : false;
|
|
|
+ var lineSystem = new BABYLON.LinesMesh(name, scene, null, undefined, undefined, useVertexColor, options.useVertexAlpha);
|
|
|
var vertexData = BABYLON.VertexData.CreateLineSystem(options);
|
|
|
vertexData.applyToMesh(lineSystem, options.updatable);
|
|
|
return lineSystem;
|
|
@@ -48188,12 +48239,15 @@ var BABYLON;
|
|
|
* Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function.
|
|
|
* The parameter `points` is an array successive Vector3.
|
|
|
* The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#lines-and-dashedlines
|
|
|
+ * The optional parameter `colors` is an array of successive Color4, one per line point.
|
|
|
+ * The optional parameter `useVertexAlpha' is to be set to `true` (default `false`) when the alpha value from the former `Color4` array must be used.
|
|
|
* When updating an instance, remember that only point positions can change, not the number of points.
|
|
|
* The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
|
|
|
*/
|
|
|
MeshBuilder.CreateLines = function (name, options, scene) {
|
|
|
if (scene === void 0) { scene = null; }
|
|
|
- var lines = MeshBuilder.CreateLineSystem(name, { lines: [options.points], updatable: options.updatable, instance: options.instance }, scene);
|
|
|
+ var colors = (options.colors) ? [options.colors] : null;
|
|
|
+ var lines = MeshBuilder.CreateLineSystem(name, { lines: [options.points], updatable: options.updatable, instance: options.instance, colors: colors, useVertexAlpha: options.useVertexAlpha }, scene);
|
|
|
return lines;
|
|
|
};
|
|
|
/**
|
|
@@ -71211,6 +71265,21 @@ var BABYLON;
|
|
|
// Are we presenting in the fullscreen fallback?
|
|
|
this._fullscreenVRpresenting = false;
|
|
|
this._useCustomVRButton = false;
|
|
|
+ this._teleportationRequested = false;
|
|
|
+ this._teleportationEnabledOnLeftController = false;
|
|
|
+ this._teleportationEnabledOnRightController = false;
|
|
|
+ this._leftControllerReady = false;
|
|
|
+ this._rightControllerReady = false;
|
|
|
+ this._teleportationAllowed = false;
|
|
|
+ this._rotationAllowed = true;
|
|
|
+ this._teleportationRequestInitiated = false;
|
|
|
+ this._xboxGamepadTeleportationRequestInitiated = false;
|
|
|
+ this._rotationRightAsked = false;
|
|
|
+ this._rotationLeftAsked = false;
|
|
|
+ this._teleportationFillColor = "#444444";
|
|
|
+ this._teleportationBorderColor = "#FFFFFF";
|
|
|
+ this._rotationAngle = 0;
|
|
|
+ this._haloCenter = new BABYLON.Vector3(0, 0, 0);
|
|
|
this._scene = scene;
|
|
|
if (!this._scene.activeCamera || isNaN(this._scene.activeCamera.position.x)) {
|
|
|
this._position = new BABYLON.Vector3(0, 2, 0);
|
|
@@ -71350,6 +71419,18 @@ var BABYLON;
|
|
|
});
|
|
|
// Raised when one of the controller has loaded successfully its associated default mesh
|
|
|
VRExperienceHelper.prototype._onDefaultMeshLoaded = function (webVRController) {
|
|
|
+ if (webVRController.hand === "left") {
|
|
|
+ this._leftControllerReady = true;
|
|
|
+ if (this._teleportationRequested && !this._teleportationEnabledOnLeftController) {
|
|
|
+ this._enableTeleportationOnController(webVRController);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (webVRController.hand === "right") {
|
|
|
+ this._rightControllerReady = true;
|
|
|
+ if (this._teleportationRequested && !this._teleportationEnabledOnRightController) {
|
|
|
+ this._enableTeleportationOnController(webVRController);
|
|
|
+ }
|
|
|
+ }
|
|
|
if (this.onControllerMeshLoaded) {
|
|
|
this.onControllerMeshLoaded(webVRController);
|
|
|
}
|
|
@@ -71433,6 +71514,7 @@ var BABYLON;
|
|
|
if (!this._webVRpresenting) {
|
|
|
this._webVRCamera.position = this._position;
|
|
|
this._scene.activeCamera = this._webVRCamera;
|
|
|
+ this._scene.imageProcessingConfiguration.applyByPostProcess = true;
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
@@ -71464,6 +71546,7 @@ var BABYLON;
|
|
|
this._scene.activeCamera.attachControl(this._canvas);
|
|
|
}
|
|
|
this.updateButtonVisibility();
|
|
|
+ this._scene.imageProcessingConfiguration.applyByPostProcess = false;
|
|
|
};
|
|
|
Object.defineProperty(VRExperienceHelper.prototype, "position", {
|
|
|
get: function () {
|
|
@@ -71478,6 +71561,351 @@ var BABYLON;
|
|
|
enumerable: true,
|
|
|
configurable: true
|
|
|
});
|
|
|
+ VRExperienceHelper.prototype.enableTeleportation = function (vrTeleportationOptions) {
|
|
|
+ var _this = this;
|
|
|
+ if (vrTeleportationOptions === void 0) { vrTeleportationOptions = {}; }
|
|
|
+ this._teleportationRequested = true;
|
|
|
+ if (vrTeleportationOptions) {
|
|
|
+ if (vrTeleportationOptions.floorMeshName) {
|
|
|
+ this._floorMeshName = vrTeleportationOptions.floorMeshName;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (this._leftControllerReady && this._webVRCamera.leftController) {
|
|
|
+ this._enableTeleportationOnController(this._webVRCamera.leftController);
|
|
|
+ }
|
|
|
+ if (this._rightControllerReady && this._webVRCamera.rightController) {
|
|
|
+ this._enableTeleportationOnController(this._webVRCamera.rightController);
|
|
|
+ }
|
|
|
+ this._postProcessMove = new BABYLON.ImageProcessingPostProcess("postProcessMove", 1.0, this._webVRCamera);
|
|
|
+ this._postProcessMove.vignetteWeight = 0;
|
|
|
+ this._postProcessMove.vignetteStretch = 0;
|
|
|
+ this._postProcessMove.vignetteColor = new BABYLON.Color4(0, 0, 0, 0);
|
|
|
+ this._postProcessMove.vignetteEnabled = false;
|
|
|
+ new BABYLON.PassPostProcess("pass", 1.0, this._webVRCamera);
|
|
|
+ this._postProcessMove.imageProcessingConfiguration = new BABYLON.ImageProcessingConfiguration();
|
|
|
+ this._scene.imageProcessingConfiguration.applyByPostProcess = false;
|
|
|
+ this._createTeleportationCircles();
|
|
|
+ this.meshSelectionPredicate = function (mesh) {
|
|
|
+ if (mesh.name.indexOf(_this._floorMeshName) !== -1) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+ this._scene.registerBeforeRender(function () {
|
|
|
+ _this._castRayAndSelectObject();
|
|
|
+ });
|
|
|
+ };
|
|
|
+ VRExperienceHelper.prototype._enableTeleportationOnController = function (webVRController) {
|
|
|
+ var _this = this;
|
|
|
+ var controllerMesh = webVRController.mesh;
|
|
|
+ if (controllerMesh) {
|
|
|
+ var childMeshes = controllerMesh.getChildMeshes();
|
|
|
+ for (var i = 0; i < childMeshes.length; i++) {
|
|
|
+ if (childMeshes[i].name === "POINTING_POSE") {
|
|
|
+ controllerMesh = childMeshes[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var laserPointer = BABYLON.Mesh.CreateCylinder("laserPointer", 3, 0.004, 0.0001, 20, 1, this._scene, false);
|
|
|
+ var laserPointerMaterial = new BABYLON.StandardMaterial("laserPointerMat", this._scene);
|
|
|
+ laserPointerMaterial.emissiveColor = new BABYLON.Color3(0.7, 0.7, 0.7);
|
|
|
+ laserPointerMaterial.alpha = 0.6;
|
|
|
+ laserPointer.material = laserPointerMaterial;
|
|
|
+ laserPointer.rotation.x = Math.PI / 2;
|
|
|
+ laserPointer.parent = controllerMesh;
|
|
|
+ laserPointer.position.z = -1.5;
|
|
|
+ laserPointer.position.y = 0;
|
|
|
+ laserPointer.isVisible = false;
|
|
|
+ webVRController.onMainButtonStateChangedObservable.add(function (stateObject) {
|
|
|
+ // Enabling / disabling laserPointer
|
|
|
+ if (stateObject.value === 1) {
|
|
|
+ laserPointer.isVisible = !laserPointer.isVisible;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ webVRController.onPadValuesChangedObservable.add(function (stateObject) {
|
|
|
+ // on pressed
|
|
|
+ if (!_this._teleportationRequestInitiated) {
|
|
|
+ if (stateObject.y < -0.6) {
|
|
|
+ laserPointer.isVisible = true;
|
|
|
+ _this._teleportationRequestInitiated = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if (stateObject.y > -0.4) {
|
|
|
+ if (_this._teleportationAllowed) {
|
|
|
+ _this._teleportCamera();
|
|
|
+ }
|
|
|
+ _this._teleportationRequestInitiated = false;
|
|
|
+ laserPointer.isVisible = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!_this._rotationLeftAsked) {
|
|
|
+ if (stateObject.x < -0.6) {
|
|
|
+ _this._rotationLeftAsked = true;
|
|
|
+ if (_this._rotationAllowed) {
|
|
|
+ _this._rotateCamera(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if (stateObject.x > -0.4) {
|
|
|
+ _this._rotationLeftAsked = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!_this._rotationRightAsked) {
|
|
|
+ if (stateObject.x > 0.6) {
|
|
|
+ _this._rotationRightAsked = true;
|
|
|
+ if (_this._rotationAllowed) {
|
|
|
+ _this._rotateCamera(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if (stateObject.x < 0.4) {
|
|
|
+ _this._rotationRightAsked = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
+ VRExperienceHelper.prototype._createTeleportationCircles = function () {
|
|
|
+ this._teleportationCircle = BABYLON.Mesh.CreateGround("teleportationCircle", 2, 2, 2, this._scene);
|
|
|
+ var length = 512;
|
|
|
+ var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", length, this._scene, true);
|
|
|
+ dynamicTexture.hasAlpha = true;
|
|
|
+ var context = dynamicTexture.getContext();
|
|
|
+ var centerX = length / 2;
|
|
|
+ var centerY = length / 2;
|
|
|
+ var radius = 200;
|
|
|
+ context.beginPath();
|
|
|
+ context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
|
|
|
+ context.fillStyle = this._teleportationFillColor;
|
|
|
+ context.fill();
|
|
|
+ context.lineWidth = 10;
|
|
|
+ context.strokeStyle = this._teleportationBorderColor;
|
|
|
+ context.stroke();
|
|
|
+ context.closePath();
|
|
|
+ dynamicTexture.update();
|
|
|
+ var teleportationCircleMaterial = new BABYLON.StandardMaterial("TextPlaneMaterial", this._scene);
|
|
|
+ teleportationCircleMaterial.diffuseTexture = dynamicTexture;
|
|
|
+ this._teleportationCircle.material = teleportationCircleMaterial;
|
|
|
+ var torus = BABYLON.Mesh.CreateTorus("torus", 0.75, 0.1, 25, this._scene, false);
|
|
|
+ torus.parent = this._teleportationCircle;
|
|
|
+ var animationInnerCircle = new BABYLON.Animation("animationInnerCircle", "position.y", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
|
|
|
+ var keys = [];
|
|
|
+ keys.push({
|
|
|
+ frame: 0,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ keys.push({
|
|
|
+ frame: 30,
|
|
|
+ value: 0.4
|
|
|
+ });
|
|
|
+ keys.push({
|
|
|
+ frame: 60,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ animationInnerCircle.setKeys(keys);
|
|
|
+ var easingFunction = new BABYLON.SineEase();
|
|
|
+ easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
|
|
|
+ animationInnerCircle.setEasingFunction(easingFunction);
|
|
|
+ torus.animations = [];
|
|
|
+ torus.animations.push(animationInnerCircle);
|
|
|
+ this._scene.beginAnimation(torus, 0, 60, true);
|
|
|
+ this._hideTeleportationCircle();
|
|
|
+ };
|
|
|
+ VRExperienceHelper.prototype._displayTeleportationCircle = function () {
|
|
|
+ this._teleportationCircle.isVisible = true;
|
|
|
+ this._teleportationCircle.getChildren()[0].isVisible = true;
|
|
|
+ };
|
|
|
+ VRExperienceHelper.prototype._hideTeleportationCircle = function () {
|
|
|
+ this._teleportationCircle.isVisible = false;
|
|
|
+ this._teleportationCircle.getChildren()[0].isVisible = false;
|
|
|
+ };
|
|
|
+ VRExperienceHelper.prototype._rotateCamera = function (right) {
|
|
|
+ var _this = this;
|
|
|
+ if (right) {
|
|
|
+ this._rotationAngle++;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this._rotationAngle--;
|
|
|
+ }
|
|
|
+ this.currentVRCamera.animations = [];
|
|
|
+ var target = BABYLON.Quaternion.FromRotationMatrix(BABYLON.Matrix.RotationY(Math.PI / 4 * this._rotationAngle));
|
|
|
+ var animationRotation = new BABYLON.Animation("animationRotation", "rotationQuaternion", 90, BABYLON.Animation.ANIMATIONTYPE_QUATERNION, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
|
|
|
+ var animationRotationKeys = [];
|
|
|
+ animationRotationKeys.push({
|
|
|
+ frame: 0,
|
|
|
+ value: this.currentVRCamera.rotationQuaternion
|
|
|
+ });
|
|
|
+ animationRotationKeys.push({
|
|
|
+ frame: 6,
|
|
|
+ value: target
|
|
|
+ });
|
|
|
+ animationRotation.setKeys(animationRotationKeys);
|
|
|
+ var easingFunction = new BABYLON.CircleEase();
|
|
|
+ easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
|
|
|
+ animationRotation.setEasingFunction(easingFunction);
|
|
|
+ this.currentVRCamera.animations.push(animationRotation);
|
|
|
+ this._postProcessMove.animations = [];
|
|
|
+ var animationPP = new BABYLON.Animation("animationPP", "vignetteWeight", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
|
|
|
+ var vignetteWeightKeys = [];
|
|
|
+ vignetteWeightKeys.push({
|
|
|
+ frame: 0,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ vignetteWeightKeys.push({
|
|
|
+ frame: 3,
|
|
|
+ value: 4
|
|
|
+ });
|
|
|
+ vignetteWeightKeys.push({
|
|
|
+ frame: 6,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ animationPP.setKeys(vignetteWeightKeys);
|
|
|
+ animationPP.setEasingFunction(easingFunction);
|
|
|
+ this._postProcessMove.animations.push(animationPP);
|
|
|
+ var animationPP2 = new BABYLON.Animation("animationPP2", "vignetteStretch", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
|
|
|
+ var vignetteStretchKeys = [];
|
|
|
+ vignetteStretchKeys.push({
|
|
|
+ frame: 0,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ vignetteStretchKeys.push({
|
|
|
+ frame: 3,
|
|
|
+ value: 10
|
|
|
+ });
|
|
|
+ vignetteStretchKeys.push({
|
|
|
+ frame: 6,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ animationPP2.setKeys(vignetteStretchKeys);
|
|
|
+ animationPP2.setEasingFunction(easingFunction);
|
|
|
+ this._postProcessMove.animations.push(animationPP2);
|
|
|
+ this._postProcessMove.vignetteWeight = 0;
|
|
|
+ this._postProcessMove.vignetteStretch = 0;
|
|
|
+ this._postProcessMove.vignetteEnabled = true;
|
|
|
+ this._scene.beginAnimation(this._postProcessMove, 0, 6, false, 1, function () {
|
|
|
+ _this._postProcessMove.vignetteEnabled = false;
|
|
|
+ });
|
|
|
+ this._scene.beginAnimation(this.currentVRCamera, 0, 6, false, 1);
|
|
|
+ };
|
|
|
+ VRExperienceHelper.prototype._moveTeleportationSelectorTo = function (coordinates) {
|
|
|
+ this._teleportationAllowed = true;
|
|
|
+ if (this._teleportationRequestInitiated || this._xboxGamepadTeleportationRequestInitiated) {
|
|
|
+ this._displayTeleportationCircle();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this._hideTeleportationCircle();
|
|
|
+ }
|
|
|
+ this._haloCenter.copyFrom(coordinates);
|
|
|
+ this._teleportationCircle.position = coordinates;
|
|
|
+ this._teleportationCircle.position.y += 0.001;
|
|
|
+ };
|
|
|
+ VRExperienceHelper.prototype._teleportCamera = function () {
|
|
|
+ var _this = this;
|
|
|
+ this.currentVRCamera.animations = [];
|
|
|
+ var animationCameraTeleportation = new BABYLON.Animation("animationCameraTeleportation", "position.x", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
|
|
|
+ var animationCameraTeleportationKeys = [];
|
|
|
+ animationCameraTeleportationKeys.push({
|
|
|
+ frame: 0,
|
|
|
+ value: this.currentVRCamera.position.x
|
|
|
+ });
|
|
|
+ animationCameraTeleportationKeys.push({
|
|
|
+ frame: 11,
|
|
|
+ value: this._haloCenter.x
|
|
|
+ });
|
|
|
+ animationCameraTeleportation.setKeys(animationCameraTeleportationKeys);
|
|
|
+ var easingFunction = new BABYLON.CircleEase();
|
|
|
+ easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
|
|
|
+ animationCameraTeleportation.setEasingFunction(easingFunction);
|
|
|
+ this.currentVRCamera.animations.push(animationCameraTeleportation);
|
|
|
+ var animationZoomIn2 = new BABYLON.Animation("animationZoomIn", "position.z", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
|
|
|
+ var keys2 = [];
|
|
|
+ keys2.push({
|
|
|
+ frame: 0,
|
|
|
+ value: this.currentVRCamera.position.z
|
|
|
+ });
|
|
|
+ keys2.push({
|
|
|
+ frame: 11,
|
|
|
+ value: this._haloCenter.z
|
|
|
+ });
|
|
|
+ animationZoomIn2.setKeys(keys2);
|
|
|
+ animationZoomIn2.setEasingFunction(easingFunction);
|
|
|
+ this.currentVRCamera.animations.push(animationZoomIn2);
|
|
|
+ this._postProcessMove.animations = [];
|
|
|
+ var animationPP = new BABYLON.Animation("animationPP", "vignetteWeight", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
|
|
|
+ var vignetteWeightKeys = [];
|
|
|
+ vignetteWeightKeys.push({
|
|
|
+ frame: 0,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ vignetteWeightKeys.push({
|
|
|
+ frame: 5,
|
|
|
+ value: 8
|
|
|
+ });
|
|
|
+ vignetteWeightKeys.push({
|
|
|
+ frame: 11,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ animationPP.setKeys(vignetteWeightKeys);
|
|
|
+ this._postProcessMove.animations.push(animationPP);
|
|
|
+ var animationPP2 = new BABYLON.Animation("animationPP2", "vignetteStretch", 90, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
|
|
|
+ var vignetteStretchKeys = [];
|
|
|
+ vignetteStretchKeys.push({
|
|
|
+ frame: 0,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ vignetteStretchKeys.push({
|
|
|
+ frame: 5,
|
|
|
+ value: 10
|
|
|
+ });
|
|
|
+ vignetteStretchKeys.push({
|
|
|
+ frame: 11,
|
|
|
+ value: 0
|
|
|
+ });
|
|
|
+ animationPP2.setKeys(vignetteStretchKeys);
|
|
|
+ this._postProcessMove.animations.push(animationPP2);
|
|
|
+ this._postProcessMove.vignetteWeight = 8;
|
|
|
+ this._postProcessMove.vignetteStretch = 10;
|
|
|
+ this._postProcessMove.vignetteEnabled = true;
|
|
|
+ this._scene.beginAnimation(this._postProcessMove, 0, 11, false, 1, function () {
|
|
|
+ _this._postProcessMove.vignetteEnabled = false;
|
|
|
+ });
|
|
|
+ this._scene.beginAnimation(this.currentVRCamera, 0, 11, false, 1);
|
|
|
+ };
|
|
|
+ VRExperienceHelper.prototype._castRayAndSelectObject = function () {
|
|
|
+ var ray;
|
|
|
+ if (!this.currentVRCamera.rightController) {
|
|
|
+ ray = this.currentVRCamera.getForwardRay();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ ray = this.currentVRCamera.rightController.getForwardRay();
|
|
|
+ }
|
|
|
+ var hit = this._scene.pickWithRay(ray, this.meshSelectionPredicate);
|
|
|
+ if (this._rayHelper) {
|
|
|
+ this._rayHelper.dispose();
|
|
|
+ }
|
|
|
+ if (this.currentVRCamera.rightController) {
|
|
|
+ //if (target) target.isVisible = false;
|
|
|
+ this._rayHelper = BABYLON.RayHelper.CreateAndShow(ray, this._scene, new BABYLON.Color3(0.7, 0.7, 0.7));
|
|
|
+ }
|
|
|
+ if (hit && hit.pickedMesh) {
|
|
|
+ // The object selected is the floor, we're in a teleportation scenario
|
|
|
+ if (hit.pickedMesh.name.indexOf(this._floorMeshName) !== -1 && hit.pickedPoint) {
|
|
|
+ this._moveTeleportationSelectorTo(hit.pickedPoint);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // If not, we're in a selection scenario
|
|
|
+ this._hideTeleportationCircle();
|
|
|
+ this._teleportationAllowed = false;
|
|
|
+ //currentMeshSelected = hit.pickedMesh;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this._teleportationAllowed = false;
|
|
|
+ this._hideTeleportationCircle();
|
|
|
+ }
|
|
|
+ };
|
|
|
VRExperienceHelper.prototype.dispose = function () {
|
|
|
if (this.isInVRMode()) {
|
|
|
this.exitVR();
|