• 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.graphics.Bitmap;
20 import android.graphics.Bitmap.Config;
21 
22 import java.util.Arrays;
23 
24 import static android.view.math.Math3DHelper.max;
25 import static android.view.math.Math3DHelper.min;
26 
27 /**
28  * 2D Triangle buffer element that colours using z value. (z scale set).
29  */
30 class TriangleBuffer {
31     int mWidth;
32     int mHeight;
33     int mImgWidth;
34     int mImgHeight;
35     int mBorder;
36     Bitmap mBitmap;
37     int mData[];
38     private float mMinX;
39     private float mMaxX;
40     private float mMinY;
41     private float mMaxY;
42 
setSize(int width, int height, int border)43     public void setSize(int width, int height, int border) {
44         if (mWidth == width && mHeight == height) {
45             return;
46         }
47         mWidth = width-2*border;
48         mHeight = height-2*border;
49         mBorder = border;
50         mImgWidth = width;
51         mImgHeight = height;
52 
53         setScale(0, width, 0, height);
54 
55         mBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
56         mData = new int[width * height];
57     }
58 
drawTriangles(int[] index, float[] vert, float[] color,float scale)59     public void drawTriangles(int[] index, float[] vert, float[] color,float scale) {
60         int indexSize = index.length / 3;
61         for (int i = 0; i < indexSize; i++) {
62             int vIndex = index[i * 3 + 0];
63             float vx = vert[vIndex * 2 + 0];
64             float vy = vert[vIndex * 2 + 1];
65             float c =  scale*color[vIndex * 4 + 3];
66             float fx3 = vx, fy3 = vy, fz3 = c;
67 
68             vIndex = index[i * 3 + 1];
69             vx = vert[vIndex * 2 + 0];
70             vy = vert[vIndex * 2 + 1];
71             c =  scale*color[vIndex * 4 + 3];
72             float fx2 = vx, fy2 = vy, fz2 = c;
73 
74             vIndex = index[i * 3 + 2];
75             vx = vert[vIndex * 2 + 0];
76             vy = vert[vIndex * 2 + 1];
77             c =  scale*color[vIndex * 4 + 3];
78             float fx1 = vx, fy1 = vy, fz1 = c;
79 
80             triangleZBuffMin(mData, mImgWidth, mImgHeight, fx3, fy3, fz3, fx2, fy2,
81                     fz2, fx1, fy1, fz1);
82             triangleZBuffMin(mData, mImgWidth, mImgHeight, fx1, fy1, fz1, fx2, fy2,
83                     fz2, fx3, fy3, fz3);
84         }
85         mBitmap.setPixels(mData, 0, mWidth, 0, 0, mWidth, mHeight);
86     }
87 
drawTriangles(float[] strip,float scale)88     public void drawTriangles(float[] strip,float scale) {
89         for (int i = 0; i < strip.length-8; i+=3) {
90             float fx3 = strip[i], fy3 = strip[i+1], fz3 = scale* strip[i+2];
91             float fx2 = strip[i+3], fy2 = strip[i+4], fz2 = scale* strip[i+5];
92             float fx1 = strip[i+6], fy1 = strip[i+7], fz1 = scale* strip[i+8];
93 
94             if (fx1*(fy2-fy3)+fx2*(fy3-fy1)+fx3*(fy1-fy2) ==0) {
95                 continue;
96             }
97             triangleZBuffMin(mData, mImgWidth, mImgHeight, fx3, fy3, fz3, fx2, fy2,
98                     fz2, fx1, fy1, fz1);
99         }
100         mBitmap.setPixels(mData, 0, mWidth, 0, 0, mWidth, mHeight);
101     }
102 
getImage()103     public Bitmap getImage() {
104         return mBitmap;
105     }
106 
triangleZBuffMin(int[] buff, int w, int h, float fx3, float fy3, float fz3, float fx2, float fy2, float fz2, float fx1, float fy1, float fz1)107     private static void triangleZBuffMin(int[] buff, int w, int h, float fx3,
108             float fy3, float fz3, float fx2, float fy2, float fz2, float fx1,
109             float fy1, float fz1) {
110         if (((fx1 - fx2) * (fy3 - fy2) - (fy1 - fy2) * (fx3 - fx2)) < 0) {
111             float tmpx = fx1;
112             float tmpy = fy1;
113             float tmpz = fz1;
114             fx1 = fx2;
115             fy1 = fy2;
116             fz1 = fz2;
117             fx2 = tmpx;
118             fy2 = tmpy;
119             fz2 = tmpz;
120         }
121         // using maxmima
122         // solve([x1*dx+y1*dy+zoff=z1,x2*dx+y2*dy+zoff=z2,x3*dx+y3*dy+zoff=z3],[dx,dy,zoff]);
123         double d = (fx1 * (fy3 - fy2) - fx2 * fy3 + fx3 * fy2 + (fx2 - fx3) * fy1);
124         if (d == 0) {
125             return;
126         }
127         float dx = (float) (-(fy1 * (fz3 - fz2) - fy2 * fz3 + fy3 * fz2 + (fy2 - fy3)
128                 * fz1) / d);
129         float dy = (float) ((fx1 * (fz3 - fz2) - fx2 * fz3 + fx3 * fz2 + (fx2 - fx3)
130                 * fz1) / d);
131         float zoff = (float) ((fx1 * (fy3 * fz2 - fy2 * fz3) + fy1
132                 * (fx2 * fz3 - fx3 * fz2) + (fx3 * fy2 - fx2 * fy3) * fz1) / d);
133 
134         // 28.4 fixed-point coordinates
135         int y1 = (int) (16.0f * fy1 + .5f);
136         int y2 = (int) (16.0f * fy2 + .5f);
137         int y3 = (int) (16.0f * fy3 + .5f);
138 
139         int x1 = (int) (16.0f * fx1 + .5f);
140         int x2 = (int) (16.0f * fx2 + .5f);
141         int x3 = (int) (16.0f * fx3 + .5f);
142 
143         int dx12 = x1 - x2;
144         int dx23 = x2 - x3;
145         int dx31 = x3 - x1;
146 
147         int dy12 = y1 - y2;
148         int dy23 = y2 - y3;
149         int dy31 = y3 - y1;
150 
151         int fdx12 = dx12 << 4;
152         int fdx23 = dx23 << 4;
153         int fdx31 = dx31 << 4;
154 
155         int fdy12 = dy12 << 4;
156         int fdy23 = dy23 << 4;
157         int fdy31 = dy31 << 4;
158 
159         int minx = (min(x1, x2, x3) + 0xF) >> 4;
160         int maxx = (max(x1, x2, x3) + 0xF) >> 4;
161         int miny = (min(y1, y2, y3) + 0xF) >> 4;
162         int maxy = (max(y1, y2, y3) + 0xF) >> 4;
163 
164         if (miny < 0) {
165             miny = 0;
166         }
167         if (minx < 0) {
168             minx = 0;
169         }
170         if (maxx > w) {
171             maxx = w;
172         }
173         if (maxy > h) {
174             maxy = h;
175         }
176         int off = miny * w;
177 
178         int c1 = dy12 * x1 - dx12 * y1;
179         int c2 = dy23 * x2 - dx23 * y2;
180         int c3 = dy31 * x3 - dx31 * y3;
181 
182         if (dy12 < 0 || (dy12 == 0 && dx12 > 0)) {
183             c1++;
184         }
185         if (dy23 < 0 || (dy23 == 0 && dx23 > 0)) {
186             c2++;
187         }
188         if (dy31 < 0 || (dy31 == 0 && dx31 > 0)) {
189             c3++;
190         }
191         int cy1 = c1 + dx12 * (miny << 4) - dy12 * (minx << 4);
192         int cy2 = c2 + dx23 * (miny << 4) - dy23 * (minx << 4);
193         int cy3 = c3 + dx31 * (miny << 4) - dy31 * (minx << 4);
194 
195         for (int y = miny; y < maxy; y++) {
196             int cx1 = cy1;
197             int cx2 = cy2;
198             int cx3 = cy3;
199             float p = zoff + dy * y;
200             for (int x = minx; x < maxx; x++) {
201                 if (cx1 > 0 && cx2 > 0 && cx3 > 0) {
202                     int point = x + off;
203                     float zval = p + dx * x;
204                     buff[point] = ((int) (zval * 255)) << 24;
205                 }
206                 cx1 -= fdy12;
207                 cx2 -= fdy23;
208                 cx3 -= fdy31;
209             }
210             cy1 += fdx12;
211             cy2 += fdx23;
212             cy3 += fdx31;
213             off += w;
214         }
215     }
216 
setScale(float minx, float maxx, float miny, float maxy)217     private void setScale(float minx, float maxx, float miny, float maxy) {
218         mMinX = minx;
219         mMaxX = maxx;
220         mMinY = miny;
221         mMaxY = maxy;
222     }
223 
clear()224     public void clear() {
225         Arrays.fill(mData, 0);
226     }
227 }