Blender V2.61 - r43446

svm_math.h

Go to the documentation of this file.
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