浏览代码

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into c2d

Adam Bowman 8 年之前
父节点
当前提交
d11dcd77ae

+ 35 - 26
canvas2D/src/Engine/babylon.canvas2d.ts

@@ -340,6 +340,8 @@
                         if (e.pickInfo.hit && e.pickInfo.pickedMesh === this._worldSpaceNode && this.worldSpaceToNodeLocal) {
                             let localPos = this.worldSpaceToNodeLocal(e.pickInfo.pickedPoint);
                             this._handlePointerEventForInteraction(e, localPos, s);
+                        } else if (this._actualIntersectionList && this._actualIntersectionList.length > 0) {
+                            this._handlePointerEventForInteraction(e, null, s);
                         }
                     });
                 }
@@ -468,15 +470,19 @@
             }
 
             // Update the this._primPointerInfo structure we'll send to observers using the PointerEvent data
-            if (!this._updatePointerInfo(eventData, localPosition)) {
-                return;
+            if (localPosition) {
+                if (!this._updatePointerInfo(eventData, localPosition)) {
+                    return;
+                }
+            } else {
+                this._primPointerInfo.canvasPointerPos = null;
             }
 
             let capturedPrim = this.getCapturedPrimitive(this._primPointerInfo.pointerId);
 
             // Make sure the intersection list is up to date, we maintain this list either in response of a mouse event (here) or before rendering the canvas.
             // Why before rendering the canvas? because some primitives may move and get away/under the mouse cursor (which is not moving). So we need to update at both location in order to always have an accurate list, which is needed for the hover state change.
-            this._updateIntersectionList(this._primPointerInfo.canvasPointerPos, capturedPrim !== null, true);
+            this._updateIntersectionList(localPosition ? this._primPointerInfo.canvasPointerPos : null, capturedPrim !== null, true);
 
             // Update the over status, same as above, it's could be done here or during rendering, but will be performed only once per render frame
             this._updateOverStatus(true);
@@ -572,35 +578,38 @@
                 return;
             }
 
-            // A little safe guard, it might happens than the event is triggered before the first render and nothing is computed, this simple check will make sure everything will be fine
-            if (!this._globalTransform) {
-                this.updateCachedStates(true);
-            }
-
             let ii = Canvas2D._interInfo;
