瀏覽代碼

Merge pull request #1140 from nockawa/engine2d

Many little improvments
David Catuhe 9 年之前
父節點
當前提交
d2ceda6a0d

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

@@ -5,7 +5,7 @@
     - Support for shaders includes ([deltakosh](https://github.com/deltakosh))
     - New mesh type : `LineSystem` ([jerome](https://github.com/jbousquie))
     - SerializationHelper for complex classes using TypeScript decorators ([deltakosh](https://github.com/deltakosh))
-    - StandardMaterial now supports Parallax and Parallax Occlusion Mapping ([nockawa](https://github.com/nockawa))
+    - StandardMaterial now supports Parallax and Parallax Occlusion Mapping ([tutorial](http://doc.babylonjs.com/tutorials/Using_parallax_mapping)) ([nockawa](https://github.com/nockawa))
     - 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))
@@ -15,6 +15,9 @@
     - Unity3D exporter: Added support for export and run (local webserver) ([davrous](https://github.com/davrous), [deltakosh](https://github.com/deltakosh))
     - Moved PBR Material to core ([deltakosh](https://github.com/deltakosh))
     - StandardMaterial.maxSimultaneousLights can define how many dynamic lights the material can handle ([deltakosh](https://github.com/deltakosh))
+	- Introduced Canvas2D feature: a 2D engine to render primitives, sprites in 2D, text. Canvas2D can be displayed in Screen Space (above the 3D scene) or in World Space to be a part of the Scene. [overview](http://doc.babylonjs.com/overviews/Using_The_Canvas2D), [tutorial](http://doc.babylonjs.com/tutorials/Using_the_Canvas2D) ([nockawa](https://github.com/nockawa))
+	- Added two new types of Texture: FontTexture and MapTexture ([quick doc](http://www.html5gamedevs.com/topic/22565-two-new-texture-types-fonttexture-and-maptexture/)) ([nockawa](https://github.com/nockawa))
+	- Added a dynamic [2D Bin Packing Algorithm](http://stackoverflow.com/questions/8762569/how-is-2d-bin-packing-achieved-programmatically), ([more info here](http://www.html5gamedevs.com/topic/22565-two-new-texture-types-fonttexture-and-maptexture/)) ([nockawa](https://github.com/nockawa))
 	  - Introduced Canvas2D feature: a 2D engine to render primitives, sprites in 2D, text. Canvas2D can be displayed in Screen Space (above the 3D scene) or in World Space to be a part of the Scene. [overview](http://doc.babylonjs.com/overviews/Using_The_Canvas2D), [tutorial](http://doc.babylonjs.com/tutorials/Using_the_Canvas2D) ([nockawa](https://github.com/nockawa))	
   - **Updates**
     - Added postprocess.enablePixelPerfectMode to avoid texture scaling/stretching when dealing with non-power of 2 resolutions. cannot be used on post-processes chain ([deltakosh](https://github.com/deltakosh))
@@ -34,9 +37,9 @@
     - 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. ([nockawa](https://github.com/nockawa))
-	  - Added RectanglePackingMap class to fix several rectangles in a big map in the most optimal way. ([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. ([nockawa](https://github.com/nockawa))
+	  - 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 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))
   - **Exporters**
     - Unity exporter now support skeletons ([sebavan](https://github.com/sebavan))

+ 2 - 2
src/Canvas2d/babylon.bounding2d.ts

@@ -124,7 +124,7 @@
 
         /**
          * Transform this BoundingInfo2D with a given matrix and store the result in an existing BoundingInfo2D instance.
-         * This is a GC friendly version, try to use it as much as possible, specially if your transformation is inside a loop, allocate the result object once for good outside of the loop and use it everytime.
+         * This is a GC friendly version, try to use it as much as possible, specially if your transformation is inside a loop, allocate the result object once for good outside of the loop and use it every time.
          * @param origin An optional normalized origin to apply before the transformation. 0;0 is top/left, 0.5;0.5 is center, etc.
          * @param matrix The matrix to use to compute the transformation
          * @param result A VALID (i.e. allocated) BoundingInfo2D object where the result will be stored
@@ -153,7 +153,7 @@
 
         /**
          * Compute the union of this BoundingInfo2D with another one and store the result in a third valid BoundingInfo2D object
-         * This is a GC friendly version, try to use it as much as possible, specially if your transformation is inside a loop, allocate the result object once for good outside of the loop and use it everytime.
+         * This is a GC friendly version, try to use it as much as possible, specially if your transformation is inside a loop, allocate the result object once for good outside of the loop and use it every time.
          * @param other the second object used to compute the union
          * @param result a VALID BoundingInfo2D instance (i.e. allocated) where the result will be stored
          */

+ 3 - 3
src/Canvas2d/babylon.brushes2d.ts

@@ -25,7 +25,7 @@
      */
     export interface IBrush2D extends ILockable {
         /**
-         * Define if the brush will use transparency/alphablending
+         * Define if the brush will use transparency / alpha blending
          * @returns true if the brush use transparency
          */
         isTransparent(): boolean;
@@ -38,7 +38,7 @@
     }
 
     /**
-     * Base class implemting the ILocable interface.
+     * Base class implementing the ILocable interface.
      * The particularity of this class is to call the protected onLock() method when the instance is about to be locked for good.
      */
     export class LockableBase implements ILockable {
@@ -67,7 +67,7 @@
     }
 
     /**
-     * This classs implements a Brush that will be drawn with a uniform solid color (i.e. the same color everywhere in the content where the brush is assigned to).
+     * This class implements a Brush that will be drawn with a uniform solid color (i.e. the same color everywhere in the content where the brush is assigned to).
      */
     @className("SolidColorBrush2D")
     export class SolidColorBrush2D extends LockableBase implements IBrush2D {

+ 11 - 5
src/Canvas2d/babylon.renderablePrim2d.ts

@@ -528,14 +528,20 @@
             }
             part.isVisible = this.isVisible;
 
-            // Which means, if there's only one data element, we're update it from this method, otherwise it is the responsability of the derived class to call updateInstanceDataPart as many times as needed, properly (look at Text2D's implementation for more information)
+            // Which means, if there's only one data element, we're update it from this method, otherwise it is the responsibility of the derived class to call updateInstanceDataPart as many times as needed, properly (look at Text2D's implementation for more information)
             if (part.dataElementCount === 1) {
                 this.updateInstanceDataPart(part);
             }
             return true;
         }
 
-        protected updateInstanceDataPart(part: InstanceDataBase, positionOffset: Vector2 = null) {
+        /**
+         * Update the instanceDataBase level properties of a part
+         * @param part the part to update
+         * @param positionOffset to use in multi part per primitive (e.g. the Text2D has N parts for N letter to display), this give the offset to apply (e.g. the position of the letter from the bottom/left corner of the text). You MUST also set customSize.
+         * @param customSize to use in multi part per primitive, this is the size of the overall primitive to display (the bounding rect's size of the Text, for instance). This is mandatory to compute correct transformation based on the Primitive's origin property.
+         */
+        protected updateInstanceDataPart(part: InstanceDataBase, positionOffset: Vector2 = null, customSize: Size = null) {
             let t = this._globalTransform.multiply(this.renderGroup.invGlobalTransform);
             let size = (<Size>this.renderGroup.viewportSize);
             let zBias = this.getActualZOffset();
@@ -543,9 +549,9 @@
             let offX = 0;
             let offY = 0;
             // If there's an offset, apply the global transformation matrix on it to get a global offset
-            if (positionOffset) {
-                offX = positionOffset.x * t.m[0] + positionOffset.y * t.m[4];
-                offY = positionOffset.x * t.m[1] + positionOffset.y * t.m[5];
+            if (positionOffset && customSize) {
+                offX = (positionOffset.x-(customSize.width*this.origin.x)) * t.m[0] + (positionOffset.y-(customSize.height*this.origin.y)) * t.m[4];
+                offY = (positionOffset.x-(customSize.width*this.origin.x)) * t.m[1] + (positionOffset.y-(customSize.height*this.origin.y)) * t.m[5];
             }
 
             // Have to convert the coordinates to clip space which is ranged between [-1;1] on X and Y axis, with 0,0 being the left/bottom corner

+ 3 - 2
src/Canvas2d/babylon.text2d.ts

@@ -287,10 +287,11 @@
                 let d = <Text2DInstanceData>part;
                 let texture = this.fontTexture;
                 let ts = texture.getSize();
-
+                let textSize = texture.measureText(this.text, this._tabulationSize);
                 let offset = Vector2.Zero();
                 let charxpos = 0;
                 d.curElement = 0;
+                let customOrigin = Vector2.Zero();
                 for (let char of this.text) {
 
                     // Line feed
@@ -313,7 +314,7 @@
                         continue;
                     }
 
-                    this.updateInstanceDataPart(d, offset);
+                    this.updateInstanceDataPart(d, offset, textSize);
 
                     let ci = texture.getChar(char);
                     offset.x += ci.charWidth;

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

@@ -161,7 +161,7 @@
             let width = measure.width;
             if (this._currentFreePosition.x + width + xMargin > textureSize.width) {
                 this._currentFreePosition.x = 0;
-                this._currentFreePosition.y += this._lineHeight + yMargin;      // +2 for safety marging
+                this._currentFreePosition.y += this._lineHeight + yMargin;      // +2 for safety margin
 
                 // No more room?
                 if (this._currentFreePosition.y > textureSize.height) {

+ 8 - 8
src/Tools/babylon.dynamicFloatArray.ts

@@ -7,10 +7,10 @@
     /**
     * The purpose of this class is to store float32 based elements of a given size (defined by the stride argument) in a dynamic fashion, that is, you can add/free elements. You can then access to a defragmented/packed version of the underlying Float32Array by calling the pack() method.
     * The intent is to maintain through time data that will be bound to a WebGlBuffer with the ability to change add/remove elements.
-    * It was first built to effiently maintain the WebGlBuffer that contain instancing based data.
+    * It was first built to efficiently maintain the WebGlBuffer that contain instancing based data.
     * Allocating an Element will return a instance of DynamicFloatArrayElement which contains the offset into the Float32Array of where the element starts, you are then responsible to copy your data using this offset.
-    * Beware, calling pack() may change the offset of some Entries because this method will defrag the Float32Array to replace empty elements by moving allocated ones at their location.
-     * This method will return an ArrayBufferView on the existing Float32Array that describes the used elements. Use this View to update the WebGLBuffer and NOT the "buffer" field of the class. The pack() method won't shrink/reallocate the buffer to keep it GC friendly, all the empty space will be put at the end of the buffer, the method just ensure there're no "free holes". 
+    * Beware, calling pack() may change the offset of some Entries because this method will defragment the Float32Array to replace empty elements by moving allocated ones at their location.
+     * This method will return an ArrayBufferView on the existing Float32Array that describes the used elements. Use this View to update the WebGLBuffer and NOT the "buffer" field of the class. The pack() method won't shrink/reallocate the buffer to keep it GC friendly, all the empty space will be put at the end of the buffer, the method just ensure there are no "free holes". 
     */
     export class DynamicFloatArray {
         /**
@@ -70,7 +70,7 @@
         /**
          * This method will pack all the used elements into a linear sequence and put all the free space at the end.
          * Instances of DynamicFloatArrayElement may have their 'offset' member changed as data could be copied from one location to another, so be sure to read/write your data based on the value inside this member after you called pack().
-         * @return the subarray that is the view of the used elements area, you can use it as a source to update a WebGLBuffer
+         * @return the subArray that is the view of the used elements area, you can use it as a source to update a WebGLBuffer
          */
         pack(): Float32Array {
 
@@ -112,12 +112,12 @@
                 // Compute the distance between this offset and the previous
                 let distance = curOffset - prevOffset;
 
-                // If the distance is the stride size, they are adjacents, it good, move to the next
+                // If the distance is the stride size, they are adjacent, it good, move to the next
                 if (distance === s) {
                     // Free zone is one element bigger
                     ++freeZoneSize;
 
-                    // as we're about to iterate to the next, the cur becomes the prev...
+                    // as we're about to iterate to the next, the cur becomes the previous...
                     prevOffset = curOffset;
 
                     continue;
@@ -161,7 +161,7 @@
                     freeZoneSize = ((curOffset - firstFreeSlotOffset) / s) + 1;
                 }
 
-                // as we're about to iterate to the next, the cur becomes the prev...
+                // as we're about to iterate to the next, the cur becomes the previous...
                 prevOffset = curOffset;
             }
 
@@ -205,7 +205,7 @@
         }
 
         /**
-         * This is the main buffer, all elements are stored inside, you use the DynamicFloatArrayElement instance of a given element to know its location into this buffer, then you have the responsability to perform write operations in this buffer at the right location!
+         * This is the main buffer, all elements are stored inside, you use the DynamicFloatArrayElement instance of a given element to know its location into this buffer, then you have the responsibility to perform write operations in this buffer at the right location!
          * Don't use this buffer for a WebGL bufferSubData() operation, but use the one returned by the pack() method.
          */
         buffer: Float32Array;

+ 3 - 3
src/Tools/babylon.rectPackingMap.ts

@@ -68,7 +68,7 @@
         protected findAndSplitNode(contentSize: Size): PackedRect {
             var node = this.findNode(contentSize);
 
-            // Not enought space...
+            // Not enough space...
             if (!node) {
                 return null;
             }
@@ -180,9 +180,9 @@
     }
 
     /**
-     * The purpose of this class is to pack several Rectangles into a big map, while trying to fit everything as optimaly as possible.
+     * The purpose of this class is to pack several Rectangles into a big map, while trying to fit everything as optimally as possible.
      * This class is typically used to build lightmaps, sprite map or to pack several little textures into a big one.
-     * Note that this class allows allocated Rectangles to be freed: that is the map is dynamically maintained so you can add/remove rectangle based on their lifecycle.
+     * Note that this class allows allocated Rectangles to be freed: that is the map is dynamically maintained so you can add/remove rectangle based on their life-cycle.
      */
     export class RectPackingMap extends PackedRect {
         /**

+ 2 - 2
src/Tools/babylon.stringDictionary.ts

@@ -1,7 +1,7 @@
 module BABYLON {
     /**
      * This class implement a typical dictionary using a string as key and the generic type T as value.
-     * The underlying implemetation relies on an associative array to ensure the best performances.
+     * The underlying implementation relies on an associative array to ensure the best performances.
      * The value can be anything including 'null' but except 'undefined'
      */
     export class StringDictionary<T> {
@@ -21,7 +21,7 @@
         /**
          * Get a value from its key or add it if it doesn't exist.
          * This method will ensure you that a given key/data will be present in the dictionary.
-         * @param key the given key to get the matchin value from
+         * @param key the given key to get the matching value from
          * @param factory the factory that will create the value if the key is not present in the dictionary.
          * The factory will only be invoked if there's no data for the given key.
          * @return the value corresponding to the key.