浏览代码

Merge pull request #1466 from nockawa/master

Canvas2D: Bug fixes
Loïc Baumann 8 年之前
父节点
当前提交
84fbef0df9

+ 1 - 27
canvas2D/src/Engine/babylon.canvas2d.ts

@@ -75,7 +75,6 @@
             isScreenSpace?: boolean,
             cachingStrategy?: number,
             enableInteraction?: boolean,
-            allow3DEventBelowCanvas?: boolean,
             origin?: Vector2,
             isVisible?: boolean,
             backgroundRoundRadius?: number,
@@ -173,8 +172,6 @@
             this._maxAdaptiveWorldSpaceCanvasSize = null;
             this._groupCacheMaps = new StringDictionary<MapTexture[]>();
 
-            this._changeFlags(SmartPropertyPrim.flagAllow3DEventsBelowCanvas, (settings.allow3DEventBelowCanvas != null) && settings.allow3DEventBelowCanvas);
-
             this._patchHierarchy(this);
 
             let enableInteraction = (settings.enableInteraction == null) ? true : settings.enableInteraction;
@@ -493,12 +490,6 @@
             }
 
             eventState.skipNextObservers = skip;
-            if (!skip && (this._isFlagSet(SmartPropertyPrim.flagAllow3DEventsBelowCanvas)===false)) {
-                eventState.skipNextObservers = true;
-                if (eventData instanceof PointerInfoPre) {
-                    eventData.skipOnPointerObservable = true;
-                }
-            }
         }
 
         private _updatePointerInfo(eventData: PointerInfoBase, localPosition: Vector2): boolean {
@@ -1079,21 +1070,6 @@
             return this.__engineData;
         }
 