-            ii.pickPosition.x = mouseLocalPos.x;
-            ii.pickPosition.y = mouseLocalPos.y;
-            ii.findFirstOnly = false;
-
-            // Fast rejection: test if the mouse pointer is outside the canvas's bounding Info
-            if (!isCapture && !this.levelBoundingInfo.doesIntersect(ii.pickPosition)) {
-                // Reset intersection info as we don't hit anything
-                ii.intersectedPrimitives = new Array<PrimitiveIntersectedInfo>();
-                ii.topMostIntersectedPrimitive = null;
-            } else {
-                // The pointer is inside the Canvas, do an intersection test
-                this.intersect(ii);
+            let outCase = mouseLocalPos == null;
+            if (!outCase) {
+                // A little safe guard, it might happens than the event is triggered before the first render and nothing is computed, this simple check will make sure everything will be fine
+                if (!this._globalTransform) {
+                    this.updateCachedStates(true);
+                }
+
+                ii.pickPosition.x = mouseLocalPos.x;
+                ii.pickPosition.y = mouseLocalPos.y;
+                ii.findFirstOnly = false;
 
-                // Sort primitives to get them from top to bottom
-                ii.intersectedPrimitives = ii.intersectedPrimitives.sort((a, b) => a.prim.actualZOffset - b.prim.actualZOffset);
+                // Fast rejection: test if the mouse pointer is outside the canvas's bounding Info
+                if (!isCapture && !this.levelBoundingInfo.doesIntersect(ii.pickPosition)) {
+                    // Reset intersection info as we don't hit anything
+                    ii.intersectedPrimitives = new Array<PrimitiveIntersectedInfo>();
+                    ii.topMostIntersectedPrimitive = null;
+                } else {
+                    // The pointer is inside the Canvas, do an intersection test
+                    this.intersect(ii);
+
+                    // Sort primitives to get them from top to bottom
+                    ii.intersectedPrimitives = ii.intersectedPrimitives.sort((a, b) => a.prim.actualZOffset - b.prim.actualZOffset);
+                }
             }
 
             {
                 // Update prev/actual intersection info, fire "overPrim" property change if needed
                 this._previousIntersectionList = this._actualIntersectionList;
-                this._actualIntersectionList = ii.intersectedPrimitives;
-                this._previousOverPrimitive = this._actualOverPrimitive;
-                this._actualOverPrimitive = ii.topMostIntersectedPrimitive;
+                this._actualIntersectionList   = outCase ? new Array<PrimitiveIntersectedInfo>() : ii.intersectedPrimitives;
+                this._previousOverPrimitive    = this._actualOverPrimitive;
+                this._actualOverPrimitive      = outCase ? null : ii.topMostIntersectedPrimitive;
 
                 let prev = (this._previousOverPrimitive != null) ? this._previousOverPrimitive.prim : null;
                 let actual = (this._actualOverPrimitive != null) ? this._actualOverPrimitive.prim : null;
@@ -1491,7 +1500,7 @@
                 this._updateOverStatus(false);
             }
 
-            this.engine.setState(false);
+            this.engine.setState(false, undefined, true);
             this._groupRender();
 
             if (!this._isScreenSpace) {

+ 1 - 1
canvas2D/src/Engine/babylon.canvas2dLayoutEngine.ts

@@ -160,7 +160,7 @@
                     }
                     let layoutArea: Size;
                     if (child._hasMargin) {
-                        child.margin.computeWithAlignment(prim.layoutArea, child.actualSize, child.marginAlignment, StackPanelLayoutEngine.dstOffset, StackPanelLayoutEngine.dstArea, true);
+                        child.margin.computeWithAlignment(prim.layoutArea, child.actualSize, child.marginAlignment, child.actualScale, StackPanelLayoutEngine.dstOffset, StackPanelLayoutEngine.dstArea, true);
                         layoutArea = StackPanelLayoutEngine.dstArea.clone();
                         child.layoutArea = layoutArea;
                     } else {

+ 3 - 3
canvas2D/src/Engine/babylon.ellipse2d.ts

@@ -362,10 +362,10 @@
                 let ib = new Float32Array(triCount * 3);
                 for (let i = 0; i < triCount; i++) {
                     ib[i * 3 + 0] = 0;
-                    ib[i * 3 + 2] = i + 1;
-                    ib[i * 3 + 1] = i + 2;
+                    ib[i * 3 + 2] = i + 2;
+                    ib[i * 3 + 1] = i + 1;
                 }
-                ib[triCount * 3 - 2] = 1;
+                ib[triCount * 3 - 1] = 1;
 
                 renderCache.fillIB = engine.createIndexBuffer(ib);
                 renderCache.fillIndicesCount = triCount * 3;

+ 7 - 0
canvas2D/src/Engine/babylon.group2d.ts

@@ -1025,6 +1025,13 @@
             }
         }
 
+        public get _cachedTexture(): MapTexture {
+            if (this._renderableData) {
+                return this._renderableData._cacheTexture;
+            }
+            return null;
+        }
+
         private _trackedNode: Node;
         protected _isRenderableGroup: boolean;
         protected _isCachedGroup: boolean;

+ 1 - 0
canvas2D/src/Engine/babylon.lines2d.ts

@@ -30,6 +30,7 @@
             }
             let canvas = instanceInfo.owner.owner;
             var engine = canvas.engine;
