Cycles: relicense GNU GPL source code to Apache version 2.0.
[blender.git] / intern / cycles / kernel / kernel_curve.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
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 CCL_NAMESPACE_BEGIN
18
19 #ifdef __HAIR__
20
21 /* curve attributes */
22
23 __device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
24 {
25         if(elem == ATTR_ELEMENT_CURVE) {
26 #ifdef __RAY_DIFFERENTIALS__
27                 if(dx) *dx = 0.0f;
28                 if(dy) *dy = 0.0f;
29 #endif
30
31                 return kernel_tex_fetch(__attributes_float, offset + sd->prim);
32         }
33         else if(elem == ATTR_ELEMENT_CURVE_KEY) {
34                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
35                 int k0 = __float_as_int(curvedata.x) + sd->segment;
36                 int k1 = k0 + 1;
37
38                 float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
39                 float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
40
41 #ifdef __RAY_DIFFERENTIALS__
42                 if(dx) *dx = sd->du.dx*(f1 - f0);
43                 if(dy) *dy = 0.0f;
44 #endif
45
46                 return (1.0f - sd->u)*f0 + sd->u*f1;
47         }
48         else {
49 #ifdef __RAY_DIFFERENTIALS__
50                 if(dx) *dx = 0.0f;
51                 if(dy) *dy = 0.0f;
52 #endif
53
54                 return 0.0f;
55         }
56 }
57
58 __device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
59 {
60         if(elem == ATTR_ELEMENT_CURVE) {
61                 /* idea: we can't derive any useful differentials here, but for tiled
62                  * mipmap image caching it would be useful to avoid reading the highest
63                  * detail level always. maybe a derivative based on the hair density
64                  * could be computed somehow? */
65 #ifdef __RAY_DIFFERENTIALS__
66                 if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
67                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
68 #endif
69
70                 return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
71         }
72         else if(elem == ATTR_ELEMENT_CURVE_KEY) {
73                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
74                 int k0 = __float_as_int(curvedata.x) + sd->segment;
75                 int k1 = k0 + 1;
76
77                 float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
78                 float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
79
80 #ifdef __RAY_DIFFERENTIALS__
81                 if(dx) *dx = sd->du.dx*(f1 - f0);
82                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
83 #endif
84
85                 return (1.0f - sd->u)*f0 + sd->u*f1;
86         }
87         else {
88 #ifdef __RAY_DIFFERENTIALS__
89                 if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
90                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
91 #endif
92
93                 return make_float3(0.0f, 0.0f, 0.0f);
94         }
95 }
96
97 /* hair info node functions */
98
99 __device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
100 {
101         float r = 0.0f;
102
103         if(sd->segment != ~0) {
104                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
105                 int k0 = __float_as_int(curvedata.x) + sd->segment;
106                 int k1 = k0 + 1;
107
108                 float4 P1 = kernel_tex_fetch(__curve_keys, k0);
109                 float4 P2 = kernel_tex_fetch(__curve_keys, k1);
110                 r = (P2.w - P1.w) * sd->u + P1.w;
111         }
112
113         return r*2.0f;
114 }
115
116 __device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
117 {       
118         float3 tgN = make_float3(0.0f,0.0f,0.0f);
119
120         if(sd->segment != ~0) {
121
122                 tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) / len_squared(sd->dPdu)));
123                 tgN = normalize(tgN);
124
125                 /* need to find suitable scaled gd for corrected normal */
126 #if 0
127                 tgN = normalize(tgN - gd * sd->dPdu);
128 #endif
129         }
130
131         return tgN;
132 }
133
134 #endif
135
136 CCL_NAMESPACE_END
137