-        /**
-         * If true is returned, pointerEvent occurring above the Canvas area also sent in 3D scene, if false they are not sent in the 3D Scene
-         */
-        public get allow3DEventBelowCanvas(): boolean {
-            return this._isFlagSet(SmartPropertyPrim.flagAllow3DEventsBelowCanvas);
-        }
-
-        /**
-         * Set true if you want pointerEvent occurring above the Canvas area to also be sent in the 3D scene.
-         * Set false if you don't want the Scene to get the events
-         */
-        public set allow3DEventBelowCanvas(value: boolean) {
-            this._changeFlags(SmartPropertyPrim.flagAllow3DEventsBelowCanvas, value);
-        }
-
         public createCanvasProfileInfoCanvas(): Canvas2D {
             if (this._profilingCanvas) {
                 return this._profilingCanvas;
@@ -1826,7 +1802,7 @@
             this.propertyChanged.add((e, st) => {
                 let mesh = this._worldSpaceNode as AbstractMesh;
                 if (mesh) {
-                    mesh.isVisible = this.isVisible;
+                    mesh.isVisible = e.newValue;
                 }
             }, Prim2DBase.isVisibleProperty.flagId);
         }
@@ -1857,7 +1833,6 @@
          *  - designUseHorizAxis: you can set this member if you use designSize to specify which axis is priority to compute the scale when the ratio of the canvas' size is different from the designSize's one.
          *  - 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.
-         *  - allow3DEventBelowCanvas: by default pointerEvent occurring above the Canvas will prevent to be also sent in the 3D Scene. If you set this setting to true, events will be sent both for Canvas and 3D Scene
          *  - isVisible: true if the canvas must be visible, false for hidden. Default is true.
          * - backgroundRoundRadius: the round radius of the background, either backgroundFill or backgroundBorder must be specified.
          * - backgroundFill: the brush to use to create a background fill for the canvas. can be a string value (see BABYLON.Canvas2D.GetBrushFromString) or a IBrush2D instance.
@@ -1887,7 +1862,6 @@
             cachingStrategy?: number,
             cacheBehavior?: number,
             enableInteraction?: boolean,
-            allow3DEventBelowCanvas?: boolean,
             isVisible?: boolean,
             backgroundRoundRadius?: number,
             backgroundFill?: IBrush2D | string,

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

@@ -62,12 +62,12 @@
         private _doUpdate(prim: Prim2DBase) {
             // Canvas ?
             if (prim instanceof Canvas2D) {
-                prim.layoutArea = prim.actualSize.multiplyByFloats(prim.scaleX, prim.scaleY);
+                prim.layoutArea = prim.actualSize; //.multiplyByFloats(prim.scaleX, prim.scaleY);
             }
 
             // Direct child of Canvas ?
             else if (prim.parent instanceof Canvas2D) {
-                prim.layoutArea = prim.owner.actualSize.multiplyByFloats(prim.owner.scaleX, prim.owner.scaleY);
+                prim.layoutArea = prim.owner.actualSize; //.multiplyByFloats(prim.owner.scaleX, prim.owner.scaleY);
             }
 
             // Indirect child of Canvas

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

@@ -829,7 +829,7 @@
                 scale = this.actualScale;
             }
 
-            if (isCanvas && this.owner.cachingStrategy===Canvas2D.CACHESTRATEGY_CANVAS) {
+            if (isCanvas && this.owner.cachingStrategy===Canvas2D.CACHESTRATEGY_CANVAS && this.owner.isScreenSpace) {
                 Group2D._s.width = this.owner.engine.getRenderWidth();
                 Group2D._s.height = this.owner.engine.getRenderHeight();
             } else {

+ 31 - 9
canvas2D/src/Engine/babylon.prim2dBase.ts

@@ -2083,7 +2083,7 @@
          */
         @dynamicLevelProperty(SmartPropertyPrim.SMARTPROPERTYPRIM_PROPCOUNT + 13, pi => Prim2DBase.actualHeightProperty = pi, false, true)
         public get actualHeight(): number {
-            return this.actualSize.width;
+            return this.actualSize.height;
         }
 
         public set actualHeight(val: number) {
@@ -2670,7 +2670,7 @@
 
                 this._debugAreaGroup = new Group2D
                     (
-                    {
+                    {   dontInheritParentScale: true,
                         parent: (this.parent!=null) ? this.parent : this, id: "###DEBUG AREA GROUP###", children:
                         [
                             new Group2D({
@@ -2772,11 +2772,13 @@
                 areaInfo[curAreaIndex++] = { off: pos, size: size, min: min, max: max };
             }
 
+            let isCanvas = this instanceof Canvas2D;
             let marginH = this._marginOffset.x + this._marginOffset.z;
             let marginV = this._marginOffset.y + this._marginOffset.w;
+            let actualSize = this.actualSize.multiplyByFloats(isCanvas ? 1 : this.scaleX, isCanvas ? 1 : this.scaleY);
 
-            let w = hasLayout ? (this.layoutAreaPos.x + this.layoutArea.width)  : (marginH + this.actualSize.width);
-            let h = hasLayout ? (this.layoutAreaPos.y + this.layoutArea.height) : (marginV + this.actualSize.height);
+            let w = hasLayout ? (this.layoutAreaPos.x + this.layoutArea.width)  : (marginH + actualSize.width);
+            let h = hasLayout ? (this.layoutAreaPos.y + this.layoutArea.height) : (marginV + actualSize.height);
             let pos = (!hasLayout && !hasMargin && !hasPadding && hasPos) ? this.actualPosition : Vector2.Zero();
 
             storeAreaInfo(pos, new Size(w, h));
@@ -2785,7 +2787,7 @@
             if (hasLayout) {
                 let layoutOffset = this.layoutAreaPos.clone();
 
-                storeAreaInfo(layoutOffset, (hasMargin || hasPadding) ? this.layoutArea.clone() : this.actualSize.clone());
+                storeAreaInfo(layoutOffset, (hasMargin || hasPadding) ? this.layoutArea.clone() : actualSize.clone());
                 curOffset = layoutOffset.clone();
             }
 
@@ -2794,7 +2796,7 @@
                 let marginOffset = curOffset.clone();
                 marginOffset.x += this._marginOffset.x;
                 marginOffset.y += this._marginOffset.y;
-                let marginArea = this.actualSize;
+                let marginArea = actualSize;
 
                 storeAreaInfo(marginOffset, marginArea);
                 curOffset = marginOffset.clone();
@@ -2934,6 +2936,8 @@
          * Make an intersection test with the primitive, all inputs/outputs are stored in the IntersectInfo2D class, see its documentation for more information.
          * @param intersectInfo contains the settings of the intersection to perform, to setup before calling this method as well as the result, available after a call to this method.
          */
+        private static _bypassGroup2DExclusion = false;
+
         public intersect(intersectInfo: IntersectInfo2D): boolean {
             if (!intersectInfo) {
                 return false;
@@ -2950,14 +2954,27 @@
                 intersectInfo.topMostIntersectedPrimitive = null;
             }
 
+            if (!Prim2DBase._bypassGroup2DExclusion && this instanceof Group2D && (<Group2D><any>this).isCachedGroup && !(<Group2D><any>this).isRenderableGroup) {
+                // Important to call this before each return to allow a good recursion next time this intersectInfo is reused
+                intersectInfo._exit(firstLevel);
+                return false;
+            }
+
             if (!intersectInfo.intersectHidden && !this.isVisible) {
+                // Important to call this before each return to allow a good recursion next time this intersectInfo is reused
+                intersectInfo._exit(firstLevel);
                 return false;
             }
 
             let id = this.id;
-            if (id!=null && id.indexOf("__cachedSpriteOfGroup__") === 0) {
-                let ownerGroup = this.getExternalData<Group2D>("__cachedGroup__");
-                return ownerGroup.intersect(intersectInfo);
+            if (id != null && id.indexOf("__cachedSpriteOfGroup__") === 0) {
+                try {
+                    Prim2DBase._bypassGroup2DExclusion = true;
+                    let ownerGroup = this.getExternalData<Group2D>("__cachedGroup__");
+                    return ownerGroup.intersect(intersectInfo);
+                } finally  {
+                    Prim2DBase._bypassGroup2DExclusion = false;
+                } 
             }
 
             // If we're testing a cachedGroup, we must reject pointer outside its levelBoundingInfo because children primitives could be partially clipped outside so we must not accept them as intersected when it's the case (because they're not visually visible).
@@ -3102,6 +3119,11 @@
                 return false;
             }
 
+            if (this._pointerEventObservable) {
+                this._pointerEventObservable.clear();
+                this._pointerEventObservable = null;
+            }
+
             if (this._actionManager) {
                 this._actionManager.dispose();
                 this._actionManager = null;

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

@@ -1279,7 +1279,6 @@
         public static flagDontInheritParentScale  = 0x0080000;    // set if the actualScale must not use its parent's scale to be computed
         public static flagGlobalTransformDirty    = 0x0100000;    // set if the global transform must be recomputed due to a local transform change
         public static flagLayoutBoundingInfoDirty = 0x0200000;    // set if the layout bounding info is dirty
-        public static flagAllow3DEventsBelowCanvas= 0x0400000;    // set if pointer events should be sent to 3D Engine when the pointer is over the Canvas
 
         private   _flags              : number;
         private   _modelKey           : string;

+ 9 - 1
canvas2D/src/Engine/babylon.sprite2d.ts

@@ -389,17 +389,25 @@
             this.alignToPixel = (settings.alignToPixel == null) ? true : settings.alignToPixel;
             this.useAlphaFromTexture = true;
 
+            // If the user doesn't set a size, we'll use the texture's one, but if the texture is not loading, we HAVE to set a temporary dummy size otherwise the positioning engine will switch the marginAlignement to stretch/stretch, and WE DON'T WANT THAT.
+            // The fucking delayed texture sprite bug is fixed!
+            if (settings.spriteSize == null) {
+                this.size = new Size(10, 10);
+            }
+
             if (settings.spriteSize == null || !texture.isReady()) {
                 if (texture.isReady()) {
                     let s = texture.getBaseSize();
                     this.size = new Size(s.width, s.height);
                 } else {
+
                     texture.onLoadObservable.add(() => {
                         if (settings.spriteSize == null) {
                             let s = texture.getBaseSize();
-                            this.size = new Size(s.width, s.height);
+                        this.size = new Size(s.width, s.height);
                         }
                         this._positioningDirty();
+                        this._setLayoutDirty();
                         this._instanceDirtyFlags |= Prim2DBase.originProperty.flagId | Sprite2D.textureProperty.flagId;  // To make sure the sprite is issued again for render
                     });
                 }