Cycles: Make object flag names more obvious that hey are object and not shader
[blender.git] / intern / cycles / kernel / geom / geom_triangle.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 /* Triangle Primitive
18  *
19  * Basic triangle with 3 vertices is used to represent mesh surfaces. For BVH
20  * ray intersection we use a precomputed triangle storage to accelerate
21  * intersection at the cost of more memory usage */
22
23 CCL_NAMESPACE_BEGIN
24
25 /* normal on triangle  */
26 ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd)
27 {
28         /* load triangle vertices */
29         const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim));
30         const float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
31         const float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
32         const float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
33
34         /* return normal */
35         if(ccl_fetch(sd, flag) & SD_OBJECT_NEGATIVE_SCALE_APPLIED)
36                 return normalize(cross(v2 - v0, v1 - v0));
37         else
38                 return normalize(cross(v1 - v0, v2 - v0));
39 }
40
41 /* point and normal on triangle  */
42 ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int object, int prim, float u, float v, float3 *P, float3 *Ng, int *shader)
43 {
44         /* load triangle vertices */
45         const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
46         float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
47         float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
48         float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
49
50         /* compute point */
51         float t = 1.0f - u - v;
52         *P = (u*v0 + v*v1 + t*v2);
53
54         /* get object flags */
55         int object_flag = kernel_tex_fetch(__object_flag, object);
56
57         /* compute normal */
58         if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED)
59                 *Ng = normalize(cross(v2 - v0, v1 - v0));
60         else
61                 *Ng = normalize(cross(v1 - v0, v2 - v0));
62
63         /* shader`*/
64         *shader = kernel_tex_fetch(__tri_shader, prim);
65 }
66
67 /* Triangle vertex locations */
68
69 ccl_device_inline void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3])
70 {
71         const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
72         P[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
73         P[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
74         P[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
75 }
76
77 /* Interpolate smooth vertex normal from vertices */
78
79 ccl_device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int prim, float u, float v)
80 {
81         /* load triangle vertices */
82         const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
83         float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
84         float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
85         float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
86
87         return normalize((1.0f - u - v)*n2 + u*n0 + v*n1);
88 }
89
90 /* Ray differentials on triangle */
91
92 ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, ccl_addr_space float3 *dPdu, ccl_addr_space float3 *dPdv)
93 {
94         /* fetch triangle vertex coordinates */
95         const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
96         const float3 p0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
97         const float3 p1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
98         const float3 p2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
99
100         /* compute derivatives of P w.r.t. uv */
101         *dPdu = (p0 - p2);
102         *dPdv = (p1 - p2);
103 }
104
105 /* Reading attributes on various triangle elements */
106
107 ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
108 {
109         if(desc.element == ATTR_ELEMENT_FACE) {
110                 if(dx) *dx = 0.0f;
111                 if(dy) *dy = 0.0f;
112
113                 return kernel_tex_fetch(__attributes_float, desc.offset + ccl_fetch(sd, prim));
114         }
115         else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
116                 uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim));
117
118                 float f0 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.x);
119                 float f1 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.y);
120                 float f2 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.z);
121
122 #ifdef __RAY_DIFFERENTIALS__
123                 if(dx) *dx = ccl_fetch(sd, du).dx*f0 + ccl_fetch(sd, dv).dx*f1 - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*f2;
124                 if(dy) *dy = ccl_fetch(sd, du).dy*f0 + ccl_fetch(sd, dv).dy*f1 - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*f2;
125 #endif
126
127                 return ccl_fetch(sd, u)*f0 + ccl_fetch(sd, v)*f1 + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*f2;
128         }
129         else if(desc.element == ATTR_ELEMENT_CORNER) {
130                 int tri = desc.offset + ccl_fetch(sd, prim)*3;
131                 float f0 = kernel_tex_fetch(__attributes_float, tri + 0);
132                 float f1 = kernel_tex_fetch(__attributes_float, tri + 1);
133                 float f2 = kernel_tex_fetch(__attributes_float, tri + 2);
134
135 #ifdef __RAY_DIFFERENTIALS__
136                 if(dx) *dx = ccl_fetch(sd, du).dx*f0 + ccl_fetch(sd, dv).dx*f1 - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*f2;
137                 if(dy) *dy = ccl_fetch(sd, du).dy*f0 + ccl_fetch(sd, dv).dy*f1 - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*f2;
138 #endif
139
140                 return ccl_fetch(sd, u)*f0 + ccl_fetch(sd, v)*f1 + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*f2;
141         }
142         else {
143                 if(dx) *dx = 0.0f;
144                 if(dy) *dy = 0.0f;
145
146                 return 0.0f;
147         }
148 }
149
150 ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
151 {
152         if(desc.element == ATTR_ELEMENT_FACE) {
153                 if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
154                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
155
156                 return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + ccl_fetch(sd, prim)));
157         }
158         else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
159                 uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim));
160
161                 float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x));
162                 float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y));
163                 float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z));
164
165 #ifdef __RAY_DIFFERENTIALS__
166                 if(dx) *dx = ccl_fetch(sd, du).dx*f0 + ccl_fetch(sd, dv).dx*f1 - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*f2;
167                 if(dy) *dy = ccl_fetch(sd, du).dy*f0 + ccl_fetch(sd, dv).dy*f1 - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*f2;
168 #endif
169
170                 return ccl_fetch(sd, u)*f0 + ccl_fetch(sd, v)*f1 + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*f2;
171         }
172         else if(desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) {
173                 int tri = desc.offset + ccl_fetch(sd, prim)*3;
174                 float3 f0, f1, f2;
175
176                 if(desc.element == ATTR_ELEMENT_CORNER) {
177                         f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
178                         f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
179                         f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
180                 }
181                 else {
182                         f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 0));
183                         f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 1));
184                         f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, tri + 2));
185                 }
186
187 #ifdef __RAY_DIFFERENTIALS__
188                 if(dx) *dx = ccl_fetch(sd, du).dx*f0 + ccl_fetch(sd, dv).dx*f1 - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*f2;
189                 if(dy) *dy = ccl_fetch(sd, du).dy*f0 + ccl_fetch(sd, dv).dy*f1 - (ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*f2;
190 #endif
191
192                 return ccl_fetch(sd, u)*f0 + ccl_fetch(sd, v)*f1 + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*f2;
193         }
194         else {
195                 if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
196                 if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
197
198                 return make_float3(0.0f, 0.0f, 0.0f);
199         }
200 }
201
202 CCL_NAMESPACE_END