Browse Source

Fixing LinesMesh cloning

David catuhe 10 năm trước cách đây
mục cha
commit
2931ae3e7c
35 tập tin đã thay đổi với 1846 bổ sung1769 xóa
  1. 1598 1589
      dist/preview release - beta/babylon.2.2.d.ts
  2. 34 27
      dist/preview release - beta/babylon.2.2.js
  3. 70 34
      dist/preview release - beta/babylon.2.2.max.js
  4. 33 26
      dist/preview release - beta/babylon.2.2.noworker.js
  5. 0 1
      src/Cameras/VR/babylon.vrDeviceOrientationCamera.js
  6. 0 1
      src/Cameras/VR/babylon.webVRCamera.js
  7. 0 1
      src/Culling/Octrees/babylon.octree.js
  8. 0 1
      src/Culling/Octrees/babylon.octreeBlock.js
  9. 0 1
      src/Lights/Shadows/babylon.shadowGenerator.js
  10. 0 1
      src/Loading/Plugins/babylon.babylonFileLoader.js
  11. 0 1
      src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js
  12. 0 1
      src/Materials/Textures/Procedurals/babylon.proceduralTexture.js
  13. 0 1
      src/Materials/Textures/Procedurals/babylon.standardProceduralTexture.js
  14. 0 1
      src/Materials/Textures/babylon.baseTexture.js
  15. 0 1
      src/Materials/Textures/babylon.cubeTexture.js
  16. 0 1
      src/Materials/Textures/babylon.dynamicTexture.js
  17. 0 1
      src/Materials/Textures/babylon.mirrorTexture.js
  18. 0 1
      src/Materials/Textures/babylon.rawTexture.js
  19. 0 1
      src/Materials/Textures/babylon.renderTargetTexture.js
  20. 0 1
      src/Materials/Textures/babylon.texture.js
  21. 0 1
      src/Materials/Textures/babylon.videoTexture.js
  22. 37 8
      src/Math/babylon.math.js
  23. 6 5
      src/Math/babylon.math.ts
  24. 6 4
      src/Mesh/babylon.linesMesh.js
  25. 6 6
      src/Mesh/babylon.linesMesh.ts
  26. 2 2
      src/Mesh/babylon.mesh.js
  27. 2 2
      src/Mesh/babylon.mesh.ts
  28. 0 1
      src/Physics/Plugins/babylon.cannonJSPlugin.js
  29. 0 1
      src/Physics/Plugins/babylon.oimoJSPlugin.js
  30. 0 1
      src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js
  31. 0 1
      src/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js
  32. 0 1
      src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js
  33. 0 1
      src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js
  34. 24 19
      src/Tools/babylon.tools.js
  35. 28 24
      src/Tools/babylon.tools.ts

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1598 - 1589
dist/preview release - beta/babylon.2.2.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 34 - 27
dist/preview release - beta/babylon.2.2.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 70 - 34
dist/preview release - beta/babylon.2.2.max.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 33 - 26
dist/preview release - beta/babylon.2.2.noworker.js


+ 0 - 1
src/Cameras/VR/babylon.vrDeviceOrientationCamera.js

@@ -46,4 +46,3 @@ var BABYLON;
     })(BABYLON.FreeCamera);
     BABYLON.VRDeviceOrientationFreeCamera = VRDeviceOrientationFreeCamera;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.vrDeviceOrientationCamera.js.map

+ 0 - 1
src/Cameras/VR/babylon.webVRCamera.js

@@ -72,4 +72,3 @@ var BABYLON;
     })(BABYLON.FreeCamera);
     BABYLON.WebVRFreeCamera = WebVRFreeCamera;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.webVRCamera.js.map

+ 0 - 1
src/Culling/Octrees/babylon.octree.js

@@ -86,4 +86,3 @@ var BABYLON;
     })();
     BABYLON.Octree = Octree;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.octree.js.map

+ 0 - 1
src/Culling/Octrees/babylon.octreeBlock.js