+            engine.setState(false, undefined, true);
 
             let depthFunction = 0;
             if (this.effectFill && this.effectBorder) {

+ 16 - 14
canvas2D/src/Engine/babylon.prim2dBase.ts

@@ -1082,7 +1082,7 @@
          * @param dstOffset the position of the content, x, y, z, w are left, bottom, right, top
          * @param dstArea the new size of the content
          */
-        public computeWithAlignment(sourceArea: Size, contentSize: Size, alignment: PrimitiveAlignment, dstOffset: Vector4, dstArea: Size, computeLayoutArea = false) {
+        public computeWithAlignment(sourceArea: Size, contentSize: Size, alignment: PrimitiveAlignment, contentScale: Vector2, dstOffset: Vector4, dstArea: Size, computeLayoutArea = false) {
             // Fetch some data
             let topType = this._getType(0, true);
             let leftType = this._getType(1, true);
@@ -1090,6 +1090,8 @@
             let bottomType = this._getType(3, true);
             let hasWidth = contentSize && (contentSize.width != null);
             let hasHeight = contentSize && (contentSize.height != null);
+            let sx = contentScale.x;
+            let sy = contentScale.y;
             let width = hasWidth ? contentSize.width : 0;
             let height = hasHeight ? contentSize.height : 0;
             let isTopAuto = topType === PrimitiveThickness.Auto;
@@ -1110,17 +1112,17 @@
                         if (computeLayoutArea) {
                             dstArea.width += this.leftPixels;
                         }
-                        dstOffset.z = sourceArea.width - (dstOffset.x + width);
+                        dstOffset.z = sourceArea.width - (dstOffset.x + (width * sx));
                         break;
 
                     }
                 case PrimitiveAlignment.AlignRight:
                     {
                         if (isRightAuto) {
-                            dstOffset.x = Math.round(sourceArea.width - width);
+                            dstOffset.x = Math.round(sourceArea.width - (width * sx));
                         } else {
                             this._computePixels(2, sourceArea, true);
-                            dstOffset.x = Math.round(sourceArea.width - (width + this.rightPixels));
+                            dstOffset.x = Math.round(sourceArea.width - ((width * sx) + this.rightPixels));
                         }
                         dstArea.width = width;
                         if (computeLayoutArea) {
@@ -1157,9 +1159,9 @@
                         }
 
                         let offset = (isLeftAuto ? 0 : this.leftPixels) - (isRightAuto ? 0 : this.rightPixels);
-                        dstOffset.x = Math.round(((sourceArea.width - width) / 2) + offset);
+                        dstOffset.x = Math.round(((sourceArea.width - (width*sx)) / 2) + offset);
                         dstArea.width = width;
-                        dstOffset.z = sourceArea.width - (dstOffset.x + width);
+                        dstOffset.z = sourceArea.width - (dstOffset.x + (width*sx));
                         break;
                     }
             }
@@ -1168,10 +1170,10 @@
                 case PrimitiveAlignment.AlignTop:
                     {
                         if (isTopAuto) {
-                            dstOffset.y = sourceArea.height - height;
+                            dstOffset.y = sourceArea.height - (height * sy);
                         } else {
                             this._computePixels(0, sourceArea, true);
-                            dstOffset.y = Math.round(sourceArea.height - (height + this.topPixels));
+                            dstOffset.y = Math.round(sourceArea.height - ((height * sy) + this.topPixels));
                         }
                         dstArea.height = height;
                         if (computeLayoutArea) {
@@ -1193,7 +1195,7 @@
                         if (computeLayoutArea) {
                             dstArea.height += this.bottomPixels;
                         }
-                        dstOffset.w = sourceArea.height - (dstOffset.y + height);
+                        dstOffset.w = sourceArea.height - (dstOffset.y + (height * sy));
                         break;
 
                     }
@@ -1225,9 +1227,9 @@
                         }
 
                         let offset = (isBottomAuto ? 0 : this.bottomPixels) - (isTopAuto ? 0 : this.topPixels);
-                        dstOffset.y = Math.round(((sourceArea.height - height) / 2) + offset);
+                        dstOffset.y = Math.round(((sourceArea.height - (height * sy)) / 2) + offset);
                         dstArea.height = height;
-                        dstOffset.w = sourceArea.height - (dstOffset.y + height);
+                        dstOffset.w = sourceArea.height - (dstOffset.y + (height * sy));
                         break;
                     }
             }
