Преглед изворни кода

New cache mecanism for StandardMaterial

David Catuhe пре 9 година
родитељ
комит
d610234e71

Разлика између датотеке није приказан због своје велике величине
+ 16 - 22
dist/preview release/babylon.core.js


+ 181 - 166
dist/preview release/babylon.d.ts

@@ -1196,6 +1196,169 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class Animatable {
+        target: any;
+        fromFrame: number;
+        toFrame: number;
+        loopAnimation: boolean;
+        speedRatio: number;
+        onAnimationEnd: any;
+        private _localDelayOffset;
+        private _pausedDelay;
+        private _animations;
+        private _paused;
+        private _scene;
+        animationStarted: boolean;
+        constructor(scene: Scene, target: any, fromFrame?: number, toFrame?: number, loopAnimation?: boolean, speedRatio?: number, onAnimationEnd?: any, animations?: any);
+        getAnimations(): Animation[];
+        appendAnimations(target: any, animations: Animation[]): void;
+        getAnimationByTargetProperty(property: string): Animation;
+        reset(): void;
+        pause(): void;
+        restart(): void;
+        stop(): void;
+        _animate(delay: number): boolean;
+    }
+}
+
+declare module BABYLON {
+    class AnimationRange {
+        name: string;
+        from: number;
+        to: number;
+        constructor(name: string, from: number, to: number);
+    }
+    class Animation {
+        name: string;
+        targetProperty: string;
+        framePerSecond: number;
+        dataType: number;
+        loopMode: number;
+        private _keys;
+        private _offsetsCache;
+        private _highLimitsCache;
+        private _stopped;
+        _target: any;
+        private _easingFunction;
+        targetPropertyPath: string[];
+        currentFrame: number;
+        allowMatricesInterpolation: boolean;
+        private _ranges;
+        static CreateAndStartAnimation(name: string, mesh: AbstractMesh, targetProperty: string, framePerSecond: number, totalFrame: number, from: any, to: any, loopMode?: number, easingFunction?: EasingFunction, onAnimationEnd?: () => void): Animatable;
+        constructor(name: string, targetProperty: string, framePerSecond: number, dataType: number, loopMode?: number);
+        createRange(name: string, from: number, to: number): void;
+        deleteRange(name: string): void;
+        getRange(name: string): AnimationRange;
+        reset(): void;
+        isStopped(): boolean;
+        getKeys(): any[];
+        getEasingFunction(): IEasingFunction;
+        setEasingFunction(easingFunction: EasingFunction): void;
+        floatInterpolateFunction(startValue: number, endValue: number, gradient: number): number;
+        quaternionInterpolateFunction(startValue: Quaternion, endValue: Quaternion, gradient: number): Quaternion;
+        vector3InterpolateFunction(startValue: Vector3, endValue: Vector3, gradient: number): Vector3;
+        vector2InterpolateFunction(startValue: Vector2, endValue: Vector2, gradient: number): Vector2;
+        color3InterpolateFunction(startValue: Color3, endValue: Color3, gradient: number): Color3;
+        matrixInterpolateFunction(startValue: Matrix, endValue: Matrix, gradient: number): Matrix;
+        clone(): Animation;
+        setKeys(values: Array<any>): void;
+        private _getKeyValue(value);
+        private _interpolate(currentFrame, repeatCount, loopMode, offsetValue?, highLimitValue?);
+        animate(delay: number, from: number, to: number, loop: boolean, speedRatio: number): boolean;
+        private static _ANIMATIONTYPE_FLOAT;
+        private static _ANIMATIONTYPE_VECTOR3;
+        private static _ANIMATIONTYPE_QUATERNION;
+        private static _ANIMATIONTYPE_MATRIX;
+        private static _ANIMATIONTYPE_COLOR3;
+        private static _ANIMATIONTYPE_VECTOR2;
+        private static _ANIMATIONLOOPMODE_RELATIVE;
+        private static _ANIMATIONLOOPMODE_CYCLE;
+        private static _ANIMATIONLOOPMODE_CONSTANT;
+        static ANIMATIONTYPE_FLOAT: number;
+        static ANIMATIONTYPE_VECTOR3: number;
+        static ANIMATIONTYPE_VECTOR2: number;
+        static ANIMATIONTYPE_QUATERNION: number;
+        static ANIMATIONTYPE_MATRIX: number;
+        static ANIMATIONTYPE_COLOR3: number;
+        static ANIMATIONLOOPMODE_RELATIVE: number;
+        static ANIMATIONLOOPMODE_CYCLE: number;
+        static ANIMATIONLOOPMODE_CONSTANT: number;
+    }
+}
+
+declare module BABYLON {
+    interface IEasingFunction {
+        ease(gradient: number): number;
+    }
+    class EasingFunction implements IEasingFunction {
+        private static _EASINGMODE_EASEIN;
+        private static _EASINGMODE_EASEOUT;
+        private static _EASINGMODE_EASEINOUT;
+        static EASINGMODE_EASEIN: number;
+        static EASINGMODE_EASEOUT: number;
+        static EASINGMODE_EASEINOUT: number;
+        private _easingMode;
+        setEasingMode(easingMode: number): void;
+        getEasingMode(): number;
+        easeInCore(gradient: number): number;
+        ease(gradient: number): number;
+    }
+    class CircleEase extends EasingFunction implements IEasingFunction {
+        easeInCore(gradient: number): number;
+    }
+    class BackEase extends EasingFunction implements IEasingFunction {
+        amplitude: number;
+        constructor(amplitude?: number);
+        easeInCore(gradient: number): number;
+    }
+    class BounceEase extends EasingFunction implements IEasingFunction {
+        bounces: number;
+        bounciness: number;
+        constructor(bounces?: number, bounciness?: number);
+        easeInCore(gradient: number): number;
+    }
+    class CubicEase extends EasingFunction implements IEasingFunction {
+        easeInCore(gradient: number): number;
+    }
+    class ElasticEase extends EasingFunction implements IEasingFunction {
+        oscillations: number;
+        springiness: number;
+        constructor(oscillations?: number, springiness?: number);
+        easeInCore(gradient: number): number;
+    }
+    class ExponentialEase extends EasingFunction implements IEasingFunction {
+        exponent: number;
+        constructor(exponent?: number);
+        easeInCore(gradient: number): number;
+    }
+    class PowerEase extends EasingFunction implements IEasingFunction {
+        power: number;
+        constructor(power?: number);
+        easeInCore(gradient: number): number;
+    }
+    class QuadraticEase extends EasingFunction implements IEasingFunction {
+        easeInCore(gradient: number): number;
+    }
+    class QuarticEase extends EasingFunction implements IEasingFunction {
+        easeInCore(gradient: number): number;
+    }
+    class QuinticEase extends EasingFunction implements IEasingFunction {
+        easeInCore(gradient: number): number;
+    }
+    class SineEase extends EasingFunction implements IEasingFunction {
+        easeInCore(gradient: number): number;
+    }
+    class BezierCurveEase extends EasingFunction implements IEasingFunction {
+        x1: number;
+        y1: number;
+        x2: number;
+        y2: number;
+        constructor(x1?: number, y1?: number, x2?: number, y2?: number);
+        easeInCore(gradient: number): number;
+    }
+}
+
+declare module BABYLON {
     class Analyser {
         SMOOTHING: number;
         FFT_SIZE: number;
@@ -1362,169 +1525,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class Animatable {
-        target: any;
-        fromFrame: number;
-        toFrame: number;
-        loopAnimation: boolean;
-        speedRatio: number;
-        onAnimationEnd: any;
-        private _localDelayOffset;
-        private _pausedDelay;
-        private _animations;
-        private _paused;
-        private _scene;
-        animationStarted: boolean;
-        constructor(scene: Scene, target: any, fromFrame?: number, toFrame?: number, loopAnimation?: boolean, speedRatio?: number, onAnimationEnd?: any, animations?: any);
-        getAnimations(): Animation[];
-        appendAnimations(target: any, animations: Animation[]): void;
-        getAnimationByTargetProperty(property: string): Animation;
-        reset(): void;
-        pause(): void;
-        restart(): void;
-        stop(): void;
-        _animate(delay: number): boolean;
-    }
-}
-
-declare module BABYLON {
-    class AnimationRange {
-        name: string;
-        from: number;
-        to: number;
-        constructor(name: string, from: number, to: number);
-    }
-    class Animation {
-        name: string;
-        targetProperty: string;
-        framePerSecond: number;
-        dataType: number;
-        loopMode: number;
-        private _keys;
-        private _offsetsCache;
-        private _highLimitsCache;
-        private _stopped;
-        _target: any;
-        private _easingFunction;
-        targetPropertyPath: string[];
-        currentFrame: number;
-        allowMatricesInterpolation: boolean;
-        private _ranges;
-        static CreateAndStartAnimation(name: string, mesh: AbstractMesh, targetProperty: string, framePerSecond: number, totalFrame: number, from: any, to: any, loopMode?: number, easingFunction?: EasingFunction, onAnimationEnd?: () => void): Animatable;
-        constructor(name: string, targetProperty: string, framePerSecond: number, dataType: number, loopMode?: number);
-        createRange(name: string, from: number, to: number): void;
-        deleteRange(name: string): void;
-        getRange(name: string): AnimationRange;
-        reset(): void;
-        isStopped(): boolean;
-        getKeys(): any[];
-        getEasingFunction(): IEasingFunction;
-        setEasingFunction(easingFunction: EasingFunction): void;
-        floatInterpolateFunction(startValue: number, endValue: number, gradient: number): number;
-        quaternionInterpolateFunction(startValue: Quaternion, endValue: Quaternion, gradient: number): Quaternion;
-        vector3InterpolateFunction(startValue: Vector3, endValue: Vector3, gradient: number): Vector3;
-        vector2InterpolateFunction(startValue: Vector2, endValue: Vector2, gradient: number): Vector2;
-        color3InterpolateFunction(startValue: Color3, endValue: Color3, gradient: number): Color3;
-        matrixInterpolateFunction(startValue: Matrix, endValue: Matrix, gradient: number): Matrix;
-        clone(): Animation;
-        setKeys(values: Array<any>): void;
-        private _getKeyValue(value);
-        private _interpolate(currentFrame, repeatCount, loopMode, offsetValue?, highLimitValue?);
-        animate(delay: number, from: number, to: number, loop: boolean, speedRatio: number): boolean;
-        private static _ANIMATIONTYPE_FLOAT;
-        private static _ANIMATIONTYPE_VECTOR3;
-        private static _ANIMATIONTYPE_QUATERNION;
-        private static _ANIMATIONTYPE_MATRIX;
-        private static _ANIMATIONTYPE_COLOR3;
-        private static _ANIMATIONTYPE_VECTOR2;
-        private static _ANIMATIONLOOPMODE_RELATIVE;
-        private static _ANIMATIONLOOPMODE_CYCLE;
-        private static _ANIMATIONLOOPMODE_CONSTANT;
-        static ANIMATIONTYPE_FLOAT: number;
-        static ANIMATIONTYPE_VECTOR3: number;
-        static ANIMATIONTYPE_VECTOR2: number;
-        static ANIMATIONTYPE_QUATERNION: number;
-        static ANIMATIONTYPE_MATRIX: number;
-        static ANIMATIONTYPE_COLOR3: number;
-        static ANIMATIONLOOPMODE_RELATIVE: number;
-        static ANIMATIONLOOPMODE_CYCLE: number;
-        static ANIMATIONLOOPMODE_CONSTANT: number;
-    }
-}
-
-declare module BABYLON {
-    interface IEasingFunction {
-        ease(gradient: number): number;
-    }
-    class EasingFunction implements IEasingFunction {
-        private static _EASINGMODE_EASEIN;
-        private static _EASINGMODE_EASEOUT;
-        private static _EASINGMODE_EASEINOUT;
-        static EASINGMODE_EASEIN: number;
-        static EASINGMODE_EASEOUT: number;
-        static EASINGMODE_EASEINOUT: number;
-        private _easingMode;
-        setEasingMode(easingMode: number): void;
-        getEasingMode(): number;
-        easeInCore(gradient: number): number;
-        ease(gradient: number): number;
-    }
-    class CircleEase extends EasingFunction implements IEasingFunction {
-        easeInCore(gradient: number): number;
-    }
-    class BackEase extends EasingFunction implements IEasingFunction {
-        amplitude: number;
-        constructor(amplitude?: number);
-        easeInCore(gradient: number): number;
-    }
-    class BounceEase extends EasingFunction implements IEasingFunction {
-        bounces: number;
-        bounciness: number;
-        constructor(bounces?: number, bounciness?: number);
-        easeInCore(gradient: number): number;
-    }
-    class CubicEase extends EasingFunction implements IEasingFunction {
-        easeInCore(gradient: number): number;
-    }
-    class ElasticEase extends EasingFunction implements IEasingFunction {
-        oscillations: number;
-        springiness: number;
-        constructor(oscillations?: number, springiness?: number);
-        easeInCore(gradient: number): number;
-    }
-    class ExponentialEase extends EasingFunction implements IEasingFunction {
-        exponent: number;
-        constructor(exponent?: number);
-        easeInCore(gradient: number): number;
-    }
-    class PowerEase extends EasingFunction implements IEasingFunction {
-        power: number;
-        constructor(power?: number);
-        easeInCore(gradient: number): number;
-    }
-    class QuadraticEase extends EasingFunction implements IEasingFunction {
-        easeInCore(gradient: number): number;
-    }
-    class QuarticEase extends EasingFunction implements IEasingFunction {
-        easeInCore(gradient: number): number;
-    }
-    class QuinticEase extends EasingFunction implements IEasingFunction {
-        easeInCore(gradient: number): number;
-    }
-    class SineEase extends EasingFunction implements IEasingFunction {
-        easeInCore(gradient: number): number;
-    }
-    class BezierCurveEase extends EasingFunction implements IEasingFunction {
-        x1: number;
-        y1: number;
-        x2: number;
-        y2: number;
-        constructor(x1?: number, y1?: number, x2?: number, y2?: number);
-        easeInCore(gradient: number): number;
-    }
-}
-
-declare module BABYLON {
     class Bone extends Node {
         name: string;
         children: Bone[];
@@ -2589,6 +2589,13 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class MaterialDefines {
+        _keys: string[];
+        isEqual(other: MaterialDefines): boolean;
+        cloneTo(other: MaterialDefines): void;
+        reset(): void;
+        toString(): string;
+    }
     class Material {
         name: string;
         private static _TriangleFillMode;
@@ -3391,6 +3398,7 @@ declare module BABYLON {
         _positions: Vector3[];
         private _isDirty;
         _masterMesh: AbstractMesh;
+        _materialDefines: MaterialDefines;
         _boundingInfo: BoundingInfo;
         private _pivotMatrix;
         _isDisposed: boolean;
@@ -4682,8 +4690,14 @@ declare module BABYLON {
         private _normals;
         private _colors;
         private _uvs;
+        private _positions32;
+        private _normals32;
+        private _colors32;
+        private _uvs32;
         private _index;
         private _shapeCounter;
+        private _copy;
+        private _color;
         private _computeParticleColor;
         private _computeParticleTexture;
         private _computeParticleRotation;
@@ -4716,12 +4730,13 @@ declare module BABYLON {
         private _sinYaw;
         private _cosYaw;
         constructor(name: string, scene: Scene);
-        buildMesh(): Mesh;
-        private _meshBuilder(p, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors);
+        buildMesh(upgradable?: boolean): Mesh;
+        private _resetCopy();
+        private _meshBuilder(p, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors, customBuilder);
         private _posToShape(positions);
         private _uvsToShapeUV(uvs);
         private _addParticle(p, idxpos, shape, shapeUV, shapeId);
-        addShape(mesh: Mesh, nb: number): number;
+        addShape(mesh: Mesh, nb: number, customBuilder?: any): number;
         resetParticle(particle: SolidParticle): void;
         setParticles(start?: number, end?: number, update?: boolean): void;
         private _quaternionRotationYPR();

Разлика између датотеке није приказан због своје велике величине
+ 25 - 32
dist/preview release/babylon.js


Разлика између датотеке није приказан због своје велике величине
+ 163 - 119
dist/preview release/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 22 - 29
dist/preview release/babylon.noworker.js


+ 1 - 0
dist/preview release/what's new.md

@@ -1,5 +1,6 @@
 - 2.3.0:
   - **Major updates**
+    - New cache mecanism for StandardMaterial ([deltakosh](https://github.com/deltakosh))
     - New Solid Particle System ([jerome](https://github.com/jbousquie))
     - New `StandardMaterial.lightmapTexture` which can be controlled with `StandardMaterial.lightmapThreshold`. [Demo here](#NEEDDEMO) ([deltakosh](https://github.com/deltakosh))
     - Support for reflection probes. [See documentation here](http://doc.babylonjs.com/tutorials/How_to_use_Reflection_probes) ([deltakosh](https://github.com/deltakosh))

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

@@ -212,7 +212,7 @@ var BABYLON;
                         engine.generateMipMapsForCubemap(this._texture);
                     }
                 }
-                engine.unBindFramebuffer(this._texture, true);
+                engine.unBindFramebuffer(this._texture, this.isCube);
             }
         };
         RenderTargetTexture.prototype.clone = function () {

+ 1 - 1
src/Materials/Textures/babylon.renderTargetTexture.ts

@@ -240,7 +240,7 @@
                     }
                 }
 
-                engine.unBindFramebuffer(this._texture, true);
+                engine.unBindFramebuffer(this._texture, this.isCube);
             }
         }
 

+ 46 - 1
src/Materials/babylon.material.js

@@ -1,9 +1,54 @@
 var BABYLON;
 (function (BABYLON) {
+    var MaterialDefines = (function () {
+        function MaterialDefines() {
+        }
+        MaterialDefines.prototype.isEqual = function (other) {
+            for (var index = 0; index < this._keys.length; index++) {
+                var prop = this._keys[index];
+                if (this[prop] !== other[prop]) {
+                    return false;
+                }
+            }
+            return true;
+        };
+        MaterialDefines.prototype.cloneTo = function (other) {
+            for (var index = 0; index < this._keys.length; index++) {
+                var prop = this._keys[index];
+                other[prop] = this[prop];
+            }
+        };
+        MaterialDefines.prototype.reset = function () {
+            for (var index = 0; index < this._keys.length; index++) {
+                var prop = this._keys[index];
+                if (prop === "BonesPerMesh") {
+                    this[prop] = 0;
+                    continue;
+                }
+                this[prop] = false;
+            }
+        };
+        MaterialDefines.prototype.toString = function () {
+            var result = "";
+            for (var index = 0; index < this._keys.length; index++) {
+                var prop = this._keys[index];
+                if (prop === "BonesPerMesh" && this[prop] > 0) {
+                    result += "#define BonesPerMesh " + this[prop] + "\n";
+                    continue;
+                }
+                if (this[prop]) {
+                    result += "#define " + prop + "\n";
+                }
+            }
+            return result;
+        };
+        return MaterialDefines;
+    })();
+    BABYLON.MaterialDefines = MaterialDefines;
     var Material = (function () {
         function Material(name, scene, doNotAdd) {
             this.name = name;
-            this.checkReadyOnEveryCall = true;
+            this.checkReadyOnEveryCall = false;
             this.checkReadyOnlyOnce = false;
             this.state = "";
             this.alpha = 1.0;

+ 56 - 1
src/Materials/babylon.material.ts

@@ -1,4 +1,59 @@
 module BABYLON {
+    export class MaterialDefines {
+        _keys: string[];
+
+        public isEqual(other: MaterialDefines): boolean {
+            for (var index = 0; index < this._keys.length; index++) {
+                var prop = this._keys[index];
+
+                if (this[prop] !== other[prop]) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        public cloneTo(other: MaterialDefines): void {
+            for (var index = 0; index < this._keys.length; index++) {
+                var prop = this._keys[index];
+
+                other[prop] = this[prop];
+            }
+        }
+
+        public reset(): void {
+            for (var index = 0; index < this._keys.length; index++) {
+                var prop = this._keys[index];
+
+                if (prop === "BonesPerMesh") {
+                    this[prop] = 0;
+                    continue;
+                }
+
+                this[prop] = false;
+            }
+        }
+
+        public toString(): string {
+            var result = "";
+            for (var index = 0; index < this._keys.length; index++) {
+                var prop = this._keys[index];
+
+                if (prop === "BonesPerMesh" && this[prop] > 0) {
+                    result += "#define BonesPerMesh " + this[prop] + "\n";
+                    continue;
+                }
+
+                if (this[prop]) {
+                    result += "#define " + prop + "\n";
+                }
+            }
+
+            return result;
+        }
+    }
+
     export class Material {
         private static _TriangleFillMode = 0;
         private static _WireFrameFillMode = 1;
@@ -28,7 +83,7 @@
         }
 
         public id: string;
-        public checkReadyOnEveryCall = true;
+        public checkReadyOnEveryCall = false;
         public checkReadyOnlyOnce = false;
         public state = "";
         public alpha = 1.0;

+ 4 - 41
src/Materials/babylon.pbrMaterial.js

@@ -6,8 +6,10 @@ var __extends = (this && this.__extends) || function (d, b) {
 var BABYLON;
 (function (BABYLON) {
     var maxSimultaneousLights = 4;
-    var PBRMaterialDefines = (function () {
+    var PBRMaterialDefines = (function (_super) {
+        __extends(PBRMaterialDefines, _super);
         function PBRMaterialDefines() {
+            _super.call(this);
             this.ALBEDO = false;
             this.CLIPPLANE = false;
             this.ALPHATEST = false;
@@ -24,47 +26,8 @@ var BABYLON;
             this.POINTSIZE = false;
             this._keys = Object.keys(this);
         }
-        PBRMaterialDefines.prototype.isEqual = function (other) {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-                if (this[prop] !== other[prop]) {
-                    return false;
-                }
-            }
-            return true;
-        };
-        PBRMaterialDefines.prototype.cloneTo = function (other) {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-                other[prop] = this[prop];
-            }
-        };
-        PBRMaterialDefines.prototype.reset = function () {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-                if (prop === "BonesPerMesh") {
-                    this[prop] = 0;
-                    continue;
-                }
-                this[prop] = false;
-            }
-        };
-        PBRMaterialDefines.prototype.toString = function () {
-            var result = "";
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-                if (prop === "BonesPerMesh" && this[prop] > 0) {
-                    result += "#define BonesPerMesh " + this[prop] + "\n";
-                    continue;
-                }
-                if (this[prop]) {
-                    result += "#define " + prop + "\n";
-                }
-            }
-            return result;
-        };
         return PBRMaterialDefines;
-    })();
+    })(BABYLON.MaterialDefines);
     var PBRMaterial = (function (_super) {
         __extends(PBRMaterial, _super);
         function PBRMaterial(name, scene) {

+ 2 - 54
src/Materials/babylon.pbrMaterial.ts

@@ -1,7 +1,7 @@
 module BABYLON {
     var maxSimultaneousLights = 4;
 
-    class PBRMaterialDefines {
+    class PBRMaterialDefines extends MaterialDefines {
         public ALBEDO = false;
         public CLIPPLANE = false;
         public ALPHATEST = false;
@@ -17,62 +17,10 @@
         public INSTANCES = false;
         public POINTSIZE = false;
 
-        _keys: string[];
-
         constructor() {
+            super();
             this._keys = Object.keys(this);
         }
-
-        public isEqual(other: PBRMaterialDefines): boolean {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-
-                if (this[prop] !== other[prop]) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        public cloneTo(other: PBRMaterialDefines): void {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-
-                other[prop] = this[prop];
-            }
-        }
-
-        public reset(): void {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-
-                if (prop === "BonesPerMesh") {
-                    this[prop] = 0;
-                    continue;
-                }
-
-                this[prop] = false;
-            }
-        }
-
-        public toString(): string {
-            var result = "";
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-
-                if (prop === "BonesPerMesh" && this[prop] > 0) {
-                    result += "#define BonesPerMesh " + this[prop] + "\n";
-                    continue;
-                }
-
-                if (this[prop]) {
-                    result += "#define " + prop + "\n";
-                }
-            }
-
-            return result;
-        }
     }
 
     export class PBRMaterial extends Material {

+ 16 - 42
src/Materials/babylon.standardMaterial.js

@@ -22,8 +22,10 @@ var BABYLON;
         return FresnelParameters;
     })();
     BABYLON.FresnelParameters = FresnelParameters;
-    var StandardMaterialDefines = (function () {
+    var StandardMaterialDefines = (function (_super) {
+        __extends(StandardMaterialDefines, _super);
         function StandardMaterialDefines() {
+            _super.call(this);
             this.DIFFUSE = false;
             this.AMBIENT = false;
             this.OPACITY = false;
@@ -97,47 +99,8 @@ var BABYLON;
             this.INVERTCUBICMAP = false;
             this._keys = Object.keys(this);
         }
-        StandardMaterialDefines.prototype.isEqual = function (other) {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-                if (this[prop] !== other[prop]) {
-                    return false;
-                }
-            }
-            return true;
-        };
-        StandardMaterialDefines.prototype.cloneTo = function (other) {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-                other[prop] = this[prop];
-            }
-        };
-        StandardMaterialDefines.prototype.reset = function () {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-                if (prop === "BonesPerMesh") {
-                    this[prop] = 0;
-                    continue;
-                }
-                this[prop] = false;
-            }
-        };
-        StandardMaterialDefines.prototype.toString = function () {
-            var result = "";
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-                if (prop === "BonesPerMesh" && this[prop] > 0) {
-                    result += "#define BonesPerMesh " + this[prop] + "\n";
-                    continue;
-                }
-                if (this[prop]) {
-                    result += "#define " + prop + "\n";
-                }
-            }
-            return result;
-        };
         return StandardMaterialDefines;
-    })();
+    })(BABYLON.MaterialDefines);
     var StandardMaterial = (function (_super) {
         __extends(StandardMaterial, _super);
         function StandardMaterial(name, scene) {
@@ -194,7 +157,12 @@ var BABYLON;
             var scene = this.getScene();
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
-                    return true;
+                    if (!mesh) {
+                        return true;
+                    }
+                    if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
+                        return true;
+                    }
                 }
             }
             var engine = scene.getEngine();
@@ -561,6 +529,12 @@ var BABYLON;
             }
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
+            if (mesh) {
+                if (!mesh._materialDefines) {
+                    mesh._materialDefines = new StandardMaterialDefines();
+                }
+                this._defines.cloneTo(mesh._materialDefines);
+            }
             return true;
         };
         StandardMaterial.prototype.unbind = function () {

+ 19 - 55
src/Materials/babylon.standardMaterial.ts

@@ -17,7 +17,7 @@
         }
     }
 
-    class StandardMaterialDefines {
+    class StandardMaterialDefines extends MaterialDefines {
         public DIFFUSE = false;
         public AMBIENT = false;
         public OPACITY = false;
@@ -90,62 +90,10 @@
         public REFLECTIONMAP_EXPLICIT = false;
         public INVERTCUBICMAP = false;
 
-        _keys: string[];
-
         constructor() {
+            super();
             this._keys = Object.keys(this);
         }
-
-        public isEqual(other: StandardMaterialDefines): boolean {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-
-                if (this[prop] !== other[prop]) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        public cloneTo(other: StandardMaterialDefines): void {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-
-                other[prop] = this[prop];
-            }
-        }
-
-        public reset(): void {
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-
-                if (prop === "BonesPerMesh") {
-                    this[prop] = 0;
-                    continue;
-                }
-
-                this[prop] = false;
-            }
-        }
-
-        public toString(): string {
-            var result = "";
-            for (var index = 0; index < this._keys.length; index++) {
-                var prop = this._keys[index];
-
-                if (prop === "BonesPerMesh" && this[prop] > 0) {
-                    result += "#define BonesPerMesh " + this[prop] + "\n";
-                    continue;
-                }
-
-                if (this[prop]) {
-                    result += "#define " + prop + "\n";
-                }
-            }
-
-            return result;
-        }
     }
 
     export class StandardMaterial extends Material {
@@ -234,7 +182,14 @@
 
             if (!this.checkReadyOnEveryCall) {
                 if (this._renderId === scene.getRenderId()) {
-                    return true;
+
+                    if (!mesh) {
+                        return true;
+                    }
+
+                    if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
+                        return true;
+                    }
                 }
             }
 
@@ -672,6 +627,15 @@
 
             this._renderId = scene.getRenderId();
             this._wasPreviouslyReady = true;
+
+            if (mesh) {
+                if (!mesh._materialDefines) {
+                    mesh._materialDefines = new StandardMaterialDefines();
+                }
+
+                this._defines.cloneTo(mesh._materialDefines);
+            }
+
             return true;
         }
 

+ 1 - 0
src/Mesh/babylon.abstractMesh.ts

@@ -109,6 +109,7 @@
         public _positions: Vector3[];
         private _isDirty = false;
         public _masterMesh: AbstractMesh;
+        public _materialDefines: MaterialDefines;
 
         public _boundingInfo: BoundingInfo;
         private _pivotMatrix = Matrix.Identity();

+ 1 - 2
src/Mesh/babylon.meshBuilder.js

@@ -330,7 +330,6 @@ var BABYLON;
             var updatable = options.updatable;
             var sideOrientation = options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
             var instance = options.instance;
-            options.arc = (options.arc <= 0) ? 1.0 : options.arc || 1.0;
             // tube geometry
             var tubePathArray = function (path, path3D, circlePaths, radius, tessellation, radiusFunction, cap, arc) {
                 var tangents = path3D.getTangents();
@@ -426,7 +425,7 @@ var BABYLON;
             var position = options.position || BABYLON.Vector3.Zero();
             var normal = options.normal || BABYLON.Vector3.Up();
             var size = options.size || new BABYLON.Vector3(1, 1, 1);
-            var angle = options.angle;
+            var angle = options.angle || 0;
             // Getting correct rotation
             if (!normal) {
                 var target = new BABYLON.Vector3(0, 0, 1);

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

@@ -495,7 +495,7 @@
             var position = options.position || Vector3.Zero();
             var normal = options.normal || Vector3.Up();
             var size = options.size || new Vector3(1, 1, 1);
-            var angle = options.angle;
+            var angle = options.angle || 0;
             
             // Getting correct rotation
             if (!normal) {

+ 94 - 32
src/Particles/babylon.solidParticleSystem.js

@@ -14,6 +14,8 @@ var BABYLON;
             this._uvs = new Array();
             this._index = 0; // indices index
             this._shapeCounter = 0;
+            this._copy = { position: BABYLON.Vector3.Zero(), rotation: BABYLON.Vector3.Zero(), scale: new BABYLON.Vector3(1, 1, 1), quaternion: null, uvs: new BABYLON.Vector4(0, 0, 1, 1), colors: null };
+            this._color = new BABYLON.Color4(0, 0, 0, 0);
             this._computeParticleColor = true;
             this._computeParticleTexture = true;
             this._computeParticleRotation = true;
@@ -47,46 +49,106 @@ var BABYLON;
             this._camera = scene.activeCamera;
         }
         // build the SPS mesh : returns the mesh
-        SolidParticleSystem.prototype.buildMesh = function () {
+        SolidParticleSystem.prototype.buildMesh = function (upgradable) {
+            if (upgradable === void 0) { upgradable = true; }
             if (this.nbParticles === 0) {
                 var triangle = BABYLON.MeshBuilder.CreateDisc("", { radius: 1, tessellation: 3 }, this._scene);
                 this.addShape(triangle, 1);
                 triangle.dispose();
             }
-            BABYLON.VertexData.ComputeNormals(this._positions, this._indices, this._normals);
+            this._positions32 = new Float32Array(this._positions);
+            this._uvs32 = new Float32Array(this._uvs);
+            this._colors32 = new Float32Array(this._colors);
+            BABYLON.VertexData.ComputeNormals(this._positions32, this._indices, this._normals);
+            this._normals32 = new Float32Array(this._normals);
             var vertexData = new BABYLON.VertexData();
-            vertexData.positions = this._positions;
+            vertexData.set(this._positions32, BABYLON.VertexBuffer.PositionKind);
             vertexData.indices = this._indices;
-            vertexData.normals = this._normals;
-            if (this._uvs) {
-                vertexData.uvs = this._uvs;
+            vertexData.set(this._normals32, BABYLON.VertexBuffer.NormalKind);
+            if (this._uvs32) {
+                vertexData.set(this._uvs32, BABYLON.VertexBuffer.UVKind);
+                ;
             }
-            if (this._colors) {
-                vertexData.colors = this._colors;
+            if (this._colors32) {
+                vertexData.set(this._colors32, BABYLON.VertexBuffer.ColorKind);
             }
             var mesh = new BABYLON.Mesh(name, this._scene);
-            vertexData.applyToMesh(mesh, true);
+            vertexData.applyToMesh(mesh, upgradable);
             this.mesh = mesh;
+            // free memory
+            this._positions = null;
+            this._normals = null;
+            this._uvs = null;
+            this._colors = null;
             return mesh;
         };
+        //reset copy
+        SolidParticleSystem.prototype._resetCopy = function () {
+            this._copy.position.x = 0;
+            this._copy.position.y = 0;
+            this._copy.position.z = 0;
+            this._copy.rotation.x = 0;
+            this._copy.rotation.y = 0;
+            this._copy.rotation.z = 0;
+            this._copy.quaternion = null;
+            this._copy.scale.x = 1;
+            this._copy.scale.y = 1;
+            this._copy.scale.z = 1;
+            this._copy.uvs.x = 0;
+            this._copy.uvs.y = 0;
+            this._copy.uvs.z = 1;
+            this._copy.uvs.w = 1;
+            this._copy.colors = null;
+        };
         // _meshBuilder : inserts the shape model in the global SPS mesh
-        SolidParticleSystem.prototype._meshBuilder = function (p, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors) {
+        SolidParticleSystem.prototype._meshBuilder = function (p, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors, customBuilder) {
             var i;
             var u = 0;
             var c = 0;
+            if (customBuilder) {
+                this._resetCopy();
+                customBuilder(this._copy, p);
+            }
+            if (this._copy.quaternion) {
+                this._quaternion.x = this._copy.quaternion.x;
+                this._quaternion.y = this._copy.quaternion.y;
+                this._quaternion.z = this._copy.quaternion.z;
+                this._quaternion.w = this._copy.quaternion.w;
+            }
+            else {
+                this._yaw = this._copy.rotation.y;
+                this._pitch = this._copy.rotation.x;
+                this._roll = this._copy.rotation.z;
+                this._quaternionRotationYPR();
+            }
+            this._quaternionToRotationMatrix();
             for (i = 0; i < shape.length; i++) {
-                positions.push(shape[i].x, shape[i].y, shape[i].z);
+                this._vertex.x = shape[i].x * this._copy.scale.x;
+                this._vertex.y = shape[i].y * this._copy.scale.y;
+                this._vertex.z = shape[i].z * this._copy.scale.z;
+                BABYLON.Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
+                positions.push(this._copy.position.x + this._rotated.x, this._copy.position.y + this._rotated.y, this._copy.position.z + this._rotated.z);
                 if (meshUV) {
-                    uvs.push(meshUV[u], meshUV[u + 1]);
+                    uvs.push((this._copy.uvs.z - this._copy.uvs.x) * meshUV[u] + this._copy.uvs.x, (this._copy.uvs.w - this._copy.uvs.y) * meshUV[u + 1] + this._copy.uvs.y);
                     u += 2;
                 }
-                if (meshCol) {
-                    colors.push(meshCol[c] || 1, meshCol[c + 1] || 1, meshCol[c + 2] || 1, meshCol[c + 3] || 1);
-                    c += 4;
+                if (this._copy.colors) {
+                    this._color = this._copy.colors;
+                }
+                else if (meshCol && meshCol[c]) {
+                    this._color.r = meshCol[c];
+                    this._color.g = meshCol[c + 1];
+                    this._color.b = meshCol[c + 2];
+                    this._color.a = meshCol[c + 3];
                 }
                 else {
-                    colors.push(1, 1, 1, 1);
+                    this._color.r = 1;
+                    this._color.g = 1;
+                    this._color.b = 1;
+                    this._color.a = 1;
                 }
+                colors.push(this._color.r, this._color.g, this._color.b, this._color.a);
+                c += 4;
             }
             for (i = 0; i < meshInd.length; i++) {
                 indices.push(p + meshInd[i]);
@@ -120,7 +182,7 @@ var BABYLON;
             this._previousParticle = this._particle;
         };
         // add solid particles from a shape model in the particles array
-        SolidParticleSystem.prototype.addShape = function (mesh, nb) {
+        SolidParticleSystem.prototype.addShape = function (mesh, nb, customBuilder) {
             var meshPos = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             var meshInd = mesh.getIndices();
             var meshUV = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
@@ -129,7 +191,7 @@ var BABYLON;
             var shapeUV = this._uvsToShapeUV(meshUV);
             // particles
             for (var i = 0; i < nb; i++) {
-                this._meshBuilder(this._index, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors);
+                this._meshBuilder(this._index, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors, customBuilder);
                 this._addParticle(this.nbParticles + i, this._positions.length, shape, shapeUV, this._shapeCounter);
                 this._index += shape.length;
             }
@@ -222,18 +284,18 @@ var BABYLON;
                         this.updateParticleVertex(this._particle, this._vertex, pt);
                     }
                     BABYLON.Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
-                    this._positions[idx] = this._particle.position.x + this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
-                    this._positions[idx + 1] = this._particle.position.y + this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
-                    this._positions[idx + 2] = this._particle.position.z + this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
+                    this._positions32[idx] = this._particle.position.x + this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
+                    this._positions32[idx + 1] = this._particle.position.y + this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
+                    this._positions32[idx + 2] = this._particle.position.z + this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
                     if (this._computeParticleColor) {
-                        this._colors[colidx] = this._particle.color.r;
-                        this._colors[colidx + 1] = this._particle.color.g;
-                        this._colors[colidx + 2] = this._particle.color.b;
-                        this._colors[colidx + 3] = this._particle.color.a;
+                        this._colors32[colidx] = this._particle.color.r;
+                        this._colors32[colidx + 1] = this._particle.color.g;
+                        this._colors32[colidx + 2] = this._particle.color.b;
+                        this._colors32[colidx + 3] = this._particle.color.a;
                     }
                     if (this._computeParticleTexture) {
-                        this._uvs[uvidx] = this._particle._shapeUV[pt * 2] * (this._particle.uvs.z - this._particle.uvs.x) + this._particle.uvs.x;
-                        this._uvs[uvidx + 1] = this._particle._shapeUV[pt * 2 + 1] * (this._particle.uvs.w - this._particle.uvs.y) + this._particle.uvs.y;
+                        this._uvs32[uvidx] = this._particle._shapeUV[pt * 2] * (this._particle.uvs.z - this._particle.uvs.x) + this._particle.uvs.x;
+                        this._uvs32[uvidx + 1] = this._particle._shapeUV[pt * 2 + 1] * (this._particle.uvs.w - this._particle.uvs.y) + this._particle.uvs.y;
                     }
                 }
                 index = idx + 3;
@@ -242,15 +304,15 @@ var BABYLON;
             }
             if (update) {
                 if (this._computeParticleColor) {
-                    this.mesh.updateVerticesData(BABYLON.VertexBuffer.ColorKind, this._colors, false, false);
+                    this.mesh.updateVerticesData(BABYLON.VertexBuffer.ColorKind, this._colors32, false, false);
                 }
                 if (this._computeParticleTexture) {
-                    this.mesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, this._uvs, false, false);
+                    this.mesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, this._uvs32, false, false);
                 }
-                this.mesh.updateVerticesData(BABYLON.VertexBuffer.PositionKind, this._positions, false, false);
+                this.mesh.updateVerticesData(BABYLON.VertexBuffer.PositionKind, this._positions32, false, false);
                 if (!this.mesh.areNormalsFrozen) {
-                    BABYLON.VertexData.ComputeNormals(this._positions, this._indices, this._normals);
-                    this.mesh.updateVerticesData(BABYLON.VertexBuffer.NormalKind, this._normals, false, false);
+                    BABYLON.VertexData.ComputeNormals(this._positions32, this._indices, this._normals32);
+                    this.mesh.updateVerticesData(BABYLON.VertexBuffer.NormalKind, this._normals32, false, false);
                 }
             }
             this.afterUpdateParticles(start, end, update);

+ 3 - 2
src/Particles/babylon.solidParticleSystem.ts

@@ -22,8 +22,8 @@ module BABYLON {
         private _uvs32: Float32Array;
         private _index: number = 0;  // indices index
         private _shapeCounter: number = 0;
-        private _copy: any = {position: Vector3.Zero(), rotation: Vector3.Zero(), scale: new Vector3(1,1,1), quaternion: null, uvs: new Vector4(0,0,1,1), colors: null};
-        private _color: Color4 = new Color4(0,0,0,0);
+        private _copy: any = { position: Vector3.Zero(), rotation: Vector3.Zero(), scale: new Vector3(1, 1, 1), quaternion: null, uvs: new Vector4(0, 0, 1, 1), colors: null };
+        private _color: Color4 = new Color4(0, 0, 0, 0);
         private _computeParticleColor: boolean = true;
         private _computeParticleTexture: boolean = true;
         private _computeParticleRotation: boolean = true;
@@ -472,3 +472,4 @@ module BABYLON {
         }
     }
 }
+