@@ -120,4 +120,3 @@ var BABYLON;
     })();
     BABYLON.OctreeBlock = OctreeBlock;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.octreeBlock.js.map

+ 0 - 1
src/Lights/Shadows/babylon.shadowGenerator.js

@@ -333,4 +333,3 @@ var BABYLON;
     })();
     BABYLON.ShadowGenerator = ShadowGenerator;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.shadowGenerator.js.map

+ 0 - 1
src/Loading/Plugins/babylon.babylonFileLoader.js

@@ -1427,4 +1427,3 @@ var BABYLON;
         });
     })(Internals = BABYLON.Internals || (BABYLON.Internals = {}));
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.babylonFileLoader.js.map

+ 0 - 1
src/Materials/Textures/Procedurals/babylon.customProceduralTexture.js

@@ -123,4 +123,3 @@ var BABYLON;
     })(BABYLON.ProceduralTexture);
     BABYLON.CustomProceduralTexture = CustomProceduralTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.customProceduralTexture.js.map

+ 0 - 1
src/Materials/Textures/Procedurals/babylon.proceduralTexture.js

@@ -248,4 +248,3 @@ var BABYLON;
     })(BABYLON.Texture);
     BABYLON.ProceduralTexture = ProceduralTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.proceduralTexture.js.map

+ 0 - 1
src/Materials/Textures/Procedurals/babylon.standardProceduralTexture.js

@@ -418,4 +418,3 @@ var BABYLON;
     })(BABYLON.ProceduralTexture);
     BABYLON.MarbleProceduralTexture = MarbleProceduralTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.standardProceduralTexture.js.map

+ 0 - 1
src/Materials/Textures/babylon.baseTexture.js

@@ -125,4 +125,3 @@ var BABYLON;
     })();
     BABYLON.BaseTexture = BaseTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.baseTexture.js.map

+ 0 - 1
src/Materials/Textures/babylon.cubeTexture.js

@@ -59,4 +59,3 @@ var BABYLON;
     })(BABYLON.BaseTexture);
     BABYLON.CubeTexture = CubeTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.cubeTexture.js.map

+ 0 - 1
src/Materials/Textures/babylon.dynamicTexture.js

@@ -92,4 +92,3 @@ var BABYLON;
     })(BABYLON.Texture);
     BABYLON.DynamicTexture = DynamicTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.dynamicTexture.js.map

+ 0 - 1
src/Materials/Textures/babylon.mirrorTexture.js

@@ -43,4 +43,3 @@ var BABYLON;
     })(BABYLON.RenderTargetTexture);
     BABYLON.MirrorTexture = MirrorTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.mirrorTexture.js.map

+ 0 - 1
src/Materials/Textures/babylon.rawTexture.js

@@ -56,4 +56,3 @@ var BABYLON;
     })(BABYLON.Texture);
     BABYLON.RawTexture = RawTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.rawTexture.js.map

+ 0 - 1
src/Materials/Textures/babylon.renderTargetTexture.js

@@ -165,4 +165,3 @@ var BABYLON;
     })(BABYLON.Texture);
     BABYLON.RenderTargetTexture = RenderTargetTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.renderTargetTexture.js.map

+ 0 - 1
src/Materials/Textures/babylon.texture.js

@@ -212,4 +212,3 @@ var BABYLON;
     })(BABYLON.BaseTexture);
     BABYLON.Texture = Texture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.texture.js.map

+ 0 - 1
src/Materials/Textures/babylon.videoTexture.js

@@ -57,4 +57,3 @@ var BABYLON;
     })(BABYLON.Texture);
     BABYLON.VideoTexture = VideoTexture;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.videoTexture.js.map

+ 37 - 8
src/Math/babylon.math.js

