Browse Source

Canvas2D Breaking Changes

Two new class: ScreenSpaceCanvas2D and WorldSpaceCanvas2D

Canvas and Primitive construction now rely on constructor instead of static CreateXXX methods.

WorldSpaceCanvas2D class renamed into WorldSpaceCanvas2DNode.

Big refactoring on Lines2D to separate the logical data computing from the rendering resource creation in order to get the intersection/boundingInfo/size information possibly before rendering. (required for layout/interaction)

Some cleanup left to be done, but will be made after more tests and stabilization performed
nockawa 9 năm trước cách đây
mục cha
commit
6f0849f2ee

+ 1 - 1
Tools/Gulp/config.json

@@ -172,7 +172,7 @@
       "../../src/Canvas2d/babylon.text2d.js",
       "../../src/Canvas2d/babylon.lines2d.js",
       "../../src/Canvas2d/babylon.canvas2d.js",
-      "../../src/Canvas2d/babylon.worldSpaceCanvas2d.js",
+      "../../src/Canvas2d/babylon.worldSpaceCanvas2dNode.js",
       "../../src/Materials/babylon.shaderMaterial.js",
       "../../src/Tools/babylon.tools.dds.js",
       "../../src/Physics/Plugins/babylon.cannonJSPlugin.js",

+ 183 - 109
src/Canvas2d/babylon.canvas2d.ts

@@ -47,121 +47,48 @@
          */
         public static CACHESTRATEGY_DONTCACHE = 4;
 
