浏览代码

New features in Tools class and MathLib

Tools
 - getClassName() now also supports objects having a getClassName():string method.
 - adding hasCodeFromStream() to compute a hash Code on a sequence of objects.

MathLib
 - getClassName() and getHashCode() is implemented for the following types: Color3/4, Vector2/3/4, Size, Quaternion, Matrix, Plane
nockawa 9 年之前
父节点
当前提交
b38f716b53
共有 3 个文件被更改,包括 158 次插入10 次删除
  1. 2 2
      dist/preview release/what's new.md
  2. 104 0
      src/Math/babylon.math.ts
  3. 52 8
      src/Tools/babylon.tools.ts

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

@@ -9,7 +9,7 @@
     - Animations blending. See [demo here](http://www.babylonjs-playground.com/#2BLI9T#3). More [info here](http://doc.babylonjs.com/tutorials/Animations#animation-blending) ([deltakosh](https://github.com/deltakosh))
     - New debuger tool: SkeletonViewer. See [demo here](http://www.babylonjs-playground.com/#1BZJVJ#8) (Adam & [deltakosh](https://github.com/deltakosh))
     - Added Camera Inputs Manager to manage camera inputs (mouse, touch, keyboard, gamepad, ...) in a composable way, without relying on class inheritance ([gleborgne](https://github.com/gleborgne))
-    - Introduced new observable system to handle events ([nockawa](https://github.com/nockawa), [deltakosh](https://github.com/deltakosh))
+    - Introduced new observable system to handle events ([quick doc](http://www.html5gamedevs.com/topic/22655-big-brother-is-back-observable-everywhere/)) ([nockawa](https://github.com/nockawa), [deltakosh](https://github.com/deltakosh))
     - Added a new VR camera : VRDeviceOrientationArcRotateCamera ([temechon](https://github.com/Temechon))
     - Unity3D exporter: Added support for lightmaps ([davrous](https://github.com/davrous), [deltakosh](https://github.com/deltakosh))
     - Unity3D exporter: Added support for export and run (local webserver) ([davrous](https://github.com/davrous), [deltakosh](https://github.com/deltakosh))
@@ -38,7 +38,7 @@
     - LinesMesh class now supports Intersection. Added the intersectionThreshold property to set a tolerance margin during intersection with wire lines. ([nockawa](https://github.com/nockawa))
     - Geometry.boundingBias property to enlarge the boundingInfo objects ([nockawa](https://github.com/nockawa))
     - Tools.ExtractMinAndMax & ExtractMinAndMaxIndexed now supports an optional Bias for Extent computation.
-	  - Added StringDictionary<T> class to implement an efficient generic typed string dictionary based on Javascript associative array. ([quick dock](http://www.html5gamedevs.com/topic/22566-be-efficient-my-friend-use-stringdictionary/)) ([nockawa](https://github.com/nockawa))
+	  - Added StringDictionary<T> class to implement an efficient generic typed string dictionary based on Javascript associative array. ([quick doc](http://www.html5gamedevs.com/topic/22566-be-efficient-my-friend-use-stringdictionary/)) ([nockawa](https://github.com/nockawa))
 	  - Added RectanglePackingMap class to fit several rectangles in a big map in the most optimal way, dynamically. ([nockawa](https://github.com/nockawa))
 	  - Added DynamicFloatArray class to store float32 based elements of a given size (stride) into one big Float32Array, with allocation/free/pack operations to then access an optimal buffer that can be used to update a WebGLBuffer dynamically.([quick doc](http://www.html5gamedevs.com/topic/22567-dynamicfloatarray-to-the-rescue-for-efficient-instanced-array/)) ([nockawa](https://github.com/nockawa))
 	  - Scene.onPointerObservable property added to enable a unique Observable event for user input (see ArcRotateCamera inputs for examples) ([nockawa](https://github.com/nockawa))

+ 104 - 0
src/Math/babylon.math.ts

@@ -48,6 +48,17 @@
             return "{R: " + this.r + " G:" + this.g + " B:" + this.b + "}";
         }
 
+        public getClassName(): string {
+            return "Color3";
+        }
+
+        public getHashCode(): number {
+            let hash = this.r || 0;
+            hash = (hash * 397) ^ (this.g || 0);
+            hash = (hash * 397) ^ (this.b || 0);
+            return hash;
+        }
+
         // Operators
         public toArray(array: number[], index?: number): Color3 {
             if (index === undefined) {
@@ -298,6 +309,18 @@
             return "{R: " + this.r + " G:" + this.g + " B:" + this.b + " A:" + this.a + "}";
         }
 
+        public getClassName(): string {
+            return "Color4";
+        }
+
+        public getHashCode(): number {
+            let hash = this.r || 0;
+            hash = (hash * 397) ^ (this.g || 0);
+            hash = (hash * 397) ^ (this.b || 0);
+            hash = (hash * 397) ^ (this.a || 0);
+            return hash;
+        }
+
         public clone(): Color4 {
             return new Color4(this.r, this.g, this.b, this.a);
         }
@@ -385,6 +408,16 @@
             return "{X: " + this.x + " Y:" + this.y + "}";
         }
 
+        public getClassName(): string {
+            return "Vector2";
+        }
+
+        public getHashCode(): number {
+            let hash = this.x || 0;
+            hash = (hash * 397) ^ (this.y || 0);
+            return hash;
+        }
+
         // Operators
         public toArray(array: number[], index: number = 0): Vector2 {
             array[index] = this.x;
@@ -640,6 +673,17 @@
             return "{X: " + this.x + " Y:" + this.y + " Z:" + this.z + "}";
         }
 
+        public getClassName(): string {
+            return "Vector3";
+        }
+
+        public getHashCode(): number {
+            let hash = this.x || 0;
+            hash = (hash * 397) ^ (this.y || 0);
+            hash = (hash * 397) ^ (this.z || 0);
+            return hash;
+        }
+
         // Operators
         public asArray(): number[] {
             var result = [];
@@ -1261,6 +1305,18 @@
             return "{X: " + this.x + " Y:" + this.y + " Z:" + this.z + "W:" + this.w + "}";
         }
 
+        public getClassName(): string {
+            return "Vector4";
+        }
+
+        public getHashCode(): number {
+            let hash = this.x || 0;
+            hash = (hash * 397) ^ (this.y || 0);
+            hash = (hash * 397) ^ (this.z || 0);
+            hash = (hash * 397) ^ (this.w || 0);
+            return hash;
+        }
+
         // Operators
         public asArray(): number[] {
             var result = [];
@@ -1579,6 +1635,20 @@
             this.height = height;
         }
 
+        public toString(): string {
+            return `{W: ${this.width}, H: ${this.height}}`;
+        }
+
+        public getClassName(): string {
+            return "Size";
+        }
+
+        public getHashCode(): number {
+            let hash = this.width || 0;
+            hash = (hash * 397) ^ (this.height || 0);
+            return hash;
+        }
+
         public clone(): Size {
             return new Size(this.width, this.height);
         }
@@ -1627,6 +1697,18 @@
             return "{X: " + this.x + " Y:" + this.y + " Z:" + this.z + " W:" + this.w + "}";
         }
 
+        public getClassName(): string {
+            return "Quaternion";
+        }
+
+        public getHashCode(): number {
+            let hash = this.x || 0;
+            hash = (hash * 397) ^ (this.y || 0);
+            hash = (hash * 397) ^ (this.z || 0);
+            hash = (hash * 397) ^ (this.w || 0);
+            return hash;
+        }
+
         public asArray(): number[] {
             return [this.x, this.y, this.z, this.w];
         }
@@ -2216,6 +2298,18 @@
                 this.m[12], this.m[13], this.m[14], this.m[15]);
         }
 
+        public getClassName(): string {
+            return "Matrix";
+        }
+
+        public getHashCode(): number {
+            let hash = this.m[0] || 0;
+            for (let i = 1; i < 16; i++) {
+                hash = (hash * 397) ^ (this.m[i] || 0);
+            }
+            return hash;
+        }
+
         public decompose(scale: Vector3, rotation: Quaternion, translation: Vector3): boolean {
             translation.x = this.m[12];
             translation.y = this.m[13];
@@ -2838,6 +2932,16 @@
             return new Plane(this.normal.x, this.normal.y, this.normal.z, this.d);
         }
 
+        public getClassName(): string {
+            return "Plane";
+        }
+
+        public getHashCode(): number {
+            let hash = this.normal.getHashCode();
+            hash = (hash * 397) ^ (this.d || 0);
+            return hash;
+        }
+
         public normalize(): Plane {
             var norm = (Math.sqrt((this.normal.x * this.normal.x) + (this.normal.y * this.normal.y) + (this.normal.z * this.normal.z)));
             var magnitude = 0;

+ 52 - 8
src/Tools/babylon.tools.ts

@@ -910,14 +910,18 @@
          */
         public static getClassName(object, isType: boolean = false): string {
             let name = null;
-            if (object instanceof Object) {
-                let classObj = isType ? object :  Object.getPrototypeOf(object);
-                name = classObj.constructor["__bjsclassName__"];
-            }
-            if (!name) {
-                name = typeof object;
-            }
 
+            if (!isType && object.getClassName) {
+                name = object.getClassName();
+            } else {
+                if (object instanceof Object) {
+                    let classObj = isType ? object : Object.getPrototypeOf(object);
+                    name = classObj.constructor["__bjsclassName__"];
+                }
+                if (!name) {
+                    name = typeof object;
+                }
+            }
             return name;
         }
 
@@ -929,6 +933,46 @@
             }
         }
 
+        /**
+         * This method can be used with hashCodeFromStream when your input is an array of values that are either: number, string, boolean or custom type implementing the getHashCode():number method.
+         * @param array
+         */
+        public static arrayOrStringFeeder(array: any): (i) => number {
+            return (index: number) =>
+            {
+                if (index >= array.length) {
+                    return null;
+                }
+
+                let val = array.charCodeAt ? array.charCodeAt(index) : array[index];
+                if (val && val.getHashCode) {
+                    val = val.getHashCode();
+                }
+                if (typeof val === "string") {
+                    return Tools.hashCodeFromStream(Tools.arrayOrStringFeeder(val));
+                }
+                return val;
+            };
+        }
+
+        /**
+         * Compute the hashCode of a stream of number
+         * To compute the HashCode on a string or an Array of data types implementing the getHashCode() method, use the arrayOrStringFeeder method.
+         * @param feeder a callback that will be called until it returns null, each valid returned values will be used to compute the hash code.
+         * @return the hash code computed
+         */
+        public static hashCodeFromStream(feeder: (index: number) => number): number {
+            // Based from here: http://stackoverflow.com/a/7616484/802124
+            let hash = 0;
+            let index = 0;
+            let chr = feeder(index++);
+            while (chr != null) {
+                hash = ((hash << 5) - hash) + chr;
+                hash |= 0;                          // Convert to 32bit integer
+                chr = feeder(index++);
+            }
+            return hash;
+        }
     }
 
     /**
@@ -943,7 +987,7 @@
         }
     }
 
-    /**
+     /**
      * An implementation of a loop for asynchronous functions.
      */
     export class AsyncLoop {