1 /* 2 * Copyright (C) 2015 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 package com.example.android.rs.vr.engine; 17 18 19 import android.graphics.Color; 20 import android.renderscript.Allocation; 21 import android.renderscript.Element; 22 import android.renderscript.RenderScript; 23 import android.renderscript.Type; 24 25 /** 26 * Defines the material properties of a pixel value 27 * RGB, Opacity diffuse specular, ambient 28 */ 29 public class Material { 30 public static final int SIZE = 64 * 1024; 31 public static final int STRIDE = 8; 32 33 Allocation mOpacityAllocation; 34 Allocation mColorMapAllocation; 35 36 public byte[] mOpacityTable = new byte[SIZE]; 37 MaterialProp[] mMaterialProp = new MaterialProp[0]; 38 public byte[] mColor = new byte[SIZE * STRIDE]; // table contain r, g, b, A, S, D 39 public static final int RED = 0; 40 public static final int GREEN = 1; 41 public static final int BLUE = 2; 42 public static final int DIFF = 4; 43 public static final int SPEC = 5; 44 public static final int AMB = 6; 45 46 public static class MaterialProp { 47 int mPos; 48 int mRed; 49 int mGreen; 50 int mBlue; 51 float mDiffuse; 52 float mSpecular; 53 float mAmbient; 54 } 55 56 /** 57 * Clamp limits to less than or equal to 255 58 * this is done with a very efficient bit fiddling trick 59 * @param c value being clamped 60 * @return values in the range 0-255 61 */ clamp(int c)62 private static int clamp(int c) { 63 final int N = 255; // the value clamp is limiting to 64 c &= ~(c >> 31); 65 c -= N; 66 c &= (c >> 31); 67 c += N; 68 return c; 69 } 70 71 public static class Opactiy { 72 int mPos; 73 float mValue; 74 } 75 76 public Opactiy[] mOpacity = new Opactiy[0]; 77 Material()78 public Material() { 79 simpleSetup(1150, 1300); 80 } 81 simpleSetup(int start, int end)82 public void simpleSetup(int start, int end) { 83 float diffuse = .7f; 84 float specular = .0f; 85 float ambient = .3f; 86 for (int i = Short.MIN_VALUE; i < Short.MAX_VALUE; i++) { 87 int off = i & 0xFFFF; 88 int p = STRIDE * (off); 89 byte v = (byte) clamp((int) (255 * (i - start) / (end - start))); 90 mColor[p + RED] = v; 91 mColor[p + GREEN] = v; 92 mColor[p + BLUE] = v; 93 mColor[p + DIFF] = (byte) (255 * diffuse); 94 mColor[p + SPEC] = (byte) (255 * specular); 95 mColor[p + AMB] = (byte) (255 * ambient); 96 mOpacityTable[off] = v; 97 } 98 } 99 setup(int[] means, int start, int end)100 public void setup(int[] means, int start, int end) { 101 int[] pos = new int[means.length - 1]; 102 int[] red = new int[means.length - 1]; 103 int[] green = new int[means.length - 1]; 104 int[] blue = new int[means.length - 1]; 105 106 for (int i = 0; i < pos.length; i++) { 107 pos[i] = (means[i] + means[i + 1]) / 2; 108 float f = i / (float) (pos.length - 1); 109 float h = 1 - f * f * f; 110 float s = (float) (1 / (1 + Math.exp((f - .5) * 5))); 111 int rgb = Color.HSVToColor(new float[]{360 * h, s, f}); 112 red[i] = (rgb >> 16) & 0xff; 113 green[i] = (rgb >> 8) & 0xff; 114 blue[i] = (rgb >> 0) & 0xff; 115 } 116 mMaterialProp = new MaterialProp[pos.length]; 117 118 float diffuse = .7f; 119 float specular = .0f; 120 float ambient = .3f; 121 for (int i = 0; i < pos.length; i++) { 122 mMaterialProp[i] = new MaterialProp(); 123 mMaterialProp[i].mAmbient = ambient; 124 mMaterialProp[i].mSpecular = specular; 125 mMaterialProp[i].mDiffuse = diffuse; 126 mMaterialProp[i].mPos = pos[i]; 127 float t = i / (float) (pos.length - 1); 128 129 mMaterialProp[i].mRed = red[i]; 130 mMaterialProp[i].mGreen = green[i]; 131 mMaterialProp[i].mBlue = blue[i]; 132 133 } 134 mOpacity = new Opactiy[2]; 135 mOpacity[0] = new Opactiy(); 136 mOpacity[0].mPos = start; 137 mOpacity[0].mValue = 0; 138 139 mOpacity[1] = new Opactiy(); 140 mOpacity[1].mPos = end; 141 mOpacity[1].mValue = 1; 142 143 buildOpacityTable(); 144 buildMaterialProp(); 145 } 146 setup(int[][] opacity, int[][] material)147 public void setup(int[][] opacity, int[][] material) { 148 mMaterialProp = new MaterialProp[material.length]; 149 150 for (int i = 0; i < material.length; i++) { 151 int rgb = material[i][1] & 0xFFFFFF; 152 153 float ambient = (material[i].length > 2) ? material[i][2] / 100.f : .2f; 154 float diffuse = (material[i].length > 3) ? material[i][3] / 100.f : .6f; 155 float specular = (material[i].length > 4) ? material[i][4] / 100.f : .2f; 156 157 mMaterialProp[i] = new MaterialProp(); 158 mMaterialProp[i].mAmbient = ambient; 159 mMaterialProp[i].mSpecular = specular; 160 mMaterialProp[i].mDiffuse = diffuse; 161 mMaterialProp[i].mRed = (rgb >> 16) & 0xff; 162 mMaterialProp[i].mGreen = (rgb >> 8) & 0xff; 163 mMaterialProp[i].mBlue = (rgb >> 0) & 0xff; 164 165 mMaterialProp[i].mPos = material[i][0]; 166 167 } 168 mOpacity = new Opactiy[opacity.length]; 169 for (int i = 0; i < opacity.length; i++) { 170 mOpacity[i] = new Opactiy(); 171 mOpacity[i].mPos = opacity[i][0]; 172 mOpacity[i].mValue = opacity[i][1] / 255.f; 173 } 174 buildOpacityTable(); 175 buildMaterialProp(); 176 } 177 setup(int start, int end)178 public void setup(int start, int end) { 179 int[] pos = {1050, 1140, 1200, 1210, 1231}; 180 181 mMaterialProp = new MaterialProp[pos.length]; 182 183 float diffuse = .7f; 184 float specular = .0f; 185 float ambient = .3f; 186 for (int i = 0; i < pos.length; i++) { 187 mMaterialProp[i] = new MaterialProp(); 188 mMaterialProp[i].mAmbient = ambient; 189 mMaterialProp[i].mSpecular = specular; 190 mMaterialProp[i].mDiffuse = diffuse; 191 mMaterialProp[i].mPos = pos[i]; 192 float t = i / (float) (pos.length - 1); 193 int rgb = (int) (Math.random() * 0xFFFFFF); 194 mMaterialProp[i].mRed = (rgb >> 16) & 0xff; 195 mMaterialProp[i].mGreen = (rgb >> 8) & 0xff; 196 mMaterialProp[i].mBlue = (rgb >> 0) & 0xff; 197 } 198 mOpacity = new Opactiy[2]; 199 mOpacity[0] = new Opactiy(); 200 mOpacity[0].mPos = start; 201 mOpacity[0].mValue = 0; 202 203 mOpacity[1] = new Opactiy(); 204 mOpacity[1].mPos = end; 205 mOpacity[1].mValue = 1; 206 207 buildOpacityTable(); 208 buildMaterialProp(); 209 } 210 buildOpacityTable()211 void buildOpacityTable() { 212 if (mOpacity.length == 0) { 213 return; 214 } 215 for (int i = Short.MIN_VALUE; i <= mOpacity[0].mPos; i++) { 216 int p = i & 0xFFFF; 217 mOpacityTable[p] = (byte) (mOpacity[0].mValue * 255); 218 } 219 for (int k = 0; k < mOpacity.length - 1; k++) { 220 for (int i = mOpacity[k].mPos; i < mOpacity[k + 1].mPos; i++) { 221 int p = i & 0xFFFF; 222 float dist = mOpacity[k + 1].mPos - mOpacity[k].mPos; 223 float t = (i - mOpacity[k].mPos) / dist; 224 float v = mOpacity[k].mValue * (1 - t) + t * mOpacity[k + 1].mValue; 225 mOpacityTable[p] = (byte) (v * 255); 226 } 227 } 228 int last = mOpacity.length - 1; 229 for (int i = mOpacity[last].mPos; i <= Short.MAX_VALUE; i++) { 230 int p = i & 0xFFFF; 231 mOpacityTable[p] = (byte) (mOpacity[last].mValue * 255); 232 233 } 234 } 235 buildMaterialProp()236 public void buildMaterialProp() { 237 MaterialProp[] m = mMaterialProp; 238 if (m.length == 0) { 239 return; 240 } 241 { 242 MaterialProp mp = m[0]; 243 int red = m[0].mRed; 244 int green = m[0].mGreen; 245 int blue = m[0].mBlue; 246 247 for (int i = Short.MIN_VALUE; i <= m[0].mPos; i++) { 248 int p = STRIDE * (i & 0xFFFF); 249 mColor[p + RED] = (byte) red; 250 mColor[p + GREEN] = (byte) green; 251 mColor[p + BLUE] = (byte) blue; 252 253 mColor[p + DIFF] = (byte) (255 * mp.mDiffuse); 254 mColor[p + SPEC] = (byte) (255 * mp.mSpecular); 255 mColor[p + AMB] = (byte) (255 * mp.mAmbient); 256 } 257 } 258 for (int k = 0; k < m.length - 1; k++) { 259 for (int i = m[k].mPos; i < m[k + 1].mPos; i++) { 260 int p = STRIDE * (i & 0xFFFF); 261 float dist = m[k + 1].mPos - m[k].mPos; 262 float t2 = (i - m[k].mPos) / dist; 263 float t1 = 1 - t2; 264 265 266 int red = (int) (m[k].mRed * t1 + m[k + 1].mRed * t2); 267 int green = (int) (m[k].mGreen * t1 + m[k + 1].mGreen * t2); 268 int blue = (int) (m[k].mBlue * t1 + m[k + 1].mBlue * t2); 269 270 float diffuse = m[k].mDiffuse * t1 + m[k + 1].mDiffuse * t2; 271 float specular = m[k].mSpecular * t1 + m[k + 1].mSpecular * t2; 272 float ambient = m[k].mAmbient * t1 + m[k + 1].mAmbient * t2; 273 274 275 mColor[p + RED] = (byte) red; 276 mColor[p + GREEN] = (byte) green; 277 mColor[p + BLUE] = (byte) blue; 278 279 mColor[p + DIFF] = (byte) (255 * diffuse); 280 mColor[p + SPEC] = (byte) (255 * specular); 281 mColor[p + AMB] = (byte) (255 * ambient); 282 } 283 } 284 { 285 int last = m.length - 1; 286 MaterialProp mp = m[last]; 287 int red = mp.mRed; 288 int green = mp.mGreen; 289 int blue = mp.mBlue; 290 for (int i = mp.mPos; i <= Short.MAX_VALUE; i++) { 291 int p = STRIDE * (i & 0xFFFF); 292 mColor[p + RED] = (byte) red; 293 mColor[p + GREEN] = (byte) green; 294 mColor[p + BLUE] = (byte) blue; 295 296 mColor[p + DIFF] = (byte) (255 * mp.mDiffuse); 297 mColor[p + SPEC] = (byte) (255 * mp.mSpecular); 298 mColor[p + AMB] = (byte) (255 * mp.mAmbient); 299 } 300 } 301 } 302 getOpacityAllocation(RenderScript rs)303 public Allocation getOpacityAllocation(RenderScript rs) { 304 if (mOpacityAllocation == null) { 305 Type.Builder b = new Type.Builder(rs, Element.U8(rs)); 306 b.setX(mOpacityTable.length); 307 mOpacityAllocation = Allocation.createTyped(rs, b.create()); 308 } 309 mOpacityAllocation.copyFromUnchecked(mOpacityTable); 310 return mOpacityAllocation; 311 } 312 getColorMapAllocation(RenderScript rs)313 public Allocation getColorMapAllocation(RenderScript rs) { 314 if (mColorMapAllocation == null) { 315 Type.Builder b = new Type.Builder(rs, Element.U8_4(rs)); 316 b.setX(mColor.length / 4); 317 mColorMapAllocation = Allocation.createTyped(rs, b.create()); 318 } 319 mColorMapAllocation.copyFromUnchecked(mColor); 320 return mColorMapAllocation; 321 } 322 } 323