Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 CCL_NAMESPACE_BEGIN 00020 00021 __device float safe_asinf(float a) 00022 { 00023 if(a <= -1.0f) 00024 return -M_PI_2_F; 00025 else if(a >= 1.0f) 00026 return M_PI_2_F; 00027 00028 return asinf(a); 00029 } 00030 00031 __device float safe_acosf(float a) 00032 { 00033 if(a <= -1.0f) 00034 return M_PI_F; 00035 else if(a >= 1.0f) 00036 return 0.0f; 00037 00038 return acosf(a); 00039 } 00040 00041 __device float safe_powf(float a, float b) 00042 { 00043 if(b == 0.0f) 00044 return 1.0f; 00045 if(a == 0.0f) 00046 return 0.0f; 00047 if(a < 0.0f && b != (int)b) 00048 return 0.0f; 00049 00050 return powf(a, b); 00051 } 00052 00053 __device float safe_logf(float a, float b) 00054 { 00055 if(a < 0.0f || b < 0.0f) 00056 return 0.0f; 00057 00058 return logf(a)/logf(b); 00059 } 00060 00061 __device float safe_divide(float a, float b) 00062 { 00063 float result; 00064 00065 if(b == 0.0f) 00066 result = 0.0f; 00067 else 00068 result = a/b; 00069 00070 return result; 00071 } 00072 00073 __device float svm_math(NodeMath type, float Fac1, float Fac2) 00074 { 00075 float Fac; 00076 00077 if(type == NODE_MATH_ADD) 00078 Fac = Fac1 + Fac2; 00079 else if(type == NODE_MATH_SUBTRACT) 00080 Fac = Fac1 - Fac2; 00081 else if(type == NODE_MATH_MULTIPLY) 00082 Fac = Fac1*Fac2; 00083 else if(type == NODE_MATH_DIVIDE) 00084 Fac = safe_divide(Fac1, Fac2); 00085 else if(type == NODE_MATH_SINE) 00086 Fac = sinf(Fac1); 00087 else if(type == NODE_MATH_COSINE) 00088 Fac = cosf(Fac1); 00089 else if(type == NODE_MATH_TANGENT) 00090 Fac = tanf(Fac1); 00091 else if(type == NODE_MATH_ARCSINE) 00092 Fac = safe_asinf(Fac1); 00093 else if(type == NODE_MATH_ARCCOSINE) 00094 Fac = safe_acosf(Fac1); 00095 else if(type == NODE_MATH_ARCTANGENT) 00096 Fac = atanf(Fac1); 00097 else if(type == NODE_MATH_POWER) 00098 Fac = safe_powf(Fac1, Fac2); 00099 else if(type == NODE_MATH_LOGARITHM) 00100 Fac = safe_logf(Fac1, Fac2); 00101 else if(type == NODE_MATH_MINIMUM) 00102 Fac = fminf(Fac1, Fac2); 00103 else if(type == NODE_MATH_MAXIMUM) 00104 Fac = fmaxf(Fac1, Fac2); 00105 else if(type == NODE_MATH_ROUND) 00106 Fac = floorf(Fac1 + 0.5f); 00107 else if(type == NODE_MATH_LESS_THAN) 00108 Fac = Fac1 < Fac2; 00109 else if(type == NODE_MATH_GREATER_THAN) 00110 Fac = Fac1 > Fac2; 00111 else 00112 Fac = 0.0f; 00113 00114 return Fac; 00115 } 00116 00117 __device float average_fac(float3 v) 00118 { 00119 return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f; 00120 } 00121 00122 __device void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2) 00123 { 00124 if(type == NODE_VECTOR_MATH_ADD) { 00125 *Vector = Vector1 + Vector2; 00126 *Fac = average_fac(*Vector); 00127 } 00128 else if(type == NODE_VECTOR_MATH_SUBTRACT) { 00129 *Vector = Vector1 - Vector2; 00130 *Fac = average_fac(*Vector); 00131 } 00132 else if(type == NODE_VECTOR_MATH_AVERAGE) { 00133 *Fac = len(Vector1 + Vector2); 00134 *Vector = normalize(Vector1 + Vector2); 00135 } 00136 else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) { 00137 *Fac = dot(Vector1, Vector2); 00138 *Vector = make_float3(0.0f, 0.0f, 0.0f); 00139 } 00140 else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) { 00141 float3 c = cross(Vector1, Vector2); 00142 *Fac = len(c); 00143 *Vector = normalize(c); 00144 } 00145 else if(type == NODE_VECTOR_MATH_NORMALIZE) { 00146 *Fac = len(Vector1); 00147 *Vector = normalize(Vector1); 00148 } 00149 else { 00150 *Fac = 0.0f; 00151 *Vector = make_float3(0.0f, 0.0f, 0.0f); 00152 } 00153 } 00154 00155 /* Nodes */ 00156 00157 __device void svm_node_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint f1_offset, uint f2_offset, int *offset) 00158 { 00159 NodeMath type = (NodeMath)itype; 00160 float f1 = stack_load_float(stack, f1_offset); 00161 float f2 = stack_load_float(stack, f2_offset); 00162 float f = svm_math(type, f1, f2); 00163 00164 uint4 node1 = read_node(kg, offset); 00165 00166 stack_store_float(stack, node1.y, f); 00167 } 00168 00169 __device void svm_node_vector_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint v1_offset, uint v2_offset, int *offset) 00170 { 00171 NodeVectorMath type = (NodeVectorMath)itype; 00172 float3 v1 = stack_load_float3(stack, v1_offset); 00173 float3 v2 = stack_load_float3(stack, v2_offset); 00174 float f; 00175 float3 v; 00176 00177 svm_vector_math(&f, &v, type, v1, v2); 00178 00179 uint4 node1 = read_node(kg, offset); 00180 00181 if(stack_valid(node1.y)) stack_store_float(stack, node1.y, f); 00182 if(stack_valid(node1.z)) stack_store_float3(stack, node1.z, v); 00183 } 00184 00185 CCL_NAMESPACE_END 00186