Selaa lähdekoodia

Merge Mac Fixes

sebastien 6 vuotta sitten
vanhempi
commit
84a4078d72
62 muutettua tiedostoa jossa 18626 lisäystä ja 17979 poistoa
  1. 6122 6088
      Playground/babylon.d.txt
  2. 1 2
      Tools/Gulp/config.json
  3. 5 2
      Tools/Gulp/gulpfile.js
  4. 3 0
      Tools/Gulp/tasks/gulpTasks-tsLint.js
  5. 5466 5436
      dist/preview release/babylon.d.ts
  6. 1 1
      dist/preview release/babylon.js
  7. 273 278
      dist/preview release/babylon.max.js
  8. 273 278
      dist/preview release/babylon.no-module.max.js
  9. 1 1
      dist/preview release/babylon.worker.js
  10. 273 278
      dist/preview release/es6.js
  11. 1 1
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  12. 1 1
      dist/preview release/loaders/babylon.glTF1FileLoader.js.map
  13. 1 1
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  14. 1 1
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js.map
  15. 1146 1031
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  16. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  17. 1146 1031
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  18. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js.map
  19. 1147 1032
      dist/preview release/loaders/babylon.glTFFileLoader.js
  20. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  21. 1147 1032
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  22. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js.map
  23. 1130 1030
      dist/preview release/loaders/babylonjs.loaders.js
  24. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  25. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  26. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js.map
  27. 4 0
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  28. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.js.map
  29. 4 0
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  30. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js.map
  31. 4 0
      dist/preview release/materialsLibrary/babylonjs.materials.d.ts
  32. 4 0
      dist/preview release/materialsLibrary/babylonjs.materials.js
  33. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.js.map
  34. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js.map
  35. 8 0
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  36. 29 25
      dist/preview release/viewer/babylon.viewer.js
  37. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  38. 5 2
      dist/preview release/what's new.md
  39. 1 1
      materialsLibrary/readme.md
  40. 1 0
      package.json
  41. 13 8
      sandbox/index.js
  42. 56 53
      src/Culling/babylon.boundingBox.ts
  43. 37 42
      src/Culling/babylon.boundingInfo.ts
  44. 33 22
      src/Culling/babylon.boundingSphere.ts
  45. 40 40
      src/Culling/babylon.ray.ts
  46. 3 3
      src/Materials/Textures/babylon.baseTexture.ts
  47. 8 8
      src/Materials/babylon.materialHelper.ts
  48. 76 36
      src/Math/babylon.math.ts
  49. 10 11
      src/Mesh/babylon.abstractMesh.ts
  50. 13 19
      src/Mesh/babylon.geometry.ts
  51. 7 2
      src/Mesh/babylon.instancedMesh.ts
  52. 0 4
      src/Mesh/babylon.linesMesh.ts
  53. 10 4
      src/Mesh/babylon.mesh.ts
  54. 9 3
      src/Mesh/babylon.subMesh.ts
  55. 1 1
      src/Mesh/babylon.transformNode.ts
  56. 21 19
      src/PostProcess/babylon.motionBlurPostProcess.ts
  57. 51 49
      src/Rendering/babylon.edgesRenderer.ts
  58. 7 85
      src/Rendering/babylon.lineEdgesRenderer.ts
  59. 4 1
      src/Shaders/motionBlur.fragment.fx
  60. 10 4
      src/babylon.scene.ts
  61. BIN
      tests/validation/ReferenceImages/LineEdgesRenderer.png
  62. 6 0
      tests/validation/config.json

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 6122 - 6088
Playground/babylon.d.txt


+ 1 - 2
Tools/Gulp/config.json

