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 }