Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca517b97 authored by ztenghui's avatar ztenghui Committed by Android (Google) Code Review
Browse files

Merge "Re-triangulate the spot shadow." into lmp-dev

parents 69828684 512e643c
Loading
Loading
Loading
Loading
+7 −30
Original line number Diff line number Diff line
@@ -91,36 +91,13 @@ inline float getTransformedAlphaFromFactoredZ(float factoredZ) {
    return getTransformedAlphaFromAlpha(getAlphaFromFactoredZ(factoredZ));
}

inline int getExtraVertexNumber(const Vector2& vector1, const Vector2& vector2,
        float divisor) {
    // When there is no distance difference, there is no need for extra vertices.
    if (vector1.lengthSquared() == 0 || vector2.lengthSquared() == 0) {
        return 0;
    }
    // The formula is :
    // extraNumber = floor(acos(dot(n1, n2)) / (M_PI / EXTRA_VERTEX_PER_PI))
    // The value ranges for each step are:
    // dot( ) --- [-1, 1]
    // acos( )     --- [0, M_PI]
    // floor(...)  --- [0, EXTRA_VERTEX_PER_PI]
    float dotProduct = vector1.dot(vector2);
    // TODO: Use look up table for the dotProduct to extraVerticesNumber
    // computation, if needed.
    float angle = acosf(dotProduct);
    return (int) floor(angle / divisor);
}

inline void checkOverflow(int used, int total, const char* bufferName) {
    LOG_ALWAYS_FATAL_IF(used > total, "Error: %s overflow!!! used %d, total %d",
            bufferName, used, total);
}

inline int getEdgeExtraAndUpdateSpike(Vector2* currentSpike,
        const Vector3& secondVertex, const Vector3& centroid) {
    Vector2 secondSpike  = {secondVertex.x - centroid.x, secondVertex.y - centroid.y};
    secondSpike.normalize();

    int result = getExtraVertexNumber(secondSpike, *currentSpike, EDGE_RADIANS_DIVISOR);
    int result = ShadowTessellator::getExtraVertexNumber(secondSpike, *currentSpike,
            EDGE_RADIANS_DIVISOR);
    *currentSpike = secondSpike;
    return result;
}
@@ -231,8 +208,8 @@ void AmbientShadow::createAmbientShadow(bool isCasterOpaque,
        Vector2 currentNormal = getNormalFromVertices(casterVertices, i,
                (i + 1) % casterVertexCount);

        int extraVerticesNumber = getExtraVertexNumber(currentNormal, previousNormal,
                CORNER_RADIANS_DIVISOR);
        int extraVerticesNumber = ShadowTessellator::getExtraVertexNumber(currentNormal,
                previousNormal, CORNER_RADIANS_DIVISOR);

        float expansionDist = innerVertex.z * heightFactor * geomFactor;
        const int cornerSlicesNumber = extraVerticesNumber + 1; // Minimal as 1.
@@ -349,9 +326,9 @@ void AmbientShadow::createAmbientShadow(bool isCasterOpaque,
    shadowVertexBuffer.updateVertexCount(vertexBufferIndex);
    shadowVertexBuffer.updateIndexCount(indexBufferIndex);

    checkOverflow(vertexBufferIndex, totalVertexCount, "Vertex Buffer");
    checkOverflow(indexBufferIndex, totalIndexCount, "Index Buffer");
    checkOverflow(umbraIndex, totalUmbraCount, "Umbra Buffer");
    ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Vertex Buffer");
    ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Index Buffer");
    ShadowTessellator::checkOverflow(umbraIndex, totalUmbraCount, "Umbra Buffer");

#if DEBUG_SHADOW
    for (int i = 0; i < vertexBufferIndex; i++) {
+24 −0
Original line number Diff line number Diff line
@@ -252,5 +252,29 @@ void ShadowTessellator::reverseVertexArray(Vertex* polygon, int len) {
    }
}

int ShadowTessellator::getExtraVertexNumber(const Vector2& vector1,
        const Vector2& vector2, float divisor) {
    // When there is no distance difference, there is no need for extra vertices.
    if (vector1.lengthSquared() == 0 || vector2.lengthSquared() == 0) {
        return 0;
    }
    // The formula is :
    // extraNumber = floor(acos(dot(n1, n2)) / (M_PI / EXTRA_VERTEX_PER_PI))
    // The value ranges for each step are:
    // dot( ) --- [-1, 1]
    // acos( )     --- [0, M_PI]
    // floor(...)  --- [0, EXTRA_VERTEX_PER_PI]
    float dotProduct = vector1.dot(vector2);
    // TODO: Use look up table for the dotProduct to extraVerticesNumber
    // computation, if needed.
    float angle = acosf(dotProduct);
    return (int) floor(angle / divisor);
}

void ShadowTessellator::checkOverflow(int used, int total, const char* bufferName) {
    LOG_ALWAYS_FATAL_IF(used > total, "Error: %s overflow!!! used %d, total %d",
            bufferName, used, total);
}

}; // namespace uirenderer
}; // namespace android
+4 −0
Original line number Diff line number Diff line
@@ -101,6 +101,10 @@ public:
     */
    static void reverseVertexArray(Vertex* polygon, int len);

    static int getExtraVertexNumber(const Vector2& vector1, const Vector2& vector2,
            float divisor);

    static void checkOverflow(int used, int total, const char* bufferName);
}; // ShadowTessellator

}; // namespace uirenderer
+770 −264

