瀏覽代碼

whats new

Trevor Baron 6 年之前
父節點
當前提交
5f40a024ad

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

@@ -83,6 +83,7 @@
 - Add support for setting renderingGroupId and creating instances to `AxesViewer` ([bghgary](https://github.com/bghgary))
 - Invert vScale of compressed ktx textures as they are inverted in the file and UNPACK_FLIP_Y_WEBGL is not supported by ktx ([TrevorDev](https://github.com/TrevorDev))
 - Enable dragging in boundingBoxGizmo without needing a parent ([TrevorDev](https://github.com/TrevorDev))
+- InvalidateRect added to AdvancedDynamicTexture to improve perf for highly populated GUIs ([TrevorDev](https://github.com/TrevorDev))
 
 ### glTF Loader
 

+ 9 - 15
gui/src/2D/advancedDynamicTexture.ts

@@ -363,17 +363,17 @@ export class AdvancedDynamicTexture extends DynamicTexture {
             // Compute intersection
             var maxLeft = Math.max(this._invalidatedRectangle.left + this._invalidatedRectangle.width, maxX);
             var maxTop = Math.max(this._invalidatedRectangle.top + this._invalidatedRectangle.height, maxY);
-            this._invalidatedRectangle.left =  Math.min(this._invalidatedRectangle.left, minX)
-            this._invalidatedRectangle.top = Math.min(this._invalidatedRectangle.top, minY)
-            this._invalidatedRectangle.width = maxLeft - this._invalidatedRectangle.left
-            this._invalidatedRectangle.height =  maxTop - this._invalidatedRectangle.top
+            this._invalidatedRectangle.left =  Math.min(this._invalidatedRectangle.left, minX);
+            this._invalidatedRectangle.top = Math.min(this._invalidatedRectangle.top, minY);
+            this._invalidatedRectangle.width = maxLeft - this._invalidatedRectangle.left;
+            this._invalidatedRectangle.height =  maxTop - this._invalidatedRectangle.top;
         }
 
         // Ensure there are no pixel fractions
-        this._invalidatedRectangle.left = Math.floor(this._invalidatedRectangle.left)
-        this._invalidatedRectangle.top = Math.floor(this._invalidatedRectangle.top)
-        this._invalidatedRectangle.width  = Math.ceil(this._invalidatedRectangle.width )
-        this._invalidatedRectangle.height = Math.ceil(this._invalidatedRectangle.height)
+        this._invalidatedRectangle.left = Math.floor(this._invalidatedRectangle.left);
+        this._invalidatedRectangle.top = Math.floor(this._invalidatedRectangle.top);
+        this._invalidatedRectangle.width  = Math.ceil(this._invalidatedRectangle.width);
+        this._invalidatedRectangle.height = Math.ceil(this._invalidatedRectangle.height);
     }
 
     /**
@@ -493,7 +493,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
             }
         }
 
-        this.invalidateRect(0,0,textureSize.width,textureSize.height);
+        this.invalidateRect(0, 0, textureSize.width, textureSize.height);
     }
 
     /** @hidden */
@@ -607,12 +607,6 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         this._isDirty = false; // Restoring the dirty state that could have been set by controls during layout processing
 
         this._rootContainer._render(context, this._invalidatedRectangle);
-        // if(this._invalidatedRectangle){
-        //     context.fillStyle = '#'+Math.floor(Math.random()*16777215).toString(16);
-        // context.fillRect(this._invalidatedRectangle.left, this._invalidatedRectangle.top, this._invalidatedRectangle.width, this._invalidatedRectangle.height);
-        // }
-        
-
         this._invalidatedRectangle = null;
     }
 

+ 2 - 4
gui/src/2D/controls/container.ts

@@ -254,9 +254,7 @@ export class Container extends Control {
             }
 
             context.fillStyle = this._background;
-
             context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-
             context.restore();
         }
     }
@@ -299,7 +297,7 @@ export class Container extends Control {
                 for (var child of this._children) {
                     // Only redraw parts of the screen that are invalidated
                     if (invalidatedRectangle) {
-                        if (!child.intersectsRect(invalidatedRectangle)) {
+                        if (!child._intersectsRect(invalidatedRectangle)) {
                             continue;
                         }
                     }
@@ -362,7 +360,7 @@ export class Container extends Control {
         for (var child of this._children) {
             // Only redraw parts of the screen that are invalidated
             if (invalidatedRectangle) {
-                if (!child.intersectsRect(invalidatedRectangle)) {
+                if (!child._intersectsRect(invalidatedRectangle)) {
                     continue;
                 }
             }

+ 35 - 36
gui/src/2D/controls/control.ts

@@ -307,7 +307,7 @@ export class Control {
         }
 
         this._scaleX = value;
-        this._transform()
+        this._transform();
         this._markAsDirty();
         this._markMatrixAsDirty();
     }
@@ -325,7 +325,7 @@ export class Control {
         }
 
         this._scaleY = value;
-        this._transform()
+        this._transform();
         this._markAsDirty();
         this._markMatrixAsDirty();
     }
@@ -1073,7 +1073,7 @@ export class Control {
     }
 
     /** @hidden */
-    public intersectsRect(rect: Measure) {
+    public _intersectsRect(rect: Measure) {
         var hit = ! (this._currentMeasure.left > rect.left + rect.width ||
              this._currentMeasure.left + this._currentMeasure.width < rect.left ||
              this._currentMeasure.top > rect.top + rect.height ||
@@ -1085,21 +1085,20 @@ export class Control {
     /** @hidden */
     protected invalidateRect() {
         if (this.host) {
-            // factor in rotation
-            var rect = BABYLON.Polygon.Rectangle(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.left + this._currentMeasure.width, this._currentMeasure.top + this._currentMeasure.height);
-            var min = new Vector2(Number.MAX_VALUE,Number.MAX_VALUE);
-            var max = new Vector2(0,0);
-            for(var i=0;i<4;i++){
-                this._invertTransformMatrix.invertToRef(this._invertTransformMatrix);
-                this._invertTransformMatrix.transformCoordinates(rect[i].x, rect[i].y, rect[i]);
-                min.x = Math.min(min.x, rect[i].x)
-                min.y = Math.min(min.y, rect[i].y)
-                max.x = Math.max(max.x, rect[i].x)
-                max.y = Math.max(max.y, rect[i].y)
-                this._invertTransformMatrix.invertToRef(this._invertTransformMatrix);
+            // Compute aabb of rotated container box (eg. to handle rotation)
+            var rectanglePoints = BABYLON.Polygon.Rectangle(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.left + this._currentMeasure.width, this._currentMeasure.top + this._currentMeasure.height);
+            var min = new Vector2(Number.MAX_VALUE, Number.MAX_VALUE);
+            var max = new Vector2(0, 0);
+            this._invertTransformMatrix.invertToRef(this._invertTransformMatrix);
+            for (var i = 0; i < 4; i++) {
+                this._invertTransformMatrix.transformCoordinates(rectanglePoints[i].x, rectanglePoints[i].y, rectanglePoints[i]);
+                min.x = Math.min(min.x, rectanglePoints[i].x);
+                min.y = Math.min(min.y, rectanglePoints[i].y);
+                max.x = Math.max(max.x, rectanglePoints[i].x);
+                max.y = Math.max(max.y, rectanglePoints[i].y);
             }
-            console.log("dirty "+this.name)
-       
+            this._invertTransformMatrix.invertToRef(this._invertTransformMatrix);
+
             this.host.invalidateRect(
                 min.x,
                 min.y,
@@ -1117,7 +1116,7 @@ export class Control {
 
         this._isDirty = true;
 
-        // Redraw only the this rectangle
+        // Redraw only this rectangle
         if (this._host) {
             this._host.markAsDirty();
             this.invalidateRect();
@@ -1150,7 +1149,7 @@ export class Control {
         // postTranslate
         var offsetX = this._currentMeasure.width * this._transformCenterX + this._currentMeasure.left;
         var offsetY = this._currentMeasure.height * this._transformCenterY + this._currentMeasure.top;
-        if(context){
+        if (context) {
             context.translate(offsetX, offsetY);
 
             // rotate
@@ -1161,7 +1160,6 @@ export class Control {
 
             // preTranslate
             context.translate(-offsetX, -offsetY);
-
         }
         // Need to update matrices?
         if (this._isMatrixDirty || this._cachedOffsetX !== offsetX || this._cachedOffsetY !== offsetY) {
@@ -1414,18 +1412,17 @@ export class Control {
         // DO nothing
     }
 
-    private _clip(context: CanvasRenderingContext2D, invalidatedRectangle?:Nullable<Measure>) {
+    private static _ClipMeasure = new Measure(0, 0, 0, 0);
+    private _clip(context: CanvasRenderingContext2D, invalidatedRectangle?: Nullable<Measure>) {
         context.beginPath();
-
-        var iMeasure = new Measure(0,0,0,0);
-        iMeasure.copyFrom(this._currentMeasure)
-        if(invalidatedRectangle){
-            var right = Math.min(invalidatedRectangle.left + invalidatedRectangle.width, this._currentMeasure.left + this._currentMeasure.width)
-            var bottom = Math.min(invalidatedRectangle.top + invalidatedRectangle.height, this._currentMeasure.top + this._currentMeasure.height)
-            iMeasure.left = Math.max(invalidatedRectangle.left, this._currentMeasure.left)
-            iMeasure.top = Math.max(invalidatedRectangle.top, this._currentMeasure.top)
-            iMeasure.width = right - iMeasure.left;
-            iMeasure.height = bottom - iMeasure.top;
+        Control._ClipMeasure.copyFrom(this._currentMeasure);
+        if (invalidatedRectangle) {
+            var right = Math.min(invalidatedRectangle.left + invalidatedRectangle.width, this._currentMeasure.left + this._currentMeasure.width);
+            var bottom = Math.min(invalidatedRectangle.top + invalidatedRectangle.height, this._currentMeasure.top + this._currentMeasure.height);
+            Control._ClipMeasure.left = Math.max(invalidatedRectangle.left, this._currentMeasure.left);
+            Control._ClipMeasure.top = Math.max(invalidatedRectangle.top, this._currentMeasure.top);
+            Control._ClipMeasure.width = right - Control._ClipMeasure.left;
+            Control._ClipMeasure.height = bottom - Control._ClipMeasure.top;
         }
 
         if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
@@ -1438,12 +1435,14 @@ export class Control {
             var topShadowOffset = Math.min(Math.min(shadowOffsetY, 0) - shadowBlur * 2, 0);
             var bottomShadowOffset = Math.max(Math.max(shadowOffsetY, 0) + shadowBlur * 2, 0);
 
-            context.rect(iMeasure.left + leftShadowOffset,
-                iMeasure.top + topShadowOffset,
-                iMeasure.width + rightShadowOffset - leftShadowOffset,
-                iMeasure.height + bottomShadowOffset - topShadowOffset);
+            context.rect(
+                Control._ClipMeasure.left + leftShadowOffset,
+                Control._ClipMeasure.top + topShadowOffset,
+                Control._ClipMeasure.width + rightShadowOffset - leftShadowOffset,
+                Control._ClipMeasure.height + bottomShadowOffset - topShadowOffset
+            );
         } else {
-            context.rect(iMeasure.left, iMeasure.top, iMeasure.width, iMeasure.height);
+            context.rect(Control._ClipMeasure.left, Control._ClipMeasure.top, Control._ClipMeasure.width, Control._ClipMeasure.height);
         }
 
         context.clip();

+ 2 - 2
gui/src/2D/controls/rectangle.ts

@@ -62,7 +62,7 @@ export class Rectangle extends Container {
 
         if (this._background) {
             context.fillStyle = this._background;
-            
+
             if (this._cornerRadius) {
                 this._drawRoundedRect(context, this._thickness / 2);
                 context.fill();
@@ -105,7 +105,7 @@ export class Rectangle extends Container {
         this._measureForChildren.top += this._thickness;
     }
 
-    private _drawRoundedRect(context: CanvasRenderingContext2D, offset: number = 0, invalidatedRectangle?: Measure): void {
+    private _drawRoundedRect(context: CanvasRenderingContext2D, offset: number = 0): void {
         var x = this._currentMeasure.left + offset;
         var y = this._currentMeasure.top + offset;
         var width = this._currentMeasure.width - offset * 2;

+ 0 - 2
gui/src/2D/controls/textBlock.ts

@@ -290,8 +290,6 @@ export class TextBlock extends Control {
             context.strokeText(text, this._currentMeasure.left + x, y);
         }
         context.fillText(text, this._currentMeasure.left + x, y);
-        // context.fillStyle = '#'+Math.floor(Math.random()*16777215).toString(16);
-        // context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
     }
 
     /** @hidden */