@@ -835,6 +835,14 @@ var BABYLON;
          * to something in order to rotate it from its local system to the given target system.
          */
         Vector3.RotationFromAxis = function (axis1, axis2, axis3) {
+            var rotation = Vector3.Zero();
+            Vector3.RotationFromAxisToRef(axis1, axis2, axis3, rotation);
+            return rotation;
+        };
+        /**
+         * The same than RotationFromAxis but updates the passed ref Vector3 parameter.
+         */
+        Vector3.RotationFromAxisToRef = function (axis1, axis2, axis3, ref) {
             var u = Vector3.Normalize(axis1);
             var w = Vector3.Normalize(axis3);
             // world axis
@@ -935,7 +943,9 @@ var BABYLON;
             if (dot < 0 && nbRevert < 2) {
                 yaw = Math.PI + yaw;
             }
-            return new Vector3(pitch, yaw, roll);
+            ref.x = pitch;
+            ref.y = yaw;
+            ref.z = roll;
         };
         return Vector3;
     })();
@@ -2815,7 +2825,13 @@ var BABYLON;
     })();
     BABYLON.Path2 = Path2;
     var Path3D = (function () {
-        function Path3D(path, firstNormal) {
+        /**
+        * new Path3D(path, normal, raw)
+        * path : an array of Vector3, the curve axis of the Path3D
+        * normal (optional) : Vector3, the first wanted normal to the curve. Ex (0, 1, 0) for a vertical normal.
+        * raw (optional, default false) : boolean, if true the returned Path3D isn't normalized. Useful to depict path acceleration or speed.
+        */
+        function Path3D(path, firstNormal, raw) {
             this.path = path;
             this._curve = new Array();
             this._distances = new Array();
@@ -2825,6 +2841,7 @@ var BABYLON;
             for (var p = 0; p < path.length; p++) {
                 this._curve[p] = path[p].clone(); // hard copy
             }
+            this._raw = raw || false;
             this._compute(firstNormal);
         }
         Path3D.prototype.getCurve = function () {
@@ -2856,16 +2873,24 @@ var BABYLON;
             var l = this._curve.length;
             // first and last tangents
             this._tangents[0] = this._getFirstNonNullVector(0);
-            this._tangents[0].normalize();
+            if (!this._raw) {
+                this._tangents[0].normalize();
+            }
             this._tangents[l - 1] = this._curve[l - 1].subtract(this._curve[l - 2]);
-            this._tangents[l - 1].normalize();
+            if (!this._raw) {
+                this._tangents[l - 1].normalize();
+            }
             // normals and binormals at first point : arbitrary vector with _normalVector()
             var tg0 = this._tangents[0];
             var pp0 = this._normalVector(this._curve[0], tg0, firstNormal);
             this._normals[0] = pp0;
-            this._normals[0].normalize();
+            if (!this._raw) {
+                this._normals[0].normalize();
+            }
             this._binormals[0] = Vector3.Cross(tg0, this._normals[0]);
-            this._binormals[0].normalize();
+            if (!this._raw) {
+                this._binormals[0].normalize();
+            }
             this._distances[0] = 0;
             // normals and binormals : next points
             var prev; // previous vector (segment)
@@ -2887,9 +2912,13 @@ var BABYLON;
                 curTang = this._tangents[i];
                 prevBinor = this._binormals[i - 1];
                 this._normals[i] = Vector3.Cross(prevBinor, curTang);
-                this._normals[i].normalize();
+                if (!this._raw) {
+                    this._normals[i].normalize();
+                }
                 this._binormals[i] = Vector3.Cross(curTang, this._normals[i]);
-                this._binormals[i].normalize();
+                if (!this._raw) {
+                    this._binormals[i].normalize();
+                }
             }
         };
         // private function getFirstNonNullVector(index)

+ 6 - 5
src/Math/babylon.math.ts

@@ -1094,10 +1094,10 @@
             // Rv3(w) = w1 = w invariant
             var u1: Vector3;
             var v1: Vector3;
-            if (Tools.WithinEpsilon(w.z, 0, Engine.Epsilon)) { 
+            if (Tools.WithinEpsilon(w.z, 0, Engine.Epsilon)) {
                 z = 1.0;
             }
-            else if (Tools.WithinEpsilon(w.x, 0, Engine.Epsilon)) { 
+            else if (Tools.WithinEpsilon(w.x, 0, Engine.Epsilon)) {
                 x = 1.0;
             }
             else {
@@ -1136,7 +1136,7 @@
             y = 0.0;
             z = 0.0;
             sign = -1;
-            if (Tools.WithinEpsilon(w.z, 0, Engine.Epsilon)) { 
+            if (Tools.WithinEpsilon(w.z, 0, Engine.Epsilon)) {
                 x = 1.0;
             }
             else {
@@ -3664,10 +3664,10 @@
                 if (!Tools.WithinEpsilon(vt.y, 1, Engine.Epsilon)) {     // search for a point in the plane 
                     point = new Vector3(0, -1, 0);
                 }
-                else if (!Tools.WithinEpsilon(vt.x, 1, Engine.Epsilon)) { 
+                else if (!Tools.WithinEpsilon(vt.x, 1, Engine.Epsilon)) {
                     point = new Vector3(1, 0, 0);
                 }
-                else if (!Tools.WithinEpsilon(vt.z, 1, Engine.Epsilon)) { 
+                else if (!Tools.WithinEpsilon(vt.z, 1, Engine.Epsilon)) {
                     point = new Vector3(0, 0, 1);
                 }
                 normal0 = Vector3.Cross(vt, point);
@@ -3843,3 +3843,4 @@
         }
     }
 }
+

+ 6 - 4
src/Mesh/babylon.linesMesh.js

@@ -8,12 +8,11 @@ var BABYLON;
 (function (BABYLON) {
     var LinesMesh = (function (_super) {
         __extends(LinesMesh, _super);
-        function LinesMesh(name, scene, updatable) {
-            if (updatable === void 0) { updatable = false; }
-            _super.call(this, name, scene);
+        function LinesMesh(name, scene, parent, source, doNotCloneChildren) {
+            if (parent === void 0) { parent = null; }
+            _super.call(this, name, scene, parent, source, doNotCloneChildren);
             this.color = new BABYLON.Color3(1, 1, 1);
             this.alpha = 1;
-            this._indices = new Array();
             this._colorShader = new BABYLON.ShaderMaterial("colorShader", scene, "color", {
                 attributes: ["position"],
                 uniforms: ["worldViewProjection", "color"],
@@ -64,6 +63,9 @@ var BABYLON;
             this._colorShader.dispose();
             _super.prototype.dispose.call(this, doNotRecurse);
         };
+        LinesMesh.prototype.clone = function (name, newParent, doNotCloneChildren) {
+            return new LinesMesh(name, this.getScene(), newParent, this, doNotCloneChildren);
+        };
         return LinesMesh;
     })(BABYLON.Mesh);
     BABYLON.LinesMesh = LinesMesh;

+ 6 - 6
src/Mesh/babylon.linesMesh.ts

@@ -4,13 +4,9 @@
         public alpha = 1;
 
         private _colorShader: ShaderMaterial;
-        private _ib: WebGLBuffer;
 
-        private _indicesLength: number;
-        private _indices = new Array<number>();
-
-        constructor(name: string, scene: Scene, updatable = false) {
-            super(name, scene);
+        constructor(name: string, scene: Scene, parent: Node = null, source?: Mesh, doNotCloneChildren?: boolean) {
+            super(name, scene, parent, source, doNotCloneChildren);
 
             this._colorShader = new ShaderMaterial("colorShader", scene, "color",
                 {
@@ -64,5 +60,9 @@
 
             super.dispose(doNotRecurse);
         }
+
+        public clone(name: string, newParent?: Node, doNotCloneChildren?: boolean): LinesMesh {
+            return new LinesMesh(name, this.getScene(), newParent, this, doNotCloneChildren);
+        }
     }
 } 

+ 2 - 2
src/Mesh/babylon.mesh.js

@@ -1223,7 +1223,7 @@ var BABYLON;
                 return linesInstance;
             }
             // lines creation
-            var lines = new BABYLON.LinesMesh(name, scene, updatable);
+            var lines = new BABYLON.LinesMesh(name, scene);
             var vertexData = BABYLON.VertexData.CreateLines(points);
             vertexData.applyToMesh(lines, updatable);
             return lines;
@@ -1277,7 +1277,7 @@ var BABYLON;
                 return linesInstance;
             }
             // dashed lines creation
-            var dashedLines = new BABYLON.LinesMesh(name, scene, updatable);
+            var dashedLines = new BABYLON.LinesMesh(name, scene);
             var vertexData = BABYLON.VertexData.CreateDashedLines(points, dashSize, gapSize, dashNb);
             vertexData.applyToMesh(dashedLines, updatable);
             dashedLines.dashSize = dashSize;

+ 2 - 2
src/Mesh/babylon.mesh.ts

@@ -1430,7 +1430,7 @@
             }
 
             // lines creation
-            var lines = new LinesMesh(name, scene, updatable);
+            var lines = new LinesMesh(name, scene);
             var vertexData = VertexData.CreateLines(points);
             vertexData.applyToMesh(lines, updatable);
             return lines;
@@ -1484,7 +1484,7 @@
                 return linesInstance;
             }
             // dashed lines creation
-            var dashedLines = new LinesMesh(name, scene, updatable);
+            var dashedLines = new LinesMesh(name, scene);
             var vertexData = VertexData.CreateDashedLines(points, dashSize, gapSize, dashNb);
             vertexData.applyToMesh(dashedLines, updatable);
             (<any>dashedLines).dashSize = dashSize;

+ 0 - 1
src/Physics/Plugins/babylon.cannonJSPlugin.js

@@ -251,4 +251,3 @@ var BABYLON;
     })();
     BABYLON.CannonJSPlugin = CannonJSPlugin;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.cannonJSPlugin.js.map

+ 0 - 1
src/Physics/Plugins/babylon.oimoJSPlugin.js

@@ -314,4 +314,3 @@ var BABYLON;
     })();
     BABYLON.OimoJSPlugin = OimoJSPlugin;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.oimoJSPlugin.js.map

+ 0 - 1
src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js

@@ -138,4 +138,3 @@ var BABYLON;
     })();
     BABYLON.PostProcessRenderEffect = PostProcessRenderEffect;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.postProcessRenderEffect.js.map

+ 0 - 1
src/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js

@@ -40,4 +40,3 @@ var BABYLON;
     })();
     BABYLON.PostProcessRenderPass = PostProcessRenderPass;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.postProcessRenderPass.js.map