File changed.

Preview size limit exceeded, changes collapsed.

+37 −9
Original line number Diff line number Diff line
@@ -26,22 +26,51 @@ namespace uirenderer {

class SpotShadow {
public:
    static void createSpotShadow_old(bool isCasterOpaque, const Vector3* poly,
            int polyLength, const Vector3& lightCenter, float lightSize,
            int lightVertexCount, VertexBuffer& retStrips);
    static void createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter,
            float lightSize, const Vector3* poly, int polyLength,
            const Vector3& polyCentroid, VertexBuffer& retstrips);

private:
    struct VertexAngleData;

    static float projectCasterToOutline(Vector2& outline,
            const Vector3& lightCenter, const Vector3& polyVertex);
    static int calculateOccludedUmbra(const Vector2* umbra, int umbraLength,
            const Vector3* poly, int polyLength, Vector2* occludedUmbra);

    static void computeSpotShadow_old(bool isCasterOpaque, const Vector3* lightPoly,
            int lightPolyLength, const Vector3& lightCenter, const Vector3* poly,
            int polyLength, VertexBuffer& shadowTriangleStrip);
    static int setupAngleList(VertexAngleData* angleDataList,
            int polyLength, const Vector2* polygon, const Vector2& centroid,
            bool isPenumbra, const char* name);

    static int convertPolysToVerticesPerRay(
            bool hasOccludedUmbraArea, const Vector2* poly2d, int polyLength,
            const Vector2* umbra, int umbraLength, const Vector2* penumbra,
            int penumbraLength, const Vector2& centroid,
            Vector2* umbraVerticesPerRay, Vector2* penumbraVerticesPerRay,
            Vector2* occludedUmbraVerticesPerRay);

    static bool checkClockwise(int maxIndex, int listLength,
            VertexAngleData* angleList, const char* name);

    static void calculateDistanceCounter(bool needsOffsetToUmbra, int angleLength,
            const VertexAngleData* allVerticesAngleData, int* distances);

    static void mergeAngleList(int maxUmbraAngleIndex, int maxPenumbraAngleIndex,
            const VertexAngleData* umbraAngleList, int umbraLength,
            const VertexAngleData* penumbraAngleList, int penumbraLength,
            VertexAngleData* allVerticesAngleData);

    static int setupPolyAngleList(float* polyAngleList, int polyAngleLength,
        const Vector2* poly2d, const Vector2& centroid);

    static bool checkPolyClockwise(int polyAngleLength, int maxPolyAngleIndex,
        const float* polyAngleList);

    static int getEdgeStartIndex(const int* offsets, int rayIndex, int totalRayNumber,
        const VertexAngleData* allVerticesAngleData);

    static int getPolyEdgeStartIndex(int maxPolyAngleIndex, int polyLength,
        const float* polyAngleList, float rayAngle);

    static void computeLightPolygon(int points, const Vector3& lightCenter,
            float size, Vector3* ret);
@@ -67,11 +96,10 @@ private:
            double x3, double y3, double x4, double y4, Vector2& ret);

    static void generateTriangleStrip(bool isCasterOpaque, float shadowStrengthScale,
            const Vector2* penumbra, int penumbraLength, const Vector2* umbra, int umbraLength,
            const Vector3* poly, int polyLength, VertexBuffer& retstrips);
            Vector2* penumbra, int penumbraLength, Vector2* umbra, int umbraLength,
            const Vector3* poly, int polyLength, VertexBuffer& retstrips, const Vector2& centroid);

#if DEBUG_SHADOW
    // Verification utility function.
    static bool testConvex(const Vector2* polygon, int polygonLength,
            const char* name);
    static void testIntersection(const Vector2* poly1, int poly1Length,
Loading