//! returns level of detail for tile (-1 if not visible) int tileLevelOfDetail(int row, int col, const matrix4x4 &world, const render::Camera &camera) { matrix4x4 quadFront( 0, span.x, span.x, 0, 0, 0, span.y, span.y, 0, 0, 0, 0, 1, 1, 1, 1 ); matrix4x4 quadBack( 0, span.x, span.x, 0, 0, 0, span.y, span.y, span.z, span.z, span.z, span.z, 1, 1, 1, 1 ); matrix4x4 transform = camera.transform() * world; quadFront = transform * quadFront; quadBack = transform * quadBack; projectQuad(quadFront); projectQuad(quadBack); bool invisible = !(quadVisible(quadFront) || quadVisible(quadBack)); if (invisible) { return -1; } // determine a bounding box around all the corners matrix4x1 bounding; matrix4x4 *faces[] = { &quadFront, &quadBack }; int p = 0; for (int j = 0; j < 2; j++) { for (int i = 0; i < 4; i++, ++p) { matrix4x1 col = (*faces[j]).column(i); if (!p || col.x < bounding._0) bounding._0 = col.x; if (!p || col.y < bounding._1) bounding._1 = col.y; if (!p || col.x > bounding._2) bounding._2 = col.x; if (!p || col.y > bounding._3) bounding._3 = col.y; } } // determine LOD by area float longDimension = std::max((bounding._3 - bounding._1), (bounding._2 - bounding._0)) / 2.0f; int lod = 0; if (longDimension > 0.75f) { lod = 0; } else if (longDimension > 0.5f) { lod = 1; } else if (longDimension > 0.25f) { lod = 2; } else { lod = 3; } return lod; }
static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion) { if (!contentSpaceTransform.isInvertible()) return contentRect; FloatRect transformedRect = contentSpaceTransform.mapRect(FloatRect(contentRect)); // Take the enclosingIntRect at each step, as we want to contain any unoccluded partial pixels in the resulting IntRect. IntRect shrunkRect = rectSubtractRegion(intersection(enclosingIntRect(transformedRect), scissorRect), occlusion); bool clamped; // FIXME: projectQuad returns invalid results when a point gets clamped. To be fixed in bug https://bugs.webkit.org/show_bug.cgi?id=80806. IntRect unoccludedRect = enclosingIntRect(projectQuad(contentSpaceTransform.inverse(), FloatQuad(FloatRect(shrunkRect)), clamped).boundingBox()); if (clamped) return contentRect; // The rect back in content space is a bounding box and may extend outside of the original contentRect, so clamp it to the contentRectBounds. return intersection(unoccludedRect, contentRect); }