Explorar o código

Canvas2D PCM Updating few APIs

nockawa %!s(int64=8) %!d(string=hai) anos
pai
achega
d33a0da243

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

@@ -221,7 +221,7 @@
             // Initialize the Primitive Collision Manager
             if (settings.enableCollisionManager) {
                 let enableBorders = settings.collisionManagerUseBorders;
-                this._primitiveCollisionManager = (settings.customCollisionManager==null) ? new BasicPrimitiviceCollisionManager(this, enableBorders) : settings.customCollisionManager(this, enableBorders);
+                this._primitiveCollisionManager = (settings.customCollisionManager==null) ? PrimitiveCollisionManagerBase.allocBasicPCM(this, enableBorders) : settings.customCollisionManager(this, enableBorders);
             }
 
             // Register this instance
@@ -1477,7 +1477,7 @@
             this._updateCanvasState(false);
 
             if (this._primitiveCollisionManager) {
-                this._primitiveCollisionManager.update();
+                this._primitiveCollisionManager._update();
             }
 
             if (this._primPointerInfo.canvasPointerPos) {

+ 19 - 4
canvas2D/src/Engine/babylon.prim2dBase.ts

@@ -1632,7 +1632,7 @@
 
             // Add in the PCM
             if (settings.levelCollision || settings.deepCollision) {
-                this._actorInfo = this.owner._primitiveCollisionManager.addActor(this, settings.deepCollision === true);
+                this._actorInfo = this.owner._primitiveCollisionManager._addActor(this, settings.deepCollision === true);
                 this._setFlags(SmartPropertyPrim.flagCollisionActor);
             } else {
                 this._actorInfo = null;
@@ -1640,13 +1640,28 @@
 
         }
 
-        public get intersectWithObservable(): Observable<DictionaryChanged<ActorInfo>> {
+        /**
+         * Return the ChangedDictionary observable of the StringDictionary containing the primitives intersecting with this one
+         */
+        public get intersectWithObservable(): Observable<DictionaryChanged<ActorInfoBase>> {
             if (!this._actorInfo) {
                 return null;
             }
             return this._actorInfo.intersectWith.dictionaryChanged;
         }
 
+        /**
+         * Return the ObservableStringDictionary containing all the primitives intersecting with this one.
+         * The key is the primitive uid, the value is the ActorInfo object
+         * @returns {} 
+         */
+        public get intersectWith(): ObservableStringDictionary<ActorInfoBase> {
+            if (!this._actorInfo) {
+                return null;
+            }
+            return this._actorInfo.intersectWith;
+        }
+
         public get actionManager(): ActionManager {
             if (!this._actionManager) {
                 this._actionManager = new ActionManager(this.owner.scene);
@@ -3220,7 +3235,7 @@
             }
 
             if (this._isFlagSet(SmartPropertyPrim.flagCollisionActor)) {
-                this.owner._primitiveCollisionManager.removeActor(this);
+                this.owner._primitiveCollisionManager._removeActor(this);
                 this._actorInfo = null;
             }
 
@@ -3912,7 +3927,7 @@
         private _actualScale : Vector2;
         private _displayDebugAreas: boolean;
         private _debugAreaGroup: Group2D;
-        private _actorInfo: ActorInfo;
+        private _actorInfo: ActorInfoBase;
 
         // Stores the step of the parent for which the current global transform was computed
         // If the parent has a new step, it means this prim's global transform must be updated

+ 130 - 28
canvas2D/src/Engine/babylon.primitiveCollisionManager.ts

@@ -1,26 +1,101 @@
 module BABYLON {
+
+    /**
+     * The base class for all implementation of a Primitive Collision Manager
+     */
     export abstract class PrimitiveCollisionManagerBase {
         constructor(owner: Canvas2D) {
             this._owner = owner;
         }
 
-        abstract addActor(actor: Prim2DBase, deep: boolean): ActorInfo;
-        abstract removeActor(actor: Prim2DBase);
+        abstract _addActor(actor: Prim2DBase, deep: boolean): ActorInfoBase;
+        abstract _removeActor(actor: Prim2DBase);
 
-        abstract update();
+        abstract _update();
 
+        /**
+         * If collisionManagerUseBorders is true during the Canvas creation, this dictionary contains all the primitives intersecting with the left border
+         */
         abstract get leftBorderIntersectedActors(): ObservableStringDictionary<Prim2DBase>;
+
+        /**
+         * If collisionManagerUseBorders is true during the Canvas creation, this dictionary contains all the primitives intersecting with the bottom border
+         */
         abstract get bottomBorderIntersectedActors(): ObservableStringDictionary<Prim2DBase>;
+
+        /**
+         * If collisionManagerUseBorders is true during the Canvas creation, this dictionary contains all the primitives intersecting with the right border
+         */
         abstract get rightBorderIntersectedActors(): ObservableStringDictionary<Prim2DBase>;
+
+        /**
+         * If collisionManagerUseBorders is true during the Canvas creation, this dictionary contains all the primitives intersecting with the top border
+         */
         abstract get topBorderIntersectedActors(): ObservableStringDictionary<Prim2DBase>;
+
+        /**
+         * This dictionary contains all the couple of intersecting primitives
+         */
         abstract get intersectedActors(): ObservableStringDictionary<{ a: Prim2DBase, b: Prim2DBase }>;
 
+        /**
+         * Renders the World AABB of all Actors
+         */
+        abstract get debugRenderAABB(): boolean;
+        abstract set debugRenderAABB(val: boolean);
+
+        /**
+         * Renders the area of the Clusters
+         */
+        abstract get debugRenderClusters(): boolean;
+        abstract set debugRenderClusters(val: boolean);
+
+        /**
+         * Display stats about the PCM on screen
+         */
+        abstract get debugStats(): boolean;
+        abstract set debugStats(val: boolean);
+
+        public static allocBasicPCM(owner: Canvas2D, enableBorders: boolean): PrimitiveCollisionManagerBase {
+            return new BasicPrimitiveCollisionManager(owner, enableBorders);
+        }
+
         protected _owner: Canvas2D;
+    }
+
+    /**
+     * Base class of an Actor
+     */
+    export abstract class ActorInfoBase {
+        /**
+         * Access the World AABB of the Actor, the vector4 is x:left, y: bottom, z: right, w: top
+         */
+        abstract get worldAABB(): Vector4;
+
+        /**
+         * Return true if the actor is enable, false otherwise
+         */
+        abstract get isEnabled(): boolean;
+
+        /**
+         * Return true is the actor boundingInfo is use, false if its levelBoundingInfo is used.
+         */
+        abstract get isDeep(): boolean;
+
+        /**
+         * Return the primitive of the actor
+         */
+        abstract get prim(): Prim2DBase;
 
+        /**
+         * Return a dictionary containing all the actors intersecting with this one
+         */
+        abstract get intersectWith(): ObservableStringDictionary<ActorInfoBase>;
     }
 
-    export class ActorInfo {
-        constructor(owner: BasicPrimitiviceCollisionManager, actor: Prim2DBase, deep: boolean) {
+    class ActorInfo extends ActorInfoBase {
+        constructor(owner: BasicPrimitiveCollisionManager, actor: Prim2DBase, deep: boolean) {
+            super();
             this.owner = owner;
             this.prim = actor;
             this.flags = 0;
@@ -91,9 +166,9 @@
 
         prim: Prim2DBase;
         flags: number;
-        owner: BasicPrimitiviceCollisionManager;
+        owner: BasicPrimitiveCollisionManager;
         presentInClusters: StringDictionary<ClusterInfo>;
-        intersectWith: ObservableStringDictionary<ActorInfo>;
+        intersectWith: ObservableStringDictionary<ActorInfoBase>;
 
         public static flagDeep       = 0x0001;      // set if the actor boundingInfo must be used instead of the levelBoundingInfo
         public static flagEnabled    = 0x0002;      // set if the actor is enabled and should be considered for intersection tests
@@ -101,7 +176,7 @@
         public static flagRemoved    = 0x0008;      // set if the actor was removed from the PCM
     }
 
-    export class ClusterInfo {
+    class ClusterInfo {
         constructor() {
             this.actors = new StringDictionary<ActorInfo>();
         }
@@ -113,7 +188,7 @@
         actors: StringDictionary<ActorInfo>;
     }
 
-    export class BasicPrimitiviceCollisionManager extends PrimitiveCollisionManagerBase {
+    class BasicPrimitiveCollisionManager extends PrimitiveCollisionManagerBase {
 
         constructor(owner: Canvas2D, enableBorders: boolean) {
             super(owner);
@@ -140,14 +215,14 @@
             }
             let flagId = Canvas2D.actualSizeProperty.flagId;
 
-            if (!BasicPrimitiviceCollisionManager.WAABBCorners) {
-                BasicPrimitiviceCollisionManager.WAABBCorners = new Array<Vector2>(4);
+            if (!BasicPrimitiveCollisionManager.WAABBCorners) {
+                BasicPrimitiveCollisionManager.WAABBCorners = new Array<Vector2>(4);
                 for (let i = 0; i < 4; i++) {
-                    BasicPrimitiviceCollisionManager.WAABBCorners[i] = Vector2.Zero();
+                    BasicPrimitiveCollisionManager.WAABBCorners[i] = Vector2.Zero();
                 }
-                BasicPrimitiviceCollisionManager.WAABBCornersCluster = new Array<Vector2>(4);
+                BasicPrimitiveCollisionManager.WAABBCornersCluster = new Array<Vector2>(4);
                 for (let i = 0; i < 4; i++) {
-                    BasicPrimitiviceCollisionManager.WAABBCornersCluster[i] = Vector2.Zero();
+                    BasicPrimitiveCollisionManager.WAABBCornersCluster[i] = Vector2.Zero();
                 }
             }
 
@@ -164,7 +239,7 @@
             this.debugStats = false;
         }
 
-        addActor(actor: Prim2DBase, deep: boolean): ActorInfo {
+        _addActor(actor: Prim2DBase, deep: boolean): ActorInfoBase {
             return this._actors.getOrAddWithFactory(actor.uid, () => {
                 let ai = new ActorInfo(this, actor, deep);
                 this.actorDirty(ai);
@@ -172,7 +247,7 @@
             });
         }
 
-        removeActor(actor: Prim2DBase) {
+        _removeActor(actor: Prim2DBase) {
             let ai = this._actors.getAndRemove(actor.uid);
             ai.setFlags(ActorInfo.flagRemoved);
             this.actorDirty(ai);
@@ -183,15 +258,18 @@
             this._dirtyActors.add(actor.prim.uid, actor);
         }
 
-        update() {
+        _update() {
             this._canvasSize.copyFrom(this._owner.actualSize);
 
             // Should we update the WireFrame2D Primitive that displays the WorldAABB ?
             if (this.debugRenderAABB) {
-                if (this._dirtyActors.count > 0) {
+                if (this._dirtyActors.count > 0 || this._debugRenderAABBDirty) {
                     this._updateAABBDisplay();
                 }
             }
+            if (this._AABBRenderPrim) {
+                this._AABBRenderPrim.levelVisible = this.debugRenderAABB;
+            }
 
             let cw = this._clusterSize.width;
             let ch = this._clusterSize.height;
@@ -216,6 +294,10 @@
             if (this.debugRenderClusters && this._clusterDirty) {
                 this._updateClusterDisplay(cw, ch);
             }
+            if (this._ClusterRenderPrim) {
+                this._ClusterRenderPrim.levelVisible = this.debugRenderClusters;
+            }
+
 
             let updateStats = this.debugStats && (this._dirtyActors.count > 0 || this._clusterDirty);
 
@@ -239,6 +321,10 @@
                 this._updateDebugStats();
             }
 
+            if (this._debugTextBackground) {
+                this._debugTextBackground.levelVisible = updateStats;
+            }
+
             // Reset the dirty actor list: everything is processed
             this._dirtyActors.clear();
         }
@@ -246,17 +332,28 @@
         /**
          * Renders the World AABB of all Actors
          */
-        public debugRenderAABB;
+        public get debugRenderAABB(): boolean {
+            return this._debugRenderAABB;
+        }
+
+        public set debugRenderAABB(val: boolean) {
+            if (this._debugRenderAABB === val) {
+                return;
+            }
+
+            this._debugRenderAABB = val;
+            this._debugRenderAABBDirty = true;
+        }
 
         /**
          * Renders the area of the Clusters
          */
-        public debugRenderClusters;
+        public debugRenderClusters: boolean;
 
         /**
          * Display stats about the PCM on screen
          */
-        public debugStats;
+        public debugStats: boolean;
 
         get intersectedActors(): ObservableStringDictionary<{ a: Prim2DBase; b: Prim2DBase }> {
             return this._intersectedActors;
@@ -334,14 +431,14 @@
             let wab = actor.worldAABB;
 
             // Build the worldAABB corners
-            let wac = BasicPrimitiviceCollisionManager.WAABBCorners;
+            let wac = BasicPrimitiveCollisionManager.WAABBCorners;
             wac[0].copyFromFloats(wab.x, wab.y); // Bottom/Left
             wac[1].copyFromFloats(wab.z, wab.y); // Bottom/Right
             wac[2].copyFromFloats(wab.z, wab.w); // Top/Right
             wac[3].copyFromFloats(wab.x, wab.w); // Top/Left
 
             let cs = this._clusterStep;
-            let wacc = BasicPrimitiviceCollisionManager.WAABBCornersCluster;
+            let wacc = BasicPrimitiveCollisionManager.WAABBCornersCluster;
             for (let i = 0; i < 4; i++) {
                 let p = wac[i];
                 let cx = (p.x - (p.x % cs.x)) / cs.x;
@@ -418,15 +515,15 @@
             }
         }
 
-        private static CandidatesActors = new StringDictionary<ActorInfo>();
-        private static PreviousIntersections = new StringDictionary<ActorInfo>();
+        private static CandidatesActors = new StringDictionary<ActorInfoBase>();
+        private static PreviousIntersections = new StringDictionary<ActorInfoBase>();
 
         // The algorithm is simple, we have previously partitioned the Actors in the Clusters: each actor has a list of the Cluster(s) it's inside.
         // Then for a given Actor that is dirty we evaluate the intersection with all the other actors present in the same Cluster(s)
         // So it's basically O(n²), BUT only inside a Cluster and only for dirty Actors.
         private _collisionDetection() {
-            let hash = BasicPrimitiviceCollisionManager.CandidatesActors;
-            let prev = BasicPrimitiviceCollisionManager.PreviousIntersections;
+            let hash = BasicPrimitiveCollisionManager.CandidatesActors;
+            let prev = BasicPrimitiveCollisionManager.PreviousIntersections;
             let opCount = 0;
 
             this._dirtyActors.forEach((k1, ai1) => {
@@ -509,6 +606,7 @@
                 });
                     
             } else {
+                this._debugTextBackground.levelVisible = true;
                 let text2d = this._debugTextBackground.children[0] as Text2D;
                 text2d.text = txt;
             }
@@ -542,11 +640,13 @@
             });
 
             if (!this._AABBRenderPrim) {
-                this._AABBRenderPrim = new WireFrame2D([g], { parent: this._owner, alignToPixel: true, id: "###DEBUG PCM AABB###" });
+                this._AABBRenderPrim = new WireFrame2D([g], { parent: this._owner, alignToPixel: false, id: "###DEBUG PCM AABB###" });
             } else {
                 this._AABBRenderPrim.wireFrameGroups.set("main", g);
                 this._AABBRenderPrim.wireFrameGroupsDirty();
             }
+
+            this._debugRenderAABBDirty = false;
         }
 
         private _updateClusterDisplay(cw: number, ch: number) {
@@ -621,6 +721,8 @@
         private _borderIntersecteddActors: ObservableStringDictionary<Prim2DBase>[];
         private _debugUpdateOpCount: PerfCounter;
         private _debugUpdateTime: PerfCounter;
+        private _debugRenderAABB: boolean;
+        private _debugRenderAABBDirty: boolean;
         private _AABBRenderPrim: WireFrame2D;
         private _ClusterRenderPrim: WireFrame2D;
         private _debugTextBackground: Rectangle2D;

+ 1 - 1
canvas2D/src/shaders/wireframe2d.vertex.fx

@@ -33,7 +33,7 @@ void main(void) {
 	vec4 pp = vec4(dot(p, transformX), dot(p, transformY), zBias.x, 1);
 	
 	if (properties.x == 1.0) {
-		pp.xy = pp.xy - mod(pp.xy, properties.yz);
+		pp.xy = pp.xy - mod(pp.xy, properties.yz) + (properties.yz*0.5);
 	}
 
 	gl_Position = pp;

+ 61 - 83
dist/preview release/canvas2D/babylon.canvas2d.d.ts

@@ -797,107 +797,76 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    /**
+     * The base class for all implementation of a Primitive Collision Manager
+     */
     abstract class PrimitiveCollisionManagerBase {
         constructor(owner: Canvas2D);
-        abstract addActor(actor: Prim2DBase, deep: boolean): ActorInfo;
-        abstract removeActor(actor: Prim2DBase): any;
-        abstract update(): any;
+        abstract _addActor(actor: Prim2DBase, deep: boolean): ActorInfoBase;
+        abstract _removeActor(actor: Prim2DBase): any;
+        abstract _update(): any;
+        /**
+         * If collisionManagerUseBorders is true during the Canvas creation, this dictionary contains all the primitives intersecting with the left border
+         */
         readonly abstract leftBorderIntersectedActors: ObservableStringDictionary<Prim2DBase>;
+        /**
+         * If collisionManagerUseBorders is true during the Canvas creation, this dictionary contains all the primitives intersecting with the bottom border
+         */
         readonly abstract bottomBorderIntersectedActors: ObservableStringDictionary<Prim2DBase>;
+        /**
+         * If collisionManagerUseBorders is true during the Canvas creation, this dictionary contains all the primitives intersecting with the right border
+         */
         readonly abstract rightBorderIntersectedActors: ObservableStringDictionary<Prim2DBase>;
+        /**
+         * If collisionManagerUseBorders is true during the Canvas creation, this dictionary contains all the primitives intersecting with the top border
+         */
         readonly abstract topBorderIntersectedActors: ObservableStringDictionary<Prim2DBase>;
+        /**
+         * This dictionary contains all the couple of intersecting primitives
+         */
         readonly abstract intersectedActors: ObservableStringDictionary<{
             a: Prim2DBase;
             b: Prim2DBase;
         }>;
-        protected _owner: Canvas2D;
-    }
-    class ActorInfo {
-        constructor(owner: BasicPrimitiviceCollisionManager, actor: Prim2DBase, deep: boolean);
-        setFlags(flags: number): void;
-        clearFlags(flags: number): void;
-        isAllFlagsSet(flags: number): boolean;
-        isSomeFlagsSet(flags: number): boolean;
-        setFlagsValue(flags: number, value: boolean): void;
-        readonly worldAABB: Vector4;
-        readonly isEnabled: boolean;
-        readonly isDeep: boolean;
-        readonly isDirty: boolean;
-        readonly isRemoved: boolean;
-        prim: Prim2DBase;
-        flags: number;
-        owner: BasicPrimitiviceCollisionManager;
-        presentInClusters: StringDictionary<ClusterInfo>;
-        intersectWith: ObservableStringDictionary<ActorInfo>;
-        static flagDeep: number;
-        static flagEnabled: number;
-        static flagDirty: number;
-        static flagRemoved: number;
-    }
-    class ClusterInfo {
-        constructor();
-        clear(): void;
-        actors: StringDictionary<ActorInfo>;
-    }
-    class BasicPrimitiviceCollisionManager extends PrimitiveCollisionManagerBase {
-        constructor(owner: Canvas2D, enableBorders: boolean);
-        addActor(actor: Prim2DBase, deep: boolean): ActorInfo;
-        removeActor(actor: Prim2DBase): void;
-        actorDirty(actor: ActorInfo): void;
-        update(): void;
         /**
          * Renders the World AABB of all Actors
          */
-        debugRenderAABB: any;
+        abstract debugRenderAABB: boolean;
         /**
          * Renders the area of the Clusters
          */
-        debugRenderClusters: any;
+        abstract debugRenderClusters: boolean;
         /**
          * Display stats about the PCM on screen
          */
-        debugStats: any;
-        readonly intersectedActors: ObservableStringDictionary<{
-            a: Prim2DBase;
-            b: Prim2DBase;
-        }>;
-        readonly leftBorderIntersectedActors: ObservableStringDictionary<Prim2DBase>;
-        readonly bottomBorderIntersectedActors: ObservableStringDictionary<Prim2DBase>;
-        readonly rightBorderIntersectedActors: ObservableStringDictionary<Prim2DBase>;
-        readonly topBorderIntersectedActors: ObservableStringDictionary<Prim2DBase>;
-        private _initializeCluster(countW, countH);
-        private _rebuildAllActors();
-        private _rebuildDirtyActors();
-        static WAABBCorners: Array<Vector2>;
-        static WAABBCornersCluster: Array<Vector2>;
-        private _processActor(actor);
-        private static CandidatesActors;
-        private static PreviousIntersections;
-        private _collisionDetection();
-        private _getCluster(x, y);
-        private _updateDebugStats();
-        private _updateAABBDisplay();
-        private _updateClusterDisplay(cw, ch);
-        private _allocClusterInfo();
-        private _freeClusterInfo(ci);
-        private _canvasSize;
-        private _clusterDirty;
-        private _clusterSize;
-        private _clusterStep;
-        private _clusters;
-        private _maxActorByCluster;
-        private _lastClusterResizeCounter;
-        private _actors;
-        private _dirtyActors;
-        private _freeClusters;
-        private _enableBorder;
-        private _intersectedActors;
-        private _borderIntersecteddActors;
-        private _debugUpdateOpCount;
-        private _debugUpdateTime;
-        private _AABBRenderPrim;
-        private _ClusterRenderPrim;
-        private _debugTextBackground;
+        abstract debugStats: boolean;
+        static allocBasicPCM(owner: Canvas2D, enableBorders: boolean): PrimitiveCollisionManagerBase;
+        protected _owner: Canvas2D;
+    }
+    /**
+     * Base class of an Actor
+     */
+    abstract class ActorInfoBase {
+        /**
+         * Access the World AABB of the Actor, the vector4 is x:left, y: bottom, z: right, w: top
+         */
+        readonly abstract worldAABB: Vector4;
+        /**
+         * Return true if the actor is enable, false otherwise
+         */
+        readonly abstract isEnabled: boolean;
+        /**
+         * Return true is the actor boundingInfo is use, false if its levelBoundingInfo is used.
+         */
+        readonly abstract isDeep: boolean;
+        /**
+         * Return the primitive of the actor
+         */
+        readonly abstract prim: Prim2DBase;
+        /**
+         * Return a dictionary containing all the actors intersecting with this one
+         */
+        readonly abstract intersectWith: ObservableStringDictionary<ActorInfoBase>;
     }
 }
 
@@ -1898,7 +1867,16 @@ declare module BABYLON {
             paddingBottom?: number | string;
             padding?: string;
         });
-        readonly intersectWithObservable: Observable<DictionaryChanged<ActorInfo>>;
+        /**
+         * Return the ChangedDictionary observable of the StringDictionary containing the primitives intersecting with this one
+         */
+        readonly intersectWithObservable: Observable<DictionaryChanged<ActorInfoBase>>;
+        /**
+         * Return the ObservableStringDictionary containing all the primitives intersecting with this one.
+         * The key is the primitive uid, the value is the ActorInfo object
+         * @returns {}
+         */
+        readonly intersectWith: ObservableStringDictionary<ActorInfoBase>;
         readonly actionManager: ActionManager;
         /**
          * From 'this' primitive, traverse up (from parent to parent) until the given predicate is true

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 116 - 56
dist/preview release/canvas2D/babylon.canvas2d.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 11 - 11
dist/preview release/canvas2D/babylon.canvas2d.min.js