|
@@ -2302,6 +2302,9 @@ var BABYLON;
|
|
|
}
|
|
|
};
|
|
|
request.addEventListener("readystatechange", onReadyStateChange);
|
|
|
+ if (Tools.UseCustomRequestHeaders) {
|
|
|
+ Tools.InjectCustomRequestHeaders(request);
|
|
|
+ }
|
|
|
request.send();
|
|
|
};
|
|
|
retryLoop(0);
|
|
@@ -3096,6 +3099,18 @@ var BABYLON;
|
|
|
console.timeEnd(counterName);
|
|
|
}
|
|
|
};
|
|
|
+ /**
|
|
|
+ * Injects the @see CustomRequestHeaders into the given request
|
|
|
+ * @param request the request that should be used for injection
|
|
|
+ */
|
|
|
+ Tools.InjectCustomRequestHeaders = function (request) {
|
|
|
+ for (var key in Tools.CustomRequestHeaders) {
|
|
|
+ var val = Tools.CustomRequestHeaders[key];
|
|
|
+ if (val) {
|
|
|
+ request.setRequestHeader(key, val);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
Object.defineProperty(Tools, "Now", {
|
|
|
/**
|
|
|
* Gets either window.performance.now() if supported or Date.now() else
|
|
@@ -3215,6 +3230,18 @@ var BABYLON;
|
|
|
*/
|
|
|
Tools.BaseUrl = "";
|
|
|
/**
|
|
|
+ * Enable/Disable Custom HTTP Request Headers globally.
|
|
|
+ * default = false
|
|
|
+ * @see CustomRequestHeaders
|
|
|
+ */
|
|
|
+ Tools.UseCustomRequestHeaders = false;
|
|
|
+ /**
|
|
|
+ * Custom HTTP Request Headers to be sent with XMLHttpRequests
|
|
|
+ * i.e. when loading files, where the server/service expects an Authorization header.
|
|
|
+ * @see InjectCustomRequestHeaders injects them to an XMLHttpRequest
|
|
|
+ */
|
|
|
+ Tools.CustomRequestHeaders = {};
|
|
|
+ /**
|
|
|
* Gets or sets the retry strategy to apply when an error happens while loading an asset
|
|
|
*/
|
|
|
Tools.DefaultRetryStrategy = RetryStrategy.ExponentialBackoff();
|
|
@@ -12918,7 +12945,7 @@ var BABYLON;
|
|
|
* Returns the current version of the framework
|
|
|
*/
|
|
|
get: function () {
|
|
|
- return "4.0.0-alpha.6";
|
|
|
+ return "4.0.0-alpha.7";
|
|
|
},
|
|
|
enumerable: true,
|
|
|
configurable: true
|
|
@@ -15699,9 +15726,10 @@ var BABYLON;
|
|
|
* @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
|
|
|
* @param format internal format. Default: RGB when extension is '.jpg' else RGBA. Ignored for compressed textures
|
|
|
* @param forcedExtension defines the extension to use to pick the right loader
|
|
|
+ * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (default: empty array)
|
|
|
* @returns a InternalTexture for assignment back into BABYLON.Texture
|
|
|
*/
|
|
|
- Engine.prototype.createTexture = function (urlArg, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer, fallback, format, forcedExtension) {
|
|
|
+ Engine.prototype.createTexture = function (urlArg, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer, fallback, format, forcedExtension, excludeLoaders) {
|
|
|
var _this = this;
|
|
|
if (samplingMode === void 0) { samplingMode = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE; }
|
|
|
if (onLoad === void 0) { onLoad = null; }
|
|
@@ -15710,6 +15738,7 @@ var BABYLON;
|
|
|
if (fallback === void 0) { fallback = null; }
|
|
|
if (format === void 0) { format = null; }
|
|
|
if (forcedExtension === void 0) { forcedExtension = null; }
|
|
|
+ if (excludeLoaders === void 0) { excludeLoaders = []; }
|
|
|
var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
|
|
|
var fromData = url.substr(0, 5) === "data:";
|
|
|
var fromBlob = url.substr(0, 5) === "blob:";
|
|
@@ -15721,7 +15750,7 @@ var BABYLON;
|
|
|
var loader = null;
|
|
|
for (var _i = 0, _a = Engine._TextureLoaders; _i < _a.length; _i++) {
|
|
|
var availableLoader = _a[_i];
|
|
|
- if (availableLoader.canLoad(extension, this._textureFormatInUse, fallback, isBase64, buffer ? true : false)) {
|
|
|
+ if (excludeLoaders.indexOf(availableLoader) === -1 && availableLoader.canLoad(extension, this._textureFormatInUse, fallback, isBase64, buffer ? true : false)) {
|
|
|
loader = availableLoader;
|
|
|
break;
|
|
|
}
|
|
@@ -15757,7 +15786,9 @@ var BABYLON;
|
|
|
if (fallbackUrl) {
|
|
|
// Add Back
|
|
|
customFallback = true;
|
|
|
- _this.createTexture(urlArg, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
|
|
|
+ excludeLoaders.push(loader);
|
|
|
+ BABYLON.Tools.Warn(loader.constructor.name + " failed when trying to load " + texture.url + ", falling back to the next supported loader");
|
|
|
+ _this.createTexture(urlArg, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture, undefined, undefined, excludeLoaders);
|
|
|
}
|
|
|
}
|
|
|
if (!customFallback) {
|
|
@@ -15775,11 +15806,16 @@ var BABYLON;
|
|
|
// processing for non-image formats
|
|
|
if (loader) {
|
|
|
var callback = function (data) {
|
|
|
- loader.loadData(data, texture, function (width, height, loadMipmap, isCompressed, done) {
|
|
|
- _this._prepareWebGLTexture(texture, scene, width, height, invertY, !loadMipmap, isCompressed, function () {
|
|
|
- done();
|
|
|
- return false;
|
|
|
- }, samplingMode);
|
|
|
+ loader.loadData(data, texture, function (width, height, loadMipmap, isCompressed, done, loadFailed) {
|
|
|
+ if (loadFailed) {
|
|
|
+ onInternalError("TextureLoader failed to load data");
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ _this._prepareWebGLTexture(texture, scene, width, height, invertY, !loadMipmap, isCompressed, function () {
|
|
|
+ done();
|
|
|
+ return false;
|
|
|
+ }, samplingMode);
|
|
|
+ }
|
|
|
});
|
|
|
};
|
|
|
if (!buffer) {
|
|
@@ -16876,9 +16912,10 @@ var BABYLON;
|
|
|
* @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
|
|
|
* @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
|
|
|
* @param fallback defines texture to use while falling back when (compressed) texture file not found.
|
|
|
+ * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (defualt: empty array)
|
|
|
* @returns the cube texture as an InternalTexture
|
|
|
*/
|
|
|
- Engine.prototype.createCubeTexture = function (rootUrl, scene, files, noMipmap, onLoad, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset, fallback) {
|
|
|
+ Engine.prototype.createCubeTexture = function (rootUrl, scene, files, noMipmap, onLoad, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset, fallback, excludeLoaders) {
|
|
|
var _this = this;
|
|
|
if (onLoad === void 0) { onLoad = null; }
|
|
|
if (onError === void 0) { onError = null; }
|
|
@@ -16887,6 +16924,7 @@ var BABYLON;
|
|
|
if (lodScale === void 0) { lodScale = 0; }
|
|
|
if (lodOffset === void 0) { lodOffset = 0; }
|
|
|
if (fallback === void 0) { fallback = null; }
|
|
|
+ if (excludeLoaders === void 0) { excludeLoaders = []; }
|
|
|
var gl = this._gl;
|
|
|
var texture = fallback ? fallback : new BABYLON.InternalTexture(this, BABYLON.InternalTexture.DATASOURCE_CUBE);
|
|
|
texture.isCube = true;
|
|
@@ -16903,16 +16941,18 @@ var BABYLON;
|
|
|
var loader = null;
|
|
|
for (var _i = 0, _a = Engine._TextureLoaders; _i < _a.length; _i++) {
|
|
|
var availableLoader = _a[_i];
|
|
|
- if (availableLoader.canLoad(extension, this._textureFormatInUse, fallback, false, false)) {
|
|
|
+ if (excludeLoaders.indexOf(availableLoader) === -1 && availableLoader.canLoad(extension, this._textureFormatInUse, fallback, false, false)) {
|
|
|
loader = availableLoader;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
var onInternalError = function (request, exception) {
|
|
|
if (loader) {
|
|
|
- var fallbackUrl = loader.getFallbackTextureUrl(rootUrl, _this._textureFormatInUse);
|
|
|
+ var fallbackUrl = loader.getFallbackTextureUrl(texture.url, _this._textureFormatInUse);
|
|
|
+ BABYLON.Tools.Warn(loader.constructor.name + " failed when trying to load " + texture.url + ", falling back to the next supported loader");
|
|
|
if (fallbackUrl) {
|
|
|
- _this.createCubeTexture(fallbackUrl, scene, files, noMipmap, onLoad, onError, format, extension, createPolynomials, lodScale, lodOffset, texture);
|
|
|
+ excludeLoaders.push(loader);
|
|
|
+ _this.createCubeTexture(fallbackUrl, scene, files, noMipmap, onLoad, onError, format, extension, createPolynomials, lodScale, lodOffset, texture, excludeLoaders);
|
|
|
}
|
|
|
}
|
|
|
if (onError && request) {
|
|
@@ -28766,6 +28806,14 @@ var BABYLON;
|
|
|
}
|
|
|
return null;
|
|
|
};
|
|
|
+ Scene.prototype._getGeometryByUniqueID = function (id) {
|
|
|
+ for (var index = 0; index < this.geometries.length; index++) {
|
|
|
+ if (this.geometries[index].uniqueId === id) {
|
|
|
+ return this.geometries[index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ };
|
|
|
/**
|
|
|
* Add a new geometry to this scene
|
|
|
* @param geometry defines the geometry to be added to the scene.
|
|
@@ -28773,7 +28821,7 @@ var BABYLON;
|
|
|
* @return a boolean defining if the geometry was added or not
|
|
|
*/
|
|
|
Scene.prototype.pushGeometry = function (geometry, force) {
|
|
|
- if (!force && this.getGeometryByID(geometry.id)) {
|
|
|
+ if (!force && this._getGeometryByUniqueID(geometry.uniqueId)) {
|
|
|
return false;
|
|
|
}
|
|
|
this.addGeometry(geometry);
|
|
@@ -31349,9 +31397,9 @@ var BABYLON;
|
|
|
return;
|
|
|
case InternalTexture.DATASOURCE_URL:
|
|
|
proxy = this._engine.createTexture(this.url, !this.generateMipMaps, this.invertY, null, this.samplingMode, function () {
|
|
|
+ proxy._swapAndDie(_this);
|
|
|
_this.isReady = true;
|
|
|
}, null, this._buffer, undefined, this.format);
|
|
|
- proxy._swapAndDie(this);
|
|
|
return;
|
|
|
case InternalTexture.DATASOURCE_RAW:
|
|
|
proxy = this._engine.createRawTexture(this._bufferView, this.baseWidth, this.baseHeight, this.format, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
|
|
@@ -31402,9 +31450,9 @@ var BABYLON;
|
|
|
return;
|
|
|
case InternalTexture.DATASOURCE_CUBE:
|
|
|
proxy = this._engine.createCubeTexture(this.url, null, this._files, !this.generateMipMaps, function () {
|
|
|
+ proxy._swapAndDie(_this);
|
|
|
_this.isReady = true;
|
|
|
}, null, this.format, this._extension);
|
|
|
- proxy._swapAndDie(this);
|
|
|
return;
|
|
|
case InternalTexture.DATASOURCE_CUBERAW:
|
|
|
proxy = this._engine.createRawCubeTexture(this._bufferViewArray, this.width, this.format, this.type, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
|
|
@@ -31414,9 +31462,9 @@ var BABYLON;
|
|
|
case InternalTexture.DATASOURCE_CUBERAW_RGBD:
|
|
|
proxy = this._engine.createRawCubeTexture(null, this.width, this.format, this.type, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
|
|
|
BABYLON.RawCubeTexture._UpdateRGBDAsync(proxy, this._bufferViewArrayArray, this._sphericalPolynomial, this._lodGenerationScale, this._lodGenerationOffset).then(function () {
|
|
|
+ proxy._swapAndDie(_this);
|
|
|
_this.isReady = true;
|
|
|
});
|
|
|
- proxy._swapAndDie(this);
|
|
|
return;
|
|
|
case InternalTexture.DATASOURCE_CUBEPREFILTERED:
|
|
|
proxy = this._engine.createPrefilteredCubeTexture(this.url, null, this._lodGenerationScale, this._lodGenerationOffset, function (proxy) {
|
|
@@ -40984,6 +41032,7 @@ var BABYLON;
|
|
|
this._isDisposed = false;
|
|
|
this._indexBufferIsUpdatable = false;
|
|
|
this.id = id;
|
|
|
+ this.uniqueId = scene.getUniqueId();
|
|
|
this._engine = scene.getEngine();
|
|
|
this._meshes = [];
|
|
|
this._scene = scene;
|
|
@@ -75424,12 +75473,12 @@ var BABYLON;
|
|
|
var _this = _super.call(this, null, scene, !generateMipMaps, invertY) || this;
|
|
|
_this._onUserActionRequestedObservable = null;
|
|
|
_this._stillImageCaptured = false;
|
|
|
- _this._poster = false;
|
|
|
+ _this._displayingPosterTexture = false;
|
|
|
_this._createInternalTexture = function () {
|
|
|
if (_this._texture != null) {
|
|
|
- if (_this._poster) {
|
|
|
+ if (_this._displayingPosterTexture) {
|
|
|
_this._texture.dispose();
|
|
|
- _this._poster = false;
|
|
|
+ _this._displayingPosterTexture = false;
|
|
|
}
|
|
|
else {
|
|
|
return;
|
|
@@ -75446,7 +75495,7 @@ var BABYLON;
|
|
|
_this._generateMipMaps = false;
|
|
|
}
|
|
|
_this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
|
|
|
- if (!_this.video.autoplay) {
|
|
|
+ if (!_this.video.autoplay && !_this._settings.poster) {
|
|
|
var oldHandler_1 = _this.video.onplaying;
|
|
|
var error_1 = false;
|
|
|
_this.video.onplaying = function () {
|
|
@@ -75494,7 +75543,7 @@ var BABYLON;
|
|
|
if (_this._texture == null) {
|
|
|
return;
|
|
|
}
|
|
|
- if (!_this._poster) {
|
|
|
+ if (!_this._displayingPosterTexture) {
|
|
|
_this._texture.dispose();
|
|
|
_this._texture = null;
|
|
|
}
|
|
@@ -75506,6 +75555,9 @@ var BABYLON;
|
|
|
if (_this.video.readyState < _this.video.HAVE_CURRENT_DATA) {
|
|
|
return;
|
|
|
}
|
|
|
+ if (_this._displayingPosterTexture) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
_this._engine.updateVideoTexture(_this._texture, _this.video, _this._invertY);
|
|
|
};
|
|
|
_this._engine = _this.getScene().getEngine();
|
|
@@ -75514,6 +75566,7 @@ var BABYLON;
|
|
|
_this.autoUpdateTexture = settings.autoUpdateTexture;
|
|
|
_this.name = name || _this._getName(src);
|
|
|
_this.video = _this._getVideo(src);
|
|
|
+ _this._settings = settings;
|
|
|
if (settings.poster) {
|
|
|
_this.video.poster = settings.poster;
|
|
|
}
|
|
@@ -75524,16 +75577,19 @@ var BABYLON;
|
|
|
_this.video.loop = settings.loop;
|
|
|
}
|
|
|
_this.video.setAttribute("playsinline", "");
|
|
|
- _this.video.addEventListener("canplay", _this._createInternalTexture);
|
|
|
_this.video.addEventListener("paused", _this._updateInternalTexture);
|
|
|
_this.video.addEventListener("seeked", _this._updateInternalTexture);
|
|
|
_this.video.addEventListener("emptied", _this.reset);
|
|
|
- if (_this.video.readyState >= _this.video.HAVE_CURRENT_DATA) {
|
|
|
- _this._createInternalTexture();
|
|
|
- }
|
|
|
- if (settings.poster) {
|
|
|
+ _this._createInternalTextureOnEvent = (settings.poster && !settings.autoPlay) ? "play" : "canplay";
|
|
|
+ _this.video.addEventListener(_this._createInternalTextureOnEvent, _this._createInternalTexture);
|
|
|
+ var videoHasEnoughData = (_this.video.readyState >= _this.video.HAVE_CURRENT_DATA);
|
|
|
+ if (settings.poster &&
|
|
|
+ (!settings.autoPlay || !videoHasEnoughData)) {
|
|
|
_this._texture = _this._engine.createTexture(settings.poster, false, true, scene);
|
|
|
- _this._poster = true;
|
|
|
+ _this._displayingPosterTexture = true;
|
|
|
+ }
|
|
|
+ else if (videoHasEnoughData) {
|
|
|
+ _this._createInternalTexture();
|
|
|
}
|
|
|
return _this;
|
|
|
}
|
|
@@ -75626,7 +75682,7 @@ var BABYLON;
|
|
|
this._onUserActionRequestedObservable.clear();
|
|
|
this._onUserActionRequestedObservable = null;
|
|
|
}
|
|
|
- this.video.removeEventListener("canplay", this._createInternalTexture);
|
|
|
+ this.video.removeEventListener(this._createInternalTextureOnEvent, this._createInternalTexture);
|
|
|
this.video.removeEventListener("paused", this._updateInternalTexture);
|
|
|
this.video.removeEventListener("seeked", this._updateInternalTexture);
|
|
|
this.video.removeEventListener("emptied", this.reset);
|
|
@@ -80300,6 +80356,9 @@ var BABYLON;
|
|
|
// It could fail when coupled with HTML5 Offline API
|
|
|
var retryManifestURL = _this._currentSceneUrl + ".manifest";
|
|
|
xhr.open("GET", retryManifestURL, true);
|
|
|
+ if (BABYLON.Tools.UseCustomRequestHeaders) {
|
|
|
+ BABYLON.Tools.InjectCustomRequestHeaders(xhr);
|
|
|
+ }
|
|
|
xhr.send();
|
|
|
}
|
|
|
else {
|
|
@@ -80307,6 +80366,9 @@ var BABYLON;
|
|
|
}
|
|
|
}, false);
|
|
|
try {
|
|
|
+ if (BABYLON.Tools.UseCustomRequestHeaders) {
|
|
|
+ BABYLON.Tools.InjectCustomRequestHeaders(xhr);
|
|
|
+ }
|
|
|
xhr.send();
|
|
|
}
|
|
|
catch (ex) {
|
|
@@ -80513,6 +80575,9 @@ var BABYLON;
|
|
|
BABYLON.Tools.Error("Error in XHR request in BABYLON.Database.");
|
|
|
image.src = url;
|
|
|
}, false);
|
|
|
+ if (BABYLON.Tools.CustomRequestHeaders) {
|
|
|
+ BABYLON.Tools.InjectCustomRequestHeaders(xhr);
|
|
|
+ }
|
|
|
xhr.send();
|
|
|
}
|
|
|
else {
|
|
@@ -80762,6 +80827,9 @@ var BABYLON;
|
|
|
BABYLON.Tools.Error("error on XHR request.");
|
|
|
callback();
|
|
|
}, false);
|
|
|
+ if (BABYLON.Tools.UseCustomRequestHeaders) {
|
|
|
+ BABYLON.Tools.InjectCustomRequestHeaders(xhr);
|
|
|
+ }
|
|
|
xhr.send();
|
|
|
}
|
|
|
else {
|
|
@@ -81963,6 +82031,9 @@ var BABYLON;
|
|
|
noConfigFile();
|
|
|
}, false);
|
|
|
try {
|
|
|
+ if (BABYLON.Tools.UseCustomRequestHeaders) {
|
|
|
+ BABYLON.Tools.InjectCustomRequestHeaders(xhr);
|
|
|
+ }
|
|
|
xhr.send();
|
|
|
}
|
|
|
catch (ex) {
|
|
@@ -101076,12 +101147,17 @@ var BABYLON;
|
|
|
/** contents of the KTX container file */
|
|
|
arrayBuffer, facesExpected, threeDExpected, textureArrayExpected) {
|
|
|
this.arrayBuffer = arrayBuffer;
|
|
|
+ /**
|
|
|
+ * If the container has been made invalid (eg. constructor failed to correctly load array buffer)
|
|
|
+ */
|
|
|
+ this.isInvalid = false;
|
|
|
// Test that it is a ktx formatted file, based on the first 12 bytes, character representation is:
|
|
|
// '�', 'K', 'T', 'X', ' ', '1', '1', '�', '\r', '\n', '\x1A', '\n'
|
|
|
// 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
|
|
|
var identifier = new Uint8Array(this.arrayBuffer, 0, 12);
|
|
|
if (identifier[0] !== 0xAB || identifier[1] !== 0x4B || identifier[2] !== 0x54 || identifier[3] !== 0x58 || identifier[4] !== 0x20 || identifier[5] !== 0x31 ||
|
|
|
identifier[6] !== 0x31 || identifier[7] !== 0xBB || identifier[8] !== 0x0D || identifier[9] !== 0x0A || identifier[10] !== 0x1A || identifier[11] !== 0x0A) {
|
|
|
+ this.isInvalid = true;
|
|
|
BABYLON.Tools.Error("texture missing KTX identifier");
|
|
|
return;
|
|
|
}
|
|
@@ -101268,7 +101344,7 @@ var BABYLON;
|
|
|
var ktx = new BABYLON.KhronosTextureContainer(data, 1);
|
|
|
callback(ktx.pixelWidth, ktx.pixelHeight, false, true, function () {
|
|
|
ktx.uploadLevels(texture, texture.generateMipMaps);
|
|
|
- });
|
|
|
+ }, ktx.isInvalid);
|
|
|
};
|
|
|
return KTXTextureLoader;
|
|
|
}());
|