// Checks if segment pq intersects any of the sides of triangle abc. bool CCLayerSorter::LayerIntersector::edgeTriangleTest(const FloatPoint& p, const FloatPoint& q, const FloatPoint& a, const FloatPoint& b, const FloatPoint& c) { FloatPoint r; if ((edgeEdgeTest(p, q, a, b, r) && checkZDiff(r)) || (edgeEdgeTest(p, q, a, c, r) && checkZDiff(r)) || (edgeEdgeTest(p, q, b, c, r) && checkZDiff(r))) return true; return false; }
// Checks whether layer "a" draws on top of layer "b". The weight value returned is an indication of // the maximum z-depth difference between the layers or zero if the layers are found to be intesecting // (some features are in front and some are behind). CCLayerSorter::ABCompareResult CCLayerSorter::checkOverlap(LayerShape* a, LayerShape* b, float zThreshold, float& weight) { weight = 0; // Early out if the projected bounds don't overlap. if (!a->projectedBounds.intersects(b->projectedBounds)) return None; FloatPoint aPoints[4] = {a->projectedQuad.p1(), a->projectedQuad.p2(), a->projectedQuad.p3(), a->projectedQuad.p4() }; FloatPoint bPoints[4] = {b->projectedQuad.p1(), b->projectedQuad.p2(), b->projectedQuad.p3(), b->projectedQuad.p4() }; // Make a list of points that inside both layer quad projections. Vector<FloatPoint> overlapPoints; // Check all four corners of one layer against the other layer's quad. for (int i = 0; i < 4; ++i) { if (a->projectedQuad.containsPoint(bPoints[i])) overlapPoints.append(bPoints[i]); if (b->projectedQuad.containsPoint(aPoints[i])) overlapPoints.append(aPoints[i]); } // Check all the edges of one layer for intersection with the other layer's edges. FloatPoint r; for (int ea = 0; ea < 4; ++ea) for (int eb = 0; eb < 4; ++eb) if (edgeEdgeTest(aPoints[ea], aPoints[(ea + 1) % 4], bPoints[eb], bPoints[(eb + 1) % 4], r)) overlapPoints.append(r); if (!overlapPoints.size()) return None; // Check the corresponding layer depth value for all overlap points to determine // which layer is in front. float maxPositive = 0; float maxNegative = 0; for (unsigned o = 0; o < overlapPoints.size(); o++) { float za = a->layerZFromProjectedPoint(overlapPoints[o]); float zb = b->layerZFromProjectedPoint(overlapPoints[o]); float diff = za - zb; if (diff > maxPositive) maxPositive = diff; if (diff < maxNegative) maxNegative = diff; } float maxDiff = (fabsf(maxPositive) > fabsf(maxNegative) ? maxPositive : maxNegative); // If the results are inconsistent (and the z difference substantial to rule out // numerical errors) then the layers are intersecting. We will still return an // order based on the maximum depth difference but with an edge weight of zero // these layers will get priority if a graph cycle is present and needs to be broken. if (maxPositive > zThreshold && maxNegative < -zThreshold) weight = 0; else weight = fabsf(maxDiff); // Maintain relative order if the layers have the same depth at all intersection points. if (maxDiff <= 0) return ABeforeB; return BBeforeA; }