summaryrefslogtreecommitdiff
path: root/java/tests/VrDemo/src/com/example/android/rs/vr/engine/Material.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/tests/VrDemo/src/com/example/android/rs/vr/engine/Material.java')
-rw-r--r--java/tests/VrDemo/src/com/example/android/rs/vr/engine/Material.java322
1 files changed, 322 insertions, 0 deletions
diff --git a/java/tests/VrDemo/src/com/example/android/rs/vr/engine/Material.java b/java/tests/VrDemo/src/com/example/android/rs/vr/engine/Material.java
new file mode 100644
index 00000000..8517754a
--- /dev/null
+++ b/java/tests/VrDemo/src/com/example/android/rs/vr/engine/Material.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2015 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 com.example.android.rs.vr.engine;
+
+
+import android.graphics.Color;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+
+/**
+ * Defines the material properties of a pixel value
+ * RGB, Opacity diffuse specular, ambient
+ */
+public class Material {
+ public static final int SIZE = 64 * 1024;
+ public static final int STRIDE = 8;
+
+ Allocation mOpacityAllocation;
+ Allocation mColorMapAllocation;
+
+ public byte[] mOpacityTable = new byte[SIZE];
+ MaterialProp[] mMaterialProp = new MaterialProp[0];
+ public byte[] mColor = new byte[SIZE * STRIDE]; // table contain r, g, b, A, S, D
+ public static final int RED = 0;
+ public static final int GREEN = 1;
+ public static final int BLUE = 2;
+ public static final int DIFF = 4;
+ public static final int SPEC = 5;
+ public static final int AMB = 6;
+
+ public static class MaterialProp {
+ int mPos;
+ int mRed;
+ int mGreen;
+ int mBlue;
+ float mDiffuse;
+ float mSpecular;
+ float mAmbient;
+ }
+
+ /**
+ * Clamp limits to less than or equal to 255
+ * this is done with a very efficient bit fiddling trick
+ * @param c value being clamped
+ * @return values in the range 0-255
+ */
+ private static int clamp(int c) {
+ final int N = 255; // the value clamp is limiting to
+ c &= ~(c >> 31);
+ c -= N;
+ c &= (c >> 31);
+ c += N;
+ return c;
+ }
+
+ public static class Opactiy {
+ int mPos;
+ float mValue;
+ }
+
+ public Opactiy[] mOpacity = new Opactiy[0];
+
+ public Material() {
+ simpleSetup(1150, 1300);
+ }
+
+ public void simpleSetup(int start, int end) {
+ float diffuse = .7f;
+ float specular = .0f;
+ float ambient = .3f;
+ for (int i = Short.MIN_VALUE; i < Short.MAX_VALUE; i++) {
+ int off = i & 0xFFFF;
+ int p = STRIDE * (off);
+ byte v = (byte) clamp((int) (255 * (i - start) / (end - start)));
+ mColor[p + RED] = v;
+ mColor[p + GREEN] = v;
+ mColor[p + BLUE] = v;
+ mColor[p + DIFF] = (byte) (255 * diffuse);
+ mColor[p + SPEC] = (byte) (255 * specular);
+ mColor[p + AMB] = (byte) (255 * ambient);
+ mOpacityTable[off] = v;
+ }
+ }
+
+ public void setup(int[] means, int start, int end) {
+ int[] pos = new int[means.length - 1];
+ int[] red = new int[means.length - 1];
+ int[] green = new int[means.length - 1];
+ int[] blue = new int[means.length - 1];
+
+ for (int i = 0; i < pos.length; i++) {
+ pos[i] = (means[i] + means[i + 1]) / 2;
+ float f = i / (float) (pos.length - 1);
+ float h = 1 - f * f * f;
+ float s = (float) (1 / (1 + Math.exp((f - .5) * 5)));
+ int rgb = Color.HSVToColor(new float[]{360 * h, s, f});
+ red[i] = (rgb >> 16) & 0xff;
+ green[i] = (rgb >> 8) & 0xff;
+ blue[i] = (rgb >> 0) & 0xff;
+ }
+ mMaterialProp = new MaterialProp[pos.length];
+
+ float diffuse = .7f;
+ float specular = .0f;
+ float ambient = .3f;
+ for (int i = 0; i < pos.length; i++) {
+ mMaterialProp[i] = new MaterialProp();
+ mMaterialProp[i].mAmbient = ambient;
+ mMaterialProp[i].mSpecular = specular;
+ mMaterialProp[i].mDiffuse = diffuse;
+ mMaterialProp[i].mPos = pos[i];
+ float t = i / (float) (pos.length - 1);
+
+ mMaterialProp[i].mRed = red[i];
+ mMaterialProp[i].mGreen = green[i];
+ mMaterialProp[i].mBlue = blue[i];
+
+ }
+ mOpacity = new Opactiy[2];
+ mOpacity[0] = new Opactiy();
+ mOpacity[0].mPos = start;
+ mOpacity[0].mValue = 0;
+
+ mOpacity[1] = new Opactiy();
+ mOpacity[1].mPos = end;
+ mOpacity[1].mValue = 1;
+
+ buildOpacityTable();
+ buildMaterialProp();
+ }
+
+ public void setup(int[][] opacity, int[][] material) {
+ mMaterialProp = new MaterialProp[material.length];
+
+ for (int i = 0; i < material.length; i++) {
+ int rgb = material[i][1] & 0xFFFFFF;
+
+ float ambient = (material[i].length > 2) ? material[i][2] / 100.f : .2f;
+ float diffuse = (material[i].length > 3) ? material[i][3] / 100.f : .6f;
+ float specular = (material[i].length > 4) ? material[i][4] / 100.f : .2f;
+
+ mMaterialProp[i] = new MaterialProp();
+ mMaterialProp[i].mAmbient = ambient;
+ mMaterialProp[i].mSpecular = specular;
+ mMaterialProp[i].mDiffuse = diffuse;
+ mMaterialProp[i].mRed = (rgb >> 16) & 0xff;
+ mMaterialProp[i].mGreen = (rgb >> 8) & 0xff;
+ mMaterialProp[i].mBlue = (rgb >> 0) & 0xff;
+
+ mMaterialProp[i].mPos = material[i][0];
+
+ }
+ mOpacity = new Opactiy[opacity.length];
+ for (int i = 0; i < opacity.length; i++) {
+ mOpacity[i] = new Opactiy();
+ mOpacity[i].mPos = opacity[i][0];
+ mOpacity[i].mValue = opacity[i][1] / 255.f;
+ }
+ buildOpacityTable();
+ buildMaterialProp();
+ }
+
+ public void setup(int start, int end) {
+ int[] pos = {1050, 1140, 1200, 1210, 1231};
+
+ mMaterialProp = new MaterialProp[pos.length];
+
+ float diffuse = .7f;
+ float specular = .0f;
+ float ambient = .3f;
+ for (int i = 0; i < pos.length; i++) {
+ mMaterialProp[i] = new MaterialProp();
+ mMaterialProp[i].mAmbient = ambient;
+ mMaterialProp[i].mSpecular = specular;
+ mMaterialProp[i].mDiffuse = diffuse;
+ mMaterialProp[i].mPos = pos[i];
+ float t = i / (float) (pos.length - 1);
+ int rgb = (int) (Math.random() * 0xFFFFFF);
+ mMaterialProp[i].mRed = (rgb >> 16) & 0xff;
+ mMaterialProp[i].mGreen = (rgb >> 8) & 0xff;
+ mMaterialProp[i].mBlue = (rgb >> 0) & 0xff;
+ }
+ mOpacity = new Opactiy[2];
+ mOpacity[0] = new Opactiy();
+ mOpacity[0].mPos = start;
+ mOpacity[0].mValue = 0;
+
+ mOpacity[1] = new Opactiy();
+ mOpacity[1].mPos = end;
+ mOpacity[1].mValue = 1;
+
+ buildOpacityTable();
+ buildMaterialProp();
+ }
+
+ void buildOpacityTable() {
+ if (mOpacity.length == 0) {
+ return;
+ }
+ for (int i = Short.MIN_VALUE; i <= mOpacity[0].mPos; i++) {
+ int p = i & 0xFFFF;
+ mOpacityTable[p] = (byte) (mOpacity[0].mValue * 255);
+ }
+ for (int k = 0; k < mOpacity.length - 1; k++) {
+ for (int i = mOpacity[k].mPos; i < mOpacity[k + 1].mPos; i++) {
+ int p = i & 0xFFFF;
+ float dist = mOpacity[k + 1].mPos - mOpacity[k].mPos;
+ float t = (i - mOpacity[k].mPos) / dist;
+ float v = mOpacity[k].mValue * (1 - t) + t * mOpacity[k + 1].mValue;
+ mOpacityTable[p] = (byte) (v * 255);
+ }
+ }
+ int last = mOpacity.length - 1;
+ for (int i = mOpacity[last].mPos; i <= Short.MAX_VALUE; i++) {
+ int p = i & 0xFFFF;
+ mOpacityTable[p] = (byte) (mOpacity[last].mValue * 255);
+
+ }
+ }
+
+ public void buildMaterialProp() {
+ MaterialProp[] m = mMaterialProp;
+ if (m.length == 0) {
+ return;
+ }
+ {
+ MaterialProp mp = m[0];
+ int red = m[0].mRed;
+ int green = m[0].mGreen;
+ int blue = m[0].mBlue;
+
+ for (int i = Short.MIN_VALUE; i <= m[0].mPos; i++) {
+ int p = STRIDE * (i & 0xFFFF);
+ mColor[p + RED] = (byte) red;
+ mColor[p + GREEN] = (byte) green;
+ mColor[p + BLUE] = (byte) blue;
+
+ mColor[p + DIFF] = (byte) (255 * mp.mDiffuse);
+ mColor[p + SPEC] = (byte) (255 * mp.mSpecular);
+ mColor[p + AMB] = (byte) (255 * mp.mAmbient);
+ }
+ }
+ for (int k = 0; k < m.length - 1; k++) {
+ for (int i = m[k].mPos; i < m[k + 1].mPos; i++) {
+ int p = STRIDE * (i & 0xFFFF);
+ float dist = m[k + 1].mPos - m[k].mPos;
+ float t2 = (i - m[k].mPos) / dist;
+ float t1 = 1 - t2;
+
+
+ int red = (int) (m[k].mRed * t1 + m[k + 1].mRed * t2);
+ int green = (int) (m[k].mGreen * t1 + m[k + 1].mGreen * t2);
+ int blue = (int) (m[k].mBlue * t1 + m[k + 1].mBlue * t2);
+
+ float diffuse = m[k].mDiffuse * t1 + m[k + 1].mDiffuse * t2;
+ float specular = m[k].mSpecular * t1 + m[k + 1].mSpecular * t2;
+ float ambient = m[k].mAmbient * t1 + m[k + 1].mAmbient * t2;
+
+
+ mColor[p + RED] = (byte) red;
+ mColor[p + GREEN] = (byte) green;
+ mColor[p + BLUE] = (byte) blue;
+
+ mColor[p + DIFF] = (byte) (255 * diffuse);
+ mColor[p + SPEC] = (byte) (255 * specular);
+ mColor[p + AMB] = (byte) (255 * ambient);
+ }
+ }
+ {
+ int last = m.length - 1;
+ MaterialProp mp = m[last];
+ int red = mp.mRed;
+ int green = mp.mGreen;
+ int blue = mp.mBlue;
+ for (int i = mp.mPos; i <= Short.MAX_VALUE; i++) {
+ int p = STRIDE * (i & 0xFFFF);
+ mColor[p + RED] = (byte) red;
+ mColor[p + GREEN] = (byte) green;
+ mColor[p + BLUE] = (byte) blue;
+
+ mColor[p + DIFF] = (byte) (255 * mp.mDiffuse);
+ mColor[p + SPEC] = (byte) (255 * mp.mSpecular);
+ mColor[p + AMB] = (byte) (255 * mp.mAmbient);
+ }
+ }
+ }
+
+ public Allocation getOpacityAllocation(RenderScript rs) {
+ if (mOpacityAllocation == null) {
+ Type.Builder b = new Type.Builder(rs, Element.U8(rs));
+ b.setX(mOpacityTable.length);
+ mOpacityAllocation = Allocation.createTyped(rs, b.create());
+ }
+ mOpacityAllocation.copyFromUnchecked(mOpacityTable);
+ return mOpacityAllocation;
+ }
+
+ public Allocation getColorMapAllocation(RenderScript rs) {
+ if (mColorMapAllocation == null) {
+ Type.Builder b = new Type.Builder(rs, Element.U8_4(rs));
+ b.setX(mColor.length / 4);
+ mColorMapAllocation = Allocation.createTyped(rs, b.create());
+ }
+ mColorMapAllocation.copyFromUnchecked(mColor);
+ return mColorMapAllocation;
+ }
+}