Przeglądaj źródła

Canvas2D: Lines2D & canvas intersection bug fixes

Lines2D:
 - BoundingBox was incorrectly computed, then rejecting wrongly the intersection test
 - Rendering was incorrectly interpreting the origin (again!)

Intersection now ignore !isPickable prim all the time
nockawa 9 lat temu
rodzic
commit
d2283a3c22

+ 20 - 12
src/Canvas2d/babylon.lines2d.ts

@@ -234,29 +234,37 @@
             this._endCap = value;
         }
 
+        private static _prevA: Vector2 = Vector2.Zero();
+        private static _prevB: Vector2 = Vector2.Zero();
+        private static _curA: Vector2 = Vector2.Zero();
+        private static _curB: Vector2 = Vector2.Zero();
+
         protected levelIntersect(intersectInfo: IntersectInfo2D): boolean {
             let pl = this.points.length;
             let l = this.closed ? pl + 1 : pl;
 
-            let originOffset = new Vector2(-0.5, -0.5);
+//            let originOffset = new Vector2(-0.5, -0.5);
             let p = intersectInfo._localPickPosition;
 
-            let prevA = this.transformPointWithOrigin(this._contour[0], originOffset);
-            let prevB = this.transformPointWithOrigin(this._contour[1], originOffset);
+            this.transformPointWithOriginToRef(this._contour[0], null, Lines2D._prevA);
+            this.transformPointWithOriginToRef(this._contour[1], null, Lines2D._prevB);
             for (let i = 1; i < l; i++) {
-                let curA = this.transformPointWithOrigin(this._contour[(i % pl) * 2 + 0], originOffset);
-                let curB = this.transformPointWithOrigin(this._contour[(i % pl) * 2 + 1], originOffset);
+                this.transformPointWithOriginToRef(this._contour[(i % pl) * 2 + 0], null, Lines2D._curA);
+                this.transformPointWithOriginToRef(this._contour[(i % pl) * 2 + 1], null, Lines2D._curB);
 
-                if (Vector2.PointInTriangle(p, prevA, prevB, curA)) {
+                if (Vector2.PointInTriangle(p, Lines2D._prevA, Lines2D._prevB, Lines2D._curA)) {
                     return true;
                 }
-                if (Vector2.PointInTriangle(p, curA, prevB, curB)) {
+                if (Vector2.PointInTriangle(p, Lines2D._curA, Lines2D._prevB, Lines2D._curB)) {
                     return true;
                 }
 
-                prevA = curA;
-                prevB = curB;
+                Lines2D._prevA.x = Lines2D._curA.x;
+                Lines2D._prevA.y = Lines2D._curA.y;
+                Lines2D._prevB.x = Lines2D._curB.x;
+                Lines2D._prevB.y = Lines2D._curB.y;
             }
+
             return false;
         }
 
@@ -284,7 +292,7 @@
         }
 
         protected updateLevelBoundingInfo() {
-            BoundingInfo2D.CreateFromSizeToRef(this.size, this._levelBoundingInfo, this.origin);
+            BoundingInfo2D.CreateFromMinMaxToRef(this._boundingMin.x, this._boundingMax.x, this._boundingMin.y, this._boundingMax.y, this._levelBoundingInfo, this.origin);
         }
 
         protected setupLines2D(owner: Canvas2D, parent: Prim2DBase, id: string, position: Vector2, origin: Vector2, points: Vector2[], fillThickness: number, startCap: number, endCap: number, fill: IBrush2D, border: IBrush2D, borderThickness: number, closed: boolean, isVisible: boolean, marginTop: number, marginLeft: number, marginRight: number, marginBottom: number, vAlignment: number, hAlignment: number) {
@@ -351,8 +359,8 @@
             let engine = this.owner.engine;
 
             // Init min/max because their being computed here
-            this.boundingMin = new Vector2(Number.MAX_VALUE, Number.MAX_VALUE);
-            this.boundingMax = new Vector2(Number.MIN_VALUE, Number.MIN_VALUE);
+            this._boundingMin = new Vector2(Number.MAX_VALUE, Number.MAX_VALUE);
+            this._boundingMax = new Vector2(Number.MIN_VALUE, Number.MIN_VALUE);
 
             let perp = (v: Vector2, res: Vector2) => {
                 res.x = v.y;

+ 15 - 13
src/Canvas2d/babylon.prim2dBase.ts

@@ -876,28 +876,30 @@
             }
 
             // Fast rejection test with boundingInfo
-            if (!this.boundingInfo.doesIntersect(intersectInfo._localPickPosition)) {
+            if (this.isPickable && !this.boundingInfo.doesIntersect(intersectInfo._localPickPosition)) {
                 // Important to call this before each return to allow a good recursion next time this intersectInfo is reused
                 intersectInfo._exit(firstLevel);
                 return false;
             }
 
             // We hit the boundingInfo that bounds this primitive and its children, now we have to test on the primitive of this level
-            let levelIntersectRes = this.levelIntersect(intersectInfo);
-            if (levelIntersectRes) {
-                let pii = new PrimitiveIntersectedInfo(this, intersectInfo._localPickPosition.clone());
-                intersectInfo.intersectedPrimitives.push(pii);
-                if (!intersectInfo.topMostIntersectedPrimitive || (intersectInfo.topMostIntersectedPrimitive.prim.getActualZOffset() > pii.prim.getActualZOffset())) {
-                    intersectInfo.topMostIntersectedPrimitive = pii;
-                }
+            let levelIntersectRes = false;
+            if (this.isPickable) {
+                levelIntersectRes = this.levelIntersect(intersectInfo);
+                if (levelIntersectRes) {
+                    let pii = new PrimitiveIntersectedInfo(this, intersectInfo._localPickPosition.clone());
+                    intersectInfo.intersectedPrimitives.push(pii);
+                    if (!intersectInfo.topMostIntersectedPrimitive || (intersectInfo.topMostIntersectedPrimitive.prim.getActualZOffset() > pii.prim.getActualZOffset())) {
+                        intersectInfo.topMostIntersectedPrimitive = pii;
+                    }
 
-                // If we must stop at the first intersection, we're done, quit!
-                if (intersectInfo.findFirstOnly) {
-                    intersectInfo._exit(firstLevel);
-                    return true;
+                    // If we must stop at the first intersection, we're done, quit!
+                    if (intersectInfo.findFirstOnly) {
+                        intersectInfo._exit(firstLevel);
+                        return true;
+                    }
                 }
             }
-
             // Recurse to children if needed
             if (!levelIntersectRes || !intersectInfo.findFirstOnly) {
                 for (let curChild of this._children) {

+ 1 - 2
src/Canvas2d/babylon.renderablePrim2d.ts

@@ -674,8 +674,7 @@
             res.y = p.y - ((this.origin.y + (originOffset ? originOffset.y : 0)) * actualSize.height);
         }
 
-        protected transformPointWithOrigin(p: Vector2, originOffset: Vector2): Vector2 {
-            let res = new Vector2(0, 0);
+        protected transformPointWithOriginToRef(p: Vector2, originOffset: Vector2, res: Vector2) {
             this.transformPointWithOriginByRef(p, originOffset, res);
             return res;
         }

+ 1 - 1
src/Shaders/lines2d.vertex.fx

@@ -60,7 +60,7 @@ void main(void) {
 #endif
 
 	vec4 pos;
-	pos.xy = position.xy - ((origin.xy-vec2(0.5,0.5)) * (boundingMax - boundingMin));
+	pos.xy = position.xy - (origin.xy * (boundingMax - boundingMin));
 	pos.z = 1.0;
 	pos.w = 1.0;
 	gl_Position = vec4(dot(pos, transformX), dot(pos, transformY), zBias.x, 1);