-        /**
-         * Create a new 2D ScreenSpace Rendering Canvas, it is a 2D rectangle that has a size (width/height) and a position relative to the bottom/left corner of the screen.
-         * ScreenSpace Canvas will be drawn in the Viewport as a 2D Layer lying to the top of the 3D Scene. Typically used for traditional UI.
-         * All caching strategies will be available.
-         * PLEASE NOTE: the origin of a Screen Space Canvas is set to [0;0] (bottom/left) which is different than the default origin of a Primitive which is centered [0.5;0.5]
-         * @param scene the Scene that owns the Canvas
-         * Options:
-         *  - id: a text identifier, for information purpose only
-         *  - pos: the position of the canvas, relative from the bottom/left of the scene's viewport. Alternatively you can set the x and y properties directly. Default value is [0, 0]
-         *  - size: the Size of the canvas. Alternatively the width and height properties can be set. If null two behaviors depend on the cachingStrategy: if it's CACHESTRATEGY_CACHECANVAS then it will always auto-fit the rendering device, in all the other modes it will fit the content of the Canvas
-         *  - cachingStrategy: either CACHESTRATEGY_TOPLEVELGROUPS, CACHESTRATEGY_ALLGROUPS, CACHESTRATEGY_CANVAS, CACHESTRATEGY_DONTCACHE. Please refer to their respective documentation for more information. Default is Canvas2D.CACHESTRATEGY_DONTCACHE
-         *  - enableInteraction: if true the pointer events will be listened and rerouted to the appropriate primitives of the Canvas2D through the Prim2DBase.onPointerEventObservable observable property. Default is true.
-         *  - isVisible: true if the canvas must be visible, false for hidden. Default is true.
-         *  - marginTop/Left/Right/Bottom: define the margin for the corresponding edge, if all of them are null, margin is not used in layout computing. Default Value is null for each.
-         *  - hAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
-         *  - vAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
-         */
-        static CreateScreenSpace(scene: Scene, options: { id?: string, x?: number, y?: number, position?: Vector2, origin?: Vector2, width?: number, height?: number, size?: Size, cachingStrategy?: number, enableInteraction?: boolean, isVisible?: boolean, marginTop?: number | string, marginLeft?: number | string, marginRight?: number | string, marginBottom?: number | string, hAlignment?: number, vAlignment?: number }): Canvas2D {
-            let c = new Canvas2D();
-
-            if (!options) {
-                c.setupCanvas(scene, null, null, 1, true, Canvas2D.CACHESTRATEGY_DONTCACHE, true, Vector2.Zero(), true, null, null, null, null, null, null);
-                c.position = Vector2.Zero();
-            } else { 
-                let pos = options.position || new Vector2(options.x || 0, options.y || 0);
-                let size = (!options.size && !options.width && !options.height) ? null : (options.size || (new Size(options.width || 0, options.height || 0)));
-
-                c.setupCanvas(scene, options.id || null, size, 1, true, options.cachingStrategy || Canvas2D.CACHESTRATEGY_DONTCACHE, options.enableInteraction || true, options.origin || Vector2.Zero(), options.isVisible || true, options.marginTop, options.marginLeft, options.marginRight, options.marginBottom, options.hAlignment || PrimitiveAlignment.AlignLeft, options.vAlignment || PrimitiveAlignment.AlignTop);
-                c.position = pos;
-            }
-
-            return c;
-        }
-
-        /**
-         * Create a new 2D WorldSpace Rendering Canvas, it is a 2D rectangle that has a size (width/height) and a world transformation information to place it in the world space.
-         * This kind of canvas can't have its Primitives directly drawn in the Viewport, they need to be cached in a bitmap at some point, as a consequence the DONT_CACHE strategy is unavailable. For now only CACHESTRATEGY_CANVAS is supported, but the remaining strategies will be soon.
-         * @param scene the Scene that owns the Canvas
-         * @param size the dimension of the Canvas in World Space
-         * Options:
-         *  - id: a text identifier, for information purpose only, default is null.
-         *  - position the position of the Canvas in World Space, default is [0,0,0]
-         *  - rotation the rotation of the Canvas in World Space, default is Quaternion.Identity()
-         *  - renderScaleFactor A scale factor applied to create the rendering texture that will be mapped in the Scene Rectangle. If you set 2 for instance the texture will be twice large in width and height. A greater value will allow to achieve a better rendering quality. Default value is 1.
-         * BE AWARE that the Canvas true dimension will be size*renderScaleFactor, then all coordinates and size will have to be express regarding this size.
-         * TIPS: if you want a renderScaleFactor independent reference of frame, create a child Group2D in the Canvas with position 0,0 and size set to null, then set its scale property to the same amount than the renderScaleFactor, put all your primitive inside using coordinates regarding the size property you pick for the Canvas and you'll be fine.
-         * - sideOrientation: Unexpected behavior occur if the value is different from Mesh.DEFAULTSIDE right now, so please use this one, which is the default.
-         * - cachingStrategy Must be CACHESTRATEGY_CANVAS for now, which is the default.
-         *  - enableInteraction: if true the pointer events will be listened and rerouted to the appropriate primitives of the Canvas2D through the Prim2DBase.onPointerEventObservable observable property. Default is false (the opposite of ScreenSpace).
-         * - isVisible: true if the canvas must be visible, false for hidden. Default is true.
-         * - customWorldSpaceNode: if specified the Canvas will be rendered in this given Node. But it's the responsibility of the caller to set the "worldSpaceToNodeLocal" property to compute the hit of the mouse ray into the node (in world coordinate system) as well as rendering the cached bitmap in the node itself. The properties cachedRect and cachedTexture of Group2D will give you what you need to do that.
-         */
-        static CreateWorldSpace(scene: Scene, size: Size, options: { id?: string, position?: Vector3, rotation?: Quaternion, renderScaleFactor?: number, sideOrientation?: number, cachingStrategy?: number, enableInteraction?: boolean, isVisible?: boolean, customWorldSpaceNode?: Node}): Canvas2D {
-
-            let cs = options && options.cachingStrategy || Canvas2D.CACHESTRATEGY_CANVAS;
-
-            if (cs !== Canvas2D.CACHESTRATEGY_CANVAS) {
-                throw new Error("Right now only the CACHESTRATEGY_CANVAS cache Strategy is supported for WorldSpace Canvas. More will come soon!");
+        constructor(scene: Scene, settings?: {
+            id               ?: string,
+            size             ?: Size,
+            renderScaleFactor?: number,
+            isScreenSpace    ?: boolean,
+            cachingStrategy  ?: number,
+            enableInteraction?: boolean,
+            origin           ?: Vector2,
+            isVisible        ?: boolean,
+            marginTop        ?: number | string,
+            marginLeft       ?: number | string,
+            marginRight      ?: number | string,
+            marginBottom     ?: number | string,
+            hAlign           ?: number,
+            vAlign           ?: number,
+        }) {
+            super(null, settings);
+
+            Prim2DBase._isCanvasInit = false;
+
+            if (!settings) {
+                settings = {};
             }
 
-            //if (cachingStrategy === Canvas2D.CACHESTRATEGY_DONTCACHE) {
-            //    throw new Error("CACHESTRATEGY_DONTCACHE cache Strategy can't be used for WorldSpace Canvas");
-            //}
-
-            let enableInteraction = options ? options.enableInteraction : true;
-            let createWorldSpaceNode = !options || (options.customWorldSpaceNode==null);
-            let isVisible = options ? options.isVisible || true : true;
-            let id = options ? options.id || null : null;
-            let rsf = options ? options.renderScaleFactor || 1 : 1;
-
-            let c = new Canvas2D();
-            c.setupCanvas(scene, id, new Size(size.width, size.height), rsf, false, cs, enableInteraction, new Vector2(0.5, 0.5), isVisible, null, null, null, null, null, null);
-
-            if (createWorldSpaceNode) {
-                let plane = new WorldSpaceCanvas2D(id, scene, c);
-                let vertexData = VertexData.CreatePlane({
-                    width: size.width,
-                    height: size.height,
-                    sideOrientation: options && options.sideOrientation || Mesh.DEFAULTSIDE
-                });
-                let mtl = new StandardMaterial(id + "_Material", scene);
-
-                c.applyCachedTexture(vertexData, mtl);
-                vertexData.applyToMesh(plane, false);
+            let renderScaleFactor = (settings.renderScaleFactor == null) ? 1    : settings.renderScaleFactor;
+            let enableInteraction = (settings.enableInteraction == null) ? true : settings.enableInteraction;
 
-                mtl.specularColor = new Color3(0, 0, 0);
-                mtl.disableLighting = true;
-                mtl.useAlphaFromDiffuseTexture = true;
-                plane.position = options && options.position || Vector3.Zero();
-                plane.rotationQuaternion = options && options.rotation || Quaternion.Identity();
-                plane.material = mtl;
-                c._worldSpaceNode = plane;
-            } else {
-                c._worldSpaceNode = options.customWorldSpaceNode;
-            }
-            return c;
-        }
-
-        protected setupCanvas(scene: Scene, name: string, size: Size, renderScaleFactor: number, isScreenSpace: boolean, cachingstrategy: number, enableInteraction: boolean, origin: Vector2, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, hAlign: number, vAlign: number) {
             let engine = scene.getEngine();
-            this._fitRenderingDevice = !size;
-            if (!size) {
-                size = new Size(engine.getRenderWidth(), engine.getRenderHeight());
+            this._fitRenderingDevice = !settings.size;
+            if (!settings.size) {
+                settings.size = new Size(engine.getRenderWidth(), engine.getRenderHeight());
             } else {
-                size.height *= renderScaleFactor;
-                size.width *= renderScaleFactor;
+                settings.size.height *= renderScaleFactor;
+                settings.size.width *= renderScaleFactor;
             }
             this.__engineData = engine.getOrAddExternalDataWithFactory("__BJSCANVAS2D__", k => new Canvas2DEngineBoundData());
             this._renderScaleFactor = renderScaleFactor;
-            this._cachingStrategy = cachingstrategy;
             this._primPointerInfo = new PrimitivePointerInfo();
             this._capturedPointers = new StringDictionary<Prim2DBase>();
             this._pickStartingPosition = Vector2.Zero();
 
-            this.setupGroup2D(this, null, name, Vector2.Zero(), origin, size, isVisible, this._cachingStrategy===Canvas2D.CACHESTRATEGY_ALLGROUPS ? Group2D.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE : Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY, marginTop, marginLeft, marginRight, marginBottom, hAlign, vAlign);
+            //this.setupGroup2D(this, null, name, Vector2.Zero(), origin, size, isVisible, this._cachingStrategy===Canvas2D.CACHESTRATEGY_ALLGROUPS ? Group2D.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE : Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY, marginTop, marginLeft, marginRight, marginBottom, hAlign, vAlign);
 
             this._hierarchyLevelMaxSiblingCount = 10;
             this._hierarchyDepthOffset = 0;
@@ -175,13 +102,12 @@
                 this.dispose();
             });
 
-            if (cachingstrategy !== Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS) {
-                this._background = Rectangle2D.Create(this, { id: "###CANVAS BACKGROUND###", width: size.width, height: size.height});
+            if (this._cachingStrategy !== Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS) {
+                this._background = new Rectangle2D(this, { id: "###CANVAS BACKGROUND###", size: settings.size}); //TODO CHECK when size is null
                 this._background.isPickable = false;
                 this._background.origin = Vector2.Zero();
                 this._background.levelVisible = false;
             }
-            this._isScreeSpace = isScreenSpace;
 
             if (this._isScreeSpace) {
                 this._afterRenderObserver = this._scene.onAfterRenderObservable.add((d, s) => {
@@ -200,6 +126,12 @@
             this._setupInteraction(enableInteraction);
         }
 
+        protected _canvasPreInit(settings: any) {
+            let cachingStrategy   = (settings.cachingStrategy == null) ? Canvas2D.CACHESTRATEGY_DONTCACHE : settings.cachingStrategy;
+            this._cachingStrategy = cachingStrategy;
+            this._isScreeSpace = (settings.isScreenSpace == null) ? true : settings.isScreenSpace;
+        }
+
         public get hierarchyLevelMaxSiblingCount(): number {
             return this._hierarchyLevelMaxSiblingCount;
         }
@@ -873,7 +805,7 @@
         private _capturedPointers: StringDictionary<Prim2DBase>;
         private _scenePrePointerObserver: Observer<PointerInfoPre>;
         private _scenePointerObserver: Observer<PointerInfo>;
-        private _worldSpaceNode: Node;
+        protected _worldSpaceNode: Node;
         private _mapCounter = 0;
         private _background: Rectangle2D;
         private _scene: Scene;
@@ -1012,14 +944,14 @@
                 // Special case if the canvas is entirely cached: create a group that will have a single sprite it will be rendered specifically at the very end of the rendering process
                 if (this._cachingStrategy === Canvas2D.CACHESTRATEGY_CANVAS) {
                     this._cachedCanvasGroup = Group2D._createCachedCanvasGroup(this);
-                    let sprite = Sprite2D.Create(this._cachedCanvasGroup, map, {id: "__cachedCanvasSprite__", spriteSize:node.contentSize, spriteLocation:node.pos});
+                    let sprite = new Sprite2D(this._cachedCanvasGroup, map, {id: "__cachedCanvasSprite__", spriteSize:node.contentSize, spriteLocation:node.pos});
                     sprite.zOrder = 1;
                     sprite.origin = Vector2.Zero();
                 }
 
                 // Create a Sprite that will be used to render this cache, the "__cachedSpriteOfGroup__" starting id is a hack to bypass exception throwing in case of the Canvas doesn't normally allows direct primitives
                 else {
-                    let sprite = Sprite2D.Create(parent, map, {id:`__cachedSpriteOfGroup__${group.id}`, x: group.position.x, y: group.position.y, spriteSize:node.contentSize, spriteLocation:node.pos});
+                    let sprite = new Sprite2D(parent, map, {id:`__cachedSpriteOfGroup__${group.id}`, x: group.position.x, y: group.position.y, spriteSize:node.contentSize, spriteLocation:node.pos});
                     sprite.origin = group.origin.clone();
                     res.sprite = sprite;
                 }
@@ -1058,4 +990,146 @@
         private static _solidColorBrushes: StringDictionary<IBrush2D> = new StringDictionary<IBrush2D>();
         private static _gradientColorBrushes: StringDictionary<IBrush2D> = new StringDictionary<IBrush2D>();
     }
+    @className("WorldSpaceCanvas2D")
+    export class WorldSpaceCanvas2D extends Canvas2D {
+        /**
+         * Create a new 2D WorldSpace Rendering Canvas, it is a 2D rectangle that has a size (width/height) and a world transformation information to place it in the world space.
+         * This kind of canvas can't have its Primitives directly drawn in the Viewport, they need to be cached in a bitmap at some point, as a consequence the DONT_CACHE strategy is unavailable. For now only CACHESTRATEGY_CANVAS is supported, but the remaining strategies will be soon.
+         * @param scene the Scene that owns the Canvas
+         * @param size the dimension of the Canvas in World Space
+         * Options:
+         *  - id: a text identifier, for information purpose only, default is null.
+         *  - position the position of the Canvas in World Space, default is [0,0,0]
+         *  - rotation the rotation of the Canvas in World Space, default is Quaternion.Identity()
+         *  - renderScaleFactor A scale factor applied to create the rendering texture that will be mapped in the Scene Rectangle. If you set 2 for instance the texture will be twice large in width and height. A greater value will allow to achieve a better rendering quality. Default value is 1.
+         * BE AWARE that the Canvas true dimension will be size*renderScaleFactor, then all coordinates and size will have to be express regarding this size.
+         * TIPS: if you want a renderScaleFactor independent reference of frame, create a child Group2D in the Canvas with position 0,0 and size set to null, then set its scale property to the same amount than the renderScaleFactor, put all your primitive inside using coordinates regarding the size property you pick for the Canvas and you'll be fine.
+         * - sideOrientation: Unexpected behavior occur if the value is different from Mesh.DEFAULTSIDE right now, so please use this one, which is the default.
+         * - cachingStrategy Must be CACHESTRATEGY_CANVAS for now, which is the default.
+         *  - enableInteraction: if true the pointer events will be listened and rerouted to the appropriate primitives of the Canvas2D through the Prim2DBase.onPointerEventObservable observable property. Default is false (the opposite of ScreenSpace).
+         * - isVisible: true if the canvas must be visible, false for hidden. Default is true.
+         * - customWorldSpaceNode: if specified the Canvas will be rendered in this given Node. But it's the responsibility of the caller to set the "worldSpaceToNodeLocal" property to compute the hit of the mouse ray into the node (in world coordinate system) as well as rendering the cached bitmap in the node itself. The properties cachedRect and cachedTexture of Group2D will give you what you need to do that.
+         */
+        constructor(scene: Scene, size: Size, settings: {
+            id                  ?: string,
+            position            ?: Vector3,
+            rotation            ?: Quaternion,
+            renderScaleFactor   ?: number,
+            sideOrientation     ?: number,
+            cachingStrategy     ?: number,
+            enableInteraction   ?: boolean,
+            isVisible           ?: boolean,
+            customWorldSpaceNode?: Node,
+        }) {
+            Prim2DBase._isCanvasInit = true;
+            let s = <any>settings;
+            s.isScreenSpace = false;
+            s.size = size.clone();
+            settings.cachingStrategy = (settings.cachingStrategy==null) ? Canvas2D.CACHESTRATEGY_CANVAS : settings.cachingStrategy;
+
+            if (settings.cachingStrategy !== Canvas2D.CACHESTRATEGY_CANVAS) {
+                throw new Error("Right now only the CACHESTRATEGY_CANVAS cache Strategy is supported for WorldSpace Canvas. More will come soon!");
+            }
+
+            super(scene, settings);
+            Prim2DBase._isCanvasInit = false;
+
+
+            //if (cachingStrategy === Canvas2D.CACHESTRATEGY_DONTCACHE) {
+            //    throw new Error("CACHESTRATEGY_DONTCACHE cache Strategy can't be used for WorldSpace Canvas");
+            //}
+
+            //let enableInteraction = settings ? settings.enableInteraction : true;
+            let createWorldSpaceNode = !settings || (settings.customWorldSpaceNode == null);
+            //let isVisible = settings ? settings.isVisible || true : true;
+            let id = settings ? settings.id || null : null;
+            //let rsf = settings ? settings.renderScaleFactor || 1 : 1;
+
+            //let c = new Canvas2D();
+            //c.setupCanvas(scene, id, new Size(size.width, size.height), rsf, false, cs, enableInteraction, new Vector2(0.5, 0.5), isVisible, null, null, null, null, null, null);
+
+            if (createWorldSpaceNode) {
+                let plane = new WorldSpaceCanvas2DNode(id, scene, this);
+                let vertexData = VertexData.CreatePlane({
+                    width: size.width,
+                    height: size.height,
+                    sideOrientation: settings && settings.sideOrientation || Mesh.DEFAULTSIDE
+                });
+                let mtl = new StandardMaterial(id + "_Material", scene);
+
+                this.applyCachedTexture(vertexData, mtl);
+                vertexData.applyToMesh(plane, false);
+
+                mtl.specularColor = new Color3(0, 0, 0);
+                mtl.disableLighting = true;
+                mtl.useAlphaFromDiffuseTexture = true;
+                plane.position = settings && settings.position || Vector3.Zero();
+                plane.rotationQuaternion = settings && settings.rotation || Quaternion.Identity();
+                plane.material = mtl;
+                this._worldSpaceNode = plane;
+            } else {
+                this._worldSpaceNode = settings.customWorldSpaceNode;
+            }
+            //            return c;
+        }
+    }
+
+    @className("ScreenSpaceCanvas2D")
+    export class ScreenSpaceCanvas2D extends Canvas2D {
+        /**
+         * Create a new 2D ScreenSpace Rendering Canvas, it is a 2D rectangle that has a size (width/height) and a position relative to the bottom/left corner of the screen.
+         * ScreenSpace Canvas will be drawn in the Viewport as a 2D Layer lying to the top of the 3D Scene. Typically used for traditional UI.
+         * All caching strategies will be available.
+         * PLEASE NOTE: the origin of a Screen Space Canvas is set to [0;0] (bottom/left) which is different than the default origin of a Primitive which is centered [0.5;0.5]
+         * @param scene the Scene that owns the Canvas
+         * Options:
+         *  - id: a text identifier, for information purpose only
+         *  - pos: the position of the canvas, relative from the bottom/left of the scene's viewport. Alternatively you can set the x and y properties directly. Default value is [0, 0]
+         *  - size: the Size of the canvas. Alternatively the width and height properties can be set. If null two behaviors depend on the cachingStrategy: if it's CACHESTRATEGY_CACHECANVAS then it will always auto-fit the rendering device, in all the other modes it will fit the content of the Canvas
+         *  - cachingStrategy: either CACHESTRATEGY_TOPLEVELGROUPS, CACHESTRATEGY_ALLGROUPS, CACHESTRATEGY_CANVAS, CACHESTRATEGY_DONTCACHE. Please refer to their respective documentation for more information. Default is Canvas2D.CACHESTRATEGY_DONTCACHE
+         *  - enableInteraction: if true the pointer events will be listened and rerouted to the appropriate primitives of the Canvas2D through the Prim2DBase.onPointerEventObservable observable property. Default is true.
+         *  - isVisible: true if the canvas must be visible, false for hidden. Default is true.
+         *  - marginTop/Left/Right/Bottom: define the margin for the corresponding edge, if all of them are null, margin is not used in layout computing. Default Value is null for each.
+         *  - hAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
+         *  - vAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
+         */
+        constructor(scene: Scene, settings?: {
+            id               ?: string,
+            x                ?: number,
+            y                ?: number,
+            position         ?: Vector2,
+            origin           ?: Vector2,
+            width            ?: number,
+            height           ?: number,
+            size             ?: Size,
+            cachingStrategy  ?: number,
+            enableInteraction?: boolean,
+            isVisible        ?: boolean,
+            marginTop        ?: number | string,
+            marginLeft       ?: number | string,
+            marginRight      ?: number | string,
+            marginBottom     ?: number | string,
+            hAlignment       ?: number,
+            vAlignment       ?: number,
+        }) {
+            Prim2DBase._isCanvasInit = true;
+            super(scene, settings);
+
+            //let c = new Canvas2D();
+
+            //if (!settings) {
+            //    c.setupCanvas(scene, null, null, 1, true, Canvas2D.CACHESTRATEGY_DONTCACHE, true, Vector2.Zero(), true, null, null, null, null, null, null);
+            //    c.position = Vector2.Zero();
+            //} else {
+            //    let pos = settings.position || new Vector2(settings.x || 0, settings.y || 0);
+            //    let size = (!settings.size && !settings.width && !settings.height) ? null : (settings.size || (new Size(settings.width || 0, settings.height || 0)));
+
+            //    c.setupCanvas(scene, settings.id || null, size, 1, true, settings.cachingStrategy || Canvas2D.CACHESTRATEGY_DONTCACHE, settings.enableInteraction || true, settings.origin || Vector2.Zero(), settings.isVisible || true, settings.marginTop, settings.marginLeft, settings.marginRight, settings.marginBottom, settings.hAlignment || PrimitiveAlignment.AlignLeft, settings.vAlignment || PrimitiveAlignment.AlignTop);
+            //    c.position = pos;
+            //}
+
+            //return c;
+        }
+    }
+
 }

+ 66 - 39
src/Canvas2d/babylon.ellipse2d.ts

@@ -202,11 +202,11 @@
             BoundingInfo2D.CreateFromSizeToRef(this.size, this._levelBoundingInfo, this.origin);
         }
 
-        protected setupEllipse2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, size: Size, subdivisions: number, fill: IBrush2D, border: IBrush2D, borderThickness: number, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
-            this.setupShape2D(owner, parent, id, position, origin, isVisible, fill, border, borderThickness, marginTop, marginLeft, marginRight, marginBottom, hAlignment, vAlignment);
-            this.size = size;
-            this.subdivisions = subdivisions;
-        }
+        //protected setupEllipse2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, size: Size, subdivisions: number, fill: IBrush2D, border: IBrush2D, borderThickness: number, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
+        //    this.setupShape2D(owner, parent, id, position, origin, isVisible, fill, border, borderThickness, marginTop, marginLeft, marginRight, marginBottom, hAlignment, vAlignment);
+        //    this.size = size;
+        //    this.subdivisions = subdivisions;
+        //}
 
         /**
          * Create an Ellipse 2D Shape primitive
@@ -225,45 +225,72 @@
          *  - hAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          *  - vAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          */
-        public static Create(parent: Prim2DBase, options: { id?: string, position?: Vector2, x?: number, y?: number, origin?: Vector2, size?: Size, width?: number, height?: number, subdivisions?: number, fill?: IBrush2D, border?: IBrush2D, borderThickness?: number, isVisible?: boolean, marginTop?: number | string, marginLeft?: number | string, marginRight?: number | string, marginBottom?: number | string, vAlignment?: number, hAlignment?: number}): Ellipse2D {
+        constructor(parent: Prim2DBase, settings?: {
+            id             ?: string,
+            position       ?: Vector2,
+            x              ?: number,
+            y              ?: number,
+            origin         ?: Vector2,
+            size           ?: Size,
+            width          ?: number,
+            height         ?: number,
+            subdivisions   ?: number,
+            fill           ?: IBrush2D,
+            border         ?: IBrush2D,
+            borderThickness?: number,
+            isVisible      ?: boolean,
+            marginTop      ?: number | string,
+            marginLeft     ?: number | string,
+            marginRight    ?: number | string,
+            marginBottom   ?: number | string,
+            vAlignment     ?: number,
+            hAlignment     ?: number,
+        }) {
+
+            super(parent.owner, parent, settings);
             Prim2DBase.CheckParent(parent);
 
-            let ellipse = new Ellipse2D();
+            //let ellipse = new Ellipse2D();
 
-            if (!options) {
-                ellipse.setupEllipse2D(parent.owner, parent, null, Vector2.Zero(), null, new Size(10, 10), 64, Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF"), null, 1, true, null, null, null, null, null, null);
+            //if (!settings) {
+            //    ellipse.setupEllipse2D(parent.owner, parent, null, Vector2.Zero(), null, new Size(10, 10), 64, Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF"), null, 1, true, null, null, null, null, null, null);
+            //} else {
+            let fill: IBrush2D;
+            if (settings.fill === undefined) {
+                fill = Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF");
             } else {
-                let fill: IBrush2D;
-                if (options.fill === undefined) {
-                    fill = Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF");
-                } else {
-                    fill = options.fill;
-                }
-                let pos = options.position || new Vector2(options.x || 0, options.y || 0);
-                let size = options.size || (new Size(options.width || 10, options.height || 10));
-
-                ellipse.setupEllipse2D
-                (
-                    parent.owner,
-                    parent,
-                    options.id || null,
-                    pos,
-                    options.origin || null,
-                    size,
-                    (options.subdivisions == null) ? 64 : options.subdivisions,
-                    fill,
-                    options.border || null,
-                    (options.borderThickness == null) ? 1 : options.borderThickness,
-                    (options.isVisible == null) ? true : options.isVisible,
-                    options.marginTop,
-                    options.marginLeft,
-                    options.marginRight,
-                    options.marginBottom,
-                    options.vAlignment,
-                    options.hAlignment);
+                fill = settings.fill;
             }
-
-            return ellipse;
+            let pos  = settings.position || new Vector2(settings.x || 0, settings.y || 0);
+            let size = settings.size || (new Size(settings.width || 10, settings.height || 10));
+            let sub  = (settings.subdivisions == null) ? 64 : settings.subdivisions;
+
+            this.position     = pos;
+            this.size         = size;
+            this.subdivisions = sub;
+
+            //    ellipse.setupEllipse2D
+            //    (
+            //        parent.owner,
+            //        parent,
+            //        settings.id || null,
+            //        pos,
+            //        settings.origin || null,
+            //        size,
+            //        (settings.subdivisions == null) ? 64 : settings.subdivisions,
+            //        fill,
+            //        settings.border || null,
+            //        (settings.borderThickness == null) ? 1 : settings.borderThickness,
+            //        (settings.isVisible == null) ? true : settings.isVisible,
+            //        settings.marginTop,
+            //        settings.marginLeft,
+            //        settings.marginRight,
+            //        settings.marginBottom,
+            //        settings.vAlignment,
+            //        settings.hAlignment);
+            //}
+
+            //return ellipse;
         }
 
         protected createModelRenderCache(modelKey: string): ModelRenderCache {

+ 40 - 43
src/Canvas2d/babylon.group2d.ts

@@ -23,13 +23,6 @@
         public static GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP = 2;
 
         /**
-         * Don't invoke directly, rely on Group2D.CreateXXX methods
-         */
-        constructor() {
-            super();
-        }
-
-        /**
          * Create an Logical or Renderable Group.
          * @param parent the parent primitive, must be a valid primitive (or the Canvas)
          * options:
@@ -43,43 +36,47 @@
          *  - hAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          *  - vAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          */
-        static CreateGroup2D(parent: Prim2DBase, options: { id?: string, position?: Vector2, x?: number, y?: number, origin?: Vector2, size?: Size, width?: number, height?: number, cacheBehavior?: number, isVisible?: boolean, marginTop?: number | string, marginLeft?: number | string, marginRight?: number | string, marginBottom?: number | string, vAlignment?: number, hAlignment?: number}): Group2D {
+        constructor(parent: Prim2DBase, settings?: {
+            id           ?: string,
+            position     ?: Vector2,
+            x            ?: number,
+            y            ?: number,
+            origin       ?: Vector2,
+            size         ?: Size,
+            width        ?: number,
+            height       ?: number,
+            cacheBehavior?: number,
+            isVisible    ?: boolean,
+            marginTop    ?: number | string,
+            marginLeft   ?: number | string,
+            marginRight  ?: number | string,
+            marginBottom ?: number | string,
+            vAlignment   ?: number,
+            hAlignment   ?: number,
+        }) {
             Prim2DBase.CheckParent(parent);
 
+            if (settings == null) {
+                settings = {};
+            }
 
-            var g = new Group2D();
-
-            if (!options) {
-                g.setupGroup2D(parent.owner, parent, null, Vector2.Zero(), null, null, true, Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY, null, null, null, null, null, null);
+            if (Prim2DBase._isCanvasInit) {
+                super(null, null, settings);
             } else {
-                let pos = options.position || new Vector2(options.x || 0, options.y || 0);
-                let size = (!options.size && !options.width && !options.height) ? null : (options.size || (new Size(options.width || 0, options.height || 0)));
-                
-                g.setupGroup2D
-                (
-                    parent.owner,
-                    parent,
-                    options.id || null,
-                    pos,
-                    options.origin || null,
-                    size,
-                    (options.isVisible == null) ? true : options.isVisible,
-                    (options.cacheBehavior == null) ? Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY : options.cacheBehavior,
-                    options.marginTop,
-                    options.marginLeft,
-                    options.marginRight,
-                    options.marginBottom,
-                    options.hAlignment || PrimitiveAlignment.AlignLeft,
-                    options.vAlignment || PrimitiveAlignment.AlignTop);
-            }
-       
-            return g;
+                super(parent.owner, parent, settings);
+            }
+ 
+            let size = (!settings.size && !settings.width && !settings.height) ? null : (settings.size || (new Size(settings.width || 0, settings.height || 0)));
+
+            this._cacheBehavior = (settings.cacheBehavior==null) ? Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY : settings.cacheBehavior;
+            this.size = size;
+            this._viewportPosition = Vector2.Zero();
         }
 
         static _createCachedCanvasGroup(owner: Canvas2D): Group2D {
-            var g = new Group2D();
-            g.setupGroup2D(owner, null, "__cachedCanvasGroup__", Vector2.Zero(), Vector2.Zero(), null, true, Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY, null, null, null, null, null, null);
-            g.origin = Vector2.Zero();
+            var g = new Group2D(owner, { id: "__cachedCanvasGroup__", position: Vector2.Zero(), origin: Vector2.Zero(), size:null, isVisible:true});
+            //g.setupGroup2D(owner, null, "__cachedCanvasGroup__", Vector2.Zero(), Vector2.Zero(), null, true, Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY, null, null, null, null, null, null);
+            //g.origin = Vector2.Zero();
             return g;
             
         }
@@ -138,12 +135,12 @@
             return true;
         }
 
-        protected setupGroup2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, size: Size, isVisible: boolean, cacheBehavior: number, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, hAlign: number, vAlign: number) {
-            this._cacheBehavior = cacheBehavior;
-            this.setupPrim2DBase(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom , hAlign, vAlign);
-            this.size = size;
-            this._viewportPosition = Vector2.Zero();
-        }
+        //protected setupGroup2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, size: Size, isVisible: boolean, cacheBehavior: number, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, hAlign: number, vAlign: number) {
+        //    this.setupPrim2DBase(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom , hAlign, vAlign);
+        //    this._cacheBehavior = cacheBehavior;
+        //    this.size = size;
+        //    this._viewportPosition = Vector2.Zero();
+        //}
 
         /**
          * @returns Returns true if the Group render content, false if it's a logical group only

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 660 - 554
src/Canvas2d/babylon.lines2d.ts


+ 53 - 17
src/Canvas2d/babylon.prim2dBase.ts

@@ -1055,12 +1055,39 @@
     export class Prim2DBase extends SmartPropertyPrim {
         static PRIM2DBASE_PROPCOUNT: number = 15;
 
-        protected setupPrim2DBase(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, isVisible: boolean, marginTop?: number | string, marginLeft?: number | string, marginRight?: number | string, marginBottom?: number | string, vAlignment?: number, hAlignment?: number) {
-            if (!(this instanceof Group2D) && !(this instanceof Sprite2D && id !== null && id.indexOf("__cachedSpriteOfGroup__") === 0) && (owner.cachingStrategy === Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS) && (parent === owner)) {
+        constructor(owner: Canvas2D, parent: Prim2DBase, settings: {
+            id?: string,
+            position?: Vector2,
+            x?: number,
+            y?: number,
+            origin?: Vector2,
+            isVisible?: boolean,
+            marginTop?: number | string,
+            marginLeft?: number | string,
+            marginRight?: number | string,
+            marginBottom?: number | string,
+            vAlignment?: number,
+            hAlignment?: number,
+        }
+        ) {
+
+            if (settings == null) {
+                settings = {};
+            }
+
+            super();
+
+            if (Prim2DBase._isCanvasInit) {
+                owner = <Canvas2D><any>this;
+                parent = null;
+
+                this._canvasPreInit(settings);
+            }
+
+            if (!(this instanceof Group2D) && !(this instanceof Sprite2D && settings.id !== null && settings.id.indexOf("__cachedSpriteOfGroup__") === 0) && (owner.cachingStrategy === Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS) && (parent === owner)) {
                 throw new Error("Can't create a primitive with the canvas as direct parent when the caching strategy is TOPLEVELGROUPS. You need to create a Group below the canvas and use it as the parent for the primitive");
             }
 
-            this.setupSmartPropertyPrim();
             this._layoutEngine = CanvasLayoutEngine.Singleton;
             this._size = Size.Zero();
             this._layoutArea = Size.Zero();
@@ -1079,7 +1106,7 @@
             this._parent = parent;
             this._margin = null;
             this._padding = null;
-            this._id = id;
+            this._id = settings.id;
             if (parent != null) {
                 this._hierarchyDepth = parent._hierarchyDepth + 1;
                 this._renderGroup = <Group2D>this.parent.traverseUp(p => p instanceof Group2D && p.isRenderableGroup);
@@ -1099,23 +1126,24 @@
                 group.detectGroupStates();
             }
 
-            this.position = position;
+            let pos = settings.position || new Vector2(settings.x || 0, settings.y || 0);
+            this.position = pos;
             this.rotation = 0;
             this.scale = 1;
-            this.levelVisible = isVisible;
-            this.origin = origin || new Vector2(0.5, 0.5);
+            this.levelVisible = (settings.isVisible==null) ? true : settings.isVisible;
+            this.origin = settings.origin || new Vector2(0.5, 0.5);
 
-            if (marginTop) {
-                this.margin.setTop(marginTop);
+            if (settings.marginTop) {
+                this.margin.setTop(settings.marginTop);
             }
-            if (marginLeft) {
-                this.margin.setLeft(marginLeft);
+            if (settings.marginLeft) {
+                this.margin.setLeft(settings.marginLeft);
             }
-            if (marginRight) {
-                this.margin.setRight(marginRight);
+            if (settings.marginRight) {
+                this.margin.setRight(settings.marginRight);
             }
-            if (marginBottom) {
-                this.margin.setBottom(marginBottom);
+            if (settings.marginBottom) {
+                this.margin.setBottom(settings.marginBottom);
             }
 
             this._parentLayoutDirty();
@@ -1401,7 +1429,10 @@
          * Note to implementers: you have to override this property and declare if necessary a @xxxxInstanceLevel decorator
          */
         public get actualSize(): Size {
-            return this._actualSize;
+            if (this._actualSize) {
+                return this._actualSize;
+            }
+            return this._size;
         }
 
         public set actualSize(value: Size) {
@@ -1885,8 +1916,13 @@
             this._instanceDirtyFlags = 0;
         }
 
+        protected _canvasPreInit(settings: any) {
+            
+        }
+
+        protected static _isCanvasInit: boolean = false;
         protected static CheckParent(parent: Prim2DBase) {
-            if (!parent) {
+            if (!Prim2DBase._isCanvasInit && !parent) {
                 throw new Error("A Primitive needs a valid Parent, it can be any kind of Primitives based types, even the Canvas (with the exception that only Group2D can be direct child of a Canvas if the cache strategy used is TOPLEVELGROUPS)");
             }
         }

+ 68 - 37
src/Canvas2d/babylon.rectangle2d.ts

@@ -293,12 +293,12 @@
             BoundingInfo2D.CreateFromSizeToRef(this.size, this._levelBoundingInfo, this.origin);
         }
 
-        protected setupRectangle2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, size: Size, roundRadius, fill: IBrush2D, border: IBrush2D, borderThickness: number, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
-            this.setupShape2D(owner, parent, id, position, origin, isVisible, fill, border, borderThickness, marginTop, marginLeft, marginRight, marginBottom, hAlignment, vAlignment);
-            this.size = size;
-            this.notRounded = !roundRadius;
-            this.roundRadius = roundRadius;
-        }
+        //protected setupRectangle2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, size: Size, roundRadius, fill: IBrush2D, border: IBrush2D, borderThickness: number, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
+        //    this.setupShape2D(owner, parent, id, position, origin, isVisible, fill, border, borderThickness, marginTop, marginLeft, marginRight, marginBottom, hAlignment, vAlignment);
+        //    this.size = size;
+        //    this.notRounded = !roundRadius;
+        //    this.roundRadius = roundRadius;
+        //}
 
         /**
          * Create an Rectangle 2D Shape primitive. May be a sharp rectangle (with sharp corners), or a rounded one.
@@ -317,39 +317,70 @@
          *  - hAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          *  - vAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          */
-        public static Create(parent: Prim2DBase, options: { id?: string, position?: Vector2, x?: number, y?: number, origin?: Vector2, size?: Size, width?: number, height?: number, roundRadius?: number, fill?: IBrush2D, border?: IBrush2D, borderThickness?: number, isVisible?: boolean, marginTop?: number | string, marginLeft?: number | string, marginRight?: number | string, marginBottom?: number | string, vAlignment?: number, hAlignment?: number}): Rectangle2D {
-            Prim2DBase.CheckParent(parent);
+        constructor(parent: Prim2DBase, settings?: {
+            id             ?: string,
+            position       ?: Vector2,
+            x              ?: number,
+            y              ?: number,
+            origin         ?: Vector2,
+            size           ?: Size,
+            width          ?: number,
+            height         ?: number,
+            roundRadius    ?: number,
+            fill           ?: IBrush2D,
+            border         ?: IBrush2D,
+            borderThickness?: number,
+            isVisible      ?: boolean,
+            marginTop      ?: number | string,
+            marginLeft     ?: number | string,
+            marginRight    ?: number | string,
+            marginBottom   ?: number | string,
+            vAlignment     ?: number,
+            hAlignment     ?: number,
+        }) {
+
+            super(parent.owner, parent, settings);
 
-            let rect = new Rectangle2D();
+            Prim2DBase.CheckParent(parent);
 
-            if (!options) {
-                rect.setupRectangle2D(parent.owner, parent, null, Vector2.Zero(), null, new Size(10, 10), 0, Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF"), null, 1, true, null, null, null, null, null, null);
-            } else {
-                let pos = options.position || new Vector2(options.x || 0, options.y || 0);
-                let size = options.size || (new Size((options.width === null) ? null : (options.width || 10), (options.height === null) ? null : (options.height || 10)));
-                let fill = options.fill===undefined ? Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF") : options.fill;
-
-                rect.setupRectangle2D
-                (
-                    parent.owner,
-                    parent,
-                    options.id || null,
-                    pos,
-                    options.origin || null,
-                    size,
-                    (options.roundRadius == null) ? 0 : options.roundRadius,
-                    fill,
-                    options.border || null,
-                    (options.borderThickness==null) ? 1 : options.borderThickness,
-                    options.isVisible || true,
-                    options.marginTop,
-                    options.marginLeft,
-                    options.marginRight,
-                    options.marginBottom,
-                    options.vAlignment,
-                    options.hAlignment);
-            }
-            return rect;
+            //let rect = new Rectangle2D();
+
+            //if (!settings) {
+            //    rect.setupRectangle2D(parent.owner, parent, null, Vector2.Zero(), null, new Size(10, 10), 0, Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF"), null, 1, true, null, null, null, null, null, null);
+            //} else {
+            let pos             = settings.position || new Vector2(settings.x || 0, settings.y || 0);
+            let size            = settings.size || (new Size((settings.width === null) ? null : (settings.width || 10), (settings.height === null) ? null : (settings.height || 10)));
+            let fill            = settings.fill === undefined ? Canvas2D.GetSolidColorBrushFromHex("#FFFFFFFF") : settings.fill;
+            let roundRadius     = (settings.roundRadius == null) ? 0 : settings.roundRadius;
+            let borderThickness = (settings.borderThickness == null) ? 1 : settings.borderThickness;
+
+            this.position        = pos;
+            this.size            = size;
+            this.fill            = fill;
+            this.roundRadius     = roundRadius;
+            this.borderThickness = borderThickness;
+
+            //rect.setupRectangle2D
+            //(
+            //    parent.owner,
+            //    parent,
+            //    settings.id || null,
+            //    pos,
+            //    settings.origin || null,
+            //    size,
+            //    (settings.roundRadius == null) ? 0 : settings.roundRadius,
+            //    fill,
+            //    settings.border || null,
+            //    (settings.borderThickness==null) ? 1 : settings.borderThickness,
+            //    settings.isVisible || true,
+            //    settings.marginTop,
+            //    settings.marginLeft,
+            //    settings.marginRight,
+            //    settings.marginBottom,
+            //    settings.vAlignment,
+            //    settings.hAlignment);
+            //}
+            //return rect;
         }
 
         public static roundSubdivisions = 16;

+ 14 - 2
src/Canvas2d/babylon.renderablePrim2d.ts

@@ -353,8 +353,20 @@
             this._isTransparent = value;
         }
 
-        setupRenderablePrim2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, hAlign: number, vAlign: number) {
-            this.setupPrim2DBase(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, hAlign, vAlign);
+        constructor(owner: Canvas2D, parent: Prim2DBase, settings?: {
+            id           ?: string,
+            position     ?: Vector2,
+            origin       ?: Vector2,
+            isVisible    ?: boolean,
+            marginTop    ?: number | string,
+            marginLeft   ?: number | string,
+            marginRight  ?: number | string,
+            marginBottom ?: number | string,
+            hAlign       ?: number,
+            vAlign       ?: number,
+        }) {
+            super(owner, parent, settings);
+//            this.setupPrim2DBase(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, hAlign, vAlign);
             this._isTransparent = false;
             this._isAlphaTest = false;
             this._transparentPrimitiveInfo = null;

+ 25 - 5
src/Canvas2d/babylon.shape2d.ts

@@ -44,12 +44,32 @@
             this._borderThickness = value;
         }
 
-        setupShape2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, isVisible: boolean, fill: IBrush2D, border: IBrush2D, borderThickness: number, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
+        constructor(owner: Canvas2D, parent: Prim2DBase, settings?: {
+            id             ?: string,
+            position       ?: Vector2,
+            origin         ?: Vector2,
+            isVisible      ?: boolean,
+            fill           ?: IBrush2D,
+            border         ?: IBrush2D,
+            borderThickness?: number,
+            marginTop      ?: number | string,
+            marginLeft     ?: number | string,
+            marginRight    ?: number | string,
+            marginBottom   ?: number | string,
+            vAlignment     ?: number,
+            hAlignment     ?: number,
+        }) {
+
+            super(owner, parent, settings);
+            //this.setupRenderablePrim2D(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, hAlignment || PrimitiveAlignment.AlignLeft, vAlignment || PrimitiveAlignment.AlignTop);
+
+            if (!settings) {
+                settings = {};
+            }
 
-            this.setupRenderablePrim2D(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, hAlignment || PrimitiveAlignment.AlignLeft, vAlignment || PrimitiveAlignment.AlignTop);
-            this.border = border;
-            this.fill = fill;
-            this.borderThickness = borderThickness;
+            this.border = settings.border;
+            this.fill = settings.fill;
+            this.borderThickness = settings.borderThickness;
         }
 
         protected getUsedShaderCategories(dataPart: InstanceDataBase): string[] {

+ 1 - 1
src/Canvas2d/babylon.smartPropertyPrim.ts

@@ -135,7 +135,7 @@
     @className("SmartPropertyPrim")
     export class SmartPropertyPrim implements IPropertyChanged {
 
-        protected setupSmartPropertyPrim() {
+        constructor() {
             this._flags = 0;
             this._modelKey = null;
             this._instanceDirtyFlags = 0;

+ 84 - 45
src/Canvas2d/babylon.sprite2d.ts

@@ -201,23 +201,23 @@
             return true;
         }
 
-        protected setupSprite2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, texture: Texture, spriteSize: Size, spriteLocation: Vector2, invertY: boolean, alignToPixel: boolean, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
-            this.setupRenderablePrim2D(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, hAlignment, vAlignment);
-            this.texture = texture;
-            this.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
-            this.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
-            this.size = spriteSize || null;
-            this.spriteLocation = spriteLocation || new Vector2(0,0);
-            this.spriteFrame = 0;
-            this.invertY = invertY;
-            this.alignToPixel = alignToPixel;
-            this._isTransparent = true;
-
-            if (!this.size) {
-                var s = texture.getSize();
-                this.size = new Size(s.width, s.height);
-            }
-        }
+        //protected setupSprite2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, texture: Texture, spriteSize: Size, spriteLocation: Vector2, invertY: boolean, alignToPixel: boolean, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
+        //    this.setupRenderablePrim2D(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, hAlignment, vAlignment);
+        //    this.texture = texture;
+        //    this.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
+        //    this.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
+        //    this.size = spriteSize || null;
+        //    this.spriteLocation = spriteLocation || new Vector2(0,0);
+        //    this.spriteFrame = 0;
+        //    this.invertY = invertY;
+        //    this.alignToPixel = alignToPixel;
+        //    this._isTransparent = true;
+
+        //    if (!this.size) {
+        //        var s = texture.getSize();
+        //        this.size = new Size(s.width, s.height);
+        //    }
+        //}
 
         /**
          * Create an 2D Sprite primitive
@@ -236,42 +236,81 @@
          *  - hAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          *  - vAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          */
-        public static Create(parent: Prim2DBase, texture: Texture, options: { id?: string, position?: Vector2, x?: number, y?: number, origin?: Vector2, spriteSize?: Size, spriteLocation?: Vector2, invertY?: boolean, alignToPixel?: boolean, isVisible?: boolean, marginTop?: number | string, marginLeft?: number | string, marginRight?: number | string, marginBottom?: number | string, vAlignment?: number, hAlignment?: number}): Sprite2D {
+        constructor(parent: Prim2DBase, texture: Texture, settings?: {
+            id            ?: string,
+            position      ?: Vector2,
+            x             ?: number,
+            y             ?: number,
+            origin        ?: Vector2,
+            spriteSize    ?: Size,
+            spriteLocation?: Vector2,
+            invertY       ?: boolean,
+            alignToPixel  ?: boolean,
+            isVisible     ?: boolean,
+            marginTop     ?: number | string,
+            marginLeft    ?: number | string,
+            marginRight   ?: number | string,
+            marginBottom  ?: number | string,
+            vAlignment    ?: number,
+            hAlignment    ?: number,
+        }) {
+
+            super(parent.owner, parent, settings);
+
             Prim2DBase.CheckParent(parent);
 
-            let sprite = new Sprite2D();
-            if (!options) {
-                sprite.setupSprite2D(parent.owner, parent, null, Vector2.Zero(), null, texture, null, null, false, true, true, null, null, null, null, null, null);
-            } else {
-                let pos = options.position || new Vector2(options.x || 0, options.y || 0);
-                sprite.setupSprite2D
-                (
-                    parent.owner,
-                    parent,
-                    options.id || null,
-                    pos,
-                    options.origin || null,
-                    texture, options.spriteSize || null,
-                    options.spriteLocation || null,
-                    (options.invertY == null) ? false : options.invertY,
-                    (options.alignToPixel == null) ? true : options.alignToPixel,
-                    (options.isVisible == null) ? true : options.isVisible,
-                    options.marginTop,
-                    options.marginLeft,
-                    options.marginRight,
-                    options.marginBottom,
-                    options.vAlignment,
-                    options.hAlignment
-                );
+            if (!settings) {
+                settings = {};
             }
 
-            return sprite;
+//            let sprite = new Sprite2D();
+            //if (!settings) {
+            //    sprite.setupSprite2D(parent.owner, parent, null, Vector2.Zero(), null, texture, null, null, false, true, true, null, null, null, null, null, null);
+            //} else {
+                //let pos = settings.position || new Vector2(settings.x || 0, settings.y || 0);
+                //sprite.setupSprite2D
+                //(
+                //    parent.owner,
+                //    parent,
+                //    settings.id || null,
+                //    pos,
+                //    settings.origin || null,
+                //    texture, settings.spriteSize || null,
+                //    settings.spriteLocation || null,
+                //    (settings.invertY == null) ? false : settings.invertY,
+                //    (settings.alignToPixel == null) ? true : settings.alignToPixel,
+                //    (settings.isVisible == null) ? true : settings.isVisible,
+                //    settings.marginTop,
+                //    settings.marginLeft,
+                //    settings.marginRight,
+                //    settings.marginBottom,
+                //    settings.vAlignment,
+                //    settings.hAlignment
+                //);
+            //}
+
+                this.texture        = texture;
+                this.texture.wrapU  = Texture.CLAMP_ADDRESSMODE;
+                this.texture.wrapV  = Texture.CLAMP_ADDRESSMODE;
+                this.size           = settings.spriteSize || null;
+                this.spriteLocation = settings.spriteLocation || new Vector2(0, 0);
+                this.spriteFrame    = 0;
+                this.invertY        = (settings.invertY==null) ? false : settings.invertY;
+                this.alignToPixel   = (settings.alignToPixel==null) ? true : settings.alignToPixel;
+                this._isTransparent = true;
+
+                if (!this.size) {
+                    var s = texture.getSize();
+                    this.size = new Size(s.width, s.height);
+                }
+
+            //return sprite;
         }
 
         static _createCachedCanvasSprite(owner: Canvas2D, texture: MapTexture, size: Size, pos: Vector2): Sprite2D {
 
-            let sprite = new Sprite2D();
-            sprite.setupSprite2D(owner, null, "__cachedCanvasSprite__", new Vector2(0, 0), null, texture, size, pos, false, true, true, null, null, null, null, null, null);
+            let sprite = new Sprite2D(owner, texture, { id:"__cachedCanvasSprite__", position: Vector2.Zero(), origin: Vector2.Zero(), spriteSize: size, spriteLocation:pos, alignToPixel: true});
+            //sprite.setupSprite2D(owner, null, "__cachedCanvasSprite__", new Vector2(0, 0), null, texture, size, pos, false, true, true, null, null, null, null, null, null);
 
             return sprite;
         }

+ 67 - 36
src/Canvas2d/babylon.text2d.ts

@@ -203,16 +203,16 @@
             BoundingInfo2D.CreateFromSizeToRef(this.actualSize, this._levelBoundingInfo, this.origin);
         }
 
-        protected setupText2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, fontName: string, text: string, areaSize: Size, defaultFontColor: Color4, tabulationSize: number, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
-            this.setupRenderablePrim2D(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, hAlignment, vAlignment);
-
-            this.fontName = fontName;
-            this.defaultFontColor = defaultFontColor;
-            this.text = text;
-            this.size = areaSize;
-            this._tabulationSize = tabulationSize;
-            this.isAlphaTest = true;
-        }
+        //protected setupText2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, fontName: string, text: string, areaSize: Size, defaultFontColor: Color4, tabulationSize: number, isVisible: boolean, marginTop: number | string, marginLeft: number | string, marginRight: number | string, marginBottom: number | string, vAlignment: number, hAlignment: number) {
+        //    this.setupRenderablePrim2D(owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, hAlignment, vAlignment);
+
+        //    this.fontName = fontName;
+        //    this.defaultFontColor = defaultFontColor;
+        //    this.text = text;
+        //    this.size = areaSize;
+        //    this._tabulationSize = tabulationSize;
+        //    this.isAlphaTest = true;
+        //}
 
         /**
          * Create a Text primitive
@@ -231,35 +231,66 @@
          *  - hAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          *  - vAlighment: define horizontal alignment of the Canvas, alignment is optional, default value null: no alignment.
          */
-        public static Create(parent: Prim2DBase, text: string, options?: { id?: string, position?: Vector2, x?: number, y?: number, origin?: Vector2, fontName?: string, defaultFontColor?: Color4, size?: Size, tabulationSize?: number, isVisible?: boolean, marginTop?: number | string, marginLeft?: number | string, marginRight?: number | string, marginBottom?: number | string, hAlignment?: number, vAlignment?: number}): Text2D {
+        constructor(parent: Prim2DBase, text: string, settings?: {
+            id              ?: string,
+            position        ?: Vector2,
+            x               ?: number,
+            y               ?: number,
+            origin          ?: Vector2,
+            fontName        ?: string,
+            defaultFontColor?: Color4,
+            size            ?: Size,
+            tabulationSize  ?: number,
+            isVisible       ?: boolean,
+            marginTop       ?: number | string,
+            marginLeft      ?: number | string,
+            marginRight     ?: number | string,
+            marginBottom    ?: number | string,
+            hAlignment      ?: number,
+            vAlignment      ?: number,
+        }) {
+
+            super(parent.owner, parent, settings);
+
             Prim2DBase.CheckParent(parent);
 
-            let text2d = new Text2D();
-            if (!options) {
-                text2d.setupText2D(parent.owner, parent, null, Vector2.Zero(), null, "12pt Arial", text, null, new Color4(1,1,1,1), 4, true, null, null, null, null, null, null);
-            } else {
-                let pos = options.position || new Vector2(options.x || 0, options.y || 0);
-                text2d.setupText2D
-                (
-                    parent.owner,
-                    parent,
-                    options.id || null,
-                    pos,
-                    options.origin || null,
-                    options.fontName || "12pt Arial",
-                    text,
-                    options.size,
-                    options.defaultFontColor || new Color4(1, 1, 1, 1),
-                    (options.tabulationSize==null) ? 4 : options.tabulationSize,
-                    (options.isVisible==null) ? true : options.isVisible,
-                    options.marginTop,
-                    options.marginLeft,
-                    options.marginRight,
-                    options.marginBottom,
-                    options.vAlignment,
-                    options.hAlignment);
+            if (!settings) {
+                settings = {};
             }
-            return text2d;
+
+            this.fontName         = (settings.fontName==null)         ? "12pt Arial"        : settings.fontName;
+            this.defaultFontColor = (settings.defaultFontColor==null) ? new Color4(1,1,1,1) : settings.defaultFontColor;
+            this._tabulationSize  = (settings.tabulationSize == null) ? 4                   : settings.tabulationSize;
+            this.text             = text;
+            this.size             = settings.size;
+            this.isAlphaTest      = true;
+
+            //let text2d = new Text2D();
+            //if (!settings) {
+            //    text2d.setupText2D(parent.owner, parent, null, Vector2.Zero(), null, "12pt Arial", text, null, new Color4(1,1,1,1), 4, true, null, null, null, null, null, null);
+            //} else {
+                //let pos = settings.position || new Vector2(settings.x || 0, settings.y || 0);
+                //text2d.setupText2D
+                //(
+                //    parent.owner,
+                //    parent,
+                //    settings.id || null,
+                //    pos,
+                //    settings.origin || null,
+                //    settings.fontName || "12pt Arial",
+                //    text,
+                //    settings.size,
+                //    settings.defaultFontColor || new Color4(1, 1, 1, 1),
+                //    (settings.tabulationSize==null) ? 4 : settings.tabulationSize,
+                //    (settings.isVisible==null) ? true : settings.isVisible,
+                //    settings.marginTop,
+                //    settings.marginLeft,
+                //    settings.marginRight,
+                //    settings.marginBottom,
+                //    settings.vAlignment,
+                //    settings.hAlignment);
+            //}
+            //return text2d;
         }
 
         protected levelIntersect(intersectInfo: IntersectInfo2D): boolean {

+ 1 - 1
src/Canvas2d/babylon.worldSpaceCanvas2d.ts

@@ -2,7 +2,7 @@
     /**
      * This is the class that is used to display a World Space Canvas into a scene
      */
-    export class WorldSpaceCanvas2D extends Mesh {
+    export class WorldSpaceCanvas2DNode extends Mesh {
         constructor(name: string, scene: Scene, canvas: Canvas2D) {
             super(name, scene);