Code cleanup / Cycles:
[blender.git] / intern / cycles / kernel / kernel_curve.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 CCL_NAMESPACE_BEGIN
20
21 #ifdef __HAIR__
22
23 /* curve attributes */
24
25 __device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
26 {
27         if(elem == ATTR_ELEMENT_CURVE) {
28 #ifdef __RAY_DIFFERENTIALS__
29                 if(dx) *dx = 0.0f;
30                 if(dy) *dy = 0.0f;
31 #endif
32
33                 return kernel_tex_fetch(__attributes_float, offset + sd->prim);
34         }
35         else if(elem == ATTR_ELEMENT_CURVE_KEY) {
36                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
37                 int k0 = __float_as_int(curvedata.x) + sd->segment;
38                 int k1 = k0 + 1;
39
40                 float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
41                 float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
42
43 #ifdef __RAY_DIFFERENTIALS__
44                 if(dx) *dx = sd->du.dx*(f1 - f0);
45                 if(dy) *dy = 0.0f;
46 #endif
47
48                 return (1.0f - sd->u)*f0 + sd->u*f1;
49         }
50         else {
51 #ifdef __RAY_DIFFERENTIALS__
52                 if(dx) *dx = 0.0f;
53                 if(dy) *dy = 0.0f;
54 #endif
55
56                 return 0.0f;
57         }
58 }
59
60 __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
61 {
62         if(elem == ATTR_ELEMENT_CURVE) {
63                 /* idea: we can't derive any useful differentials here, but for tiled
64                  * mipmap image caching it would be useful to avoid reading the highest
65                  * detail level always. maybe a derivative based on the hair density
66                  * could be computed somehow? */
67 #ifdef __RAY_DIFFERENTIALS__
68                 if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
69                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
70 #endif
71
72                 return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
73         }
74         else if(elem == ATTR_ELEMENT_CURVE_KEY) {
75                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
76                 int k0 = __float_as_int(curvedata.x) + sd->segment;
77                 int k1 = k0 + 1;
78
79                 float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
80                 float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
81
82 #ifdef __RAY_DIFFERENTIALS__
83                 if(dx) *dx = sd->du.dx*(f1 - f0);
84                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
85 #endif
86
87                 return (1.0f - sd->u)*f0 + sd->u*f1;
88         }
89         else {
90 #ifdef __RAY_DIFFERENTIALS__
91                 if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
92                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
93 #endif
94
95                 return make_float3(0.0f, 0.0f, 0.0f);
96         }
97 }
98
99 /* hair info node functions */
100
101 __device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
102 {
103         float r = 0.0f;
104
105         if(sd->segment != ~0) {
106                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
107                 int k0 = __float_as_int(curvedata.x) + sd->segment;
108                 int k1 = k0 + 1;
109
110                 float4 P1 = kernel_tex_fetch(__curve_keys, k0);
111                 float4 P2 = kernel_tex_fetch(__curve_keys, k1);
112                 r = (P2.w - P1.w) * sd->u + P1.w;
113         }
114
115         return r*2.0f;
116 }
117
118 __device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
119 {       
120         float3 tgN = make_float3(0.0f,0.0f,0.0f);
121
122         if(sd->segment != ~0) {
123                 float normalmix = kernel_data.curve.normalmix;
124
125                 tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu)));
126                 tgN = normalize(tgN);
127
128                 /* need to find suitable scaled gd for corrected normal */
129 #if 0
130                 if (kernel_data.curve.use_tangent_normal_correction)
131                         tgN = normalize(tgN - gd * sd->dPdu);
132 #endif
133         }
134
135         return tgN;
136 }
137
138 #endif
139
140 CCL_NAMESPACE_END
141