|
@@ -15823,8 +15823,7 @@ var BABYLON;
|
|
|
customFallback = true;
|
|
|
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, texture.invertY, scene, samplingMode, null, onError, buffer, texture, undefined, undefined, excludeLoaders);
|
|
|
- return;
|
|
|
+ _this.createTexture(urlArg, noMipmap, texture.invertY, scene, samplingMode, null, null, buffer, texture, undefined, undefined, excludeLoaders);
|
|
|
}
|
|
|
}
|
|
|
if (!customFallback) {
|
|
@@ -15832,8 +15831,7 @@ var BABYLON;
|
|
|
texture.onLoadedObservable.remove(onLoadObserver);
|
|
|
}
|
|
|
if (BABYLON.Tools.UseFallbackTexture) {
|
|
|
- _this.createTexture(BABYLON.Tools.fallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);
|
|
|
- return;
|
|
|
+ _this.createTexture(BABYLON.Tools.fallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, null, buffer, texture);
|
|
|
}
|
|
|
}
|
|
|
if (onError) {
|
|
@@ -19572,8 +19570,25 @@ var BABYLON;
|
|
|
* @returns true if there is an intersection
|
|
|
*/
|
|
|
BoundingSphere.prototype.isInFrustum = function (frustumPlanes) {
|
|
|
+ var center = this.centerWorld;
|
|
|
+ var radius = this.radiusWorld;
|
|
|
for (var i = 0; i < 6; i++) {
|
|
|
- if (frustumPlanes[i].dotCoordinate(this.centerWorld) <= -this.radiusWorld) {
|
|
|
+ if (frustumPlanes[i].dotCoordinate(center) <= -radius) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * Tests if the bounding sphere center is in between the frustum planes.
|
|
|
+ * Used for optimistic fast inclusion.
|
|
|
+ * @param frustumPlanes defines the frustum planes to test
|
|
|
+ * @returns true if the sphere center is in between the frustum planes
|
|
|
+ */
|
|
|
+ BoundingSphere.prototype.isCenterInFrustum = function (frustumPlanes) {
|
|
|
+ var center = this.centerWorld;
|
|
|
+ for (var i = 0; i < 6; i++) {
|
|
|
+ if (frustumPlanes[i].dotCoordinate(center) < 0) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
@@ -20010,15 +20025,22 @@ var BABYLON;
|
|
|
/**
|
|
|
* Returns `true` if the bounding info is within the frustum defined by the passed array of planes.
|
|
|
* @param frustumPlanes defines the frustum to test
|
|
|
- * @param strategy defines the strategy to use for the culling (default is BABYLON.Scene.CULLINGSTRATEGY_STANDARD)
|
|
|
+ * @param strategy defines the strategy to use for the culling (default is BABYLON.AbstractMesh.CULLINGSTRATEGY_STANDARD)
|
|
|
* @returns true if the bounding info is in the frustum planes
|
|
|
*/
|
|
|
BoundingInfo.prototype.isInFrustum = function (frustumPlanes, strategy) {
|
|
|
if (strategy === void 0) { strategy = BABYLON.AbstractMesh.CULLINGSTRATEGY_STANDARD; }
|
|
|
+ var inclusionTest = (strategy === BABYLON.AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION || strategy === BABYLON.AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY);
|
|
|
+ if (inclusionTest) {
|
|
|
+ if (this.boundingSphere.isCenterInFrustum(frustumPlanes)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
if (!this.boundingSphere.isInFrustum(frustumPlanes)) {
|
|
|
return false;
|
|
|
}
|
|
|
- if (strategy === BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY) {
|
|
|
+ var bSphereOnlyTest = (strategy === BABYLON.AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY || strategy === BABYLON.AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY);
|
|
|
+ if (bSphereOnlyTest) {
|
|
|
return true;
|
|
|
}
|
|
|
return this.boundingBox.isInFrustum(frustumPlanes);
|
|
@@ -21273,7 +21295,16 @@ var BABYLON;
|
|
|
if (scene === void 0) { scene = null; }
|
|
|
var _this = _super.call(this, name, scene, false) || this;
|
|
|
_this._facetData = new _FacetDataStorage();
|
|
|
- /** Gets ot sets the culling strategy to use to find visible meshes */
|
|
|
+ /**
|
|
|
+ * The culling strategy to use to check whether the mesh must be rendered or not.
|
|
|
+ * This value can be changed at any time and will be used on the next render mesh selection.
|
|
|
+ * The possible values are :
|
|
|
+ * - AbstractMesh.CULLINGSTRATEGY_STANDARD
|
|
|
+ * - AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY
|
|
|
+ * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION
|
|
|
+ * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY
|
|
|
+ * Please read each static variable documentation to get details about the culling process.
|
|
|
+ * */
|
|
|
_this.cullingStrategy = AbstractMesh.CULLINGSTRATEGY_STANDARD;
|
|
|
// Events
|
|
|
/**
|
|
@@ -23074,10 +23105,40 @@ var BABYLON;
|
|
|
AbstractMesh.OCCLUSION_ALGORITHM_TYPE_ACCURATE = 0;
|
|
|
/** Use a conservative occlusion algorithm */
|
|
|
AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE = 1;
|
|
|
- /** Default culling strategy with bounding box and bounding sphere and then frustum culling */
|
|
|
+ /** Default culling strategy : this is an exclusion test and it's the more accurate.
|
|
|
+ * Test order :
|
|
|
+ * Is the bounding sphere outside the frustum ?
|
|
|
+ * If not, are the bounding box vertices outside the frustum ?
|
|
|
+ * It not, then the cullable object is in the frustum.
|
|
|
+ */
|
|
|
AbstractMesh.CULLINGSTRATEGY_STANDARD = 0;
|
|
|
- /** Culling strategy with bounding sphere only and then frustum culling */
|
|
|
+ /** Culling strategy : Bounding Sphere Only.
|
|
|
+ * This is an exclusion test. It's faster than the standard strategy because the bounding box is not tested.
|
|
|
+ * It's also less accurate than the standard because some not visible objects can still be selected.
|
|
|
+ * Test : is the bounding sphere outside the frustum ?
|
|
|
+ * If not, then the cullable object is in the frustum.
|
|
|
+ */
|
|
|
AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY = 1;
|
|
|
+ /** Culling strategy : Optimistic Inclusion.
|
|
|
+ * This in an inclusion test first, then the standard exclusion test.
|
|
|
+ * This can be faster when a cullable object is expected to be almost always in the camera frustum.
|
|
|
+ * This could also be a little slower than the standard test when the tested object center is not the frustum but one of its bounding box vertex is still inside.
|
|
|
+ * Anyway, it's as accurate as the standard strategy.
|
|
|
+ * Test :
|
|
|
+ * Is the cullable object bounding sphere center in the frustum ?
|
|
|
+ * If not, apply the default culling strategy.
|
|
|
+ */
|
|
|
+ AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION = 2;
|
|
|
+ /** Culling strategy : Optimistic Inclusion then Bounding Sphere Only.
|
|
|
+ * This in an inclusion test first, then the bounding sphere only exclusion test.
|
|
|
+ * This can be the fastest test when a cullable object is expected to be almost always in the camera frustum.
|
|
|
+ * This could also be a little slower than the BoundingSphereOnly strategy when the tested object center is not in the frustum but its bounding sphere still intersects it.
|
|
|
+ * It's less accurate than the standard strategy and as accurate as the BoundingSphereOnly strategy.
|
|
|
+ * Test :
|
|
|
+ * Is the cullable object bounding sphere center in the frustum ?
|
|
|
+ * If not, apply the Bounding Sphere Only strategy. No Bounding Box is tested here.
|
|
|
+ */
|
|
|
+ AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY = 3;
|
|
|
return AbstractMesh;
|
|
|
}(BABYLON.TransformNode));
|
|
|
BABYLON.AbstractMesh = AbstractMesh;
|
|
@@ -26372,7 +26433,7 @@ var BABYLON;
|
|
|
/**
|
|
|
* an optional map from Geometry Id to Geometry index in the 'geometries' array
|
|
|
*/
|
|
|
- _this.geometriesById = null;
|
|
|
+ _this.geometriesByUniqueId = null;
|
|
|
_this._defaultMeshCandidates = {
|
|
|
data: [],
|
|
|
length: 0
|
|
@@ -26412,10 +26473,10 @@ var BABYLON;
|
|
|
_this._imageProcessingConfiguration = new BABYLON.ImageProcessingConfiguration();
|
|
|
}
|
|
|
_this.setDefaultCandidateProviders();
|
|
|
- if (options && options.useGeometryIdsMap === true) {
|
|
|
- _this.geometriesById = {};
|
|
|
+ if (options && options.useGeometryUniqueIdsMap === true) {
|
|
|
+ _this.geometriesByUniqueId = {};
|
|
|
}
|
|
|
- _this.useMaterialMeshMap = options && options.useGeometryIdsMap || false;
|
|
|
+ _this.useMaterialMeshMap = options && options.useGeometryUniqueIdsMap || false;
|
|
|
_this.useClonedMeshhMap = options && options.useClonedMeshhMap || false;
|
|
|
_this._engine.onNewSceneAddedObservable.notifyObservers(_this);
|
|
|
return _this;
|
|
@@ -28657,8 +28718,8 @@ var BABYLON;
|
|
|
* @param newGeometry The geometry to add
|
|
|
*/
|
|
|
Scene.prototype.addGeometry = function (newGeometry) {
|
|
|
- if (this.geometriesById) {
|
|
|
- this.geometriesById[newGeometry.id] = this.geometries.length;
|
|
|
+ if (this.geometriesByUniqueId) {
|
|
|
+ this.geometriesByUniqueId[newGeometry.uniqueId] = this.geometries.length;
|
|
|
}
|
|
|
this.geometries.push(newGeometry);
|
|
|
};
|
|
@@ -28890,29 +28951,29 @@ var BABYLON;
|
|
|
* @return the geometry or null if none found.
|
|
|
*/
|
|
|
Scene.prototype.getGeometryByID = function (id) {
|
|
|
- if (this.geometriesById) {
|
|
|
- var index_1 = this.geometriesById[id];
|
|
|
+ for (var index = 0; index < this.geometries.length; index++) {
|
|
|
+ if (this.geometries[index].id === id) {
|
|
|
+ return this.geometries[index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ };
|
|
|
+ Scene.prototype._getGeometryByUniqueID = function (uniqueId) {
|
|
|
+ if (this.geometriesByUniqueId) {
|
|
|
+ var index_1 = this.geometriesByUniqueId[uniqueId];
|
|
|
if (index_1 !== undefined) {
|
|
|
return this.geometries[index_1];
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
for (var index = 0; index < this.geometries.length; index++) {
|
|
|
- if (this.geometries[index].id === id) {
|
|
|
+ if (this.geometries[index].uniqueId === uniqueId) {
|
|
|
return this.geometries[index];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
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.
|
|
@@ -28938,8 +28999,8 @@ var BABYLON;
|
|
|
*/
|
|
|
Scene.prototype.removeGeometry = function (geometry) {
|
|
|
var index;
|
|
|
- if (this.geometriesById) {
|
|
|
- index = this.geometriesById[geometry.id];
|
|
|
+ if (this.geometriesByUniqueId) {
|
|
|
+ index = this.geometriesByUniqueId[geometry.uniqueId];
|
|
|
if (index === undefined) {
|
|
|
return false;
|
|
|
}
|
|
@@ -28953,9 +29014,9 @@ var BABYLON;
|
|
|
if (index !== this.geometries.length - 1) {
|
|
|
var lastGeometry = this.geometries[this.geometries.length - 1];
|
|
|
this.geometries[index] = lastGeometry;
|
|
|
- if (this.geometriesById) {
|
|
|
- this.geometriesById[lastGeometry.id] = index;
|
|
|
- this.geometriesById[geometry.id] = undefined;
|
|
|
+ if (this.geometriesByUniqueId) {
|
|
|
+ this.geometriesByUniqueId[lastGeometry.uniqueId] = index;
|
|
|
+ this.geometriesByUniqueId[geometry.uniqueId] = undefined;
|
|
|
}
|
|
|
}
|
|
|
this.geometries.pop();
|
|
@@ -102318,23 +102379,23 @@ var BABYLON;
|
|
|
BABYLON.Tools.Error("texture missing KTX identifier");
|
|
|
return;
|
|
|
}
|
|
|
- // load the reset of the header in native 32 bit int
|
|
|
- var header = new Int32Array(this.arrayBuffer, 12, 13);
|
|
|
- // determine of the remaining header values are recorded in the opposite endianness & require conversion
|
|
|
- var oppositeEndianess = header[0] === 0x01020304;
|
|
|
- // read all the header elements in order they exist in the file, without modification (sans endainness)
|
|
|
- this.glType = oppositeEndianess ? this.switchEndianness(header[1]) : header[1]; // must be 0 for compressed textures
|
|
|
- this.glTypeSize = oppositeEndianess ? this.switchEndianness(header[2]) : header[2]; // must be 1 for compressed textures
|
|
|
- this.glFormat = oppositeEndianess ? this.switchEndianness(header[3]) : header[3]; // must be 0 for compressed textures
|
|
|
- this.glInternalFormat = oppositeEndianess ? this.switchEndianness(header[4]) : header[4]; // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)
|
|
|
- this.glBaseInternalFormat = oppositeEndianess ? this.switchEndianness(header[5]) : header[5]; // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)
|
|
|
- this.pixelWidth = oppositeEndianess ? this.switchEndianness(header[6]) : header[6]; // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)
|
|
|
- this.pixelHeight = oppositeEndianess ? this.switchEndianness(header[7]) : header[7]; // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)
|
|
|
- this.pixelDepth = oppositeEndianess ? this.switchEndianness(header[8]) : header[8]; // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)
|
|
|
- this.numberOfArrayElements = oppositeEndianess ? this.switchEndianness(header[9]) : header[9]; // used for texture arrays
|
|
|
- this.numberOfFaces = oppositeEndianess ? this.switchEndianness(header[10]) : header[10]; // used for cubemap textures, should either be 1 or 6
|
|
|
- this.numberOfMipmapLevels = oppositeEndianess ? this.switchEndianness(header[11]) : header[11]; // number of levels; disregard possibility of 0 for compressed textures
|
|
|
- this.bytesOfKeyValueData = oppositeEndianess ? this.switchEndianness(header[12]) : header[12]; // the amount of space after the header for meta-data
|
|
|
+ // load the reset of the header in native 32 bit uint
|
|
|
+ var dataSize = Uint32Array.BYTES_PER_ELEMENT;
|
|
|
+ var headerDataView = new DataView(this.arrayBuffer, 12, 13 * dataSize);
|
|
|
+ var endianness = headerDataView.getUint32(0, true);
|
|
|
+ var littleEndian = endianness === 0x04030201;
|
|
|
+ this.glType = headerDataView.getUint32(1 * dataSize, littleEndian); // must be 0 for compressed textures
|
|
|
+ this.glTypeSize = headerDataView.getUint32(2 * dataSize, littleEndian); // must be 1 for compressed textures
|
|
|
+ this.glFormat = headerDataView.getUint32(3 * dataSize, littleEndian); // must be 0 for compressed textures
|
|
|
+ this.glInternalFormat = headerDataView.getUint32(4 * dataSize, littleEndian); // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)
|
|
|
+ this.glBaseInternalFormat = headerDataView.getUint32(5 * dataSize, littleEndian); // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)
|
|
|
+ this.pixelWidth = headerDataView.getUint32(6 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)
|
|
|
+ this.pixelHeight = headerDataView.getUint32(7 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)
|
|
|
+ this.pixelDepth = headerDataView.getUint32(8 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)
|
|
|
+ this.numberOfArrayElements = headerDataView.getUint32(9 * dataSize, littleEndian); // used for texture arrays
|
|
|
+ this.numberOfFaces = headerDataView.getUint32(10 * dataSize, littleEndian); // used for cubemap textures, should either be 1 or 6
|
|
|
+ this.numberOfMipmapLevels = headerDataView.getUint32(11 * dataSize, littleEndian); // number of levels; disregard possibility of 0 for compressed textures
|
|
|
+ this.bytesOfKeyValueData = headerDataView.getUint32(12 * dataSize, littleEndian); // the amount of space after the header for meta-data
|
|
|
// Make sure we have a compressed type. Not only reduces work, but probably better to let dev know they are not compressing.
|
|
|
if (this.glType !== 0) {
|
|
|
BABYLON.Tools.Error("only compressed formats currently supported");
|
|
@@ -102360,19 +102421,6 @@ var BABYLON;
|
|
|
// would need to make this more elaborate & adjust checks above to support more than one load type
|
|
|
this.loadType = KhronosTextureContainer.COMPRESSED_2D;
|
|
|
}
|
|
|
- //
|
|
|
- /**
|
|
|
- * Revert the endianness of a value.
|
|
|
- * Not as fast hardware based, but will probably never need to use
|
|
|
- * @param val defines the value to convert
|
|
|
- * @returns the new value
|
|
|
- */
|
|
|
- KhronosTextureContainer.prototype.switchEndianness = function (val) {
|
|
|
- return ((val & 0xFF) << 24)
|
|
|
- | ((val & 0xFF00) << 8)
|
|
|
- | ((val >> 8) & 0xFF00)
|
|
|
- | ((val >> 24) & 0xFF);
|
|
|
- };
|
|
|
/**
|
|
|
* Uploads KTX content to a Babylon Texture.
|
|
|
* It is assumed that the texture has already been created & is currently bound
|