@@ -1477,8 +1477,7 @@
         }
         }
     },
     },
     "typescript": [
     "typescript": [
-        "../../src/**/*.ts",
-        "!../../src/**/*.d.ts"
+        "../../src/**/*.ts"
     ],
     ],
     "workers": [
     "workers": [
         {
         {

+ 5 - 2
Tools/Gulp/gulpfile.js

@@ -11,6 +11,7 @@ var cleants = require("gulp-clean-ts-extends");
 var replace = require("gulp-replace");
 var replace = require("gulp-replace");
 var expect = require("gulp-expect-file");
 var expect = require("gulp-expect-file");
 var optimisejs = require("gulp-optimize-js");
 var optimisejs = require("gulp-optimize-js");
+var filter = require('gulp-filter');
 var path = require("path");
 var path = require("path");
 var webpack = require('webpack');
 var webpack = require('webpack');
 var webpackStream = require("webpack-stream");
 var webpackStream = require("webpack-stream");
@@ -239,10 +240,12 @@ gulp.task("build", gulp.series("shaders", function build() {
 }));
 }));
 
 
 /*
 /*
-* Compiles all typescript files and creating a js and a declaration file.
-*/
+ * Compiles all typescript files and creating a js and a declaration file.
+ */
 gulp.task("typescript-compile", function() {
 gulp.task("typescript-compile", function() {
+    const dtsFilter = filter(['**', '!**/*.d.ts'], {restore: false});
     var tsResult = gulp.src(config.typescript)
     var tsResult = gulp.src(config.typescript)
+        .pipe(dtsFilter)
         .pipe(sourcemaps.init())
         .pipe(sourcemaps.init())
         .pipe(tsProject({
         .pipe(tsProject({
             summarizeFailureOutput: true
             summarizeFailureOutput: true

+ 3 - 0
Tools/Gulp/tasks/gulpTasks-tsLint.js

@@ -3,6 +3,7 @@ var gulp = require("gulp");
 var merge2 = require("merge2");
 var merge2 = require("merge2");
 var gulpTslint = require("gulp-tslint");
 var gulpTslint = require("gulp-tslint");
 var minimist = require("minimist");
 var minimist = require("minimist");
+var filter = require('gulp-filter');
 
 
 // Parse Command Line.
 // Parse Command Line.
 var commandLineOptions = minimist(process.argv.slice(2), {
 var commandLineOptions = minimist(process.argv.slice(2), {
@@ -23,7 +24,9 @@ var config = require("../config.json");
  * TsLint all typescript files from the src directory.
  * TsLint all typescript files from the src directory.
  */
  */
 gulp.task("typescript-tsLint", function() {
 gulp.task("typescript-tsLint", function() {
+    const dtsFilter = filter(['**', '!**/*.d.ts'], { restore: false });
     return gulp.src(config.typescript)
     return gulp.src(config.typescript)
+        .pipe(dtsFilter)
         .pipe(gulpTslint(tsLintConfig))
         .pipe(gulpTslint(tsLintConfig))
         .pipe(gulpTslint.report());
         .pipe(gulpTslint.report());
 });
 });

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5466 - 5436
dist/preview release/babylon.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/babylon.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 273 - 278
dist/preview release/babylon.max.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 273 - 278
dist/preview release/babylon.no-module.max.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/babylon.worker.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 273 - 278
dist/preview release/es6.js


+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -2426,7 +2426,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
 __export(__webpack_require__(/*! ./glTFBinaryExtension */ "./src/glTF/1.0/glTFBinaryExtension.ts"));
 __export(__webpack_require__(/*! ./glTFBinaryExtension */ "./src/glTF/1.0/glTFBinaryExtension.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderV1 */ "./src/glTF/1.0/glTFLoaderV1.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderV1 */ "./src/glTF/1.0/glTFLoaderV1.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderExtension */ "./src/glTF/1.0/glTFLoaderExtension.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderExtension */ "./src/glTF/1.0/glTFLoaderExtension.ts"));
-//export * from "./glTFLoaderInterfaces";
+__export(__webpack_require__(/*! ./glTFLoaderInterfaces */ "./src/glTF/1.0/glTFLoaderInterfaces.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderUtils */ "./src/glTF/1.0/glTFLoaderUtils.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderUtils */ "./src/glTF/1.0/glTFLoaderUtils.ts"));
 __export(__webpack_require__(/*! ./glTFMaterialsCommonExtension */ "./src/glTF/1.0/glTFMaterialsCommonExtension.ts"));
 __export(__webpack_require__(/*! ./glTFMaterialsCommonExtension */ "./src/glTF/1.0/glTFMaterialsCommonExtension.ts"));
 
 

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.js.map


+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.min.js

@@ -2426,7 +2426,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
 __export(__webpack_require__(/*! ./glTFBinaryExtension */ "./src/glTF/1.0/glTFBinaryExtension.ts"));
 __export(__webpack_require__(/*! ./glTFBinaryExtension */ "./src/glTF/1.0/glTFBinaryExtension.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderV1 */ "./src/glTF/1.0/glTFLoaderV1.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderV1 */ "./src/glTF/1.0/glTFLoaderV1.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderExtension */ "./src/glTF/1.0/glTFLoaderExtension.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderExtension */ "./src/glTF/1.0/glTFLoaderExtension.ts"));
-//export * from "./glTFLoaderInterfaces";
+__export(__webpack_require__(/*! ./glTFLoaderInterfaces */ "./src/glTF/1.0/glTFLoaderInterfaces.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderUtils */ "./src/glTF/1.0/glTFLoaderUtils.ts"));
 __export(__webpack_require__(/*! ./glTFLoaderUtils */ "./src/glTF/1.0/glTFLoaderUtils.ts"));
 __export(__webpack_require__(/*! ./glTFMaterialsCommonExtension */ "./src/glTF/1.0/glTFMaterialsCommonExtension.ts"));
 __export(__webpack_require__(/*! ./glTFMaterialsCommonExtension */ "./src/glTF/1.0/glTFMaterialsCommonExtension.ts"));
 
 

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.min.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1146 - 1031
dist/preview release/loaders/babylon.glTF2FileLoader.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1146 - 1031
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1147 - 1032
dist/preview release/loaders/babylon.glTFFileLoader.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1147 - 1032
dist/preview release/loaders/babylon.glTFFileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1130 - 1030
dist/preview release/loaders/babylonjs.loaders.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js.map


+ 4 - 0
dist/preview release/materialsLibrary/babylon.gridMaterial.js

@@ -353,6 +353,10 @@ var GridMaterial = /** @class */ (function (_super) {
         babylonjs_1.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
         babylonjs_1.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
         this._afterBind(mesh, this._activeEffect);
         this._afterBind(mesh, this._activeEffect);
     };
     };
+    /**
+     * Dispose the material and its associated resources.
+     * @param forceDisposeEffect will also dispose the used effect when true
+     */
     GridMaterial.prototype.dispose = function (forceDisposeEffect) {
     GridMaterial.prototype.dispose = function (forceDisposeEffect) {
         _super.prototype.dispose.call(this, forceDisposeEffect);
         _super.prototype.dispose.call(this, forceDisposeEffect);
     };
     };

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.js.map


+ 4 - 0
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js

@@ -353,6 +353,10 @@ var GridMaterial = /** @class */ (function (_super) {
         babylonjs_1.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
         babylonjs_1.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
         this._afterBind(mesh, this._activeEffect);
         this._afterBind(mesh, this._activeEffect);
     };
     };
+    /**
+     * Dispose the material and its associated resources.
+     * @param forceDisposeEffect will also dispose the used effect when true
+     */
     GridMaterial.prototype.dispose = function (forceDisposeEffect) {
     GridMaterial.prototype.dispose = function (forceDisposeEffect) {
         _super.prototype.dispose.call(this, forceDisposeEffect);
         _super.prototype.dispose.call(this, forceDisposeEffect);
     };
     };

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js.map


+ 4 - 0
dist/preview release/materialsLibrary/babylonjs.materials.d.ts

@@ -212,6 +212,10 @@ declare module BABYLON {
             needAlphaBlendingForMesh(mesh: BABYLON.AbstractMesh): boolean;
             needAlphaBlendingForMesh(mesh: BABYLON.AbstractMesh): boolean;
             isReadyForSubMesh(mesh: BABYLON.AbstractMesh, subMesh: BABYLON.SubMesh, useInstances?: boolean): boolean;
             isReadyForSubMesh(mesh: BABYLON.AbstractMesh, subMesh: BABYLON.SubMesh, useInstances?: boolean): boolean;
             bindForSubMesh(world: BABYLON.Matrix, mesh: BABYLON.Mesh, subMesh: BABYLON.SubMesh): void;
             bindForSubMesh(world: BABYLON.Matrix, mesh: BABYLON.Mesh, subMesh: BABYLON.SubMesh): void;
+            /**
+                * Dispose the material and its associated resources.
+                * @param forceDisposeEffect will also dispose the used effect when true
+                */
             dispose(forceDisposeEffect?: boolean): void;
             dispose(forceDisposeEffect?: boolean): void;
             clone(name: string): GridMaterial;
             clone(name: string): GridMaterial;
             serialize(): any;
             serialize(): any;

+ 4 - 0
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -2168,6 +2168,10 @@ var GridMaterial = /** @class */ (function (_super) {
         babylonjs_1.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
         babylonjs_1.MaterialHelper.BindFogParameters(scene, mesh, this._activeEffect);
         this._afterBind(mesh, this._activeEffect);
         this._afterBind(mesh, this._activeEffect);
     };
     };
+    /**
+     * Dispose the material and its associated resources.
+     * @param forceDisposeEffect will also dispose the used effect when true
+     */
     GridMaterial.prototype.dispose = function (forceDisposeEffect) {
     GridMaterial.prototype.dispose = function (forceDisposeEffect) {
         _super.prototype.dispose.call(this, forceDisposeEffect);
         _super.prototype.dispose.call(this, forceDisposeEffect);
     };
     };

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/materialsLibrary/babylonjs.materials.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/materialsLibrary/babylonjs.materials.min.js.map


+ 8 - 0
dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts

@@ -302,6 +302,10 @@ declare module 'babylonjs-materials/src/grid/gridMaterial' {
             needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
             needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
             isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
             isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
             bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
             bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+            /**
+                * Dispose the material and its associated resources.
+                * @param forceDisposeEffect will also dispose the used effect when true
+                */
             dispose(forceDisposeEffect?: boolean): void;
             dispose(forceDisposeEffect?: boolean): void;
             clone(name: string): GridMaterial;
             clone(name: string): GridMaterial;
             serialize(): any;
             serialize(): any;
@@ -839,6 +843,10 @@ declare module BABYLON {
             needAlphaBlendingForMesh(mesh: BABYLON.AbstractMesh): boolean;
             needAlphaBlendingForMesh(mesh: BABYLON.AbstractMesh): boolean;
             isReadyForSubMesh(mesh: BABYLON.AbstractMesh, subMesh: BABYLON.SubMesh, useInstances?: boolean): boolean;
             isReadyForSubMesh(mesh: BABYLON.AbstractMesh, subMesh: BABYLON.SubMesh, useInstances?: boolean): boolean;
             bindForSubMesh(world: BABYLON.Matrix, mesh: BABYLON.Mesh, subMesh: BABYLON.SubMesh): void;
             bindForSubMesh(world: BABYLON.Matrix, mesh: BABYLON.Mesh, subMesh: BABYLON.SubMesh): void;
+            /**
+                * Dispose the material and its associated resources.
+                * @param forceDisposeEffect will also dispose the used effect when true
+                */
             dispose(forceDisposeEffect?: boolean): void;
             dispose(forceDisposeEffect?: boolean): void;
             clone(name: string): GridMaterial;
             clone(name: string): GridMaterial;
             serialize(): any;
             serialize(): any;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 29 - 25
dist/preview release/viewer/babylon.viewer.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 5 - 2
dist/preview release/what's new.md

@@ -32,6 +32,7 @@
   - Added an option `useClonedMeshhMap` in the `Scene` constructor options. When set to true, each `Mesh` will have and will keep up-to-date a map of cloned meshes. This is to avoid browsing all the meshes of the scene to retrieve the ones that have the current mesh as source mesh. Disabled by default
   - Added an option `useClonedMeshhMap` in the `Scene` constructor options. When set to true, each `Mesh` will have and will keep up-to-date a map of cloned meshes. This is to avoid browsing all the meshes of the scene to retrieve the ones that have the current mesh as source mesh. Disabled by default
   - Added `blockfreeActiveMeshesAndRenderingGroups` property in the `Scene`, following the same model as `blockMaterialDirtyMechanism`. This is to avoid calling `Scene.freeActiveMeshes` and `Scene.freeRenderingGroups` for each disposed mesh when we dispose several meshes in a row. One have to set `blockfreeActiveMeshesAndRenderingGroups` to `true` just before disposing the meshes, and set it back to `false` just after
   - Added `blockfreeActiveMeshesAndRenderingGroups` property in the `Scene`, following the same model as `blockMaterialDirtyMechanism`. This is to avoid calling `Scene.freeActiveMeshes` and `Scene.freeRenderingGroups` for each disposed mesh when we dispose several meshes in a row. One have to set `blockfreeActiveMeshesAndRenderingGroups` to `true` just before disposing the meshes, and set it back to `false` just after
   - Prevented code from doing useless and possible time consuming computation when disposing the `ShaderMaterial` of a `LinesMesh`
   - Prevented code from doing useless and possible time consuming computation when disposing the `ShaderMaterial` of a `LinesMesh`
+- Align `BoundingBox` and `BoundingSphere` API and behavior for clarity and simplicity. As a consequence, the `BoundingBox`'s method `setWorldMatrix` has been removed and the underlying world matrix cannot be modified but by calling `reConstruct` or `update`. ([barroij](https://github.com/barroij))
 
 
 ### glTF Loader
 ### glTF Loader
 
 
@@ -48,8 +49,9 @@
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with pointer up being fire twice ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with pointer up being fire twice ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with particle systems being update once per camera instead of once per frame ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with particle systems being update once per camera instead of once per frame ([Deltakosh](https://github.com/deltakosh))
-
-
+- Handle properly the `LinesMesh` `intersectionThreshold` by using its value directly when the intersection against a `Ray` is checked, instead of extending the `BoundingInfo` accordingly ([barroij](https://github.com/barroij))
+- Fixed the `LineEdgesRenderer` used for edge rendering of `LinesMesh` handle properly LinesMesh made of disconnected lines + Make it work for instance of `LinesMesh` ([barroij](https://github.com/barroij))
+- Fixed `Matrix.toNormalMatrix`function ([barroij](https://github.com/barroij))
 ### Viewer
 ### Viewer
 
 
 ### Loaders
 ### Loaders
@@ -59,3 +61,4 @@
 - `Database.IDBStorageEnabled` is now false by default ([Deltakosh](https://github.com/deltakosh))
 - `Database.IDBStorageEnabled` is now false by default ([Deltakosh](https://github.com/deltakosh))
 - `Database.openAsync` was renamed by `Database.open` ([Deltakosh](https://github.com/deltakosh))
 - `Database.openAsync` was renamed by `Database.open` ([Deltakosh](https://github.com/deltakosh))
 - `scene.database` was renamed to `scene.offlineProvider` ([Deltakosh](https://github.com/deltakosh))
 - `scene.database` was renamed to `scene.offlineProvider` ([Deltakosh](https://github.com/deltakosh))
+- `BoundingBox.setWorldMatrix` was removed. `BoundingBox.getWorldMatrix` now returns a `Readonly<Matrix>` ([barroij](https://github.com/barroij))

+ 1 - 1
materialsLibrary/readme.md

@@ -1,6 +1,6 @@
 # Materials library
 # Materials library
 
 
-To get a detailled tutorial, please read the [documentation](http://doc.babylonjs.com/tutorials/How_to_create_a_material_for_materialsLibrary)
+To get a detailled tutorial, please read the [documentation](https://doc.babylonjs.com/how_to/how_to_create_a_material_for_materialslibrary)
 
 
 For every material, you can find a detailled documentation [here](http://doc.babylonjs.com/extensions) under **materials library** tag.
 For every material, you can find a detailled documentation [here](http://doc.babylonjs.com/extensions) under **materials library** tag.
 
 

+ 1 - 0
package.json

@@ -67,6 +67,7 @@
         "gulp-content-to-variable": "^0.1.0",
         "gulp-content-to-variable": "^0.1.0",
         "gulp-debug": "^4.0.0",
         "gulp-debug": "^4.0.0",
         "gulp-expect-file": "^1.0.0",
         "gulp-expect-file": "^1.0.0",
+        "gulp-filter": "^5.1.0",
         "gulp-optimize-js": "^1.1.0",
         "gulp-optimize-js": "^1.1.0",
         "gulp-rename": "^1.4.0",
         "gulp-rename": "^1.4.0",
         "gulp-replace": "~1.0.0",
         "gulp-replace": "~1.0.0",

+ 13 - 8
sandbox/index.js

@@ -16,6 +16,8 @@ var dropdownLabel = document.getElementById("dropdownLabel");
 var dropdownContent = document.getElementById("dropdownContent");
 var dropdownContent = document.getElementById("dropdownContent");
 var playBtn = document.getElementById("playBtn");
 var playBtn = document.getElementById("playBtn");
 var slider = document.getElementById("slider");
 var slider = document.getElementById("slider");
+var footer = document.getElementById("footer");
+var canvas = document.getElementById("renderCanvas");
 
 
 var indexOf = location.href.indexOf("?");
 var indexOf = location.href.indexOf("?");
 if (indexOf !== -1) {
 if (indexOf !== -1) {
@@ -41,11 +43,14 @@ if (indexOf !== -1) {
     }
     }
 }
 }
 
 
+if (kiosk) {
+    footer.style.display = "none";
+    canvas.style.height = "100%";
+}
+
 if (BABYLON.Engine.isSupported()) {
 if (BABYLON.Engine.isSupported()) {
-    var canvas = document.getElementById("renderCanvas");
     var engine = new BABYLON.Engine(canvas, true, { premultipliedAlpha: false, preserveDrawingBuffer: true });
     var engine = new BABYLON.Engine(canvas, true, { premultipliedAlpha: false, preserveDrawingBuffer: true });
     var htmlInput = document.getElementById("files");
     var htmlInput = document.getElementById("files");
-    var footer = document.getElementById("footer");
     var btnInspector = document.getElementById("btnInspector");
     var btnInspector = document.getElementById("btnInspector");
     var errorZone = document.getElementById("errorZone");
     var errorZone = document.getElementById("errorZone");
     var filesInput;
     var filesInput;
@@ -128,7 +133,7 @@ if (BABYLON.Engine.isSupported()) {
         btnInspector.classList.remove("hidden");
         btnInspector.classList.remove("hidden");
 
 
         currentScene = babylonScene;
         currentScene = babylonScene;
-        document.title = "BabylonJS - " + sceneFile.name;
+        document.title = "Babylon.js - " + sceneFile.name;
         // Fix for IE, otherwise it will change the default filter for files selection after first use
         // Fix for IE, otherwise it will change the default filter for files selection after first use
         htmlInput.value = "";
         htmlInput.value = "";
 
 
@@ -210,7 +215,7 @@ if (BABYLON.Engine.isSupported()) {
     };
     };
 
 
     var sceneError = function(sceneFile, babylonScene, message) {
     var sceneError = function(sceneFile, babylonScene, message) {
-        document.title = "BabylonJS - " + sceneFile.name;
+        document.title = "Babylon.js - " + sceneFile.name;
         document.getElementById("logo").className = "";
         document.getElementById("logo").className = "";
         canvas.style.opacity = 0;
         canvas.style.opacity = 0;
 
 
@@ -298,10 +303,6 @@ if (BABYLON.Engine.isSupported()) {
         }
         }
     });
     });
 
 
-    if (kiosk) {
-        footer.style.display = "none";
-    }
-
     btnInspector.addEventListener('click', function() {
     btnInspector.addEventListener('click', function() {
         if (currentScene) {
         if (currentScene) {
             if (currentScene.debugLayer.isVisible()) {
             if (currentScene.debugLayer.isVisible()) {
@@ -321,10 +322,14 @@ if (BABYLON.Engine.isSupported()) {
         if (event.keyCode === 32 && event.target.nodeName !== "INPUT") {
         if (event.keyCode === 32 && event.target.nodeName !== "INPUT") {
             if (footer.style.display === "none") {
             if (footer.style.display === "none") {
                 footer.style.display = "block";
                 footer.style.display = "block";
+                canvas.style.height = "calc(100% - 56px)";                
+                engine.resize();
             }
             }
             else {
             else {
                 footer.style.display = "none";
                 footer.style.display = "none";
+                canvas.style.height = "100%";
                 errorZone.style.display = "none";
                 errorZone.style.display = "none";
+                engine.resize();
                 if (debugLayerEnabled) {
                 if (debugLayerEnabled) {
                     currentScene.debugLayer.hide();
                     currentScene.debugLayer.hide();
                     debugLayerEnabled = false;
                     debugLayerEnabled = false;

+ 56 - 53
src/Culling/babylon.boundingBox.ts

@@ -1,4 +1,4 @@
-module BABYLON {
+module BABYLON {
     /**
     /**
      * Class used to store bounding box information
      * Class used to store bounding box information
      */
      */
@@ -6,50 +6,50 @@
         /**
         /**
          * Gets the 8 vectors representing the bounding box in local space
          * Gets the 8 vectors representing the bounding box in local space
          */
          */
-        public vectors: Vector3[] = Tools.BuildArray(8, Vector3.Zero);
+        public readonly vectors: Vector3[] = Tools.BuildArray(8, Vector3.Zero);
         /**
         /**
          * Gets the center of the bounding box in local space
          * Gets the center of the bounding box in local space
          */
          */
-        public center: Vector3 = Vector3.Zero();
+        public readonly center: Vector3 = Vector3.Zero();
         /**
         /**
          * Gets the center of the bounding box in world space
          * Gets the center of the bounding box in world space
          */
          */
-        public centerWorld: Vector3 = Vector3.Zero();
+        public readonly centerWorld: Vector3 = Vector3.Zero();
         /**
         /**
          * Gets the extend size in local space
          * Gets the extend size in local space
          */
          */
-        public extendSize: Vector3 = Vector3.Zero();
+        public readonly extendSize: Vector3 = Vector3.Zero();
         /**
         /**
          * Gets the extend size in world space
          * Gets the extend size in world space
          */
          */
-        public extendSizeWorld: Vector3 = Vector3.Zero();
+        public readonly extendSizeWorld: Vector3 = Vector3.Zero();
         /**
         /**
          * Gets the OBB (object bounding box) directions
          * Gets the OBB (object bounding box) directions
          */
          */
-        public directions: Vector3[] = Tools.BuildArray(3, Vector3.Zero);
+        public readonly directions: Vector3[] = Tools.BuildArray(3, Vector3.Zero);
         /**
         /**
          * Gets the 8 vectors representing the bounding box in world space
          * Gets the 8 vectors representing the bounding box in world space
          */
          */
-        public vectorsWorld: Vector3[] = Tools.BuildArray(8, Vector3.Zero);
+        public readonly vectorsWorld: Vector3[] = Tools.BuildArray(8, Vector3.Zero);
         /**
         /**
          * Gets the minimum vector in world space
          * Gets the minimum vector in world space
          */
          */
-        public minimumWorld: Vector3 = Vector3.Zero();
+        public readonly minimumWorld: Vector3 = Vector3.Zero();
         /**
         /**
          * Gets the maximum vector in world space
          * Gets the maximum vector in world space
          */
          */
-        public maximumWorld: Vector3 = Vector3.Zero();
+        public readonly maximumWorld: Vector3 = Vector3.Zero();
         /**
         /**
          * Gets the minimum vector in local space
          * Gets the minimum vector in local space
          */
          */
-        public minimum: Vector3 = Vector3.Zero();
+        public readonly minimum: Vector3 = Vector3.Zero();
         /**
         /**
          * Gets the maximum vector in local space
          * Gets the maximum vector in local space
          */
          */
-        public maximum: Vector3 = Vector3.Zero();
+        public readonly maximum: Vector3 = Vector3.Zero();
 
 
-        private _worldMatrix: Matrix;
-        private static TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
+        private _worldMatrix: Readonly<Matrix>;
+        private static readonly TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
 
 
         /**
         /**
          * @hidden
          * @hidden
@@ -62,19 +62,19 @@
          * @param max defines the maximum vector (in local space)
          * @param max defines the maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
          * @param worldMatrix defines the new world matrix
          */
          */
-        constructor(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+        constructor(min: Readonly<Vector3>, max: Readonly<Vector3>, worldMatrix?: Readonly<Matrix>) {
             this.reConstruct(min, max, worldMatrix);
             this.reConstruct(min, max, worldMatrix);
         }
         }
 
 
         // Methods
         // Methods
 
 
         /**
         /**
-         * Recreates the entire bounding box from scratch
+         * Recreates the entire bounding box from scratch as if we call the constructor in place
          * @param min defines the new minimum vector (in local space)
          * @param min defines the new minimum vector (in local space)
          * @param max defines the new maximum vector (in local space)
          * @param max defines the new maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
          * @param worldMatrix defines the new world matrix
          */
          */
-        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+        public reConstruct(min: Readonly<Vector3>, max: Readonly<Vector3>, worldMatrix?: Readonly<Matrix>) {
             const minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
             const minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
             const vectors = this.vectors;
             const vectors = this.vectors;
 
 
@@ -93,7 +93,7 @@
             max.addToRef(min, this.center).scaleInPlace(0.5);
             max.addToRef(min, this.center).scaleInPlace(0.5);
             max.subtractToRef(min, this.extendSize).scaleInPlace(0.5);
             max.subtractToRef(min, this.extendSize).scaleInPlace(0.5);
 
 
-            this._update(worldMatrix || this._worldMatrix || Matrix.Identity());
+            this._update(worldMatrix || Matrix.IdentityReadOnly);
         }
         }
 
 
         /**
         /**
@@ -112,7 +112,7 @@
             const min = this.center.subtractToRef(newRadius, tmpVectors[1]);
             const min = this.center.subtractToRef(newRadius, tmpVectors[1]);
             const max = this.center.addToRef(newRadius, tmpVectors[2]);
             const max = this.center.addToRef(newRadius, tmpVectors[2]);
 
 
-            this.reConstruct(min, max);
+            this.reConstruct(min, max, this._worldMatrix);
 
 
             return this;
             return this;
         }
         }
@@ -121,42 +121,44 @@
          * Gets the world matrix of the bounding box
          * Gets the world matrix of the bounding box
          * @returns a matrix
          * @returns a matrix
          */
          */
-        public getWorldMatrix(): Matrix {
+        public getWorldMatrix(): Readonly<Matrix> {
             return this._worldMatrix;
             return this._worldMatrix;
         }
         }
 
 
-        /**
-         * Sets the world matrix stored in the bounding box
-         * @param matrix defines the matrix to store
-         * @returns current bounding box
-         */
-        public setWorldMatrix(matrix: Matrix): BoundingBox {
-            this._worldMatrix.copyFrom(matrix);
-            return this;
-        }
-
         /** @hidden */
         /** @hidden */
-        public _update(world: Matrix): void {
+        public _update(world: Readonly<Matrix>): void {
             const minWorld = this.minimumWorld;
             const minWorld = this.minimumWorld;
             const maxWorld = this.maximumWorld;
             const maxWorld = this.maximumWorld;
             const directions = this.directions;
             const directions = this.directions;
-
-            minWorld.setAll(Number.MAX_VALUE);
-            maxWorld.setAll(-Number.MAX_VALUE);
-
             const vectorsWorld = this.vectorsWorld;
             const vectorsWorld = this.vectorsWorld;
             const vectors = this.vectors;
             const vectors = this.vectors;
-            for (let index = 0; index < 8; ++index) {
-                const v = vectorsWorld[index];
-                Vector3.TransformCoordinatesToRef(vectors[index], world, v);
-                minWorld.minimizeInPlace(v);
-                maxWorld.maximizeInPlace(v);
+
+            if (!world.isIdentity()) {
+                minWorld.setAll(Number.MAX_VALUE);
+                maxWorld.setAll(-Number.MAX_VALUE);
+
+                for (let index = 0; index < 8; ++index) {
+                    const v = vectorsWorld[index];
+                    Vector3.TransformCoordinatesToRef(vectors[index], world, v);
+                    minWorld.minimizeInPlace(v);
+                    maxWorld.maximizeInPlace(v);
+                }
+
+                // Extend
+                maxWorld.subtractToRef(minWorld, this.extendSizeWorld).scaleInPlace(0.5);
+                maxWorld.addToRef(minWorld, this.centerWorld).scaleInPlace(0.5);
             }
             }
+            else {
+                minWorld.copyFrom(this.minimum);
+                maxWorld.copyFrom(this.maximum);
+                for (let index = 0; index < 8; ++index) {
+                    vectorsWorld[index].copyFrom(vectors[index]);
+                }
 
 
-            // Extend
-            maxWorld.subtractToRef(minWorld, this.extendSizeWorld).scaleInPlace(0.5);
-            // OOBB
-            maxWorld.addToRef(minWorld, this.centerWorld).scaleInPlace(0.5);
+                // Extend
+                this.extendSizeWorld.copyFrom(this.extendSize);
+                this.centerWorld.copyFrom(this.center);
+            }
 
 
             Vector3.FromArrayToRef(world.m, 0, directions[0]);
             Vector3.FromArrayToRef(world.m, 0, directions[0]);
             Vector3.FromArrayToRef(world.m, 4, directions[1]);
             Vector3.FromArrayToRef(world.m, 4, directions[1]);
@@ -170,7 +172,7 @@
          * @param frustumPlanes defines the frustum planes to test
          * @param frustumPlanes defines the frustum planes to test
          * @returns true if there is an intersection
          * @returns true if there is an intersection
          */
          */
-        public isInFrustum(frustumPlanes: Plane[]): boolean {
+        public isInFrustum(frustumPlanes: Array<Readonly<Plane>>): boolean {
             return BoundingBox.IsInFrustum(this.vectorsWorld, frustumPlanes);
             return BoundingBox.IsInFrustum(this.vectorsWorld, frustumPlanes);
         }
         }
 
 
@@ -179,7 +181,7 @@
          * @param frustumPlanes defines the frustum planes to test
          * @param frustumPlanes defines the frustum planes to test
          * @returns true if there is an inclusion
          * @returns true if there is an inclusion
          */
          */
-        public isCompletelyInFrustum(frustumPlanes: Plane[]): boolean {
+        public isCompletelyInFrustum(frustumPlanes: Array<Readonly<Plane>>): boolean {
             return BoundingBox.IsCompletelyInFrustum(this.vectorsWorld, frustumPlanes);
             return BoundingBox.IsCompletelyInFrustum(this.vectorsWorld, frustumPlanes);
         }
         }
 
 
@@ -188,7 +190,7 @@
          * @param point defines the point to test
          * @param point defines the point to test
          * @returns true if the point is inside the bounding box
          * @returns true if the point is inside the bounding box
          */
          */
-        public intersectsPoint(point: Vector3): boolean {
+        public intersectsPoint(point: Readonly<Vector3>): boolean {
             const min = this.minimumWorld;
             const min = this.minimumWorld;
             const max = this.maximumWorld;
             const max = this.maximumWorld;
             const minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
             const minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
@@ -215,7 +217,7 @@
          * @param sphere defines the sphere to test
          * @param sphere defines the sphere to test
          * @returns true if there is an intersection
          * @returns true if there is an intersection
          */
          */
-        public intersectsSphere(sphere: BoundingSphere): boolean {
+        public intersectsSphere(sphere: Readonly<BoundingSphere>): boolean {
             return BoundingBox.IntersectsSphere(this.minimumWorld, this.maximumWorld, sphere.centerWorld, sphere.radiusWorld);
             return BoundingBox.IntersectsSphere(this.minimumWorld, this.maximumWorld, sphere.centerWorld, sphere.radiusWorld);
         }
         }
 
 
@@ -225,7 +227,7 @@
          * @param max defines the max vector to use
          * @param max defines the max vector to use
          * @returns true if there is an intersection
          * @returns true if there is an intersection
          */
          */
-        public intersectsMinMax(min: Vector3, max: Vector3): boolean {
+        public intersectsMinMax(min: Readonly<Vector3>, max: Readonly<Vector3>): boolean {
             const myMin = this.minimumWorld;
             const myMin = this.minimumWorld;
             const myMax = this.maximumWorld;
             const myMax = this.maximumWorld;
             const myMinX = myMin.x, myMinY = myMin.y, myMinZ = myMin.z, myMaxX = myMax.x, myMaxY = myMax.y, myMaxZ = myMax.z;
             const myMinX = myMin.x, myMinY = myMin.y, myMinZ = myMin.z, myMaxX = myMax.x, myMaxY = myMax.y, myMaxZ = myMax.z;
@@ -265,8 +267,9 @@
          * @param sphereRadius defines the sphere radius
          * @param sphereRadius defines the sphere radius
          * @returns true if there is an intersection
          * @returns true if there is an intersection
          */
          */
-        public static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean {
-            var vector = Vector3.Clamp(sphereCenter, minPoint, maxPoint);
+        public static IntersectsSphere(minPoint: Readonly<Vector3>, maxPoint: Readonly<Vector3>, sphereCenter: Readonly<Vector3>, sphereRadius: number): boolean {
+            const vector = BoundingBox.TmpVector3[0];
+            Vector3.ClampToRef(sphereCenter, minPoint, maxPoint, vector);
             var num = Vector3.DistanceSquared(sphereCenter, vector);
             var num = Vector3.DistanceSquared(sphereCenter, vector);
             return (num <= (sphereRadius * sphereRadius));
             return (num <= (sphereRadius * sphereRadius));
         }
         }
@@ -277,7 +280,7 @@
          * @param frustumPlanes defines the frustum planes to test
          * @param frustumPlanes defines the frustum planes to test
          * @return true if there is an inclusion
          * @return true if there is an inclusion
          */
          */
-        public static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean {
+        public static IsCompletelyInFrustum(boundingVectors: Array<Readonly<Vector3>>, frustumPlanes: Array<Readonly<Plane>>): boolean {
             for (var p = 0; p < 6; ++p) {
             for (var p = 0; p < 6; ++p) {
                 const frustumPlane = frustumPlanes[p];
                 const frustumPlane = frustumPlanes[p];
                 for (var i = 0; i < 8; ++i) {
                 for (var i = 0; i < 8; ++i) {
@@ -295,7 +298,7 @@
          * @param frustumPlanes defines the frustum planes to test
          * @param frustumPlanes defines the frustum planes to test
          * @return true if there is an intersection
          * @return true if there is an intersection
          */
          */
-        public static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean {
+        public static IsInFrustum(boundingVectors: Array<Readonly<Vector3>>, frustumPlanes: Array<Readonly<Plane>>): boolean {
             for (var p = 0; p < 6; ++p) {
             for (var p = 0; p < 6; ++p) {
                 let canReturnFalse = true;
                 let canReturnFalse = true;
                 const frustumPlane = frustumPlanes[p];
                 const frustumPlane = frustumPlanes[p];

+ 37 - 42
src/Culling/babylon.boundingInfo.ts

@@ -1,25 +1,22 @@
 module BABYLON {
 module BABYLON {
-    var computeBoxExtents = (axis: Vector3, box: BoundingBox) => {
-        var p = Vector3.Dot(box.centerWorld, axis);
-
-        var r0 = Math.abs(Vector3.Dot(box.directions[0], axis)) * box.extendSize.x;
-        var r1 = Math.abs(Vector3.Dot(box.directions[1], axis)) * box.extendSize.y;
-        var r2 = Math.abs(Vector3.Dot(box.directions[2], axis)) * box.extendSize.z;
-
-        var r = r0 + r1 + r2;
-        return {
-            min: p - r,
-            max: p + r
-        };
+    const _result0 = { min: 0, max: 0};
+    const _result1 = { min: 0, max: 0};
+    const computeBoxExtents = (axis: Readonly<Vector3>, box: Readonly<BoundingBox>, result: {min: number, max: number}) => {
+        const p = Vector3.Dot(box.centerWorld, axis);
+
+        const r0 = Math.abs(Vector3.Dot(box.directions[0], axis)) * box.extendSize.x;
+        const r1 = Math.abs(Vector3.Dot(box.directions[1], axis)) * box.extendSize.y;
+        const r2 = Math.abs(Vector3.Dot(box.directions[2], axis)) * box.extendSize.z;
+
+        const r = r0 + r1 + r2;
+        result.min = p - r;
+        result.max = p + r;
     };
     };
 
 
-    var extentsOverlap = (min0: number, max0: number, min1: number, max1: number): boolean => !(min0 > max1 || min1 > max0);
-
-    var axisOverlap = (axis: Vector3, box0: BoundingBox, box1: BoundingBox): boolean => {
-        var result0 = computeBoxExtents(axis, box0);
-        var result1 = computeBoxExtents(axis, box1);
-
-        return extentsOverlap(result0.min, result0.max, result1.min, result1.max);
+    const axisOverlap = (axis: Vector3, box0: BoundingBox, box1: BoundingBox): boolean => {
+        computeBoxExtents(axis, box0, _result0);
+        computeBoxExtents(axis, box1, _result1);
+        return !(_result0.min > _result1.max || _result1.min > _result0.max);
     };
     };
 
 
     /**
     /**
@@ -49,32 +46,34 @@ module BABYLON {
         /**
         /**
          * Bounding box for the mesh
          * Bounding box for the mesh
          */
          */
-        public boundingBox: BoundingBox;
+        public readonly boundingBox: BoundingBox;
         /**
         /**
          * Bounding sphere for the mesh
          * Bounding sphere for the mesh
          */
          */
-        public boundingSphere: BoundingSphere;
+        public readonly boundingSphere: BoundingSphere;
 
 
         private _isLocked = false;
         private _isLocked = false;
 
 
+        private static readonly TmpVector3 = Tools.BuildArray(2, Vector3.Zero);
+
         /**
         /**
          * Constructs bounding info
          * Constructs bounding info
          * @param minimum min vector of the bounding box/sphere
          * @param minimum min vector of the bounding box/sphere
          * @param maximum max vector of the bounding box/sphere
          * @param maximum max vector of the bounding box/sphere
          * @param worldMatrix defines the new world matrix
          * @param worldMatrix defines the new world matrix
          */
          */
-        constructor(minimum: Vector3, maximum: Vector3, worldMatrix?: Matrix) {
+        constructor(minimum: Readonly<Vector3>, maximum: Readonly<Vector3>, worldMatrix?: Readonly<Matrix>) {
             this.boundingBox = new BoundingBox(minimum, maximum, worldMatrix);
             this.boundingBox = new BoundingBox(minimum, maximum, worldMatrix);
             this.boundingSphere = new BoundingSphere(minimum, maximum, worldMatrix);
             this.boundingSphere = new BoundingSphere(minimum, maximum, worldMatrix);
         }
         }
 
 
         /**
         /**
-         * Recreates the entire bounding info from scratch
+         * Recreates the entire bounding info from scratch as if we call the constructor in place
          * @param min defines the new minimum vector (in local space)
          * @param min defines the new minimum vector (in local space)
          * @param max defines the new maximum vector (in local space)
          * @param max defines the new maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
          * @param worldMatrix defines the new world matrix
          */
          */
-        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+        public reConstruct(min: Readonly<Vector3>, max: Readonly<Vector3>, worldMatrix?: Readonly<Matrix>) {
             this.boundingBox.reConstruct(min, max, worldMatrix);
             this.boundingBox.reConstruct(min, max, worldMatrix);
             this.boundingSphere.reConstruct(min, max, worldMatrix);
             this.boundingSphere.reConstruct(min, max, worldMatrix);
         }
         }
@@ -106,10 +105,10 @@ module BABYLON {
 
 
         // Methods
         // Methods
         /**
         /**
-         * Updates the boudning sphere and box
+         * Updates the bounding sphere and box
          * @param world world matrix to be used to update
          * @param world world matrix to be used to update
          */
          */
-        public update(world: Matrix) {
+        public update(world: Readonly<Matrix>) {
             if (this._isLocked) {
             if (this._isLocked) {
                 return;
                 return;
             }
             }
@@ -123,13 +122,13 @@ module BABYLON {
          * @param extend New extend of the bounding info
          * @param extend New extend of the bounding info
          * @returns the current bounding info
          * @returns the current bounding info
          */
          */
-        public centerOn(center: Vector3, extend: Vector3): BoundingInfo {
+        public centerOn(center: Readonly<Vector3>, extend: Readonly<Vector3>): BoundingInfo {
 
 
-            const minimum = Tmp.Vector3[0].copyFrom(center).subtractInPlace(extend);
-            const maximum = Tmp.Vector3[1].copyFrom(center).addInPlace(extend);
+            const minimum = BoundingInfo.TmpVector3[0].copyFrom(center).subtractInPlace(extend);
+            const maximum = BoundingInfo.TmpVector3[1].copyFrom(center).addInPlace(extend);
 
 
-            this.boundingBox.reConstruct(minimum, maximum);
-            this.boundingSphere.reConstruct(minimum, maximum);
+            this.boundingBox.reConstruct(minimum, maximum, this.boundingBox.getWorldMatrix());
+            this.boundingSphere.reConstruct(minimum, maximum, this.boundingBox.getWorldMatrix());
 
 
             return this;
             return this;
         }
         }
@@ -152,7 +151,7 @@ module BABYLON {
          * @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.Scene.CULLINGSTRATEGY_STANDARD)
          * @returns true if the bounding info is in the frustum planes
          * @returns true if the bounding info is in the frustum planes
          */
          */
-        public isInFrustum(frustumPlanes: Plane[], strategy: number = AbstractMesh.CULLINGSTRATEGY_STANDARD): boolean {
+        public isInFrustum(frustumPlanes: Array<Readonly<Plane>>, strategy: number = AbstractMesh.CULLINGSTRATEGY_STANDARD): boolean {
             if (!this.boundingSphere.isInFrustum(frustumPlanes)) {
             if (!this.boundingSphere.isInFrustum(frustumPlanes)) {
                 return false;
                 return false;
             }
             }
@@ -167,9 +166,9 @@ module BABYLON {
 		 * Gets the world distance between the min and max points of the bounding box
 		 * Gets the world distance between the min and max points of the bounding box
 		 */
 		 */
         public get diagonalLength(): number {
         public get diagonalLength(): number {
-            let boundingBox = this.boundingBox;
-            let size = boundingBox.maximumWorld.subtract(boundingBox.minimumWorld);
-            return size.length();
+            const boundingBox = this.boundingBox;
+            const diag = boundingBox.maximumWorld.subtractToRef(boundingBox.minimumWorld, BoundingInfo.TmpVector3[0]);
+            return diag.length();
         }
         }
 
 
         /**
         /**
@@ -178,7 +177,7 @@ module BABYLON {
          * @param frustumPlanes Camera near/planes
          * @param frustumPlanes Camera near/planes
          * @returns true if the object is in frustum otherwise false
          * @returns true if the object is in frustum otherwise false
          */
          */
-        public isCompletelyInFrustum(frustumPlanes: Plane[]): boolean {
+        public isCompletelyInFrustum(frustumPlanes: Array<Readonly<Plane>>): boolean {
             return this.boundingBox.isCompletelyInFrustum(frustumPlanes);
             return this.boundingBox.isCompletelyInFrustum(frustumPlanes);
         }
         }
         /** @hidden */
         /** @hidden */
@@ -192,7 +191,7 @@ module BABYLON {
          * @param point the point to check intersection with
          * @param point the point to check intersection with
          * @returns if the point intersects
          * @returns if the point intersects
          */
          */
-        public intersectsPoint(point: Vector3): boolean {
+        public intersectsPoint(point: Readonly<Vector3>): boolean {
             if (!this.boundingSphere.centerWorld) {
             if (!this.boundingSphere.centerWorld) {
                 return false;
                 return false;
             }
             }
@@ -215,11 +214,7 @@ module BABYLON {
          * @param precise if the intersection should be done using OBB
          * @param precise if the intersection should be done using OBB
          * @returns if the bounding info intersects
          * @returns if the bounding info intersects
          */
          */
-        public intersects(boundingInfo: BoundingInfo, precise: boolean): boolean {
-            if (!this.boundingSphere.centerWorld || !boundingInfo.boundingSphere.centerWorld) {
-                return false;
-            }
-
+        public intersects(boundingInfo: Readonly<BoundingInfo>, precise: boolean): boolean {
             if (!BoundingSphere.Intersects(this.boundingSphere, boundingInfo.boundingSphere)) {
             if (!BoundingSphere.Intersects(this.boundingSphere, boundingInfo.boundingSphere)) {
                 return false;
                 return false;
             }
             }

+ 33 - 22
src/Culling/babylon.boundingSphere.ts

@@ -1,7 +1,4 @@
 module BABYLON {
 module BABYLON {
-    // This matrix is used as a value to reset the bounding box.
-    const _identityMatrix = Matrix.Identity();
-
     /**
     /**
      * Class used to store bounding sphere information
      * Class used to store bounding sphere information
      */
      */
@@ -9,7 +6,7 @@ module BABYLON {
         /**
         /**
          * Gets the center of the bounding sphere in local space
          * Gets the center of the bounding sphere in local space
          */
          */
-        public center = Vector3.Zero();
+        public readonly center = Vector3.Zero();
         /**
         /**
          * Radius of the bounding sphere in local space
          * Radius of the bounding sphere in local space
          */
          */
@@ -17,7 +14,7 @@ module BABYLON {
         /**
         /**
          * Gets the center of the bounding sphere in world space
          * Gets the center of the bounding sphere in world space
          */
          */
-        public centerWorld = Vector3.Zero();
+        public readonly centerWorld = Vector3.Zero();
         /**
         /**
          * Radius of the bounding sphere in world space
          * Radius of the bounding sphere in world space
          */
          */
@@ -25,13 +22,14 @@ module BABYLON {
         /**
         /**
          * Gets the minimum vector in local space
          * Gets the minimum vector in local space
          */
          */
-        public minimum = Vector3.Zero();
+        public readonly minimum = Vector3.Zero();
         /**
         /**
          * Gets the maximum vector in local space
          * Gets the maximum vector in local space
          */
          */
-        public maximum = Vector3.Zero();
+        public readonly maximum = Vector3.Zero();
 
 
-        private static TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
+        private _worldMatrix: Readonly<Matrix>;
+        private static readonly TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
 
 
         /**
         /**
          * Creates a new bounding sphere
          * Creates a new bounding sphere
@@ -39,17 +37,17 @@ module BABYLON {
          * @param max defines the maximum vector (in local space)
          * @param max defines the maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
          * @param worldMatrix defines the new world matrix
          */
          */
-        constructor(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+        constructor(min: Readonly<Vector3>, max: Readonly<Vector3>, worldMatrix?: Readonly<Matrix>) {
             this.reConstruct(min, max, worldMatrix);
             this.reConstruct(min, max, worldMatrix);
         }
         }
 
 
         /**
         /**
-         * Recreates the entire bounding sphere from scratch
+         * Recreates the entire bounding sphere from scratch as if we call the constructor in place
          * @param min defines the new minimum vector (in local space)
          * @param min defines the new minimum vector (in local space)
          * @param max defines the new maximum vector (in local space)
          * @param max defines the new maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
          * @param worldMatrix defines the new world matrix
          */
          */
-        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+        public reConstruct(min: Readonly<Vector3>, max: Readonly<Vector3>, worldMatrix?: Readonly<Matrix>) {
             this.minimum.copyFrom(min);
             this.minimum.copyFrom(min);
             this.maximum.copyFrom(max);
             this.maximum.copyFrom(max);
 
 
@@ -58,7 +56,7 @@ module BABYLON {
             max.addToRef(min, this.center).scaleInPlace(0.5);
             max.addToRef(min, this.center).scaleInPlace(0.5);
             this.radius = distance * 0.5;
             this.radius = distance * 0.5;
 
 
-            this._update(worldMatrix || _identityMatrix);
+            this._update(worldMatrix || Matrix.IdentityReadOnly);
         }
         }
 
 
         /**
         /**
@@ -73,18 +71,32 @@ module BABYLON {
             const min = this.center.subtractToRef(tempRadiusVector, tmpVectors[1]);
             const min = this.center.subtractToRef(tempRadiusVector, tmpVectors[1]);
             const max = this.center.addToRef(tempRadiusVector, tmpVectors[2]);
             const max = this.center.addToRef(tempRadiusVector, tmpVectors[2]);
 
 
-            this.reConstruct(min, max);
+            this.reConstruct(min, max, this._worldMatrix);
 
 
             return this;
             return this;
         }
         }
 
 
+        /**
+         * Gets the world matrix of the bounding box
+         * @returns a matrix
+         */
+        public getWorldMatrix(): Readonly<Matrix> {
+            return this._worldMatrix;
+        }
+
         // Methods
         // Methods
         /** @hidden */
         /** @hidden */
-        public _update(world: Matrix): void {
-            Vector3.TransformCoordinatesToRef(this.center, world, this.centerWorld);
-            const tempVector = BoundingSphere.TmpVector3[0];
-            Vector3.TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, world, tempVector);
-            this.radiusWorld = Math.max(Math.abs(tempVector.x), Math.abs(tempVector.y), Math.abs(tempVector.z)) * this.radius;
+        public _update(worldMatrix: Readonly<Matrix>): void {
+            if (!worldMatrix.isIdentity()) {
+                Vector3.TransformCoordinatesToRef(this.center, worldMatrix, this.centerWorld);
+                const tempVector = BoundingSphere.TmpVector3[0];
+                Vector3.TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, worldMatrix, tempVector);
+                this.radiusWorld = Math.max(Math.abs(tempVector.x), Math.abs(tempVector.y), Math.abs(tempVector.z)) * this.radius;
+            }
+            else {
+                this.centerWorld.copyFrom(this.center);
+                this.radiusWorld = this.radius;
+            }
         }
         }
 
 
         /**
         /**
@@ -92,7 +104,7 @@ module BABYLON {
          * @param frustumPlanes defines the frustum planes to test
          * @param frustumPlanes defines the frustum planes to test
          * @returns true if there is an intersection
          * @returns true if there is an intersection
          */
          */
-        public isInFrustum(frustumPlanes: Plane[]): boolean {
+        public isInFrustum(frustumPlanes: Array<Readonly<Plane>>): boolean {
             for (var i = 0; i < 6; i++) {
             for (var i = 0; i < 6; i++) {
                 if (frustumPlanes[i].dotCoordinate(this.centerWorld) <= -this.radiusWorld) {
                 if (frustumPlanes[i].dotCoordinate(this.centerWorld) <= -this.radiusWorld) {
                     return false;
                     return false;
@@ -107,7 +119,7 @@ module BABYLON {
          * @param point defines the point to test
          * @param point defines the point to test
          * @returns true if the point is inside the bounding sphere
          * @returns true if the point is inside the bounding sphere
          */
          */
-        public intersectsPoint(point: Vector3): boolean {
+        public intersectsPoint(point: Readonly<Vector3>): boolean {
             const squareDistance = Vector3.DistanceSquared(this.centerWorld, point);
             const squareDistance = Vector3.DistanceSquared(this.centerWorld, point);
             if (this.radiusWorld * this.radiusWorld < squareDistance) {
             if (this.radiusWorld * this.radiusWorld < squareDistance) {
                 return false;
                 return false;
@@ -123,7 +135,7 @@ module BABYLON {
          * @param sphere1 sphere 1
          * @param sphere1 sphere 1
          * @returns true if the speres intersect
          * @returns true if the speres intersect
          */
          */
-        public static Intersects(sphere0: BoundingSphere, sphere1: BoundingSphere): boolean {
+        public static Intersects(sphere0: Readonly<BoundingSphere>, sphere1: Readonly<BoundingSphere>): boolean {
             const squareDistance = Vector3.DistanceSquared(sphere0.centerWorld, sphere1.centerWorld);
             const squareDistance = Vector3.DistanceSquared(sphere0.centerWorld, sphere1.centerWorld);
             const radiusSum = sphere0.radiusWorld + sphere1.radiusWorld;
             const radiusSum = sphere0.radiusWorld + sphere1.radiusWorld;
 
 
@@ -133,6 +145,5 @@ module BABYLON {
 
 
             return true;
             return true;
         }
         }
-
     }
     }
 }
 }

+ 40 - 40
src/Culling/babylon.ray.ts

@@ -3,11 +3,13 @@ module BABYLON {
      * Class representing a ray with position and direction
      * Class representing a ray with position and direction
      */
      */
     export class Ray {
     export class Ray {
-        private _edge1: Vector3;
-        private _edge2: Vector3;
-        private _pvec: Vector3;
-        private _tvec: Vector3;
-        private _qvec: Vector3;
+        private static readonly _edge1 = Vector3.Zero();
+        private static readonly _edge2 = Vector3.Zero();
+        private static readonly _pvec = Vector3.Zero();
+        private static readonly _tvec = Vector3.Zero();
+        private static readonly _qvec = Vector3.Zero();
+        private static readonly _min = Vector3.Zero();
+        private static readonly _max = Vector3.Zero();
 
 
         private _tmpRay: Ray;
         private _tmpRay: Ray;
 
 
@@ -31,9 +33,12 @@ module BABYLON {
          * Checks if the ray intersects a box
          * Checks if the ray intersects a box
          * @param minimum bound of the box
          * @param minimum bound of the box
          * @param maximum bound of the box
          * @param maximum bound of the box
+         * @param intersectionTreshold extra extend to be added to the box in all direction
          * @returns if the box was hit
          * @returns if the box was hit
          */
          */
-        public intersectsBoxMinMax(minimum: Vector3, maximum: Vector3): boolean {
+        public intersectsBoxMinMax(minimum: Vector3, maximum: Vector3, intersectionTreshold: number = 0): boolean {
+            const newMinimum = Ray._min.copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);
+            const newMaximum = Ray._max.copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);
             var d = 0.0;
             var d = 0.0;
             var maxValue = Number.MAX_VALUE;
             var maxValue = Number.MAX_VALUE;
             var inv: number;
             var inv: number;
@@ -41,14 +46,14 @@ module BABYLON {
             var max: number;
             var max: number;
             var temp: number;
             var temp: number;
             if (Math.abs(this.direction.x) < 0.0000001) {
             if (Math.abs(this.direction.x) < 0.0000001) {
-                if (this.origin.x < minimum.x || this.origin.x > maximum.x) {
+                if (this.origin.x < newMinimum.x || this.origin.x > newMaximum.x) {
                     return false;
                     return false;
                 }
                 }
             }
             }
             else {
             else {
                 inv = 1.0 / this.direction.x;
                 inv = 1.0 / this.direction.x;
-                min = (minimum.x - this.origin.x) * inv;
-                max = (maximum.x - this.origin.x) * inv;
+                min = (newMinimum.x - this.origin.x) * inv;
+                max = (newMaximum.x - this.origin.x) * inv;
                 if (max === -Infinity) {
                 if (max === -Infinity) {
                     max = Infinity;
                     max = Infinity;
                 }
                 }
@@ -68,14 +73,14 @@ module BABYLON {
             }
             }
 
 
             if (Math.abs(this.direction.y) < 0.0000001) {
             if (Math.abs(this.direction.y) < 0.0000001) {
-                if (this.origin.y < minimum.y || this.origin.y > maximum.y) {
+                if (this.origin.y < newMinimum.y || this.origin.y > newMaximum.y) {
                     return false;
                     return false;
                 }
                 }
             }
             }
             else {
             else {
                 inv = 1.0 / this.direction.y;
                 inv = 1.0 / this.direction.y;
-                min = (minimum.y - this.origin.y) * inv;
-                max = (maximum.y - this.origin.y) * inv;
+                min = (newMinimum.y - this.origin.y) * inv;
+                max = (newMaximum.y - this.origin.y) * inv;
 
 
                 if (max === -Infinity) {
                 if (max === -Infinity) {
                     max = Infinity;
                     max = Infinity;
@@ -96,14 +101,14 @@ module BABYLON {
             }
             }
 
 
             if (Math.abs(this.direction.z) < 0.0000001) {
             if (Math.abs(this.direction.z) < 0.0000001) {
-                if (this.origin.z < minimum.z || this.origin.z > maximum.z) {
+                if (this.origin.z < newMinimum.z || this.origin.z > newMaximum.z) {
                     return false;
                     return false;
                 }
                 }
             }
             }
             else {
             else {
                 inv = 1.0 / this.direction.z;
                 inv = 1.0 / this.direction.z;
-                min = (minimum.z - this.origin.z) * inv;
-                max = (maximum.z - this.origin.z) * inv;
+                min = (newMinimum.z - this.origin.z) * inv;
+                max = (newMaximum.z - this.origin.z) * inv;
 
 
                 if (max === -Infinity) {
                 if (max === -Infinity) {
                     max = Infinity;
                     max = Infinity;
@@ -128,23 +133,26 @@ module BABYLON {
         /**
         /**
          * Checks if the ray intersects a box
          * Checks if the ray intersects a box
          * @param box the bounding box to check
          * @param box the bounding box to check
+         * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction
          * @returns if the box was hit
          * @returns if the box was hit
          */
          */
-        public intersectsBox(box: BoundingBox): boolean {
-            return this.intersectsBoxMinMax(box.minimum, box.maximum);
+        public intersectsBox(box: BoundingBox, intersectionTreshold: number = 0): boolean {
+            return this.intersectsBoxMinMax(box.minimum, box.maximum, intersectionTreshold);
         }
         }
 
 
         /**
         /**
          * If the ray hits a sphere
          * If the ray hits a sphere
          * @param sphere the bounding sphere to check
          * @param sphere the bounding sphere to check
+         * @param intersectionTreshold extra extend to be added to the BoundingSphere in all direction
          * @returns true if it hits the sphere
          * @returns true if it hits the sphere
          */
          */
-        public intersectsSphere(sphere: BoundingSphere): boolean {
+        public intersectsSphere(sphere: BoundingSphere, intersectionTreshold: number = 0): boolean {
             var x = sphere.center.x - this.origin.x;
             var x = sphere.center.x - this.origin.x;
             var y = sphere.center.y - this.origin.y;
             var y = sphere.center.y - this.origin.y;
             var z = sphere.center.z - this.origin.z;
             var z = sphere.center.z - this.origin.z;
             var pyth = (x * x) + (y * y) + (z * z);
             var pyth = (x * x) + (y * y) + (z * z);
-            var rr = sphere.radius * sphere.radius;
+            const radius = sphere.radius + intersectionTreshold;
+            var rr = radius * radius;
 
 
             if (pyth <= rr) {
             if (pyth <= rr) {
                 return true;
                 return true;
@@ -168,18 +176,10 @@ module BABYLON {
          * @returns intersection information if hit
          * @returns intersection information if hit
          */
          */
         public intersectsTriangle(vertex0: Vector3, vertex1: Vector3, vertex2: Vector3): Nullable<IntersectionInfo> {
         public intersectsTriangle(vertex0: Vector3, vertex1: Vector3, vertex2: Vector3): Nullable<IntersectionInfo> {
-            if (!this._edge1) {
-                this._edge1 = Vector3.Zero();
-                this._edge2 = Vector3.Zero();
-                this._pvec = Vector3.Zero();
-                this._tvec = Vector3.Zero();
-                this._qvec = Vector3.Zero();
-            }
-
-            vertex1.subtractToRef(vertex0, this._edge1);
-            vertex2.subtractToRef(vertex0, this._edge2);
-            Vector3.CrossToRef(this.direction, this._edge2, this._pvec);
-            var det = Vector3.Dot(this._edge1, this._pvec);
+            vertex1.subtractToRef(vertex0, Ray._edge1);
+            vertex2.subtractToRef(vertex0, Ray._edge2);
+            Vector3.CrossToRef(this.direction, Ray._edge2, Ray._pvec);
+            var det = Vector3.Dot(Ray._edge1, Ray._pvec);
 
 
             if (det === 0) {
             if (det === 0) {
                 return null;
                 return null;
@@ -187,24 +187,24 @@ module BABYLON {
 
 
             var invdet = 1 / det;
             var invdet = 1 / det;
 
 
-            this.origin.subtractToRef(vertex0, this._tvec);
+            this.origin.subtractToRef(vertex0, Ray._tvec);
 
 
-            var bu = Vector3.Dot(this._tvec, this._pvec) * invdet;
+            var bu = Vector3.Dot(Ray._tvec, Ray._pvec) * invdet;
 
 
             if (bu < 0 || bu > 1.0) {
             if (bu < 0 || bu > 1.0) {
                 return null;
                 return null;
             }
             }
 
 
-            Vector3.CrossToRef(this._tvec, this._edge1, this._qvec);
+            Vector3.CrossToRef(Ray._tvec, Ray._edge1, Ray._qvec);
 
 
-            var bv = Vector3.Dot(this.direction, this._qvec) * invdet;
+            var bv = Vector3.Dot(this.direction, Ray._qvec) * invdet;
 
 
             if (bv < 0 || bu + bv > 1.0) {
             if (bv < 0 || bu + bv > 1.0) {
                 return null;
                 return null;
             }
             }
 
 
             //check if the distance is longer than the predefined length.
             //check if the distance is longer than the predefined length.
-            var distance = Vector3.Dot(this._edge2, this._qvec) * invdet;
+            var distance = Vector3.Dot(Ray._edge2, Ray._qvec) * invdet;
             if (distance > this.length) {
             if (distance > this.length) {
                 return null;
                 return null;
             }
             }
@@ -353,7 +353,7 @@ module BABYLON {
                 if (-d < 0.0) {
                 if (-d < 0.0) {
                     sN = 0.0;
                     sN = 0.0;
                 } else if (-d > a) {
                 } else if (-d > a) {
-                    sN = sD;
+                    sN = sD;
                        }
                        }
                 else {
                 else {
                     sN = -d;
                     sN = -d;
@@ -441,7 +441,7 @@ module BABYLON {
         * @param world a matrix to transform the ray to. Default is the identity matrix.
         * @param world a matrix to transform the ray to. Default is the identity matrix.
         * @returns the new ray
         * @returns the new ray
         */
         */
-        public static CreateNewFromTo(origin: Vector3, end: Vector3, world: Matrix = Matrix.Identity()): Ray {
+        public static CreateNewFromTo(origin: Vector3, end: Vector3, world: Readonly<Matrix> = Matrix.IdentityReadOnly): Ray {
             var direction = end.subtract(origin);
             var direction = end.subtract(origin);
             var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
             var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
             direction.normalize();
             direction.normalize();
@@ -455,7 +455,7 @@ module BABYLON {
          * @param matrix matrix to apply
          * @param matrix matrix to apply
          * @returns the resulting new ray
          * @returns the resulting new ray
          */
          */
-        public static Transform(ray: Ray, matrix: Matrix): Ray {
+        public static Transform(ray: Ray, matrix: Readonly<Matrix>): Ray {
             var result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
             var result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
             Ray.TransformToRef(ray, matrix, result);
             Ray.TransformToRef(ray, matrix, result);
 
 
@@ -468,7 +468,7 @@ module BABYLON {
          * @param matrix matrix to apply
          * @param matrix matrix to apply
          * @param result ray to store result in
          * @param result ray to store result in
          */
          */
-        public static TransformToRef(ray: Ray, matrix: Matrix, result: Ray): void {
+        public static TransformToRef(ray: Ray, matrix: Readonly<Matrix>, result: Ray): void {
             Vector3.TransformCoordinatesToRef(ray.origin, matrix, result.origin);
             Vector3.TransformCoordinatesToRef(ray.origin, matrix, result.origin);
             Vector3.TransformNormalToRef(ray.direction, matrix, result.direction);
             Vector3.TransformNormalToRef(ray.direction, matrix, result.direction);
             result.length = ray.length;
             result.length = ray.length;

+ 3 - 3
src/Materials/Textures/babylon.baseTexture.ts

@@ -293,7 +293,7 @@ module BABYLON {
          * @returns the transformation matrix
          * @returns the transformation matrix
          */
          */
         public getTextureMatrix(): Matrix {
         public getTextureMatrix(): Matrix {
-            return Matrix.IdentityReadOnly;
+            return <Matrix>Matrix.IdentityReadOnly;
         }
         }
 
 
         /**
         /**
@@ -301,7 +301,7 @@ module BABYLON {
          * @returns the reflection matrix
          * @returns the reflection matrix
          */
          */
         public getReflectionTextureMatrix(): Matrix {
         public getReflectionTextureMatrix(): Matrix {
-            return Matrix.IdentityReadOnly;
+            return <Matrix>Matrix.IdentityReadOnly;
         }
         }
 
 
         /**
         /**
@@ -367,7 +367,7 @@ module BABYLON {
          */
          */
         public getBaseSize(): ISize {
         public getBaseSize(): ISize {
             if (!this.isReady() || !this._texture) {
             if (!this.isReady() || !this._texture) {
-                return Size.Zero();
+                return Size.Zero();
             }
             }
 
 
             if (this._texture._size) {
             if (this._texture._size) {

+ 8 - 8
src/Materials/babylon.materialHelper.ts

@@ -32,7 +32,7 @@ module BABYLON {
         public static PrepareDefinesForMergedUV(texture: BaseTexture, defines: any, key: string): void {
         public static PrepareDefinesForMergedUV(texture: BaseTexture, defines: any, key: string): void {
             defines._needUVs = true;
             defines._needUVs = true;
             defines[key] = true;
             defines[key] = true;
-            if (texture.getTextureMatrix().isIdentity(true)) {
+            if (texture.getTextureMatrix().isIdentityAs3x2()) {
                 defines[key + "DIRECTUV"] = texture.coordinatesIndex + 1;
                 defines[key + "DIRECTUV"] = texture.coordinatesIndex + 1;
                 if (texture.coordinatesIndex === 0) {
                 if (texture.coordinatesIndex === 0) {
                     defines["MAINUV1"] = true;
                     defines["MAINUV1"] = true;
@@ -53,7 +53,7 @@ module BABYLON {
         public static BindTextureMatrix(texture: BaseTexture, uniformBuffer: UniformBuffer, key: string): void {
         public static BindTextureMatrix(texture: BaseTexture, uniformBuffer: UniformBuffer, key: string): void {
             var matrix = texture.getTextureMatrix();
             var matrix = texture.getTextureMatrix();
 
 
-            if (!matrix.isIdentity(true)) {
+            if (!matrix.isIdentityAs3x2()) {
                 uniformBuffer.updateMatrix(key + "Matrix", matrix);
                 uniformBuffer.updateMatrix(key + "Matrix", matrix);
             }
             }
         }
         }
@@ -245,14 +245,14 @@ module BABYLON {
 
 
                     switch (light.falloffType) {
                     switch (light.falloffType) {
                         case Light.FALLOFF_GLTF:
                         case Light.FALLOFF_GLTF:
-                        defines["LIGHT_FALLOFF_GLTF" + lightIndex] = true;
-                        break;
+                            defines["LIGHT_FALLOFF_GLTF" + lightIndex] = true;
+                            break;
                         case Light.FALLOFF_PHYSICAL:
                         case Light.FALLOFF_PHYSICAL:
-                        defines["LIGHT_FALLOFF_PHYSICAL" + lightIndex] = true;
-                        break;
+                            defines["LIGHT_FALLOFF_PHYSICAL" + lightIndex] = true;
+                            break;
                         case Light.FALLOFF_STANDARD:
                         case Light.FALLOFF_STANDARD:
-                        defines["LIGHT_FALLOFF_STANDARD" + lightIndex] = true;
-                        break;
+                            defines["LIGHT_FALLOFF_STANDARD" + lightIndex] = true;
+                            break;
                     }
                     }
 
 
                     // Specular
                     // Specular

+ 76 - 36
src/Math/babylon.math.ts

@@ -76,11 +76,7 @@ module BABYLON {
          * @param index defines an optional index in the target array to define where to start storing values
          * @param index defines an optional index in the target array to define where to start storing values
          * @returns the current Color3 object
          * @returns the current Color3 object
          */
          */
-        public toArray(array: FloatArray, index?: number): Color3 {
-            if (index === undefined) {
-                index = 0;
-            }
-
+        public toArray(array: FloatArray, index: number = 0): Color3 {
             array[index] = this.r;
             array[index] = this.r;
             array[index + 1] = this.g;
             array[index + 1] = this.g;
             array[index + 2] = this.b;
             array[index + 2] = this.b;
@@ -93,7 +89,7 @@ module BABYLON {
          * @param alpha defines the alpha component on the new Color4 object (default is 1)
          * @param alpha defines the alpha component on the new Color4 object (default is 1)
          * @returns a new Color4 object
          * @returns a new Color4 object
          */
          */
-        public toColor4(alpha = 1): Color4 {
+        public toColor4(alpha: number = 1): Color4 {
             return new Color4(this.r, this.g, this.b, alpha);
             return new Color4(this.r, this.g, this.b, alpha);
         }
         }
 
 
@@ -2106,10 +2102,7 @@ module BABYLON {
          * @param offset defines the offset in the source array
          * @param offset defines the offset in the source array
          * @returns the new Vector3
          * @returns the new Vector3
          */
          */
-        public static FromArray(array: ArrayLike<number>, offset?: number): Vector3 {
-            if (!offset) {
-                offset = 0;
-            }
+        public static FromArray(array: ArrayLike<number>, offset: number = 0): Vector3 {
             return new Vector3(array[offset], array[offset + 1], array[offset + 2]);
             return new Vector3(array[offset], array[offset + 1], array[offset + 2]);
         }
         }
 
 
@@ -2235,7 +2228,7 @@ module BABYLON {
          * @param transformation defines the transformation matrix
          * @param transformation defines the transformation matrix
          * @param result defines the Vector3 where to store the result
          * @param result defines the Vector3 where to store the result
          */
          */
-        public static TransformCoordinatesToRef(vector: Vector3, transformation: Matrix, result: Vector3): void {
+        public static TransformCoordinatesToRef(vector: Vector3, transformation: Readonly<Matrix>, result: Vector3): void {
             return Vector3.TransformCoordinatesFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
             return Vector3.TransformCoordinatesFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
         }
         }
 
 
@@ -2248,7 +2241,7 @@ module BABYLON {
          * @param transformation defines the transformation matrix
          * @param transformation defines the transformation matrix
          * @param result defines the Vector3 where to store the result
          * @param result defines the Vector3 where to store the result
          */
          */
-        public static TransformCoordinatesFromFloatsToRef(x: number, y: number, z: number, transformation: Matrix, result: Vector3): void {
+        public static TransformCoordinatesFromFloatsToRef(x: number, y: number, z: number, transformation: Readonly<Matrix>, result: Vector3): void {
             const m = transformation.m;
             const m = transformation.m;
             var rx = x * m[0] + y * m[4] + z * m[8] + m[12];
             var rx = x * m[0] + y * m[4] + z * m[8] + m[12];
             var ry = x * m[1] + y * m[5] + z * m[9] + m[13];
             var ry = x * m[1] + y * m[5] + z * m[9] + m[13];
@@ -2280,7 +2273,7 @@ module BABYLON {
          * @param transformation defines the transformation matrix
          * @param transformation defines the transformation matrix
          * @param result defines the Vector3 where to store the result
          * @param result defines the Vector3 where to store the result
          */
          */
-        public static TransformNormalToRef(vector: Vector3, transformation: Matrix, result: Vector3): void {
+        public static TransformNormalToRef(vector: Vector3, transformation: Readonly<Matrix>, result: Vector3): void {
             this.TransformNormalFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
             this.TransformNormalFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
         }
         }
 
 
@@ -2293,7 +2286,7 @@ module BABYLON {
          * @param transformation defines the transformation matrix
          * @param transformation defines the transformation matrix
          * @param result defines the Vector3 where to store the result
          * @param result defines the Vector3 where to store the result
          */
          */
-        public static TransformNormalFromFloatsToRef(x: number, y: number, z: number, transformation: Matrix, result: Vector3): void {
+        public static TransformNormalFromFloatsToRef(x: number, y: number, z: number, transformation: Readonly<Matrix>, result: Vector3): void {
             const m = transformation.m;
             const m = transformation.m;
             result.x = x * m[0] + y * m[4] + z * m[8];
             result.x = x * m[0] + y * m[4] + z * m[8];
             result.y = x * m[1] + y * m[5] + z * m[9];
             result.y = x * m[1] + y * m[5] + z * m[9];
@@ -2338,6 +2331,20 @@ module BABYLON {
          * @returns the new Vector3
          * @returns the new Vector3
          */
          */
         public static Clamp(value: Vector3, min: Vector3, max: Vector3): Vector3 {
         public static Clamp(value: Vector3, min: Vector3, max: Vector3): Vector3 {
+            const v = new Vector3();
+            Vector3.ClampToRef(value, min, max, v);
+            return v;
+        }
+        /**
+         * Sets the given vector "result" with the coordinates of "value", if the vector "value" is in the cube defined by the vectors "min" and "max"
+         * If a coordinate value of "value" is lower than one of the "min" coordinate, then this "value" coordinate is set with the "min" one
+         * If a coordinate value of "value" is greater than one of the "max" coordinate, then this "value" coordinate is set with the "max" one
+         * @param value defines the current value
+         * @param min defines the lower range value
+         * @param max defines the upper range value
+         * @param result defines the Vector3 where to store the result
+         */
+        public static ClampToRef(value: Vector3, min: Vector3, max: Vector3, result: Vector3): void {
             var x = value.x;
             var x = value.x;
             x = (x > max.x) ? max.x : x;
             x = (x > max.x) ? max.x : x;
             x = (x < min.x) ? min.x : x;
             x = (x < min.x) ? min.x : x;
@@ -2350,7 +2357,7 @@ module BABYLON {
             z = (z > max.z) ? max.z : z;
             z = (z > max.z) ? max.z : z;
             z = (z < min.z) ? min.z : z;
             z = (z < min.z) ? min.z : z;
 
 
-            return new Vector3(x, y, z);
+            result.copyFromFloats(x, y, z);
         }
         }
 
 
         /**
         /**
@@ -4220,7 +4227,6 @@ module BABYLON {
      * Class used to store matrix data (4x4)
      * Class used to store matrix data (4x4)
      */
      */
     export class Matrix {
     export class Matrix {
-        private static _tempQuaternion: Quaternion = new Quaternion();
         private static _xAxis: Vector3 = Vector3.Zero();
         private static _xAxis: Vector3 = Vector3.Zero();
         private static _yAxis: Vector3 = Vector3.Zero();
         private static _yAxis: Vector3 = Vector3.Zero();
         private static _zAxis: Vector3 = Vector3.Zero();
         private static _zAxis: Vector3 = Vector3.Zero();
@@ -4229,6 +4235,8 @@ module BABYLON {
 
 
         private _isIdentity = false;
         private _isIdentity = false;
         private _isIdentityDirty = true;
         private _isIdentityDirty = true;
+        private _isIdentity3x2 = true;
+        private _isIdentity3x2Dirty = true;
         /**
         /**
          * Gets the update flag of the matrix which is an unique number for the matrix.
          * Gets the update flag of the matrix which is an unique number for the matrix.
          * It will be incremented every time the matrix data change.
          * It will be incremented every time the matrix data change.
@@ -4245,26 +4253,33 @@ module BABYLON {
         public _markAsUpdated() {
         public _markAsUpdated() {
             this.updateFlag = Matrix._updateFlagSeed++;
             this.updateFlag = Matrix._updateFlagSeed++;
             this._isIdentityDirty = true;
             this._isIdentityDirty = true;
+            this._isIdentity3x2Dirty = true;
+        }
+
+        /** @hidden */
+        private _updateIdentityStatus(isIdentity: boolean) {
+            this.updateFlag = Matrix._updateFlagSeed++;
+            this._isIdentityDirty = false;
+            this._isIdentity = isIdentity;
         }
         }
 
 
         /**
         /**
          * Creates an empty matrix (filled with zeros)
          * Creates an empty matrix (filled with zeros)
          */
          */
         public constructor() {
         public constructor() {
-            this._markAsUpdated();
+            this._updateIdentityStatus(false);
         }
         }
 
 
         // Properties
         // Properties
 
 
         /**
         /**
-         * Check if the current matrix is indentity
-         * @param considerAsTextureMatrix defines if the current matrix must be considered as a texture matrix (3x2)
+         * Check if the current matrix is identity
          * @returns true is the matrix is the identity matrix
          * @returns true is the matrix is the identity matrix
          */
          */
-        public isIdentity(considerAsTextureMatrix = false): boolean {
+        public isIdentity(): boolean {
             if (this._isIdentityDirty) {
             if (this._isIdentityDirty) {
                 this._isIdentityDirty = false;
                 this._isIdentityDirty = false;
-                if (this.m[0] !== 1.0 || this.m[5] !== 1.0 || this.m[15] !== 1.0) {
+                if (this.m[0] !== 1.0 || this.m[5] !== 1.0 || this.m[10] !== 1.0 || this.m[15] !== 1.0) {
                     this._isIdentity = false;
                     this._isIdentity = false;
                 } else if (this.m[1] !== 0.0 || this.m[2] !== 0.0 || this.m[3] !== 0.0 ||
                 } else if (this.m[1] !== 0.0 || this.m[2] !== 0.0 || this.m[3] !== 0.0 ||
                     this.m[4] !== 0.0 || this.m[6] !== 0.0 || this.m[7] !== 0.0 ||
                     this.m[4] !== 0.0 || this.m[6] !== 0.0 || this.m[7] !== 0.0 ||
@@ -4274,14 +4289,33 @@ module BABYLON {
                 } else {
                 } else {
                     this._isIdentity = true;
                     this._isIdentity = true;
                 }
                 }
+            }
 
 
-                if (!considerAsTextureMatrix && this.m[10] !== 1.0) {
-                    this._isIdentity = false;
+            return this._isIdentity;
+        }
+
+        /**
+         * Check if the current matrix is identity as a texture matrix (3x2 store in 4x4)
+         * @returns true is the matrix is the identity matrix
+         */
+        public isIdentityAs3x2(): boolean {
+            if (this._isIdentity3x2Dirty) {
+                this._isIdentity3x2Dirty = false;
+                if (this.m[0] !== 1.0 || this.m[5] !== 1.0 || this.m[15] !== 1.0) {
+                    this._isIdentity3x2 = false;
+                } else if (this.m[1] !== 0.0 || this.m[2] !== 0.0 || this.m[3] !== 0.0 ||
+                    this.m[4] !== 0.0 || this.m[6] !== 0.0 || this.m[7] !== 0.0 ||
+                    this.m[8] !== 0.0 || this.m[9] !== 0.0 || this.m[10] !== 0.0 || this.m[11] !== 0.0 ||
+                    this.m[12] !== 0.0 || this.m[13] !== 0.0 || this.m[14] !== 0.0) {
+                    this._isIdentity3x2 = false;
+                } else {
+                    this._isIdentity3x2 = true;
                 }
                 }
             }
             }
 
 
-            return this._isIdentity;
+            return this._isIdentity3x2;
         }
         }
+
         /**
         /**
          * Gets the determinant of the matrix
          * Gets the determinant of the matrix
          * @returns the matrix determinant
          * @returns the matrix determinant
@@ -4333,7 +4367,7 @@ module BABYLON {
                 this.m[index] = 0.0;
                 this.m[index] = 0.0;
             }
             }
 
 
-            this._markAsUpdated();
+            this._updateIdentityStatus(false);
             return this;
             return this;
         }
         }
 
 
@@ -4509,7 +4543,7 @@ module BABYLON {
          * @param other defines the second operand
          * @param other defines the second operand
          * @returns a new matrix set with the multiplication result of the current Matrix and the given one
          * @returns a new matrix set with the multiplication result of the current Matrix and the given one
          */
          */
-        public multiply(other: Matrix): Matrix {
+        public multiply(other: Readonly<Matrix>): Matrix {
             var result = new Matrix();
             var result = new Matrix();
             this.multiplyToRef(other, result);
             this.multiplyToRef(other, result);
             return result;
             return result;
@@ -4520,7 +4554,7 @@ module BABYLON {
          * @param other defines the source matrix
          * @param other defines the source matrix
          * @returns the current updated matrix
          * @returns the current updated matrix
          */
          */
-        public copyFrom(other: Matrix): Matrix {
+        public copyFrom(other: Readonly<Matrix>): Matrix {
             for (var index = 0; index < 16; index++) {
             for (var index = 0; index < 16; index++) {
                 this.m[index] = other.m[index];
                 this.m[index] = other.m[index];
             }
             }
@@ -4548,7 +4582,7 @@ module BABYLON {
          * @param result defines the matrix where to store the multiplication
          * @param result defines the matrix where to store the multiplication
          * @returns the current matrix
          * @returns the current matrix
          */
          */
-        public multiplyToRef(other: Matrix, result: Matrix): Matrix {
+        public multiplyToRef(other: Readonly<Matrix>, result: Matrix): Matrix {
             this.multiplyToArray(other, result.m, 0);
             this.multiplyToArray(other, result.m, 0);
 
 
             result._markAsUpdated();
             result._markAsUpdated();
@@ -4562,7 +4596,7 @@ module BABYLON {
          * @param offset defines the offset in the target array where to start storing values
          * @param offset defines the offset in the target array where to start storing values
          * @returns the current matrix
          * @returns the current matrix
          */
          */
-        public multiplyToArray(other: Matrix, result: Float32Array, offset: number): Matrix {
+        public multiplyToArray(other: Readonly<Matrix>, result: Float32Array, offset: number): Matrix {
             var tm0 = this.m[0];
             var tm0 = this.m[0];
             var tm1 = this.m[1];
             var tm1 = this.m[1];
             var tm2 = this.m[2];
             var tm2 = this.m[2];
@@ -4830,8 +4864,9 @@ module BABYLON {
          * @param ref matrix to store the result
          * @param ref matrix to store the result
          */
          */
         public toNormalMatrix(ref: Matrix): void {
         public toNormalMatrix(ref: Matrix): void {
-            this.invertToRef(ref);
-            ref.transpose();
+            const tmp = MathTmp.Matrix[0];
+            this.invertToRef(tmp);
+            tmp.transposeToRef(ref);
             var m = ref.m;
             var m = ref.m;
             Matrix.FromValuesToRef(
             Matrix.FromValuesToRef(
                 m[0], m[1], m[2], 0,
                 m[0], m[1], m[2], 0,
@@ -4990,7 +5025,7 @@ module BABYLON {
         /**
         /**
          * Gets an identity matrix that must not be updated
          * Gets an identity matrix that must not be updated
          */
          */
-        public static get IdentityReadOnly(): Matrix {
+        public static get IdentityReadOnly(): Readonly<Matrix> {
             return Matrix._identityReadOnly;
             return Matrix._identityReadOnly;
         }
         }
 
 
@@ -5078,10 +5113,12 @@ module BABYLON {
          * @returns a new identity matrix
          * @returns a new identity matrix
          */
          */
         public static Identity(): Matrix {
         public static Identity(): Matrix {
-            return Matrix.FromValues(1.0, 0.0, 0.0, 0.0,
+            const identity = Matrix.FromValues(1.0, 0.0, 0.0, 0.0,
                 0.0, 1.0, 0.0, 0.0,
                 0.0, 1.0, 0.0, 0.0,
                 0.0, 0.0, 1.0, 0.0,
                 0.0, 0.0, 1.0, 0.0,
                 0.0, 0.0, 0.0, 1.0);
                 0.0, 0.0, 0.0, 1.0);
+            identity._updateIdentityStatus(true);
+            return identity;
         }
         }
 
 
         /**
         /**
@@ -5093,6 +5130,7 @@ module BABYLON {
                 0.0, 1.0, 0.0, 0.0,
                 0.0, 1.0, 0.0, 0.0,
                 0.0, 0.0, 1.0, 0.0,
                 0.0, 0.0, 1.0, 0.0,
                 0.0, 0.0, 0.0, 1.0, result);
                 0.0, 0.0, 0.0, 1.0, result);
+            result._updateIdentityStatus(true);
         }
         }
 
 
         /**
         /**
@@ -5100,10 +5138,12 @@ module BABYLON {
          * @returns a new zero matrix
          * @returns a new zero matrix
          */
          */
         public static Zero(): Matrix {
         public static Zero(): Matrix {
-            return Matrix.FromValues(0.0, 0.0, 0.0, 0.0,
+            const zero = Matrix.FromValues(0.0, 0.0, 0.0, 0.0,
                 0.0, 0.0, 0.0, 0.0,
                 0.0, 0.0, 0.0, 0.0,
                 0.0, 0.0, 0.0, 0.0,
                 0.0, 0.0, 0.0, 0.0,
                 0.0, 0.0, 0.0, 0.0);
                 0.0, 0.0, 0.0, 0.0);
+            zero._updateIdentityStatus(false);
+            return zero;
         }
         }
 
 
         /**
         /**
@@ -5309,8 +5349,8 @@ module BABYLON {
          * @param result defines the target matrix
          * @param result defines the target matrix
          */
          */
         public static RotationYawPitchRollToRef(yaw: number, pitch: number, roll: number, result: Matrix): void {
         public static RotationYawPitchRollToRef(yaw: number, pitch: number, roll: number, result: Matrix): void {
-            Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, this._tempQuaternion);
-            this._tempQuaternion.toRotationMatrix(result);
+            Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, MathTmp.Quaternion[0]);
+            MathTmp.Quaternion[0].toRotationMatrix(result);
         }
         }
 
 
         /**
         /**

+ 10 - 11
src/Mesh/babylon.abstractMesh.ts

@@ -266,13 +266,13 @@ module BABYLON {
 
 
             // remove from material mesh map id needed
             // remove from material mesh map id needed
             if (this._material && this._material.meshMap) {
             if (this._material && this._material.meshMap) {
-                this._material.meshMap[this.uniqueId] = undefined;
+                this._material.meshMap[this.uniqueId] = undefined;
             }
             }
 
 
             this._material = value;
             this._material = value;
 
 
             if (value && value.meshMap) {
             if (value && value.meshMap) {
-                value.meshMap[this.uniqueId] = this;
+                value.meshMap[this.uniqueId] = this;
             }
             }
 
 
             if (this.onMaterialChangedObservable.hasObservers) {
             if (this.onMaterialChangedObservable.hasObservers) {
@@ -1298,8 +1298,9 @@ module BABYLON {
          */
          */
         public intersects(ray: Ray, fastCheck?: boolean): PickingInfo {
         public intersects(ray: Ray, fastCheck?: boolean): PickingInfo {
             var pickingInfo = new PickingInfo();
             var pickingInfo = new PickingInfo();
-
-            if (!this.subMeshes || !this._boundingInfo || !ray.intersectsSphere(this._boundingInfo.boundingSphere) || !ray.intersectsBox(this._boundingInfo.boundingBox)) {
+            const intersectionTreshold = this.getClassName() === "LinesMesh" ? (<LinesMesh>(this as any)).intersectionThreshold : 0;
+            const boundingInfo = this._boundingInfo;
+            if (!this.subMeshes || !boundingInfo || !ray.intersectsSphere(boundingInfo.boundingSphere, intersectionTreshold) || !ray.intersectsBox(boundingInfo.boundingBox, intersectionTreshold)) {
                 return pickingInfo;
                 return pickingInfo;
             }
             }
 
 
@@ -1335,13 +1336,11 @@ module BABYLON {
 
 
             if (intersectInfo) {
             if (intersectInfo) {
                 // Get picked point
                 // Get picked point
-                var world = this.getWorldMatrix();
-                var worldOrigin = Vector3.TransformCoordinates(ray.origin, world);
-                var direction = ray.direction.clone();
-                direction = direction.scale(intersectInfo.distance);
-                var worldDirection = Vector3.TransformNormal(direction, world);
-
-                var pickedPoint = worldOrigin.add(worldDirection);
+                const world = this.getWorldMatrix();
+                const worldOrigin = Vector3.TransformCoordinates(ray.origin, world);
+                const direction = ray.direction.scaleToRef(intersectInfo.distance, Tmp.Vector3[0]);
+                const worldDirection = Vector3.TransformNormal(direction, world);
+                const pickedPoint = worldDirection.addInPlace(worldOrigin);
 
 
                 // Return result
                 // Return result
                 pickingInfo.hit = true;
                 pickingInfo.hit = true;

+ 13 - 19
src/Mesh/babylon.geometry.ts

@@ -62,9 +62,6 @@ module BABYLON {
          */
          */
         public set boundingBias(value: Vector2) {
         public set boundingBias(value: Vector2) {
             if (this._boundingBias) {
             if (this._boundingBias) {
-                if (this._boundingBias.equals(value)) {
-                    return;
-                }
                 this._boundingBias.copyFrom(value);
                 this._boundingBias.copyFrom(value);
             }
             }
             else {
             else {
@@ -120,11 +117,6 @@ module BABYLON {
 
 
             // applyToMesh
             // applyToMesh
             if (mesh) {
             if (mesh) {
-                if (mesh.getClassName() === "LinesMesh") {
-                    this.boundingBias = new Vector2(0, (<LinesMesh>mesh).intersectionThreshold);
-                    this._updateExtend();
-                }
-
                 this.applyToMesh(mesh);
                 this.applyToMesh(mesh);
                 mesh.computeWorldMatrix(true);
                 mesh.computeWorldMatrix(true);
             }
             }
@@ -317,18 +309,20 @@ module BABYLON {
                 this._updateExtend(data);
                 this._updateExtend(data);
             }
             }
 
 
-            var meshes = this._meshes;
-            var numOfMeshes = meshes.length;
             this._resetPointsArrayCache();
             this._resetPointsArrayCache();
 
 
-            for (var index = 0; index < numOfMeshes; index++) {
-                var mesh = meshes[index];
-                if (updateExtends) {
-                    mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
-
-                    for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
-                        var subMesh = mesh.subMeshes[subIndex];
+            if (updateExtends) {
+                var meshes = this._meshes;
+                for (const mesh of meshes) {
+                    if (mesh._boundingInfo) {
+                        mesh._boundingInfo.reConstruct(this._extend.minimum, this._extend.maximum);
+                    }
+                    else {
+                        mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
+                    }
 
 
+                    const subMeshes = mesh.subMeshes;
+                    for (const subMesh of subMeshes) {
                         subMesh.refreshBoundingInfo();
                         subMesh.refreshBoundingInfo();
                     }
                     }
                 }
                 }
@@ -681,7 +675,7 @@ module BABYLON {
                 }
                 }
                 var buffer = this._vertexBuffers[kind].getBuffer();
                 var buffer = this._vertexBuffers[kind].getBuffer();
                 if (buffer) {
                 if (buffer) {
-                    buffer.references = numOfMeshes;
+                    buffer.references = numOfMeshes;
                 }
                 }
 
 
                 if (kind === VertexBuffer.PositionKind) {
                 if (kind === VertexBuffer.PositionKind) {
@@ -815,7 +809,7 @@ module BABYLON {
         /** @hidden */
         /** @hidden */
         public _generatePointsArray(): boolean {
         public _generatePointsArray(): boolean {
             if (this._positions) {
             if (this._positions) {
-                return true;
+                return true;
             }
             }
 
 
             var data = this.getVerticesData(VertexBuffer.PositionKind);
             var data = this.getVerticesData(VertexBuffer.PositionKind);

+ 7 - 2
src/Mesh/babylon.instancedMesh.ts

@@ -214,13 +214,18 @@ module BABYLON {
         }
         }
 
 
         /**
         /**
-         * Sets a new updated BoundingInfo to the mesh.
+         * reconstructs and updates the BoundingInfo of the mesh.
          * @returns the mesh.
          * @returns the mesh.
          */
          */
         public refreshBoundingInfo(): InstancedMesh {
         public refreshBoundingInfo(): InstancedMesh {
             var meshBB = this._sourceMesh.getBoundingInfo();
             var meshBB = this._sourceMesh.getBoundingInfo();
 
 
-            this._boundingInfo = new BoundingInfo(meshBB.minimum.clone(), meshBB.maximum.clone());
+            if (this._boundingInfo) {
+                this._boundingInfo.reConstruct(meshBB.minimum, meshBB.maximum);
+            }
+            else {
+                this._boundingInfo = new BoundingInfo(meshBB.minimum, meshBB.maximum);
+            }
 
 
             this._updateBoundingInfo();
             this._updateBoundingInfo();
             return this;
             return this;

+ 0 - 4
src/Mesh/babylon.linesMesh.ts

@@ -31,11 +31,7 @@ module BABYLON {
             if (this._intersectionThreshold === value) {
             if (this._intersectionThreshold === value) {
                 return;
                 return;
             }
             }
-
             this._intersectionThreshold = value;
             this._intersectionThreshold = value;
-            if (this.geometry) {
-                this.geometry.boundingBias = new Vector2(0, value);
-            }
         }
         }
 
 
         private _intersectionThreshold: number;
         private _intersectionThreshold: number;

+ 10 - 4
src/Mesh/babylon.mesh.ts

@@ -871,9 +871,10 @@ module BABYLON {
         /** @hidden */
         /** @hidden */
         public _registerInstanceForRenderId(instance: InstancedMesh, renderId: number): Mesh {
         public _registerInstanceForRenderId(instance: InstancedMesh, renderId: number): Mesh {
             if (!this._instanceDataStorage.visibleInstances) {
             if (!this._instanceDataStorage.visibleInstances) {
-                this._instanceDataStorage.visibleInstances = {};
-                this._instanceDataStorage.visibleInstances.defaultRenderId = renderId;
-                this._instanceDataStorage.visibleInstances.selfDefaultRenderId = this._renderId;
+                this._instanceDataStorage.visibleInstances = {
+                    defaultRenderId: renderId,
+                    selfDefaultRenderId: this._renderId
+                };
             }
             }
 
 
             if (!this._instanceDataStorage.visibleInstances[renderId]) {
             if (!this._instanceDataStorage.visibleInstances[renderId]) {
@@ -903,7 +904,12 @@ module BABYLON {
             if (data) {
             if (data) {
                 const bias = this.geometry ? this.geometry.boundingBias : null;
                 const bias = this.geometry ? this.geometry.boundingBias : null;
                 var extend = Tools.ExtractMinAndMax(data, 0, this.getTotalVertices(), bias);
                 var extend = Tools.ExtractMinAndMax(data, 0, this.getTotalVertices(), bias);
-                this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+                if (this._boundingInfo) {
+                    this._boundingInfo.reConstruct(extend.minimum, extend.maximum);
+                }
+                else {
+                    this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+                }
             }
             }
 
 
             if (this.subMeshes) {
             if (this.subMeshes) {

+ 9 - 3
src/Mesh/babylon.subMesh.ts

@@ -214,7 +214,13 @@ module BABYLON {
             } else {
             } else {
                 extend = Tools.ExtractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount, this._renderingMesh.geometry.boundingBias);
                 extend = Tools.ExtractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount, this._renderingMesh.geometry.boundingBias);
             }
             }
-            this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+
+            if (this._boundingInfo) {
+                this._boundingInfo.reConstruct(extend.minimum, extend.maximum);
+            }
+            else {
+                this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+            }
             return this;
             return this;
         }
         }
 
 
@@ -469,10 +475,10 @@ module BABYLON {
                 var vertexIndex = indices[index];
                 var vertexIndex = indices[index];
 
 
                 if (vertexIndex < minVertexIndex) {
                 if (vertexIndex < minVertexIndex) {
-                    minVertexIndex = vertexIndex;
+                    minVertexIndex = vertexIndex;
                 }
                 }
                 if (vertexIndex > maxVertexIndex) {
                 if (vertexIndex > maxVertexIndex) {
-                    maxVertexIndex = vertexIndex;
+                    maxVertexIndex = vertexIndex;
                 }
                 }
             }
             }
 
 

+ 1 - 1
src/Mesh/babylon.transformNode.ts

@@ -306,7 +306,7 @@ module BABYLON {
          * @param postMultiplyPivotMatrix defines if the pivot matrix must be cancelled in the world matrix. When this parameter is set to true (default), the inverse of the pivot matrix is also applied at the end to cancel the transformation effect
          * @param postMultiplyPivotMatrix defines if the pivot matrix must be cancelled in the world matrix. When this parameter is set to true (default), the inverse of the pivot matrix is also applied at the end to cancel the transformation effect
          * @returns the current TransformNode
          * @returns the current TransformNode
         */
         */
-        public setPivotMatrix(matrix: Matrix, postMultiplyPivotMatrix = true): TransformNode {
+        public setPivotMatrix(matrix: Readonly<Matrix>, postMultiplyPivotMatrix = true): TransformNode {
             this._pivotMatrix.copyFrom(matrix);
             this._pivotMatrix.copyFrom(matrix);
             this._cache.pivotMatrixUpdated = true;
             this._cache.pivotMatrixUpdated = true;
             this._postMultiplyPivotMatrix = postMultiplyPivotMatrix;
             this._postMultiplyPivotMatrix = postMultiplyPivotMatrix;

+ 21 - 19
src/PostProcess/babylon.motionBlurPostProcess.ts

@@ -29,7 +29,10 @@ module BABYLON {
          */
          */
         public set motionBlurSamples(samples: number) {
         public set motionBlurSamples(samples: number) {
             this._motionBlurSamples = samples;
             this._motionBlurSamples = samples;
-            this.updateEffect("#define SAMPLES " + samples.toFixed(1));
+
+            if (this._geometryBufferRenderer) {
+                this.updateEffect("#define GEOMETRY_SUPPORTED\n#define SAMPLES " + samples.toFixed(1));
+            }
         }
         }
 
 
         private _motionBlurSamples: number = 32;
         private _motionBlurSamples: number = 32;
@@ -48,31 +51,30 @@ module BABYLON {
          * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          */
          */
         constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
         constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
-            super(name, "motionBlur", ["motionStrength", "motionScale", "screenSize"], ["velocitySampler"], options, camera, samplingMode, engine, reusable, "#define SAMPLES 64.0", textureType, undefined, null, blockCompilation);
+            super(name, "motionBlur", ["motionStrength", "motionScale", "screenSize"], ["velocitySampler"], options, camera, samplingMode, engine, reusable, "#define GEOMETRY_SUPPORTED\n#define SAMPLES 64.0", textureType, undefined, null, blockCompilation);
 
 
             this._geometryBufferRenderer = scene.enableGeometryBufferRenderer();
             this._geometryBufferRenderer = scene.enableGeometryBufferRenderer();
 
 
-            if (this._geometryBufferRenderer) {
-                if (!this._geometryBufferRenderer.isSupported) {
-                    Tools.Warn("Multiple Render Target support needed to compute object based motion blur");
-                    this.dispose();
-                    return;
-                }
-
+            if (!this._geometryBufferRenderer) {
+                // Geometry buffer renderer is not supported. So, work as a passthrough.
+                Tools.Warn("Multiple Render Target support needed to compute object based motion blur");
+                this.updateEffect();
+            } else {
+                // Geometry buffer renderer is supported.
                 this._geometryBufferRenderer.enableVelocity = true;
                 this._geometryBufferRenderer.enableVelocity = true;
-            }
 
 
-            this.onApply = (effect: Effect) => {
-                effect.setVector2("screenSize", new Vector2(this.width, this.height));
+                this.onApply = (effect: Effect) => {
+                    effect.setVector2("screenSize", new Vector2(this.width, this.height));
 
 
-                effect.setFloat("motionScale", scene.getAnimationRatio());
-                effect.setFloat("motionStrength", this.motionStrength);
+                    effect.setFloat("motionScale", scene.getAnimationRatio());
+                    effect.setFloat("motionStrength", this.motionStrength);
 
 
-                if (this._geometryBufferRenderer) {
-                    const velocityIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE);
-                    effect.setTexture("velocitySampler", this._geometryBufferRenderer.getGBuffer().textures[velocityIndex]);
-                }
-            };
+                    if (this._geometryBufferRenderer) {
+                        const velocityIndex = this._geometryBufferRenderer.getTextureIndex(GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE);
+                        effect.setTexture("velocitySampler", this._geometryBufferRenderer.getGBuffer().textures[velocityIndex]);
+                    }
+                };
+            }
         }
         }
 
 
         /**
         /**

+ 51 - 49
src/Rendering/babylon.edgesRenderer.ts

@@ -62,6 +62,28 @@ module BABYLON {
         return this;
         return this;
     };
     };
 
 
+    export interface InstancedMesh {
+        /**
+         * Enables the edge rendering mode on the mesh.
+         * This mode makes the mesh edges visible
+         * @param epsilon defines the maximal distance between two angles to detect a face
+         * @param checkVerticesInsteadOfIndices indicates that we should check vertex list directly instead of faces
+         * @returns the currentInstancedMesh
+         * @see https://www.babylonjs-playground.com/#19O9TU#0
+         */
+        enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean): InstancedMesh;
+    }
+
+    InstancedMesh.prototype.enableEdgesRendering = function(epsilon = 0.95, checkVerticesInsteadOfIndices = false): InstancedMesh {
+        if (this.sourceMesh.getClassName() === 'LinesMesh') {
+            LinesMesh.prototype.enableEdgesRendering.apply(this, arguments);
+        }
+        else {
+            AbstractMesh.prototype.enableEdgesRendering.apply(this, arguments);
+        }
+        return this;
+    };
+
     /**
     /**
      * FaceAdjacencies Helper class to generate edges
      * FaceAdjacencies Helper class to generate edges
      */
      */
@@ -262,59 +284,39 @@ module BABYLON {
             }
             }
 
 
             if (needToCreateLine) {
             if (needToCreateLine) {
-                var offset = this._linesPositions.length / 3;
-                var normal = p0.subtract(p1);
-                normal.normalize();
-
-                // Positions
-                this._linesPositions.push(p0.x);
-                this._linesPositions.push(p0.y);
-                this._linesPositions.push(p0.z);
-
-                this._linesPositions.push(p0.x);
-                this._linesPositions.push(p0.y);
-                this._linesPositions.push(p0.z);
-
-                this._linesPositions.push(p1.x);
-                this._linesPositions.push(p1.y);
-                this._linesPositions.push(p1.z);
-
-                this._linesPositions.push(p1.x);
-                this._linesPositions.push(p1.y);
-                this._linesPositions.push(p1.z);
-
-                // Normals
-                this._linesNormals.push(p1.x);
-                this._linesNormals.push(p1.y);
-                this._linesNormals.push(p1.z);
-                this._linesNormals.push(-1);
-
-                this._linesNormals.push(p1.x);
-                this._linesNormals.push(p1.y);
-                this._linesNormals.push(p1.z);
-                this._linesNormals.push(1);
-
-                this._linesNormals.push(p0.x);
-                this._linesNormals.push(p0.y);
-                this._linesNormals.push(p0.z);
-                this._linesNormals.push(-1);
-
-                this._linesNormals.push(p0.x);
-                this._linesNormals.push(p0.y);
-                this._linesNormals.push(p0.z);
-                this._linesNormals.push(1);
-
-                // Indices
-                this._linesIndices.push(offset);
-                this._linesIndices.push(offset + 1);
-                this._linesIndices.push(offset + 2);
-                this._linesIndices.push(offset);
-                this._linesIndices.push(offset + 2);
-                this._linesIndices.push(offset + 3);
+                this.createLine(p0, p1, this._linesPositions.length / 3);
             }
             }
         }
         }
 
 
         /**
         /**
+         * push line into the position, normal and index buffer
+         * @protected
+         */
+        protected createLine(p0: Vector3, p1: Vector3, offset: number) {
+            // Positions
+            this._linesPositions.push(
+                p0.x, p0.y, p0.z,
+                p0.x, p0.y, p0.z,
+                p1.x, p1.y, p1.z,
+                p1.x, p1.y, p1.z
+            );
+
+            // Normals
+            this._linesNormals.push(
+                p1.x, p1.y, p1.z, -1,
+                p1.x, p1.y, p1.z, 1,
+                p0.x, p0.y, p0.z, -1,
+                p0.x, p0.y, p0.z, 1
+            );
+
+            // Indices
+            this._linesIndices.push(
+                offset, offset + 1, offset + 2,
+                offset, offset + 2, offset + 3
+            );
+        }
+
+        /**
          * Generates lines edges from adjacencjes
          * Generates lines edges from adjacencjes
          * @private
          * @private
          */
          */

+ 7 - 85
src/Rendering/babylon.lineEdgesRenderer.ts

@@ -1,15 +1,5 @@
 module BABYLON {
 module BABYLON {
     /**
     /**
-     * FaceAdjacencies Helper class to generate edges
-     */
-    class FaceAdjacencies {
-        public edges = new Array<number>();
-        public p0: Vector3;
-        public p1: Vector3;
-        public edgesConnectedCount = 0;
-    }
-
-    /**
      * LineEdgesRenderer for LineMeshes to remove unnecessary triangulation
      * LineEdgesRenderer for LineMeshes to remove unnecessary triangulation
      */
      */
     export class LineEdgesRenderer extends EdgesRenderer {
     export class LineEdgesRenderer extends EdgesRenderer {
@@ -26,66 +16,6 @@ module BABYLON {
         }
         }
 
 
         /**
         /**
-         * Always create the edge since its a line so only important things are p0 and p1
-         * @param  faceIndex not important for LineMesh
-         * @param  edge not important for LineMesh
-         * @param  faceNormals not important for LineMesh
-         * @param  p0 beginnig of line
-         * @param  p1 end of line
-         */
-        protected _checkEdge(faceIndex: number, edge: number, faceNormals: Array<Vector3>, p0: Vector3, p1: Vector3): void {
-                var offset = this._linesPositions.length / 3;
-                var normal = p0.subtract(p1);
-                normal.normalize();
-
-                // Positions
-                this._linesPositions.push(p0.x);
-                this._linesPositions.push(p0.y);
-                this._linesPositions.push(p0.z);
-
-                this._linesPositions.push(p0.x);
-                this._linesPositions.push(p0.y);
-                this._linesPositions.push(p0.z);
-
-                this._linesPositions.push(p1.x);
-                this._linesPositions.push(p1.y);
-                this._linesPositions.push(p1.z);
-
-                this._linesPositions.push(p1.x);
-                this._linesPositions.push(p1.y);
-                this._linesPositions.push(p1.z);
-
-                // Normals
-                this._linesNormals.push(p1.x);
-                this._linesNormals.push(p1.y);
-                this._linesNormals.push(p1.z);
-                this._linesNormals.push(-1);
-
-                this._linesNormals.push(p1.x);
-                this._linesNormals.push(p1.y);
-                this._linesNormals.push(p1.z);
-                this._linesNormals.push(1);
-
-                this._linesNormals.push(p0.x);
-                this._linesNormals.push(p0.y);
-                this._linesNormals.push(p0.z);
-                this._linesNormals.push(-1);
-
-                this._linesNormals.push(p0.x);
-                this._linesNormals.push(p0.y);
-                this._linesNormals.push(p0.z);
-                this._linesNormals.push(1);
-
-                // Indices
-                this._linesIndices.push(offset);
-                this._linesIndices.push(offset + 1);
-                this._linesIndices.push(offset + 2);
-                this._linesIndices.push(offset);
-                this._linesIndices.push(offset + 2);
-                this._linesIndices.push(offset + 3);
-        }
-
-        /**
          * Generate edges for each line in LinesMesh. Every Line should be rendered as edge.
          * Generate edges for each line in LinesMesh. Every Line should be rendered as edge.
          */
          */
         _generateEdgesLines(): void {
         _generateEdgesLines(): void {
@@ -96,21 +26,13 @@ module BABYLON {
                 return;
                 return;
             }
             }
 
 
-            // First let's find adjacencies
-            var adjacencies = new Array<FaceAdjacencies>();
-            var faceNormals = new Array<Vector3>();
-            var index: number;
-            for (let i = 0; i < (positions.length / 3) - 1 ; i++) {
-                const currentAdjecancy  = new FaceAdjacencies();
-                currentAdjecancy.p0 = new Vector3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
-                currentAdjecancy.p1 = new Vector3(positions[(i + 1) * 3], positions[(i + 1) * 3 + 1], positions[(i + 1) * 3 + 2]);
-                adjacencies.push(currentAdjecancy);
-            }
-            // Create lines
-            for (index = 0; index < adjacencies.length; index++) {
-                // We need a line when a face has no adjacency on a specific edge or if all the adjacencies has an angle greater than epsilon
-                var current = adjacencies[index];
-                this._checkEdge(index, current.edges[0], faceNormals, current.p0, current.p1);
+            const p0 = Tmp.Vector3[0];
+            const p1 = Tmp.Vector3[1];
+            const len = indices.length - 1;
+            for (let i = 0, offset = 0; i < len; i += 2, offset += 4) {
+                Vector3.FromArrayToRef(positions, 3 * indices[i], p0);
+                Vector3.FromArrayToRef(positions, 3 * indices[i + 1], p1);
+                this.createLine(p0, p1, offset);
             }
             }
 
 
             // Merge into a single mesh
             // Merge into a single mesh

+ 4 - 1
src/Shaders/motionBlur.fragment.fx

@@ -10,6 +10,7 @@ uniform vec2 screenSize;
 
 
 void main(void)
 void main(void)
 {
 {
+    #ifdef GEOMETRY_SUPPORTED
     vec2 texelSize = 1.0 / screenSize;
     vec2 texelSize = 1.0 / screenSize;
     vec2 velocityColor = texture2D(velocitySampler, vUV).rg;
     vec2 velocityColor = texture2D(velocitySampler, vUV).rg;
 	
 	
@@ -33,6 +34,8 @@ void main(void)
         result += texture2D(textureSampler, offset);
         result += texture2D(textureSampler, offset);
     }
     }
 
 
-	//gl_FragColor = vec4(velocityColor, 0.0, 1.0);
 	gl_FragColor = result / float(samplesCount);
 	gl_FragColor = result / float(samplesCount);
+    #else
+    gl_FragColor = texture2D(textureSampler, vUV);
+    #endif
 }
 }

+ 10 - 4
src/babylon.scene.ts

@@ -1883,6 +1883,9 @@ module BABYLON {
                         checkPicking = act.hasPickTriggers;
                         checkPicking = act.hasPickTriggers;
                     }
                     }
                 }
                 }
+
+                let needToIgnoreNext = false;
+
                 if (checkPicking) {
                 if (checkPicking) {
                     let btn = evt.button;
                     let btn = evt.button;
                     clickInfo.hasSwiped = this._isPointerSwiping();
                     clickInfo.hasSwiped = this._isPointerSwiping();
@@ -1908,6 +1911,7 @@ module BABYLON {
                                 btn !== this._previousButtonPressed) {
                                 btn !== this._previousButtonPressed) {
                                 clickInfo.singleClick = true;
                                 clickInfo.singleClick = true;
                                 cb(clickInfo, this._currentPickResult);
                                 cb(clickInfo, this._currentPickResult);
+                                needToIgnoreNext = true;
                             }
                             }
                         }
                         }
                         // at least one double click is required to be check and exclusive double click is enabled
                         // at least one double click is required to be check and exclusive double click is enabled
@@ -1963,6 +1967,7 @@ module BABYLON {
                                         cb(clickInfo, this._currentPickResult);
                                         cb(clickInfo, this._currentPickResult);
                                     }
                                     }
                                 }
                                 }
+                                needToIgnoreNext = true;
                             }
                             }
                             // just the first click of the double has been raised
                             // just the first click of the double has been raised
                             else {
                             else {
@@ -1976,7 +1981,7 @@ module BABYLON {
                     }
                     }
                 }
                 }
 
 
-                clickInfo.ignore = true;
+                clickInfo.ignore = needToIgnoreNext;
                 cb(clickInfo, this._currentPickResult);
                 cb(clickInfo, this._currentPickResult);
             };
             };
 
 
@@ -2015,6 +2020,10 @@ module BABYLON {
                     canvas.focus();
                     canvas.focus();
                 }
                 }
 
 
+                this._startingPointerPosition.x = this._pointerX;
+                this._startingPointerPosition.y = this._pointerY;
+                this._startingPointerTime = Date.now();
+
                 // PreObservable support
                 // PreObservable support
                 if (this._checkPrePointerObservable(null, evt, PointerEventTypes.POINTERDOWN)) {
                 if (this._checkPrePointerObservable(null, evt, PointerEventTypes.POINTERDOWN)) {
                     return;
                     return;
@@ -2025,9 +2034,6 @@ module BABYLON {
                 }
                 }
 
 
                 this._pointerCaptures[evt.pointerId] = true;
                 this._pointerCaptures[evt.pointerId] = true;
-                this._startingPointerPosition.x = this._pointerX;
-                this._startingPointerPosition.y = this._pointerY;
-                this._startingPointerTime = Date.now();
 
 
                 if (!this.pointerDownPredicate) {
                 if (!this.pointerDownPredicate) {
                     this.pointerDownPredicate = (mesh: AbstractMesh): boolean => {
                     this.pointerDownPredicate = (mesh: AbstractMesh): boolean => {

BIN
tests/validation/ReferenceImages/LineEdgesRenderer.png


+ 6 - 0
tests/validation/config.json

@@ -2,6 +2,12 @@
   "root": "https://rawgit.com/BabylonJS/Website/master",
   "root": "https://rawgit.com/BabylonJS/Website/master",
   "tests": [
   "tests": [
     {
     {
+      "title": "LineEdgesRenderer",
+      "playgroundId": "#T90MQ4#1",
+      "renderCount": 50,
+      "referenceImage": "LineEdgesRenderer.png"
+    },
+    {
       "title": "Solid particle system",
       "title": "Solid particle system",
       "playgroundId": "#WCDZS#92",
       "playgroundId": "#WCDZS#92",
       "renderCount": 150,
       "renderCount": 150,