All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.view.shadow.AmbientShadowVertexCalculator Maven / Gradle / Ivy

/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view.shadow;

import android.view.math.Math3DHelper;

/**
 * Generates vertices, colours, and indices required for ambient shadow. Ambient shadows are
 * assumed to be raycasted from the centroid of the polygon, and reaches upto a ratio based on
 * the polygon's z-height.
 */
class AmbientShadowVertexCalculator {

    private final float[] mVertex;
    private final float[] mColor;
    private final int[] mIndex;
    private final AmbientShadowConfig mConfig;

    public AmbientShadowVertexCalculator(AmbientShadowConfig config) {
        mConfig = config;

        int size = mConfig.getPolygon().length / 3;

        mVertex = new float[size * 2 * 2];
        mColor = new float[size * 2 * 4];
        mIndex = new int[(size * 3 - 2) * 3];
    }

    /**
     * Generates ambient shadow triangulation using configuration provided
     */
    public void generateVertex() {
        float[] polygon = mConfig.getPolygon();
        float cx = mConfig.getLightSourcePosition()[0];
        float cy = mConfig.getLightSourcePosition()[1];

        int polygonLength = polygon.length/3;

        float opacity = .8f * (0.5f / (mConfig.getEdgeScale() / 10f));

        int trShift = 0;
        for (int i = 0; i < polygonLength; ++i, trShift += 6) {
            int shift = i * 4;
            int colorShift = i * 8;
            int idxShift = i * 2;

            float px = polygon[3 * i + 0];
            float py = polygon[3 * i + 1];
            mVertex[shift + 0] = px;
            mVertex[shift + 1] = py;

            // TODO: I do not really understand this but this matches the previous behavior.
            // The weird bit is that for outlines with low elevation the ambient shadow is
            // entirely drawn underneath the shadow caster. This is most probably incorrect
            float h = polygon[3 * i + 2] * mConfig.getShadowBoundRatio();

            mVertex[shift + 2] = cx + h * (px - cx);
            mVertex[shift + 3] = cy + h * (py - cy);

            mColor[colorShift + 3] = opacity;

            mIndex[trShift + 0] = idxShift + 0;
            mIndex[trShift + 1] = idxShift + 1;
            mIndex[trShift + 2] = idxShift + 2;

            mIndex[trShift + 3] = idxShift + 1;
            mIndex[trShift + 4] = idxShift + 2;
            mIndex[trShift + 5] = idxShift + 3;
        }
        // cycle back to the front
        mIndex[trShift - 1] = 1;
        mIndex[trShift - 2] = 0;
        mIndex[trShift - 4] = 0;

        // Filling the shadow right under the outline. Can we skip that?
        for (int i = 1; i < polygonLength - 1; ++i, trShift += 3) {
            mIndex[trShift + 0] = 0;
            mIndex[trShift + 1] = 2 * i;
            mIndex[trShift + 2] = 2 * (i+1);
        }
    }

    public int[] getIndex() {
        return mIndex;
    }

    /**
     * @return list of vertices in 2d in format : {x1, y1, x2, y2 ...}
     */
    public float[] getVertex() {
        return mVertex;
    }

    public float[] getColor() {
        return mColor;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy