Просмотр исходного кода

Validating math.ts updates for Polygon

David Catuhe 10 лет назад
Родитель
Сommit
e29c466400

+ 1 - 1
Babylon/Audio/babylon.audioengine.ts

@@ -5,7 +5,7 @@
         public masterGain: GainNode;
 
         constructor() {
-             // creating the audio context 
+            // creating the audio context 
             try {
                 if (typeof AudioContext !== 'undefined') {
                     this.audioContext = new AudioContext();

+ 57 - 30
Babylon/Audio/babylon.sound.js

@@ -10,10 +10,13 @@
         */
         function Sound(name, url, scene, readyToPlayCallback, options) {
             var _this = this;
-            this.maxDistance = 20;
             this.autoplay = false;
             this.loop = false;
-            this.useBabylonJSAttenuation = true;
+            this.useCustomAttenuation = false;
+            this.spatialSound = false;
+            this.refDistance = 1;
+            this.rolloffFactor = 1;
+            this.maxDistance = 100;
             this._position = BABYLON.Vector3.Zero();
             this._localDirection = new BABYLON.Vector3(1, 0, 0);
             this._volume = 1;
@@ -30,8 +33,14 @@
             this._scene = scene;
             this._audioEngine = this._scene.getEngine().getAudioEngine();
             this._readyToPlayCallback = readyToPlayCallback;
-            this._attenuationFunction = function (currentVolume, currentDistance, maxDistance) {
-                return currentVolume * (1 - currentDistance / maxDistance);
+
+            // Default custom attenuation function is a linear attenuation
+            this._customAttenuationFunction = function (currentVolume, currentDistance, maxDistance) {
+                if (currentDistance < maxDistance) {
+                    return currentVolume * (1 - currentDistance / maxDistance);
+                } else {
+                    return 0;
+                }
             };
             if (options) {
                 if (options.maxDistance) {
@@ -46,26 +55,41 @@
                 if (options.volume) {
                     this._volume = options.volume;
                 }
-                if (options.useBabylonJSAttenuation) {
-                    this.useBabylonJSAttenuation = options.useBabylonJSAttenuation;
+                if (options.useCustomAttenuation) {
+                    this.maxDistance = Number.MAX_VALUE;
+                    this.useCustomAttenuation = options.useCustomAttenuation;
+                }
+                if (options.spatialSound) {
+                    this.spatialSound = options.spatialSound;
                 }
             }
 
             if (this._audioEngine.canUseWebAudio) {
                 this._soundGain = this._audioEngine.audioContext.createGain();
                 this._soundGain.gain.value = this._volume;
-                this._soundPanner = this._audioEngine.audioContext.createPanner();
-                this._soundPanner.connect(this._soundGain);
+                if (this.spatialSound) {
+                    this._createSpatialParameters();
+                } else {
+                    this._audioNode = this._soundGain;
+                }
                 this._scene.mainSoundTrack.AddSound(this);
                 BABYLON.Tools.LoadFile(url, function (data) {
                     _this._soundLoaded(data);
                 }, null, null, true);
             }
         }
+        Sound.prototype._createSpatialParameters = function () {
+            this._soundPanner = this._audioEngine.audioContext.createPanner();
+            this._soundPanner.distanceModel = "linear";
+            this._soundPanner.maxDistance = this.maxDistance;
+            this._soundGain.connect(this._soundPanner);
+            this._audioNode = this._soundPanner;
+        };
+
         Sound.prototype.connectToSoundTrackAudioNode = function (soundTrackAudioNode) {
             if (this._audioEngine.canUseWebAudio) {
-                this._soundGain.disconnect();
-                this._soundGain.connect(soundTrackAudioNode);
+                this._audioNode.disconnect();
+                this._audioNode.connect(soundTrackAudioNode);
             }
         };
 
@@ -94,7 +118,7 @@
         Sound.prototype.setPosition = function (newPosition) {
             this._position = newPosition;
 
-            if (this._isPlaying) {
+            if (this._isPlaying && this.spatialSound) {
                 this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
             }
         };
@@ -115,22 +139,14 @@
         };
 
         Sound.prototype.updateDistanceFromListener = function () {
-            if (this._connectedMesh) {
+            if (this._connectedMesh && this.useCustomAttenuation) {
                 var distance = this._connectedMesh.getDistanceToCamera(this._scene.activeCamera);
-
-                if (this.useBabylonJSAttenuation) {
-                    if (distance < this.maxDistance) {
-                        //this._soundGain.gain.value = this._volume * (1 - distance / this.maxDistance);
-                        this._soundGain.gain.value = this._attenuationFunction(this._volume, distance, this.maxDistance);
-                    } else {
-                        this._soundGain.gain.value = 0;
-                    }
-                }
+                this._soundGain.gain.value = this._customAttenuationFunction(this._volume, distance, this.maxDistance);
             }
         };
 
         Sound.prototype.setAttenuationFunction = function (callback) {
-            this._attenuationFunction = callback;
+            this._customAttenuationFunction = callback;
         };
 
         /**
@@ -143,14 +159,20 @@
                     var startTime = time ? this._audioEngine.audioContext.currentTime + time : 0;
                     this._soundSource = this._audioEngine.audioContext.createBufferSource();
                     this._soundSource.buffer = this._audioBuffer;
-                    this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
-                    if (this._isDirectional) {
-                        this._soundPanner.coneInnerAngle = this._coneInnerAngle;
-                        this._soundPanner.coneOuterAngle = this._coneOuterAngle;
-                        this._soundPanner.coneOuterGain = this._coneOuterGain;
-                        this._soundPanner.setOrientation(this._localDirection.x, this._localDirection.y, this._localDirection.z);
+                    if (this.spatialSound) {
+                        this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
+                        if (this._isDirectional) {
+                            this._soundPanner.coneInnerAngle = this._coneInnerAngle;
+                            this._soundPanner.coneOuterAngle = this._coneOuterAngle;
+                            this._soundPanner.coneOuterGain = this._coneOuterGain;
+                            if (this._connectedMesh) {
+                                this._updateDirection();
+                            } else {
+                                this._soundPanner.setOrientation(this._localDirection.x, this._localDirection.y, this._localDirection.z);
+                            }
+                        }
                     }
-                    this._soundSource.connect(this._soundPanner);
+                    this._soundSource.connect(this._audioNode);
                     this._soundSource.loop = this.loop;
                     this._soundSource.start(startTime);
                     this._isPlaying = true;
@@ -171,11 +193,12 @@
         };
 
         Sound.prototype.pause = function () {
-            //this._soundSource.p
+            // TODO
         };
 
         Sound.prototype.setVolume = function (newVolume) {
             this._volume = newVolume;
+            this._soundGain.gain.value = newVolume;
         };
 
         Sound.prototype.getVolume = function () {
@@ -185,6 +208,10 @@
         Sound.prototype.attachToMesh = function (meshToConnectTo) {
             var _this = this;
             this._connectedMesh = meshToConnectTo;
+            if (!this.spatialSound) {
+                this._createSpatialParameters();
+                this.spatialSound = true;
+            }
             meshToConnectTo.registerAfterWorldMatrixUpdate(function (connectedMesh) {
                 return _this._onRegisterAfterWorldMatrixUpdate(connectedMesh);
             });

+ 62 - 31
Babylon/Audio/babylon.sound.ts

@@ -1,10 +1,13 @@
 module BABYLON {
     export class Sound {
-        public maxDistance: number = 20;
         public autoplay: boolean = false;
         public loop: boolean = false;
-        public useBabylonJSAttenuation: boolean = true;
+        public useCustomAttenuation: boolean = false;
         public soundTrackId: number;
+        public spatialSound: boolean = false;
+        public refDistance: number = 1;
+        public rolloffFactor: number = 1;
+        public maxDistance: number = 100;
         private _position: Vector3 = Vector3.Zero();
         private _localDirection: Vector3 = new Vector3(1,0,0);
         private _volume: number = 1;
@@ -18,6 +21,7 @@
         private _soundSource: AudioBufferSourceNode;
         private _soundPanner: PannerNode;
         private _soundGain: GainNode;
+        private _audioNode: AudioNode;
         // Used if you'd like to create a directional sound.
         // If not set, the sound will be omnidirectional
         private _coneInnerAngle: number = null;
@@ -26,7 +30,7 @@
         private _scene: BABYLON.Scene;
         private _name: string;
         private _connectedMesh: BABYLON.AbstractMesh;
-        private _attenuationFunction: (currentVolume: number, currentDistance: number, maxDistance: number) => number;
+        private _customAttenuationFunction: (currentVolume: number, currentDistance: number, maxDistance: number) => number;
 
         /**
         * Create a sound and attach it to a scene
@@ -40,29 +44,53 @@
             this._scene = scene;
             this._audioEngine = this._scene.getEngine().getAudioEngine();
             this._readyToPlayCallback = readyToPlayCallback;
-            this._attenuationFunction = (currentVolume: number, currentDistance: number, maxDistance: number) => { return currentVolume * (1 - currentDistance / maxDistance)  };
+            // Default custom attenuation function is a linear attenuation
+            this._customAttenuationFunction = (currentVolume: number, currentDistance: number, maxDistance: number) => { 
+                if (currentDistance < maxDistance) {
+                    return currentVolume * (1 - currentDistance / maxDistance);
+                }
+                else {
+                    return 0;
+                }
+            };
             if (options) {
                 if (options.maxDistance) { this.maxDistance = options.maxDistance; }
                 if (options.autoplay) { this.autoplay = options.autoplay; }
                 if (options.loop) { this.loop = options.loop; }
                 if (options.volume) { this._volume = options.volume; }
-                if (options.useBabylonJSAttenuation) { this.useBabylonJSAttenuation = options.useBabylonJSAttenuation; }
+                if (options.useCustomAttenuation) {
+                    this.maxDistance = Number.MAX_VALUE;
+                    this.useCustomAttenuation = options.useCustomAttenuation;
+                }
+                if (options.spatialSound) { this.spatialSound = options.spatialSound; }
             }
 
             if (this._audioEngine.canUseWebAudio) {
                 this._soundGain = this._audioEngine.audioContext.createGain();
                 this._soundGain.gain.value = this._volume;
-                this._soundPanner = this._audioEngine.audioContext.createPanner();
-                this._soundPanner.connect(this._soundGain);
+                if (this.spatialSound) {
+                    this._createSpatialParameters();
+                }
+                else {
+                    this._audioNode = this._soundGain;
+                }
                 this._scene.mainSoundTrack.AddSound(this);
                 BABYLON.Tools.LoadFile(url, (data) => { this._soundLoaded(data); }, null, null, true);
             }
         }
 
+        private _createSpatialParameters() {
+            this._soundPanner = this._audioEngine.audioContext.createPanner();
+            this._soundPanner.distanceModel = "linear";
+            this._soundPanner.maxDistance = this.maxDistance;
+            this._soundGain.connect(this._soundPanner);
+            this._audioNode = this._soundPanner;
+        }
+
         public connectToSoundTrackAudioNode(soundTrackAudioNode: AudioNode) {
             if (this._audioEngine.canUseWebAudio) {
-                this._soundGain.disconnect();
-                this._soundGain.connect(soundTrackAudioNode);
+                this._audioNode.disconnect();
+                this._audioNode.connect(soundTrackAudioNode);
             }
         }
 
@@ -91,7 +119,7 @@
         public setPosition(newPosition: Vector3) {
             this._position = newPosition;
 
-            if (this._isPlaying) {
+            if (this._isPlaying && this.spatialSound) {
                 this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
             }
         }
@@ -112,23 +140,14 @@
         }
 
         public updateDistanceFromListener() {
-            if (this._connectedMesh) {
+            if (this._connectedMesh && this.useCustomAttenuation) {
                 var distance = this._connectedMesh.getDistanceToCamera(this._scene.activeCamera);
-
-                if (this.useBabylonJSAttenuation) {
-                    if (distance < this.maxDistance) {
-                        //this._soundGain.gain.value = this._volume * (1 - distance / this.maxDistance);
-                        this._soundGain.gain.value = this._attenuationFunction(this._volume, distance, this.maxDistance);
-                    }
-                    else {
-                        this._soundGain.gain.value = 0;
-                    }
-                }
+                this._soundGain.gain.value = this._customAttenuationFunction(this._volume, distance, this.maxDistance);
             }
         }
-
+        
         public setAttenuationFunction(callback: (currentVolume: number, currentDistance: number, maxDistance: number) => number) {
-            this._attenuationFunction = callback;
+            this._customAttenuationFunction = callback;
         }
 
         /**
@@ -141,14 +160,21 @@
                     var startTime = time ? this._audioEngine.audioContext.currentTime + time : 0;
                     this._soundSource = this._audioEngine.audioContext.createBufferSource();
                     this._soundSource.buffer = this._audioBuffer;
-                    this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
-                    if (this._isDirectional) {
-                        this._soundPanner.coneInnerAngle = this._coneInnerAngle;
-                        this._soundPanner.coneOuterAngle = this._coneOuterAngle;
-                        this._soundPanner.coneOuterGain = this._coneOuterGain;
-                        this._soundPanner.setOrientation(this._localDirection.x, this._localDirection.y, this._localDirection.z);
+                    if (this.spatialSound) {
+                        this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
+                        if (this._isDirectional) {
+                            this._soundPanner.coneInnerAngle = this._coneInnerAngle;
+                            this._soundPanner.coneOuterAngle = this._coneOuterAngle;
+                            this._soundPanner.coneOuterGain = this._coneOuterGain;
+                            if (this._connectedMesh) {
+                                this._updateDirection();
+                            }
+                            else {
+                                this._soundPanner.setOrientation(this._localDirection.x, this._localDirection.y, this._localDirection.z);
+                            }
+                        }
                     }
-                    this._soundSource.connect(this._soundPanner);
+                    this._soundSource.connect(this._audioNode);
                     this._soundSource.loop = this.loop;
                     this._soundSource.start(startTime);
                     this._isPlaying = true;
@@ -170,11 +196,12 @@
         }
 
         public pause() {
-            //this._soundSource.p
+            // TODO
         }
 
         public setVolume(newVolume: number) {
             this._volume = newVolume;
+            this._soundGain.gain.value = newVolume;
         }
 
         public getVolume(): number {
@@ -183,6 +210,10 @@
 
         public attachToMesh(meshToConnectTo: BABYLON.AbstractMesh) {
             this._connectedMesh = meshToConnectTo;
+            if (!this.spatialSound) {
+                this._createSpatialParameters();
+                this.spatialSound = true;
+            }
             meshToConnectTo.registerAfterWorldMatrixUpdate((connectedMesh: BABYLON.AbstractMesh) => this._onRegisterAfterWorldMatrixUpdate(connectedMesh));
         }
 

+ 15 - 11
Babylon/Math/babylon.math.js

@@ -575,7 +575,7 @@
         };
 
         Vector3.prototype.equalsWithEpsilon = function (otherVector) {
-            return Math.abs(this.x - otherVector.x) < Engine.Epsilon && Math.abs(this.y - otherVector.y) < Engine.Epsilon && Math.abs(this.z - otherVector.z) < Engine.Epsilon;
+            return Math.abs(this.x - otherVector.x) < BABYLON.Engine.Epsilon && Math.abs(this.y - otherVector.y) < BABYLON.Engine.Epsilon && Math.abs(this.z - otherVector.z) < BABYLON.Engine.Epsilon;
         };
 
         Vector3.prototype.equalsToFloats = function (x, y, z) {
@@ -858,7 +858,7 @@
             var vector = Vector3.TransformCoordinates(source, matrix);
             var num = source.x * matrix.m[3] + source.y * matrix.m[7] + source.z * matrix.m[11] + matrix.m[15];
 
-            if (Tools.WithinEpsilon(num, 1.0)) {
+            if (BABYLON.Tools.WithinEpsilon(num, 1.0)) {
                 vector = vector.scale(1.0 / num);
             }
 
@@ -873,7 +873,7 @@
             var vector = Vector3.TransformCoordinates(source, matrix);
             var num = source.x * matrix.m[3] + source.y * matrix.m[7] + source.z * matrix.m[11] + matrix.m[15];
 
-            if (Tools.WithinEpsilon(num, 1.0)) {
+            if (BABYLON.Tools.WithinEpsilon(num, 1.0)) {
                 vector = vector.scale(1.0 / num);
             }
 
@@ -1020,7 +1020,7 @@
         };
 
         Vector4.prototype.equalsWithEpsilon = function (otherVector) {
-            return Math.abs(this.x - otherVector.x) < Engine.Epsilon && Math.abs(this.y - otherVector.y) < Engine.Epsilon && Math.abs(this.z - otherVector.z) < Engine.Epsilon && Math.abs(this.w - otherVector.w) < Engine.Epsilon;
+            return Math.abs(this.x - otherVector.x) < BABYLON.Engine.Epsilon && Math.abs(this.y - otherVector.y) < BABYLON.Engine.Epsilon && Math.abs(this.z - otherVector.z) < BABYLON.Engine.Epsilon && Math.abs(this.w - otherVector.w) < BABYLON.Engine.Epsilon;
         };
 
         Vector4.prototype.equalsToFloats = function (x, y, z, w) {
@@ -2140,7 +2140,7 @@
         };
 
         Plane.prototype.transform = function (transformation) {
-            var transposedMatrix = BABYLON.Matrix.Transpose(transformation);
+            var transposedMatrix = Matrix.Transpose(transformation);
             var x = this.normal.x;
             var y = this.normal.y;
             var z = this.normal.z;
@@ -2151,7 +2151,7 @@
             var normalZ = (((x * transposedMatrix.m[8]) + (y * transposedMatrix.m[9])) + (z * transposedMatrix.m[10])) + (d * transposedMatrix.m[11]);
             var finalD = (((x * transposedMatrix.m[12]) + (y * transposedMatrix.m[13])) + (z * transposedMatrix.m[14])) + (d * transposedMatrix.m[15]);
 
-            return new BABYLON.Plane(normalX, normalY, normalZ, finalD);
+            return new Plane(normalX, normalY, normalZ, finalD);
         };
 
         Plane.prototype.dotCoordinate = function (point) {
@@ -2465,7 +2465,7 @@
                 return null;
             }
 
-            return new IntersectionInfo(bu, bv, distance);
+            return new BABYLON.IntersectionInfo(bu, bv, distance);
         };
 
         // Statics
@@ -2692,7 +2692,8 @@
         }
         Path2.prototype.addLineTo = function (x, y) {
             if (closed) {
-                throw "cannot add lines to closed paths";
+                BABYLON.Tools.Error("cannot add lines to closed paths");
+                return this;
             }
             var newPoint = new Vector2(x, y);
             var previousPoint = this._points[this._points.length - 1];
@@ -2704,7 +2705,8 @@
         Path2.prototype.addArcTo = function (midX, midY, endX, endY, numberOfSegments) {
             if (typeof numberOfSegments === "undefined") { numberOfSegments = 36; }
             if (closed) {
-                throw "cannot add arcs to closed paths";
+                BABYLON.Tools.Error("cannot add arcs to closed paths");
+                return this;
             }
             var startPoint = this._points[this._points.length - 1];
             var midPoint = new Vector2(midX, midY);
@@ -2749,7 +2751,8 @@
 
         Path2.prototype.getPointAtLengthPosition = function (normalizedLengthPosition) {
             if (normalizedLengthPosition < 0 || normalizedLengthPosition > 1) {
-                throw "normalized length position should be between 0 and 1.";
+                BABYLON.Tools.Error("normalized length position should be between 0 and 1.");
+                return;
             }
 
             var lengthPosition = normalizedLengthPosition * this.length();
@@ -2772,7 +2775,7 @@
                 previousOffset = nextOffset;
             }
 
-            throw "internal error";
+            BABYLON.Tools.Error("internal error");
         };
 
         Path2.StartingAt = function (x, y) {
@@ -2782,3 +2785,4 @@
     })();
     BABYLON.Path2 = Path2;
 })(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.math.js.map

+ 10 - 7
Babylon/Math/babylon.math.ts

@@ -2144,7 +2144,7 @@
         }
 
         public transform(transformation: Matrix): Plane {
-            var transposedMatrix = BABYLON.Matrix.Transpose(transformation);
+            var transposedMatrix = Matrix.Transpose(transformation);
             var x = this.normal.x;
             var y = this.normal.y;
             var z = this.normal.z;
@@ -2155,7 +2155,7 @@
             var normalZ = (((x * transposedMatrix.m[8]) + (y * transposedMatrix.m[9])) + (z * transposedMatrix.m[10])) + (d * transposedMatrix.m[11]);
             var finalD = (((x * transposedMatrix.m[12]) + (y * transposedMatrix.m[13])) + (z * transposedMatrix.m[14])) + (d * transposedMatrix.m[15]);
 
-            return new BABYLON.Plane(normalX, normalY, normalZ, finalD);
+            return new Plane(normalX, normalY, normalZ, finalD);
         }
 
 
@@ -2615,7 +2615,7 @@
         private _onchange = new Array <(cursor: PathCursor) => void>();
 
         value: number = 0;
-        animations = new Array<BABYLON.Animation>();
+        animations = new Array<Animation>();
 
         constructor(private path: Path2) {
         }
@@ -2680,7 +2680,8 @@
 
         addLineTo(x: number, y: number): Path2 {
             if (closed) {
-                throw "cannot add lines to closed paths";
+                Tools.Error("cannot add lines to closed paths");
+                return this;
             }
             var newPoint = new Vector2(x, y);
             var previousPoint = this._points[this._points.length - 1];
@@ -2691,7 +2692,8 @@
 
         addArcTo(midX: number, midY: number, endX: number, endY: number, numberOfSegments = 36): Path2 {
             if (closed) {
-                throw "cannot add arcs to closed paths";
+                Tools.Error("cannot add arcs to closed paths");
+                return this;
             }
             var startPoint = this._points[this._points.length - 1];
             var midPoint = new Vector2(midX, midY);
@@ -2735,7 +2737,8 @@
 
         getPointAtLengthPosition(normalizedLengthPosition: number): Vector2 {
             if (normalizedLengthPosition < 0 || normalizedLengthPosition > 1) {
-                throw "normalized length position should be between 0 and 1.";
+                Tools.Error("normalized length position should be between 0 and 1.");
+                return;
             }
 
             var lengthPosition = normalizedLengthPosition * this.length();
@@ -2761,7 +2764,7 @@
                 previousOffset = nextOffset;
             }
 
-            throw "internal error";
+            Tools.Error("internal error");
         }
 
         static StartingAt(x: number, y: number): Path2 {

+ 16 - 23
Babylon/Mesh/babylon.polygonmesh.js

@@ -13,15 +13,7 @@ var BABYLON;
             this.index = index;
         }
         return IndexedVector2;
-    })(Vector2);
-
-    function nearlyEqual(a, b, epsilon) {
-        if (typeof epsilon === "undefined") { epsilon = 0.0001; }
-        if (a === b) {
-            return true;
-        }
-        return Math.abs(a - b) < epsilon;
-    }
+    })(BABYLON.Vector2);
 
     var PolygonPoints = (function () {
         function PolygonPoints() {
@@ -31,7 +23,7 @@ var BABYLON;
             var _this = this;
             var result = new Array();
             originalPoints.forEach(function (point) {
-                if (result.length === 0 || !(nearlyEqual(point.x, result[0].x) && nearlyEqual(point.y, result[0].y))) {
+                if (result.length === 0 || !(BABYLON.Tools.WithinEpsilon(point.x, result[0].x) && BABYLON.Tools.WithinEpsilon(point.y, result[0].y))) {
                     var newPoint = new IndexedVector2(point, _this.elements.length);
                     result.push(newPoint);
                     _this.elements.push(newPoint);
@@ -42,8 +34,8 @@ var BABYLON;
         };
 
         PolygonPoints.prototype.computeBounds = function () {
-            var lmin = new Vector2(this.elements[0].x, this.elements[0].y);
-            var lmax = new Vector2(this.elements[0].x, this.elements[0].y);
+            var lmin = new BABYLON.Vector2(this.elements[0].x, this.elements[0].y);
+            var lmax = new BABYLON.Vector2(this.elements[0].x, this.elements[0].y);
 
             this.elements.forEach(function (point) {
                 // x
@@ -76,10 +68,10 @@ var BABYLON;
         }
         Polygon.Rectangle = function (xmin, ymin, xmax, ymax) {
             return [
-                new Vector2(xmin, ymin),
-                new Vector2(xmax, ymin),
-                new Vector2(xmax, ymax),
-                new Vector2(xmin, ymax)
+                new BABYLON.Vector2(xmin, ymin),
+                new BABYLON.Vector2(xmax, ymin),
+                new BABYLON.Vector2(xmax, ymax),
+                new BABYLON.Vector2(xmin, ymax)
             ];
         };
 
@@ -93,7 +85,7 @@ var BABYLON;
             var increment = (Math.PI * 2) / numberOfSides;
 
             for (var i = 0; i < numberOfSides; i++) {
-                result.push(new Vector2(cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius));
+                result.push(new BABYLON.Vector2(cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius));
                 angle -= increment;
             }
 
@@ -112,7 +104,7 @@ var BABYLON;
         };
 
         Polygon.StartingAt = function (x, y) {
-            return Path2.StartingAt(x, y);
+            return BABYLON.Path2.StartingAt(x, y);
         };
         return Polygon;
     })();
@@ -129,7 +121,7 @@ var BABYLON;
             this._scene = scene;
 
             var points;
-            if (contours instanceof Path2) {
+            if (contours instanceof BABYLON.Path2) {
                 points = contours.getPoints();
             } else {
                 points = contours;
@@ -144,7 +136,7 @@ var BABYLON;
 
         PolygonMeshBuilder.prototype.build = function (updatable) {
             if (typeof updatable === "undefined") { updatable = false; }
-            var result = new Mesh(this._name, this._scene);
+            var result = new BABYLON.Mesh(this._name, this._scene);
 
             var normals = [];
             var positions = [];
@@ -166,9 +158,9 @@ var BABYLON;
                 });
             });
 
-            result.setVerticesData(positions, VertexBuffer.PositionKind, updatable);
-            result.setVerticesData(normals, VertexBuffer.NormalKind, updatable);
-            result.setVerticesData(uvs, VertexBuffer.UVKind, updatable);
+            result.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind, updatable);
+            result.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind, updatable);
+            result.setVerticesData(uvs, BABYLON.VertexBuffer.UVKind, updatable);
             result.setIndices(indices);
 
             return result;
@@ -177,3 +169,4 @@ var BABYLON;
     })();
     BABYLON.PolygonMeshBuilder = PolygonMeshBuilder;
 })(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.polygonMesh.js.map

+ 1 - 9
Babylon/Mesh/babylon.polygonmesh.ts

@@ -5,14 +5,6 @@
         }
     }
 
-    function nearlyEqual(a: number, b: number, epsilon: number = 0.0001): boolean {
-        if (a === b) {
-            return true;
-        }
-        return Math.abs(a - b) < epsilon;
-    }
-
-
     class PolygonPoints {
         elements = new Array<IndexedVector2>();
 
@@ -20,7 +12,7 @@
 
             var result = new Array<IndexedVector2>();
             originalPoints.forEach(point => {
-                if (result.length === 0 || !(nearlyEqual(point.x, result[0].x) && nearlyEqual(point.y, result[0].y))) {
+                if (result.length === 0 || !(Tools.WithinEpsilon(point.x, result[0].x) && Tools.WithinEpsilon(point.y, result[0].y))) {
                     var newPoint = new IndexedVector2(point, this.elements.length);
                     result.push(newPoint);
                     this.elements.push(newPoint);

+ 2 - 2
Babylon/babylon.scene.js

@@ -1189,14 +1189,14 @@
                 audioEngine.audioContext.listener.setOrientation(cameraDirection.x, cameraDirection.y, cameraDirection.z, 0, 1, 0);
                 for (var i = 0; i < this.mainSoundTrack.soundCollection.length; i++) {
                     var sound = this.mainSoundTrack.soundCollection[i];
-                    if (sound.useBabylonJSAttenuation) {
+                    if (sound.useCustomAttenuation) {
                         sound.updateDistanceFromListener();
                     }
                 }
                 for (var i = 0; i < this.soundTracks.length; i++) {
                     for (var j = 0; j < this.soundTracks[i].soundCollection.length; j++) {
                         var sound = this.soundTracks[i].soundCollection[j];
-                        if (sound.useBabylonJSAttenuation) {
+                        if (sound.useCustomAttenuation) {
                             sound.updateDistanceFromListener();
                         }
                     }

+ 2 - 2
Babylon/babylon.scene.ts

@@ -1271,14 +1271,14 @@
                 audioEngine.audioContext.listener.setOrientation(cameraDirection.x, cameraDirection.y, cameraDirection.z, 0, 1, 0);
                 for (var i = 0; i < this.mainSoundTrack.soundCollection.length; i++) {
                     var sound = this.mainSoundTrack.soundCollection[i];
-                    if (sound.useBabylonJSAttenuation) {
+                    if (sound.useCustomAttenuation) {
                         sound.updateDistanceFromListener();
                     }
                 }
                 for (var i = 0; i < this.soundTracks.length; i++) {
                     for (var j = 0; j < this.soundTracks[i].soundCollection.length; j++) {
                         var sound = this.soundTracks[i].soundCollection[j];
-                        if (sound.useBabylonJSAttenuation) {
+                        if (sound.useCustomAttenuation) {
                             sound.updateDistanceFromListener();
                         }
                     }

+ 195 - 40
babylon.2.0-alpha.debug.js

@@ -2145,7 +2145,7 @@ var __extends = this.__extends || function (d, b) {
         };
 
         Plane.prototype.transform = function (transformation) {
-            var transposedMatrix = BABYLON.Matrix.Transpose(transformation);
+            var transposedMatrix = Matrix.Transpose(transformation);
             var x = this.normal.x;
             var y = this.normal.y;
             var z = this.normal.z;
@@ -2156,7 +2156,7 @@ var __extends = this.__extends || function (d, b) {
             var normalZ = (((x * transposedMatrix.m[8]) + (y * transposedMatrix.m[9])) + (z * transposedMatrix.m[10])) + (d * transposedMatrix.m[11]);
             var finalD = (((x * transposedMatrix.m[12]) + (y * transposedMatrix.m[13])) + (z * transposedMatrix.m[14])) + (d * transposedMatrix.m[15]);
 
-            return new BABYLON.Plane(normalX, normalY, normalZ, finalD);
+            return new Plane(normalX, normalY, normalZ, finalD);
         };
 
         Plane.prototype.dotCoordinate = function (point) {
@@ -2627,18 +2627,92 @@ var __extends = this.__extends || function (d, b) {
     })();
     BABYLON.Arc2 = Arc2;
 
+    var PathCursor = (function () {
+        function PathCursor(path) {
+            this.path = path;
+            this._onchange = new Array();
+            this.value = 0;
+            this.animations = new Array();
+        }
+        PathCursor.prototype.getPoint = function () {
+            var point = this.path.getPointAtLengthPosition(this.value);
+            return new Vector3(point.x, 0, point.y);
+        };
+
+        PathCursor.prototype.moveAhead = function (step) {
+            if (typeof step === "undefined") { step = 0.002; }
+            this.move(step);
+        };
+
+        PathCursor.prototype.moveBack = function (step) {
+            if (typeof step === "undefined") { step = 0.002; }
+            this.move(-step);
+        };
+
+        PathCursor.prototype.move = function (step) {
+            if (Math.abs(step) > 1) {
+                throw "step size should be less than 1.";
+            }
+
+            this.value += step;
+            this.ensureLimits();
+            this.raiseOnChange();
+        };
+
+        PathCursor.prototype.ensureLimits = function () {
+            while (this.value > 1) {
+                this.value -= 1;
+            }
+            while (this.value < 0) {
+                this.value += 1;
+            }
+        };
+
+        // used by animation engine
+        PathCursor.prototype.markAsDirty = function (propertyName) {
+            this.ensureLimits();
+            this.raiseOnChange();
+        };
+
+        PathCursor.prototype.raiseOnChange = function () {
+            var _this = this;
+            this._onchange.forEach(function (f) {
+                return f(_this);
+            });
+        };
+
+        PathCursor.prototype.onchange = function (f) {
+            this._onchange.push(f);
+        };
+        return PathCursor;
+    })();
+    BABYLON.PathCursor = PathCursor;
+
     var Path2 = (function () {
         function Path2(x, y) {
             this._points = [];
+            this._length = 0;
+            this.closed = false;
             this._points.push(new Vector2(x, y));
         }
         Path2.prototype.addLineTo = function (x, y) {
-            this._points.push(new Vector2(x, y));
+            if (closed) {
+                BABYLON.Tools.Error("cannot add lines to closed paths");
+                return this;
+            }
+            var newPoint = new Vector2(x, y);
+            var previousPoint = this._points[this._points.length - 1];
+            this._points.push(newPoint);
+            this._length += newPoint.subtract(previousPoint).length();
             return this;
         };
 
         Path2.prototype.addArcTo = function (midX, midY, endX, endY, numberOfSegments) {
             if (typeof numberOfSegments === "undefined") { numberOfSegments = 36; }
+            if (closed) {
+                BABYLON.Tools.Error("cannot add arcs to closed paths");
+                return this;
+            }
             var startPoint = this._points[this._points.length - 1];
             var midPoint = new Vector2(midX, midY);
             var endPoint = new Vector2(endX, endY);
@@ -2660,9 +2734,55 @@ var __extends = this.__extends || function (d, b) {
         };
 
         Path2.prototype.close = function () {
+            this.closed = true;
+            return this;
+        };
+
+        Path2.prototype.length = function () {
+            var result = this._length;
+
+            if (!this.closed) {
+                var lastPoint = this._points[this._points.length - 1];
+                var firstPoint = this._points[0];
+                result += (firstPoint.subtract(lastPoint).length());
+            }
+
+            return result;
+        };
+
+        Path2.prototype.getPoints = function () {
             return this._points;
         };
 
+        Path2.prototype.getPointAtLengthPosition = function (normalizedLengthPosition) {
+            if (normalizedLengthPosition < 0 || normalizedLengthPosition > 1) {
+                BABYLON.Tools.Error("normalized length position should be between 0 and 1.");
+                return;
+            }
+
+            var lengthPosition = normalizedLengthPosition * this.length();
+
+            var previousOffset = 0;
+            for (var i = 0; i < this._points.length; i++) {
+                var j = (i + 1) % this._points.length;
+
+                var a = this._points[i];
+                var b = this._points[j];
+                var bToA = b.subtract(a);
+
+                var nextOffset = (bToA.length() + previousOffset);
+                if (lengthPosition >= previousOffset && lengthPosition <= nextOffset) {
+                    var dir = bToA.normalize();
+                    var localOffset = lengthPosition - previousOffset;
+
+                    return new Vector2(a.x + (dir.x * localOffset), a.y + (dir.y * localOffset));
+                }
+                previousOffset = nextOffset;
+            }
+
+            BABYLON.Tools.Error("internal error");
+        };
+
         Path2.StartingAt = function (x, y) {
             return new Path2(x, y);
         };
@@ -9709,14 +9829,14 @@ var BABYLON;
                 audioEngine.audioContext.listener.setOrientation(cameraDirection.x, cameraDirection.y, cameraDirection.z, 0, 1, 0);
                 for (var i = 0; i < this.mainSoundTrack.soundCollection.length; i++) {
                     var sound = this.mainSoundTrack.soundCollection[i];
-                    if (sound.useBabylonJSAttenuation) {
+                    if (sound.useCustomAttenuation) {
                         sound.updateDistanceFromListener();
                     }
                 }
                 for (var i = 0; i < this.soundTracks.length; i++) {
                     for (var j = 0; j < this.soundTracks[i].soundCollection.length; j++) {
                         var sound = this.soundTracks[i].soundCollection[j];
-                        if (sound.useBabylonJSAttenuation) {
+                        if (sound.useCustomAttenuation) {
                             sound.updateDistanceFromListener();
                         }
                     }
@@ -29316,10 +29436,13 @@ var BABYLON;
         */
         function Sound(name, url, scene, readyToPlayCallback, options) {
             var _this = this;
-            this.maxDistance = 20;
             this.autoplay = false;
             this.loop = false;
-            this.useBabylonJSAttenuation = true;
+            this.useCustomAttenuation = false;
+            this.spatialSound = false;
+            this.refDistance = 1;
+            this.rolloffFactor = 1;
+            this.maxDistance = 100;
             this._position = BABYLON.Vector3.Zero();
             this._localDirection = new BABYLON.Vector3(1, 0, 0);
             this._volume = 1;
@@ -29336,8 +29459,14 @@ var BABYLON;
             this._scene = scene;
             this._audioEngine = this._scene.getEngine().getAudioEngine();
             this._readyToPlayCallback = readyToPlayCallback;
-            this._attenuationFunction = function (currentVolume, currentDistance, maxDistance) {
-                return currentVolume * (1 - currentDistance / maxDistance);
+
+            // Default custom attenuation function is a linear attenuation
+            this._customAttenuationFunction = function (currentVolume, currentDistance, maxDistance) {
+                if (currentDistance < maxDistance) {
+                    return currentVolume * (1 - currentDistance / maxDistance);
+                } else {
+                    return 0;
+                }
             };
             if (options) {
                 if (options.maxDistance) {
@@ -29352,26 +29481,41 @@ var BABYLON;
                 if (options.volume) {
                     this._volume = options.volume;
                 }
-                if (options.useBabylonJSAttenuation) {
-                    this.useBabylonJSAttenuation = options.useBabylonJSAttenuation;
+                if (options.useCustomAttenuation) {
+                    this.maxDistance = Number.MAX_VALUE;
+                    this.useCustomAttenuation = options.useCustomAttenuation;
+                }
+                if (options.spatialSound) {
+                    this.spatialSound = options.spatialSound;
                 }
             }
 
             if (this._audioEngine.canUseWebAudio) {
                 this._soundGain = this._audioEngine.audioContext.createGain();
                 this._soundGain.gain.value = this._volume;
-                this._soundPanner = this._audioEngine.audioContext.createPanner();
-                this._soundPanner.connect(this._soundGain);
+                if (this.spatialSound) {
+                    this._createSpatialParameters();
+                } else {
+                    this._audioNode = this._soundGain;
+                }
                 this._scene.mainSoundTrack.AddSound(this);
                 BABYLON.Tools.LoadFile(url, function (data) {
                     _this._soundLoaded(data);
                 }, null, null, true);
             }
         }
+        Sound.prototype._createSpatialParameters = function () {
+            this._soundPanner = this._audioEngine.audioContext.createPanner();
+            this._soundPanner.distanceModel = "linear";
+            this._soundPanner.maxDistance = this.maxDistance;
+            this._soundGain.connect(this._soundPanner);
+            this._audioNode = this._soundPanner;
+        };
+
         Sound.prototype.connectToSoundTrackAudioNode = function (soundTrackAudioNode) {
             if (this._audioEngine.canUseWebAudio) {
-                this._soundGain.disconnect();
-                this._soundGain.connect(soundTrackAudioNode);
+                this._audioNode.disconnect();
+                this._audioNode.connect(soundTrackAudioNode);
             }
         };
 
@@ -29400,7 +29544,7 @@ var BABYLON;
         Sound.prototype.setPosition = function (newPosition) {
             this._position = newPosition;
 
-            if (this._isPlaying) {
+            if (this._isPlaying && this.spatialSound) {
                 this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
             }
         };
@@ -29421,22 +29565,14 @@ var BABYLON;
         };
 
         Sound.prototype.updateDistanceFromListener = function () {
-            if (this._connectedMesh) {
+            if (this._connectedMesh && this.useCustomAttenuation) {
                 var distance = this._connectedMesh.getDistanceToCamera(this._scene.activeCamera);
-
-                if (this.useBabylonJSAttenuation) {
-                    if (distance < this.maxDistance) {
-                        //this._soundGain.gain.value = this._volume * (1 - distance / this.maxDistance);
-                        this._soundGain.gain.value = this._attenuationFunction(this._volume, distance, this.maxDistance);
-                    } else {
-                        this._soundGain.gain.value = 0;
-                    }
-                }
+                this._soundGain.gain.value = this._customAttenuationFunction(this._volume, distance, this.maxDistance);
             }
         };
 
         Sound.prototype.setAttenuationFunction = function (callback) {
-            this._attenuationFunction = callback;
+            this._customAttenuationFunction = callback;
         };
 
         /**
@@ -29449,14 +29585,20 @@ var BABYLON;
                     var startTime = time ? this._audioEngine.audioContext.currentTime + time : 0;
                     this._soundSource = this._audioEngine.audioContext.createBufferSource();
                     this._soundSource.buffer = this._audioBuffer;
-                    this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
-                    if (this._isDirectional) {
-                        this._soundPanner.coneInnerAngle = this._coneInnerAngle;
-                        this._soundPanner.coneOuterAngle = this._coneOuterAngle;
-                        this._soundPanner.coneOuterGain = this._coneOuterGain;
-                        this._soundPanner.setOrientation(this._localDirection.x, this._localDirection.y, this._localDirection.z);
-                    }
-                    this._soundSource.connect(this._soundPanner);
+                    if (this.spatialSound) {
+                        this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
+                        if (this._isDirectional) {
+                            this._soundPanner.coneInnerAngle = this._coneInnerAngle;
+                            this._soundPanner.coneOuterAngle = this._coneOuterAngle;
+                            this._soundPanner.coneOuterGain = this._coneOuterGain;
+                            if (this._connectedMesh) {
+                                this._updateDirection();
+                            } else {
+                                this._soundPanner.setOrientation(this._localDirection.x, this._localDirection.y, this._localDirection.z);
+                            }
+                        }
+                    }
+                    this._soundSource.connect(this._audioNode);
                     this._soundSource.loop = this.loop;
                     this._soundSource.start(startTime);
                     this._isPlaying = true;
@@ -29477,11 +29619,12 @@ var BABYLON;
         };
 
         Sound.prototype.pause = function () {
-            //this._soundSource.p
+            // TODO
         };
 
         Sound.prototype.setVolume = function (newVolume) {
             this._volume = newVolume;
+            this._soundGain.gain.value = newVolume;
         };
 
         Sound.prototype.getVolume = function () {
@@ -29491,6 +29634,10 @@ var BABYLON;
         Sound.prototype.attachToMesh = function (meshToConnectTo) {
             var _this = this;
             this._connectedMesh = meshToConnectTo;
+            if (!this.spatialSound) {
+                this._createSpatialParameters();
+                this.spatialSound = true;
+            }
             meshToConnectTo.registerAfterWorldMatrixUpdate(function (connectedMesh) {
                 return _this._onRegisterAfterWorldMatrixUpdate(connectedMesh);
             });
@@ -30421,14 +30568,22 @@ var BABYLON;
 
     var PolygonMeshBuilder = (function () {
         function PolygonMeshBuilder(name, contours, scene) {
-            this.name = name;
-            this.scene = scene;
             this._points = new PolygonPoints();
             if (!("poly2tri" in window)) {
                 throw "PolygonMeshBuilder cannot be used because poly2tri is not referenced";
             }
 
-            this._swctx = new poly2tri.SweepContext(this._points.add(contours));
+            this._name = name;
+            this._scene = scene;
+
+            var points;
+            if (contours instanceof BABYLON.Path2) {
+                points = contours.getPoints();
+            } else {
+                points = contours;
+            }
+
+            this._swctx = new poly2tri.SweepContext(this._points.add(points));
         }
         PolygonMeshBuilder.prototype.addHole = function (hole) {
             this._swctx.addHole(this._points.add(hole));
@@ -30437,7 +30592,7 @@ var BABYLON;
 
         PolygonMeshBuilder.prototype.build = function (updatable) {
             if (typeof updatable === "undefined") { updatable = false; }
-            var result = new BABYLON.Mesh(this.name, this.scene);
+            var result = new BABYLON.Mesh(this._name, this._scene);
 
             var normals = [];
             var positions = [];

Разница между файлами не показана из-за своего большого размера
+ 12 - 12
babylon.2.0-alpha.js