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 17#pragma version(1) 18#pragma rs java_package_name(com.example.android.rs.vr.engine) 19#pragma rs_fp_relaxed 20 21int size; 22int z; 23rs_allocation volume; 24 25static float sigmoid(float f) { 26 return (float) (1 / (1 + exp(f / 2))); 27} 28 29static float pillDistance(float3 p1, float3 p2, float3 img) { 30 31 if (dot(p2 - p1, img - p1) > 0 && dot(p1 - p2, img - p2) > 0) { 32 return length(cross(img - p1, img - p2)) / length(p2 - p1); 33 } 34 return min(distance(p1, img), distance(p2, img)); 35} 36 37static short pill(float3 p1, float3 p2, float rad, short max, float3 img) { 38 return (short) (max * sigmoid(pillDistance(p1, p2, img) - rad)); 39} 40 41static short cogPill(float3 p1, float3 p2, float rad, short max, float3 img) { 42 float3 vec = (p1 + p2) / 2 - img; 43 float angle = fabs(2 * fract(atan2pi(vec.z, vec.y) * 5) - 1); 44 return (short) (max 45 * sigmoid(pillDistance(p1, p2, img) - rad * (1 + angle / 2))); 46} 47 48static float cylinderDistance(float3 p1, float3 p2, float3 img) { 49 float dot1 = dot(p2 - p1, img - p1); 50 float dot2 = dot(p1 - p2, img - p2); 51 if (dot1 > 0 && dot2 > 0) { 52 return length(cross(img - p1, img - p2)) / length(p2 - p1); 53 } 54 return -dot1 * dot2; 55} 56 57static short cylinder(float3 p1, float3 p2, float rad, short max, float3 img) { 58 return (short) (max * sigmoid(cylinderDistance(p1, p2, img) - rad)); 59} 60 61static short cogCylinder(float3 p1, float3 p2, float rad, short max, float3 img) { 62 float3 vec = (p1 + p2) / 2 - img; 63 float angle = fabs(2 * fract(atan2pi(vec.y, vec.x) * 6) - 1); 64 return (short) (max 65 * sigmoid(cylinderDistance(p1, p2, img) - rad * (1 + angle / 5))); 66} 67 68static float distanceCircle(float3 center, float radius, float3 normal, 69 float3 img) { 70 float3 pc = img - center; 71 float tmp1 = dot(normal, pc); 72 tmp1 = tmp1 * tmp1; 73 float tmp2 = (sqrt(length(pc) * length(pc) - tmp1) - radius); 74 return tmp1 + tmp2 * tmp2; 75} 76 77static short circle(float3 center, float circleRadius, float3 normal, float rad, 78 short max, float3 img) { 79 return (short) (max 80 * sigmoid(distanceCircle(center, circleRadius, normal, img) - rad)); 81} 82 83static float distanceDisk(float3 center, float radius, float3 normal, 84 float3 img) { 85 float3 pc = img - center; 86 float tmp1 = dot(normal, pc); 87 tmp1 = tmp1 * tmp1; 88 float tmp2 = (sqrt(length(pc) * length(pc) - tmp1) - radius); 89 if (length(pc - dot(normal, pc) * normal) > radius) { 90 return (tmp1 + tmp2 * tmp2); 91 } 92 return tmp1; 93} 94 95/* Unused function: 96static short disk(float3 center, float circleRadius, float3 normal, float rad, 97 short max, float3 img) { 98 return (short) (max 99 * sigmoid(distanceDisk(center, circleRadius, normal, img) - rad)); 100} 101*/ 102 103static short cogDisk(float3 center, float circleRadius, float3 normal, 104 float rad, short max, float3 img) { 105 float3 vec = center - img; 106 float angle = fabs(2 * fract(atan2pi(vec.y, vec.x) * 20) - 1); 107 return (short) (max 108 * sigmoid( 109 distanceDisk(center, circleRadius * (1 + angle / 10), 110 normal, img) - rad)); 111} 112 113static float andyBody(float3 img) { 114 short v = 0; 115 { // body 116 float3 p1 = { size * 0.5f, size * 0.5f, size * 0.3f }; 117 float3 p2 = { size * 0.5f, size * 0.5f, size * 0.65f }; 118 float radius = size * 0.22f; 119 v = max(v, cylinder(p1, p2, radius, 144, img)); 120 p2.z = size * 0.4f; 121 v = max(v, pill(p1, p2, radius, 144, img)); 122 float3 normal = { 0.0f, 0.0f, 1.0f }; 123 v -= circle(p1, radius*0.9f, normal, size * 0.05f, 144, img); 124 } 125 float armOffset = 0.27f; 126 { // arm 1 127 float3 p1 = { size * (0.5f - armOffset), size * 0.5f, size * 0.4f }; 128 float3 p2 = { size * (0.5f - armOffset), size * 0.5f, size * 0.57f }; 129 v = max(v, pill(p1, p2, size * 0.09f, 144, img)); 130 } 131 { // arm 2 132 float3 p1 = { size * (0.5f + armOffset), size * 0.5f, size * 0.4f }; 133 float3 p2 = { size * (0.5f + armOffset), size * 0.5f, size * 0.57f }; 134 v = max(v, pill(p1, p2, size * 0.09f, 144, img)); 135 } 136 { // leg 1 137 float3 p1 = { size * 0.6f, size * 0.5f, size * 0.6f }; 138 float3 p2 = { size * 0.6f, size * 0.5f, size * 0.8f }; 139 v = max(v, pill(p1, p2, size * 0.08f, 144, img)); 140 } 141 { // leg 2 142 float3 p1 = { size * 0.4f, size * 0.5f, size * 0.6f }; 143 float3 p2 = { size * 0.4f, size * 0.5f, size * 0.8f }; 144 v = max(v, pill(p1, p2, size * 0.08f, 144, img)); 145 } 146 float3 p1 = { size * 0.5f, size * 0.5f, size * 0.3f }; 147 ; 148 { // antenna 149 float spacex = .1f; 150 151 float3 p2 = { size * (0.5f - spacex), size * 0.5f, size * 0.07f }; 152 v = max(v, pill(p1, p2, size * 0.017f, 400, img)); 153 float3 p3 = { size * (0.5f + spacex), size * 0.5f, size * 0.07f }; 154 v = max(v, pill(p1, p3, size * 0.017f, 400, img)); 155 } 156 { // eyes 157 float spacex = .105f; 158 float3 p2 = { size * (0.5f - spacex), size * 0.4f, size * 0.2f }; 159 float3 p3 = { size * (0.5f + spacex), size * 0.4f, size * 0.2f }; 160 v -= pill(p2, p2, size * 0.018f, 144, img); 161 v -= pill(p3, p3, size * 0.018f, 144, img); 162 v = max(v, pill(p1, p2, size * 0.032f, 400, img)); 163 v = max(v, pill(p1, p3, size * 0.032f, 400, img)); 164 } 165 return v; 166 167} 168 169static float andySkeleton(float3 img) { 170 short v = 0; 171 { // body 172 float3 p1 = { size * 0.5f, size * 0.5f, size * 0.3f }; 173 float radius = size * 0.15f; 174 175 float3 normal = { 0.0f, 0.0f, 1.0f }; 176 for (int i = 0; i < 5; i++) { 177 p1.z += size * 0.04f; 178 v += circle(p1, radius, normal, size * 0.07f, 400, img); 179 } 180 p1.z = size * 0.3f; 181 float3 p2 = { size * 0.5f, size * 0.5f, size * 0.6f }; 182 v = max(v, cogDisk(p2, radius * 0.7f, normal, size * 0.07f, 400, img)); 183 v = max(v, cogCylinder(p1, p2, size * 0.04f, 400, img)); 184 } 185 186 float armOffset = 0.27f; 187 { 188 float3 p1 = { size * (0.5f - armOffset), size * 0.5f, size * 0.4f }; 189 float3 p2 = { size * (0.5f + armOffset), size * 0.5f, size * 0.4f }; 190 v = max(v, cogPill(p1, p2, size * 0.02f, 400, img)); 191 } 192 193 { // arm 1 194 float3 p1 = { size * (0.5f - armOffset), size * 0.5f, size * 0.4f }; 195 float3 p2 = { size * (0.5f - armOffset), size * 0.5f, size * 0.57f }; 196 v = max(v, pill(p1, p2, size * 0.02f, 400, img)); 197 } 198 { // arm 2 199 float3 p1 = { size * (0.5f + armOffset), size * 0.5f, size * 0.4f }; 200 float3 p2 = { size * (0.5f + armOffset), size * 0.5f, size * 0.57f }; 201 v = max(v, pill(p1, p2, size * 0.02f, 400, img)); 202 } 203 { // leg 1 204 float3 p1 = { size * 0.6f, size * 0.5f, size * 0.6f }; 205 float3 p2 = { size * 0.6f, size * 0.5f, size * 0.8f }; 206 v = max(v, pill(p1, p2, size * 0.02f, 400, img)); 207 } 208 { // leg 2 209 float3 p1 = { size * 0.4f, size * 0.5f, size * 0.6f }; 210 float3 p2 = { size * 0.4f, size * 0.5f, size * 0.8f }; 211 v = max(v, pill(p1, p2, size * 0.02f, 400, img)); 212 } 213 return v; 214} 215 216short __attribute__((kernel)) andy(uint32_t x, uint32_t y) { 217 float3 img = { x, y, z }; 218 float v = andyBody(img); 219 v = max(v, andySkeleton(img)); 220 return v; 221 222} 223 224void __attribute__((kernel)) copy(short in, uint32_t x, uint32_t y) { 225 rsSetElementAt_short(volume, in, x, y, z); 226} 227