+ 0 - 1
src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js

@@ -110,4 +110,3 @@ var BABYLON;
     })();
     BABYLON.PostProcessRenderPipeline = PostProcessRenderPipeline;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.postProcessRenderPipeline.js.map

+ 0 - 1
src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js

@@ -58,4 +58,3 @@ var BABYLON;
     })();
     BABYLON.PostProcessRenderPipelineManager = PostProcessRenderPipelineManager;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.postProcessRenderPipelineManager.js.map

+ 24 - 19
src/Tools/babylon.tools.js

@@ -385,7 +385,7 @@ var BABYLON;
                 }
             }
         };
-        Tools.DumpFramebuffer = function (width, height, engine) {
+        Tools.DumpFramebuffer = function (width, height, engine, successCallback) {
             // Read the contents of the framebuffer
             var numberOfChannelsByLine = width * 4;
             var halfHeight = height / 2;
@@ -416,27 +416,32 @@ var BABYLON;
             castData.set(data);
             context.putImageData(imageData, 0, 0);
             var base64Image = screenshotCanvas.toDataURL();
-            //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.
-            if (("download" in document.createElement("a"))) {
-                var a = window.document.createElement("a");
-                a.href = base64Image;
-                var date = new Date();
-                var stringDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
-                a.setAttribute("download", "screenshot_" + stringDate + ".png");
-                window.document.body.appendChild(a);
-                a.addEventListener("click", function () {
-                    a.parentElement.removeChild(a);
-                });
-                a.click();
+            if (successCallback) {
+                successCallback(base64Image);
             }
             else {
-                var newWindow = window.open("");
-                var img = newWindow.document.createElement("img");
-                img.src = base64Image;
-                newWindow.document.body.appendChild(img);
+                //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.
+                if (("download" in document.createElement("a"))) {
+                    var a = window.document.createElement("a");
+                    a.href = base64Image;
+                    var date = new Date();
+                    var stringDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
+                    a.setAttribute("download", "screenshot_" + stringDate + ".png");
+                    window.document.body.appendChild(a);
+                    a.addEventListener("click", function () {
+                        a.parentElement.removeChild(a);
+                    });
+                    a.click();
+                }
+                else {
+                    var newWindow = window.open("");
+                    var img = newWindow.document.createElement("img");
+                    img.src = base64Image;
+                    newWindow.document.body.appendChild(img);
+                }
             }
         };
-        Tools.CreateScreenshot = function (engine, camera, size) {
+        Tools.CreateScreenshot = function (engine, camera, size, successCallback) {
             var width;
             var height;
             var scene = camera.getScene();
@@ -477,7 +482,7 @@ var BABYLON;
             var texture = new BABYLON.RenderTargetTexture("screenShot", size, scene, false, false);
             texture.renderList = scene.meshes;
             texture.onAfterRender = function () {
-                Tools.DumpFramebuffer(width, height, engine);
+                Tools.DumpFramebuffer(width, height, engine, successCallback);
             };
             scene.incrementRenderId();
             texture.render(true);

+ 28 - 24
src/Tools/babylon.tools.ts

@@ -462,7 +462,7 @@
             }
         }
 
-        public static DumpFramebuffer(width: number, height: number, engine: Engine): void {
+        public static DumpFramebuffer(width: number, height: number, engine: Engine, successCallback?: (data: String) => void): void {
             // Read the contents of the framebuffer
             var numberOfChannelsByLine = width * 4;
             var halfHeight = height / 2;
@@ -500,31 +500,35 @@
 
             var base64Image = screenshotCanvas.toDataURL();
 
-            //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.
-            if (("download" in document.createElement("a"))) {
-                var a = window.document.createElement("a");
-                a.href = base64Image;
-                var date = new Date();
-                var stringDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
-                a.setAttribute("download", "screenshot_" + stringDate + ".png");
-
-                window.document.body.appendChild(a);
-
-                a.addEventListener("click", () => {
-                    a.parentElement.removeChild(a);
-                });
-                a.click();
-
-                //Or opening a new tab with the image if it is not possible to automatically start download.
+            if (successCallback) {
+                successCallback(base64Image);
             } else {
-                var newWindow = window.open("");
-                var img = newWindow.document.createElement("img");
-                img.src = base64Image;
-                newWindow.document.body.appendChild(img);
+                //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.
+                if (("download" in document.createElement("a"))) {
+                    var a = window.document.createElement("a");
+                    a.href = base64Image;
+                    var date = new Date();
+                    var stringDate = date.getFullYear() + "-" + date.getMonth() + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
+                    a.setAttribute("download", "screenshot_" + stringDate + ".png");
+
+                    window.document.body.appendChild(a);
+
+                    a.addEventListener("click", () => {
+                        a.parentElement.removeChild(a);
+                    });
+                    a.click();
+
+                    //Or opening a new tab with the image if it is not possible to automatically start download.
+                } else {
+                    var newWindow = window.open("");
+                    var img = newWindow.document.createElement("img");
+                    img.src = base64Image;
+                    newWindow.document.body.appendChild(img);
+                }
             }
         }
 
-        public static CreateScreenshot(engine: Engine, camera: Camera, size: any): void {
+        public static CreateScreenshot(engine: Engine, camera: Camera, size: any, successCallback?: (data: String) => void): void {
             var width: number;
             var height: number;
 
@@ -573,7 +577,7 @@
             texture.renderList = scene.meshes;
 
             texture.onAfterRender = () => {
-                Tools.DumpFramebuffer(width, height, engine);
+                Tools.DumpFramebuffer(width, height, engine, successCallback);
             };
 
             scene.incrementRenderId();
@@ -929,4 +933,4 @@
             }, callback);
         }
     }
-} 
+}