瀏覽代碼

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

David Catuhe 6 年之前
父節點
當前提交
681abc1948

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

@@ -23,7 +23,7 @@
   - Added new [ScrollViewer](https://doc.babylonjs.com/how_to/scrollviewer) with mouse wheel scrolling for larger containers to be viewed using Sliders ([JohnK](https://github.com/BabylonJSGuide/) / [Deltakosh](https://github.com/deltakosh))
   - Moved to a measure / draw mechanism ([Deltakosh](https://github.com/deltakosh))
   - Added support for [nine patch stretch](https://www.babylonjs-playground.com/#G5H9IN#2) mode for images. ([Deltakosh](https://github.com/deltakosh))
-  - InvalidateRect added to AdvancedDynamicTexture to improve perf for highly populated GUIs ([TrevorDev](https://github.com/TrevorDev))
+  - InvalidateRect added to AdvancedDynamicTexture to improve perf for heavily populated GUIs ([TrevorDev](https://github.com/TrevorDev))
 
 ## Updates
 
@@ -144,6 +144,7 @@
 - CannonJS ignores connectedPivot joint parameter ([TrevorDev](https://github.com/TrevorDev))
 - Fix case sensitive paths ([mrdunk](https://github.com))
 - Attaching a BoundingBoxGizmo on a child should not remove its parent ([TrevorDev](https://github.com/TrevorDev)))
+- AmmoJS fix include issue caused after modules update and use world contact point to be consistent with oimo and cannon ([TrevorDev](https://github.com/TrevorDev)))
 
 ### Core Engine
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))

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

@@ -346,39 +346,27 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         this._useInvalidateRectOptimization = value;
     }
 
-    private _clearRectangle: Nullable<Measure> = null;
+    // Invalidated rectangle which is the combination of all invalidated controls after they have been rotated into absolute position
     private _invalidatedRectangle: Nullable<Measure> = null;
     /**
      * Invalidates a rectangle area on the gui texture
-     * @param clearMinX left most position of the rectangle to clear in the texture
-     * @param clearMinY top most position of the rectangle to clear in the texture
-     * @param clearMaxX right most position of the rectangle to clear in the texture
-     * @param clearMaxY bottom most position of the rectangle to clear in the texture
-     * @param minX left most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-     * @param minY top most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-     * @param maxX right most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
-     * @param maxY bottom most position of the rectangle to invalidate in absolute coordinates (not taking in account local transformation)
+     * @param invalidMinX left most position of the rectangle to invalidate in the texture
+     * @param invalidMinY top most position of the rectangle to invalidate in the texture
+     * @param invalidMaxX right most position of the rectangle to invalidate in the texture
+     * @param invalidMaxY bottom most position of the rectangle to invalidate in the texture
      */
-    public invalidateRect(clearMinX: number, clearMinY: number, clearMaxX: number, clearMaxY: number, minX: number, minY: number, maxX: number, maxY: number) {
+    public invalidateRect(invalidMinX: number, invalidMinY: number, invalidMaxX: number, invalidMaxY: number) {
         if (!this._useInvalidateRectOptimization) {
             return;
         }
-        if (!this._clearRectangle || !this._invalidatedRectangle) {
-            this._clearRectangle = new Measure(clearMinX, clearMinY, clearMaxX - clearMinX + 1, clearMaxY - clearMinY + 1);
-            this._invalidatedRectangle = new Measure(minX, minY, maxX - minX + 1, maxY - minY + 1);
+        if (!this._invalidatedRectangle) {
+            this._invalidatedRectangle = new Measure(invalidMinX, invalidMinY, invalidMaxX - invalidMinX + 1, invalidMaxY - invalidMinY + 1);
         } else {
             // Compute intersection
-            var maxX = Math.ceil(Math.max(this._clearRectangle.left + this._clearRectangle.width - 1, clearMaxX));
-            var maxY = Math.ceil(Math.max(this._clearRectangle.top + this._clearRectangle.height - 1, clearMaxY));
-            this._clearRectangle.left = Math.floor(Math.min(this._clearRectangle.left, clearMinX));
-            this._clearRectangle.top = Math.floor(Math.min(this._clearRectangle.top, clearMinY));
-            this._clearRectangle.width = maxX - this._clearRectangle.left + 1;
-            this._clearRectangle.height = maxY - this._clearRectangle.top + 1;
-
-            maxX = Math.max(this._invalidatedRectangle.left + this._invalidatedRectangle.width - 1, maxX);
-            maxY = Math.max(this._invalidatedRectangle.top + this._invalidatedRectangle.height - 1, maxY);
-            this._invalidatedRectangle.left = Math.min(this._invalidatedRectangle.left, minX);
-            this._invalidatedRectangle.top = Math.min(this._invalidatedRectangle.top, minY);
+            var maxX = Math.ceil(Math.max(this._invalidatedRectangle.left + this._invalidatedRectangle.width - 1, invalidMaxX));
+            var maxY = Math.ceil(Math.max(this._invalidatedRectangle.top + this._invalidatedRectangle.height - 1, invalidMaxY));
+            this._invalidatedRectangle.left = Math.floor(Math.min(this._invalidatedRectangle.left, invalidMinX));
+            this._invalidatedRectangle.top = Math.floor(Math.min(this._invalidatedRectangle.top, invalidMinY));
             this._invalidatedRectangle.width = maxX - this._invalidatedRectangle.left + 1;
             this._invalidatedRectangle.height = maxY - this._invalidatedRectangle.top + 1;
         }
@@ -480,7 +468,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
                 this._rootContainer._markAllAsDirty();
             }
         }
-        this.invalidateRect(0, 0, textureSize.width - 1, textureSize.height - 1, 0, 0, textureSize.width - 1, textureSize.height - 1);
+        this.invalidateRect(0, 0, textureSize.width - 1, textureSize.height - 1);
     }
     /** @hidden */
     public _getGlobalViewport(scene: Scene): Viewport {
@@ -563,8 +551,8 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         this._isDirty = false; // Restoring the dirty state that could have been set by controls during layout processing
 
         // Clear
-        if (this._clearRectangle) {
-            this._clearMeasure.copyFrom(this._clearRectangle);
+        if (this._invalidatedRectangle) {
+            this._clearMeasure.copyFrom(this._invalidatedRectangle);
         } else {
             this._clearMeasure.copyFromFloats(0, 0, renderWidth, renderHeight);
         }
@@ -580,7 +568,6 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         this.onBeginRenderObservable.notifyObservers(this);
         this._rootContainer._render(context, this._invalidatedRectangle);
         this.onEndRenderObservable.notifyObservers(this);
-        this._clearRectangle = null;
         this._invalidatedRectangle = null;
     }
     /** @hidden */

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

@@ -285,12 +285,12 @@ export class Container extends Control {
 
     /** @hidden */
     public _layout(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean {
-        if (!this.isVisible || this.notRenderable) {
+        if (!this.isDirty && (!this.isVisible || this.notRenderable)) {
             return false;
         }
 
         if (this._isDirty) {
-            this._tempCurrentMeasure.copyFrom(this._currentMeasure);
+            this._currentMeasure.transformToRef(this._transformMatrix, this._prevCurrentMeasureTransformedIntoGlobalSpace);
         }
 
         let rebuildCount = 0;
@@ -348,12 +348,7 @@ export class Container extends Control {
         context.restore();
 
         if (this._isDirty) {
-            this.invalidateRect(
-                Math.min(this._currentMeasure.left, this._tempCurrentMeasure.left),
-                Math.min(this._currentMeasure.top, this._tempCurrentMeasure.top),
-                Math.max(this._currentMeasure.left + this._currentMeasure.width, this._tempCurrentMeasure.left + this._tempCurrentMeasure.width) - 1,
-                Math.max(this._currentMeasure.top + this._currentMeasure.height, this._tempCurrentMeasure.top + this._tempCurrentMeasure.height) - 1
-            );
+            this.invalidateRect();
 
             this._isDirty = false;
         }
@@ -378,7 +373,7 @@ export class Container extends Control {
             // Only redraw parts of the screen that are invalidated
             if (invalidatedRectangle) {
                 if (!child._intersectsRect(invalidatedRectangle)) {
-                    // continue;
+                    continue;
                 }
             }
             child._render(context, invalidatedRectangle);

File diff suppressed because it is too large
+ 1861 - 1871
gui/src/2D/controls/control.ts


+ 41 - 0
gui/src/2D/measure.ts

@@ -1,3 +1,5 @@
+import { Matrix2D } from "./math2D";
+import { Vector2, Polygon } from "babylonjs";
 
 /**
  * Class used to store 2D control sizes
@@ -48,6 +50,45 @@ export class Measure {
     }
 
     /**
+     * Computes the axis aligned bounding box measure for two given measures
+     * @param a Input measure
+     * @param b Input measure
+     * @param result the resulting bounding measure
+     */
+    public static CombineToRef(a: Measure, b: Measure, result: Measure) {
+        var left = Math.min(a.left, b.left);
+        var top = Math.min(a.top, b.top);
+        var right = Math.max(a.left + a.width, b.left + b.width);
+        var bottom = Math.max(a.top + a.height, b.top + b.height);
+        result.left = left;
+        result.top = top;
+        result.width = right - left;
+        result.height = bottom - top;
+    }
+
+    /**
+     * Computes the axis aligned bounding box of the measure after it is modified by a given transform
+     * @param transform the matrix to transform the measure before computing the AABB
+     * @param result the resulting AABB
+     */
+    public transformToRef(transform: Matrix2D, result: Measure) {
+        var rectanglePoints = Polygon.Rectangle(this.left, this.top, this.left + this.width, this.top + this.height);
+        var min = new Vector2(Number.MAX_VALUE, Number.MAX_VALUE);
+        var max = new Vector2(0, 0);
+        for (var i = 0; i < 4; i++) {
+            transform.transformCoordinates(rectanglePoints[i].x, rectanglePoints[i].y, rectanglePoints[i]);
+            min.x = Math.floor(Math.min(min.x, rectanglePoints[i].x));
+            min.y = Math.floor(Math.min(min.y, rectanglePoints[i].y));
+            max.x = Math.ceil(Math.max(max.x, rectanglePoints[i].x));
+            max.y = Math.ceil(Math.max(max.y, rectanglePoints[i].y));
+        }
+        result.left = min.x;
+        result.top = min.y;
+        result.width = max.x - min.x;
+        result.height = max.y - min.y;
+    }
+
+    /**
      * Check equality between this measure and another one
      * @param other defines the other measures
      * @returns true if both measures are equals

+ 24 - 4
src/Physics/Plugins/ammoJSPlugin.ts

@@ -1,4 +1,4 @@
-import { Quaternion, Vector3 } from "../../Maths/math";
+import { Quaternion, Vector3, Matrix } from "../../Maths/math";
 import { IPhysicsEnginePlugin, PhysicsImpostorJoint } from "../../Physics/IPhysicsEngine";
 import { Logger } from "../../Misc/logger";
 import { PhysicsImpostor, IPhysicsEnabledObject } from "../../Physics/physicsImpostor";
@@ -18,7 +18,7 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
     /**
      * Reference to the Ammo library
      */
-    public bjsAMMO: any;
+    public bjsAMMO: any = {};
     /**
      * Created ammoJS world which physics bodies are added to
      */
@@ -55,9 +55,11 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
      */
     public constructor(private _useDeltaForWorldStep: boolean = true, ammoInjection: any = Ammo) {
         if (typeof ammoInjection === "function") {
-            ammoInjection();
+            ammoInjection(this.bjsAMMO);
+        }else {
+            this.bjsAMMO = ammoInjection;
         }
-        this.bjsAMMO = ammoInjection;
+
         if (!this.isSupported()) {
             Logger.Error("AmmoJS is not available. Please make sure you included the js file.");
             return;
@@ -197,6 +199,8 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
         }
     }
 
+    private _tmpVector = new Vector3();
+    private _tmpMatrix = new Matrix();
     /**
      * Applies an implulse on the imposter
      * @param impostor imposter to apply impulse
@@ -206,6 +210,14 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
     public applyImpulse(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
         var worldPoint = this._tmpAmmoVectorA;
         var impulse = this._tmpAmmoVectorB;
+
+        // Convert contactPoint into world space
+        if (impostor.object && impostor.object.getWorldMatrix) {
+            impostor.object.getWorldMatrix().invertToRef(this._tmpMatrix);
+            Vector3.TransformCoordinatesToRef(contactPoint, this._tmpMatrix, this._tmpVector);
+            contactPoint = this._tmpVector;
+        }
+
         worldPoint.setValue(contactPoint.x, contactPoint.y, contactPoint.z);
         impulse.setValue(force.x, force.y, force.z);
 
@@ -221,6 +233,14 @@ export class AmmoJSPlugin implements IPhysicsEnginePlugin {
     public applyForce(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
         var worldPoint = this._tmpAmmoVectorA;
         var impulse = this._tmpAmmoVectorB;
+
+        // Convert contactPoint into world space
+        if (impostor.object && impostor.object.getWorldMatrix) {
+            impostor.object.getWorldMatrix().invertToRef(this._tmpMatrix);
+            Vector3.TransformCoordinatesToRef(contactPoint, this._tmpMatrix, this._tmpVector);
+            contactPoint = this._tmpVector;
+        }
+
         worldPoint.setValue(contactPoint.x, contactPoint.y, contactPoint.z);
         impulse.setValue(force.x, force.y, force.z);
 

二進制
tests/validation/ReferenceImages/TransformStackPanel.png


+ 5 - 0
tests/validation/config.json

@@ -2,6 +2,11 @@
   "root": "https://rawgit.com/BabylonJS/Website/master",
   "tests": [
     {
+      "title": "GUI Transform StackPanel",
+      "playgroundId": "#BS60AB#0",
+      "referenceImage": "TransformStackPanel.png"
+    },
+    {
       "title": "GUI StackPanel",
       "playgroundId": "#LLVZ90#0",
       "referenceImage": "StackPanel.png"