@@ -3615,8 +3617,8 @@
 
             // Apply margin
             if (this._hasMargin) {
-                this.margin.computeWithAlignment(this.layoutArea, this.size || this.actualSize, this.marginAlignment, this._marginOffset, Prim2DBase._size);
-                this.actualSize = Prim2DBase._size.clone();
+                let contentSize = this.size || this.actualSize;
+                this.margin.computeWithAlignment(this.layoutArea, contentSize, this.marginAlignment, this.actualScale, this._marginOffset, Prim2DBase._size);
             }
 
             if (this._hasPadding) {
@@ -3624,7 +3626,7 @@
                 if (isSizeAuto) {
                     // Changing the padding has resize the prim, which forces us to recompute margin again
                     if (this._hasMargin) {
-                        this.margin.computeWithAlignment(this.layoutArea, Prim2DBase._size, this.marginAlignment, this._marginOffset, Prim2DBase._size);
+                        this.margin.computeWithAlignment(this.layoutArea, Prim2DBase._size, this.marginAlignment, this.actualScale, this._marginOffset, Prim2DBase._size);
                     }
 
                 } else {

+ 2 - 1
dist/preview release/canvas2D/babylon.canvas2d.d.ts

@@ -1779,7 +1779,7 @@ declare module BABYLON {
          * @param dstOffset the position of the content, x, y, z, w are left, bottom, right, top
          * @param dstArea the new size of the content
          */
-        computeWithAlignment(sourceArea: Size, contentSize: Size, alignment: PrimitiveAlignment, dstOffset: Vector4, dstArea: Size, computeLayoutArea?: boolean): void;
+        computeWithAlignment(sourceArea: Size, contentSize: Size, alignment: PrimitiveAlignment, contentScale: Vector2, dstOffset: Vector4, dstArea: Size, computeLayoutArea?: boolean): void;
         /**
          * Compute an area and its position considering this thickness properties based on a given source area
          * @param sourceArea the source area
@@ -2822,6 +2822,7 @@ declare module BABYLON {
         protected static _unS: Vector2;
         protected handleGroupChanged(prop: Prim2DPropInfo): void;
         private detectGroupStates();
+        readonly _cachedTexture: MapTexture;
         private _trackedNode;
         protected _isRenderableGroup: boolean;
         protected _isCachedGroup: boolean;

+ 66 - 42
dist/preview release/canvas2D/babylon.canvas2d.js

@@ -3110,7 +3110,7 @@ var BABYLON;
                     }
                     var layoutArea = void 0;
                     if (child._hasMargin) {
-                        child.margin.computeWithAlignment(prim.layoutArea, child.actualSize, child.marginAlignment, StackPanelLayoutEngine_1.dstOffset, StackPanelLayoutEngine_1.dstArea, true);
+                        child.margin.computeWithAlignment(prim.layoutArea, child.actualSize, child.marginAlignment, child.actualScale, StackPanelLayoutEngine_1.dstOffset, StackPanelLayoutEngine_1.dstArea, true);
                         layoutArea = StackPanelLayoutEngine_1.dstArea.clone();
                         child.layoutArea = layoutArea;
                     }
@@ -5583,7 +5583,7 @@ var BABYLON;
          * @param dstOffset the position of the content, x, y, z, w are left, bottom, right, top
          * @param dstArea the new size of the content
          */
-        PrimitiveThickness.prototype.computeWithAlignment = function (sourceArea, contentSize, alignment, dstOffset, dstArea, computeLayoutArea) {
+        PrimitiveThickness.prototype.computeWithAlignment = function (sourceArea, contentSize, alignment, contentScale, dstOffset, dstArea, computeLayoutArea) {
             if (computeLayoutArea === void 0) { computeLayoutArea = false; }
             // Fetch some data
             var topType = this._getType(0, true);
@@ -5592,6 +5592,8 @@ var BABYLON;
             var bottomType = this._getType(3, true);
             var hasWidth = contentSize && (contentSize.width != null);
             var hasHeight = contentSize && (contentSize.height != null);
+            var sx = contentScale.x;
+            var sy = contentScale.y;
             var width = hasWidth ? contentSize.width : 0;
             var height = hasHeight ? contentSize.height : 0;
             var isTopAuto = topType === PrimitiveThickness_1.Auto;
@@ -5612,17 +5614,17 @@ var BABYLON;
                         if (computeLayoutArea) {
                             dstArea.width += this.leftPixels;
                         }
-                        dstOffset.z = sourceArea.width - (dstOffset.x + width);
+                        dstOffset.z = sourceArea.width - (dstOffset.x + (width * sx));
                         break;
                     }
                 case PrimitiveAlignment.AlignRight:
                     {
                         if (isRightAuto) {
-                            dstOffset.x = Math.round(sourceArea.width - width);
+                            dstOffset.x = Math.round(sourceArea.width - (width * sx));
                         }
                         else {
                             this._computePixels(2, sourceArea, true);
-                            dstOffset.x = Math.round(sourceArea.width - (width + this.rightPixels));
+                            dstOffset.x = Math.round(sourceArea.width - ((width * sx) + this.rightPixels));
                         }
                         dstArea.width = width;
                         if (computeLayoutArea) {
@@ -5658,9 +5660,9 @@ var BABYLON;
                             this._computePixels(2, sourceArea, true);
                         }
                         var offset = (isLeftAuto ? 0 : this.leftPixels) - (isRightAuto ? 0 : this.rightPixels);
-                        dstOffset.x = Math.round(((sourceArea.width - width) / 2) + offset);
+                        dstOffset.x = Math.round(((sourceArea.width - (width * sx)) / 2) + offset);
                         dstArea.width = width;
-                        dstOffset.z = sourceArea.width - (dstOffset.x + width);
+                        dstOffset.z = sourceArea.width - (dstOffset.x + (width * sx));
                         break;
                     }
             }
@@ -5668,11 +5670,11 @@ var BABYLON;
                 case PrimitiveAlignment.AlignTop:
                     {
                         if (isTopAuto) {
-                            dstOffset.y = sourceArea.height - height;
+                            dstOffset.y = sourceArea.height - (height * sy);
                         }
                         else {
                             this._computePixels(0, sourceArea, true);
-                            dstOffset.y = Math.round(sourceArea.height - (height + this.topPixels));
+                            dstOffset.y = Math.round(sourceArea.height - ((height * sy) + this.topPixels));
                         }
                         dstArea.height = height;
                         if (computeLayoutArea) {
@@ -5694,7 +5696,7 @@ var BABYLON;
                         if (computeLayoutArea) {
                             dstArea.height += this.bottomPixels;
                         }
-                        dstOffset.w = sourceArea.height - (dstOffset.y + height);
+                        dstOffset.w = sourceArea.height - (dstOffset.y + (height * sy));
                         break;
                     }
                 case PrimitiveAlignment.AlignStretch:
@@ -5724,9 +5726,9 @@ var BABYLON;
                             this._computePixels(3, sourceArea, true);
                         }
                         var offset = (isBottomAuto ? 0 : this.bottomPixels) - (isTopAuto ? 0 : this.topPixels);
-                        dstOffset.y = Math.round(((sourceArea.height - height) / 2) + offset);
+                        dstOffset.y = Math.round(((sourceArea.height - (height * sy)) / 2) + offset);
                         dstArea.height = height;
-                        dstOffset.w = sourceArea.height - (dstOffset.y + height);
+                        dstOffset.w = sourceArea.height - (dstOffset.y + (height * sy));
                         break;
                     }
             }
@@ -7810,15 +7812,15 @@ var BABYLON;
             }
             // Apply margin
             if (this._hasMargin) {
-                this.margin.computeWithAlignment(this.layoutArea, this.size || this.actualSize, this.marginAlignment, this._marginOffset, Prim2DBase_1._size);
-                this.actualSize = Prim2DBase_1._size.clone();
+                var contentSize = this.size || this.actualSize;
+                this.margin.computeWithAlignment(this.layoutArea, contentSize, this.marginAlignment, this.actualScale, this._marginOffset, Prim2DBase_1._size);
             }
             if (this._hasPadding) {
                 // Two cases from here: the size of the Primitive is Auto, its content can't be shrink, so we resize the primitive itself
                 if (isSizeAuto) {
                     // Changing the padding has resize the prim, which forces us to recompute margin again
                     if (this._hasMargin) {
-                        this.margin.computeWithAlignment(this.layoutArea, Prim2DBase_1._size, this.marginAlignment, this._marginOffset, Prim2DBase_1._size);
+                        this.margin.computeWithAlignment(this.layoutArea, Prim2DBase_1._size, this.marginAlignment, this.actualScale, this._marginOffset, Prim2DBase_1._size);
                     }
                 }
                 else {
@@ -10603,6 +10605,16 @@ var BABYLON;
                 }
             }
         };
