• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.view.shadow;
18 
19 import android.view.math.Math3DHelper;
20 
21 /**
22  * Generates vertices, colours, and indices required for ambient shadow. Ambient shadows are
23  * assumed to be raycasted from the centroid of the polygon, and reaches upto a ratio based on
24  * the polygon's z-height.
25  */
26 class AmbientShadowVertexCalculator {
27 
28     private final float[] mVertex;
29     private final float[] mColor;
30     private final int[] mIndex;
31     private final AmbientShadowConfig mConfig;
32 
AmbientShadowVertexCalculator(AmbientShadowConfig config)33     public AmbientShadowVertexCalculator(AmbientShadowConfig config) {
34         mConfig = config;
35 
36         int size = mConfig.getPolygon().length / 3;
37 
38         mVertex = new float[size * 2 * 2];
39         mColor = new float[size * 2 * 4];
40         mIndex = new int[(size * 3 - 2) * 3];
41     }
42 
43     /**
44      * Generates ambient shadow triangulation using configuration provided
45      */
generateVertex()46     public void generateVertex() {
47         float[] polygon = mConfig.getPolygon();
48         float cx = mConfig.getLightSourcePosition()[0];
49         float cy = mConfig.getLightSourcePosition()[1];
50 
51         int polygonLength = polygon.length/3;
52 
53         float opacity = .8f * (0.5f / (mConfig.getEdgeScale() / 10f));
54 
55         int trShift = 0;
56         for (int i = 0; i < polygonLength; ++i, trShift += 6) {
57             int shift = i * 4;
58             int colorShift = i * 8;
59             int idxShift = i * 2;
60 
61             float px = polygon[3 * i + 0];
62             float py = polygon[3 * i + 1];
63             mVertex[shift + 0] = px;
64             mVertex[shift + 1] = py;
65 
66             // TODO: I do not really understand this but this matches the previous behavior.
67             // The weird bit is that for outlines with low elevation the ambient shadow is
68             // entirely drawn underneath the shadow caster. This is most probably incorrect
69             float h = polygon[3 * i + 2] * mConfig.getShadowBoundRatio();
70 
71             mVertex[shift + 2] = cx + h * (px - cx);
72             mVertex[shift + 3] = cy + h * (py - cy);
73 
74             mColor[colorShift + 3] = opacity;
75 
76             mIndex[trShift + 0] = idxShift + 0;
77             mIndex[trShift + 1] = idxShift + 1;
78             mIndex[trShift + 2] = idxShift + 2;
79 
80             mIndex[trShift + 3] = idxShift + 1;
81             mIndex[trShift + 4] = idxShift + 2;
82             mIndex[trShift + 5] = idxShift + 3;
83         }
84         // cycle back to the front
85         mIndex[trShift - 1] = 1;
86         mIndex[trShift - 2] = 0;
87         mIndex[trShift - 4] = 0;
88 
89         // Filling the shadow right under the outline. Can we skip that?
90         for (int i = 1; i < polygonLength - 1; ++i, trShift += 3) {
91             mIndex[trShift + 0] = 0;
92             mIndex[trShift + 1] = 2 * i;
93             mIndex[trShift + 2] = 2 * (i+1);
94         }
95     }
96 
getIndex()97     public int[] getIndex() {
98         return mIndex;
99     }
100 
101     /**
102      * @return list of vertices in 2d in format : {x1, y1, x2, y2 ...}
103      */
getVertex()104     public float[] getVertex() {
105         return mVertex;
106     }
107 
getColor()108     public float[] getColor() {
109         return mColor;
110     }
111 }
112