+        Object.defineProperty(Group2D.prototype, "_cachedTexture", {
+            get: function () {
+                if (this._renderableData) {
+                    return this._renderableData._cacheTexture;
+                }
+                return null;
+            },
+            enumerable: true,
+            configurable: true
+        });
         return Group2D;
     }(BABYLON.Prim2DBase));
     Group2D.GROUP2D_PROPCOUNT = BABYLON.Prim2DBase.PRIM2DBASE_PROPCOUNT + 5;
@@ -11992,10 +12004,10 @@ var BABYLON;
                 var ib = new Float32Array(triCount * 3);
                 for (var i = 0; i < triCount; i++) {
                     ib[i * 3 + 0] = 0;
-                    ib[i * 3 + 2] = i + 1;
-                    ib[i * 3 + 1] = i + 2;
+                    ib[i * 3 + 2] = i + 2;
+                    ib[i * 3 + 1] = i + 1;
                 }
-                ib[triCount * 3 - 2] = 1;
+                ib[triCount * 3 - 1] = 1;
                 renderCache.fillIB = engine.createIndexBuffer(ib);
                 renderCache.fillIndicesCount = triCount * 3;
                 // Get the instanced version of the effect, if the engine does not support it, null is return and we'll only draw on by one
@@ -13696,6 +13708,7 @@ var BABYLON;
             }
             var canvas = instanceInfo.owner.owner;
             var engine = canvas.engine;
+            engine.setState(false, undefined, true);
             var depthFunction = 0;
             if (this.effectFill && this.effectBorder) {
                 depthFunction = engine.getDepthFunction();
@@ -15195,6 +15208,9 @@ var BABYLON;
                             var localPos = _this.worldSpaceToNodeLocal(e.pickInfo.pickedPoint);
                             _this._handlePointerEventForInteraction(e, localPos, s);
                         }
+                        else if (_this._actualIntersectionList && _this._actualIntersectionList.length > 0) {
+                            _this._handlePointerEventForInteraction(e, null, s);
+                        }
                     });
                 }
                 else {
@@ -15262,13 +15278,18 @@ var BABYLON;
                 return;
             }
             // Update the this._primPointerInfo structure we'll send to observers using the PointerEvent data
-            if (!this._updatePointerInfo(eventData, localPosition)) {
-                return;
+            if (localPosition) {
+                if (!this._updatePointerInfo(eventData, localPosition)) {
+                    return;
+                }
+            }
+            else {
+                this._primPointerInfo.canvasPointerPos = null;
             }
             var capturedPrim = this.getCapturedPrimitive(this._primPointerInfo.pointerId);
             // Make sure the intersection list is up to date, we maintain this list either in response of a mouse event (here) or before rendering the canvas.
             // Why before rendering the canvas? because some primitives may move and get away/under the mouse cursor (which is not moving). So we need to update at both location in order to always have an accurate list, which is needed for the hover state change.
-            this._updateIntersectionList(this._primPointerInfo.canvasPointerPos, capturedPrim !== null, true);
+            this._updateIntersectionList(localPosition ? this._primPointerInfo.canvasPointerPos : null, capturedPrim !== null, true);
             // Update the over status, same as above, it's could be done here or during rendering, but will be performed only once per render frame
             this._updateOverStatus(true);
             // Check if we have nothing to raise
@@ -15353,32 +15374,35 @@ var BABYLON;
             if (!force && (this.scene.getRenderId() === this._intersectionRenderId)) {
                 return;
             }
-            // A little safe guard, it might happens than the event is triggered before the first render and nothing is computed, this simple check will make sure everything will be fine
-            if (!this._globalTransform) {
-                this.updateCachedStates(true);
-            }
             var ii = Canvas2D_1._interInfo;
-            ii.pickPosition.x = mouseLocalPos.x;
-            ii.pickPosition.y = mouseLocalPos.y;
-            ii.findFirstOnly = false;
-            // Fast rejection: test if the mouse pointer is outside the canvas's bounding Info
-            if (!isCapture && !this.levelBoundingInfo.doesIntersect(ii.pickPosition)) {
-                // Reset intersection info as we don't hit anything
-                ii.intersectedPrimitives = new Array();
-                ii.topMostIntersectedPrimitive = null;
-            }
-            else {
-                // The pointer is inside the Canvas, do an intersection test
-                this.intersect(ii);
-                // Sort primitives to get them from top to bottom
-                ii.intersectedPrimitives = ii.intersectedPrimitives.sort(function (a, b) { return a.prim.actualZOffset - b.prim.actualZOffset; });
+            var outCase = mouseLocalPos == null;
+            if (!outCase) {
+                // A little safe guard, it might happens than the event is triggered before the first render and nothing is computed, this simple check will make sure everything will be fine
+                if (!this._globalTransform) {
+                    this.updateCachedStates(true);
+                }
+                ii.pickPosition.x = mouseLocalPos.x;
+                ii.pickPosition.y = mouseLocalPos.y;
+                ii.findFirstOnly = false;
+                // Fast rejection: test if the mouse pointer is outside the canvas's bounding Info
+                if (!isCapture && !this.levelBoundingInfo.doesIntersect(ii.pickPosition)) {
+                    // Reset intersection info as we don't hit anything
+                    ii.intersectedPrimitives = new Array();
+                    ii.topMostIntersectedPrimitive = null;
+                }
+                else {
+                    // The pointer is inside the Canvas, do an intersection test
+                    this.intersect(ii);
+                    // Sort primitives to get them from top to bottom
+                    ii.intersectedPrimitives = ii.intersectedPrimitives.sort(function (a, b) { return a.prim.actualZOffset - b.prim.actualZOffset; });
+                }
             }
             {
                 // Update prev/actual intersection info, fire "overPrim" property change if needed
                 this._previousIntersectionList = this._actualIntersectionList;
-                this._actualIntersectionList = ii.intersectedPrimitives;
+                this._actualIntersectionList = outCase ? new Array() : ii.intersectedPrimitives;
                 this._previousOverPrimitive = this._actualOverPrimitive;
-                this._actualOverPrimitive = ii.topMostIntersectedPrimitive;
+                this._actualOverPrimitive = outCase ? null : ii.topMostIntersectedPrimitive;
                 var prev = (this._previousOverPrimitive != null) ? this._previousOverPrimitive.prim : null;
                 var actual = (this._actualOverPrimitive != null) ? this._actualOverPrimitive.prim : null;
                 if (prev !== actual) {
@@ -16143,7 +16167,7 @@ var BABYLON;
                 this._updateIntersectionList(this._primPointerInfo.canvasPointerPos, false, false);
                 this._updateOverStatus(false);
             }
-            this.engine.setState(false);
+            this.engine.setState(false, undefined, true);
             this._groupRender();
             if (!this._isScreenSpace) {
                 if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagWorldCacheChanged)) {

文件差异内容过多而无法显示
+ 9 - 9
dist/preview release/canvas2D/babylon.canvas2d.min.js


+ 2 - 1
inspector/src/adapters/Canvas2DAdapter.ts

@@ -36,7 +36,8 @@ module INSPECTOR {
             let toAddDirty = [
                 'actualZOffset', 'isSizeAuto', 'layoutArea', 'layoutAreaPos', 'contentArea', 
                 'marginOffset', 'paddingOffset', 'isPickable', 'isContainer', 'boundingInfo', 
-                'levelBoundingInfo', 'isSizedByContent', 'isPositionAuto', 'actualScale', 'layoutBoundingInfo'];
+                'levelBoundingInfo', 'isSizedByContent', 'isPositionAuto', 'actualScale', 'layoutBoundingInfo', 
+                '_cachedTexture'];
             for (let dirty of toAddDirty) {
                 let infos = new Property(dirty, this.actualObject);
                 propertiesLines.push(new PropertyLine(infos));

+ 1 - 1
inspector/src/helpers/Helpers.ts

@@ -128,7 +128,7 @@ module INSPECTOR {
             div.style.display = 'none';
             div.appendChild(clone);
             let value = Inspector.WINDOW.getComputedStyle(clone)[cssAttribute];
-            div.remove();
+            div.parentNode.removeChild(div);
             return value;
         }
         

+ 5 - 8
inspector/src/tabs/ConsoleTab.ts

@@ -60,6 +60,7 @@ module INSPECTOR {
             this._bjsPanelContent.innerHTML = BABYLON.Tools.LogCache;
             BABYLON.Tools.OnNewCacheEntry = (entry: string) => {
                 this._bjsPanelContent.innerHTML += entry;
+                this._bjsPanelContent.scrollTop = this._bjsPanelContent.scrollHeight; 
             };
 
             // Testing
@@ -87,15 +88,11 @@ module INSPECTOR {
             let callerLine = Helpers.CreateDiv('caller', this._consolePanelContent);
             callerLine.textContent = caller;
 
-            let line = Helpers.CreateDiv(type, this._consolePanelContent);
-            if (typeof message === "string") {
-                line.textContent += message ; 
-            } else {
-                line.textContent += JSON.stringify(message) ;
-                line.classList.add('object')
-            }
-        }
+            let line = Helpers.CreateDiv(type, this._consolePanelContent); 
+            line.textContent += message ; 
 
+            this._consolePanelContent.scrollTop = this._consolePanelContent.scrollHeight; 
+        }
         private _addConsoleLog(...params : any[]) {
             
             // Get caller name if not null

+ 31 - 35
inspector/test/index.js

@@ -94,41 +94,37 @@ var Test = (function () {
      * Create the canvas2D
      */
     Test.prototype._createCanvas = function () {
-        var canvas = new BABYLON.ScreenSpaceCanvas2D(this.scene, {
-            id: "Hello world SC",
-            size: new BABYLON.Size(300, 100),
-            backgroundFill: "#4040408F",
-            backgroundRoundRadius: 50,
-            children: [
-                new BABYLON.Text2D("Hello World!", {
-                    id: "text",
-                    marginAlignment: "h: center, v:center",
-                    fontName: "20pt Arial",
-                })
-            ]
-        });
-        var infoCanvas = new BABYLON.ScreenSpaceCanvas2D(this.scene, { id: "PINK CUBE SC", size: new BABYLON.Size(500, 500) });
-        var text2 = new BABYLON.Text2D("UnbindTime", { parent: infoCanvas, id: "Text", marginAlignment: "h: left, v: bottom", fontName: "10pt Arial" });
-        canvas = new BABYLON.WorldSpaceCanvas2D(this.scene, new BABYLON.Size(150, 150), {
-            id: "WorldSpaceCanvas",
-            worldPosition: new BABYLON.Vector3(0, 0, 0),
-            worldRotation: BABYLON.Quaternion.RotationYawPitchRoll(Math.PI / 4, Math.PI / 4, 0),
-            enableInteraction: true,
-            backgroundFill: "#C0C0C040",
-            backgroundRoundRadius: 20,
-            children: [
-                new BABYLON.Text2D("World Space Canvas", { fontName: "8pt Arial", marginAlignment: "h: center, v: bottom", fontSuperSample: true })
-            ]
-        });
-        var rect = new BABYLON.Rectangle2D({ parent: canvas, x: 45, y: 45, width: 30, height: 30, fill: null, border: BABYLON.Canvas2D.GetGradientColorBrush(new BABYLON.Color4(0.9, 0.3, 0.9, 1), new BABYLON.Color4(1.0, 1.0, 1.0, 1)), borderThickness: 2 });
-        var buttonRect = new BABYLON.Rectangle2D({ parent: canvas, id: "button", x: 12, y: 12, width: 50, height: 15, fill: "#40C040FF", roundRadius: 2, children: [new BABYLON.Text2D("Click Me!", { fontName: "8pt Arial", marginAlignment: "h: center, v: center", fontSuperSample: true })] });
-        var button2Rect = new BABYLON.Rectangle2D({ parent: canvas, id: "button2", x: 70, y: 12, width: 40, height: 15, fill: "#4040C0FF", roundRadius: 2, isVisible: false, children: [new BABYLON.Text2D("Great!", { fontName: "8pt Arial", marginAlignment: "h: center, v: center", fontSuperSample: true })] });
-        ;
-        buttonRect.pointerEventObservable.add(function (d, s) {
-            button2Rect.levelVisible = !button2Rect.levelVisible;
-        }, BABYLON.PrimitivePointerInfo.PointerUp);
-        var insideRect = new BABYLON.Rectangle2D({ parent: rect, width: 10, height: 10, marginAlignment: "h: center, v: center", fill: "#0040F0FF" });
-        insideRect.roundRadius = 2;
+        // object hierarchy  g1 -> g2 -> rect
+            
+            // when cachingStrategy is 1 or 2 - everything is rendered
+            // when it is 3 - only direct children of g1 are rendered
+            var canvas = new BABYLON.ScreenSpaceCanvas2D(this.scene, 
+                { id: "ScreenCanvas", 
+                cachingStrategy: BABYLON.Canvas2D.CACHESTRATEGY_DONTCACHE });           // 1
+                // cachingStrategy: BABYLON.Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS });      // 2 
+                // cachingStrategy: BABYLON.Canvas2D.CACHESTRATEGY_ALLGROUPS });           // 3
+            
+            canvas.createCanvasProfileInfoCanvas();
+
+            // parent group            
+            var g1 = new BABYLON.Group2D({parent: canvas, id: "G1",
+                x: 50, y: 50, size: new BABYLON.Size(60, 60)});
+
+            // just to see it    
+            let frame1 = new BABYLON.Rectangle2D({parent: g1, 
+                         x : 0, y: 0,  size: g1.size, border: "#FF0000FF" });
+            
+            // child group
+            let g2 = new BABYLON.Group2D({parent: g1, id: "G2",  
+                        x: 10, y: 10, size: new BABYLON.Size(40, 40)});
+
+            // just to see it
+            let frame2 = new BABYLON.Rectangle2D({parent: g2, x : 0, y: 0, size: g2.size, border: "#0000FFFF" }); 
+            
+            let rect =   new BABYLON.Rectangle2D({parent: g2, x : 10, y: 10, size: new BABYLON.Size(20, 20), 
+                                fill: "#00FF00FF" }) ;              
+                      
+            return canvas;
     };
     return Test;
 }());