ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / kernel / geom / geom_motion_triangle_shader.h
1 /*
2  * Copyright 2011-2016 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 /* Motion Triangle Primitive
18  *
19  * These are stored as regular triangles, plus extra positions and normals at
20  * times other than the frame center. Computing the triangle vertex positions
21  * or normals at a given ray time is a matter of interpolation of the two steps
22  * between which the ray time lies.
23  *
24  * The extra positions and normals are stored as ATTR_STD_MOTION_VERTEX_POSITION
25  * and ATTR_STD_MOTION_VERTEX_NORMAL mesh attributes.
26  */
27
28 CCL_NAMESPACE_BEGIN
29
30 /* Setup of motion triangle specific parts of ShaderData, moved into this one
31  * function to more easily share computation of interpolated positions and
32  * normals */
33
34 /* return 3 triangle vertex normals */
35 ccl_device_noinline void motion_triangle_shader_setup(
36     KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, bool is_local)
37 {
38   /* Get shader. */
39   sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
40   /* Get motion info. */
41   /* TODO(sergey): This logic is really similar to motion_triangle_vertices(),
42    * can we de-duplicate something here?
43    */
44   int numsteps, numverts;
45   object_motion_info(kg, sd->object, &numsteps, &numverts, NULL);
46   /* Figure out which steps we need to fetch and their interpolation factor. */
47   int maxstep = numsteps * 2;
48   int step = min((int)(sd->time * maxstep), maxstep - 1);
49   float t = sd->time * maxstep - step;
50   /* Find attribute. */
51   AttributeElement elem;
52   int offset = find_attribute_motion(kg, sd->object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
53   kernel_assert(offset != ATTR_STD_NOT_FOUND);
54   /* Fetch vertex coordinates. */
55   float3 verts[3], next_verts[3];
56   uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
57   motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
58   motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
59   /* Interpolate between steps. */
60   verts[0] = (1.0f - t) * verts[0] + t * next_verts[0];
61   verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
62   verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
63   /* Compute refined position. */
64 #ifdef __BVH_LOCAL__
65   if (is_local) {
66     sd->P = motion_triangle_refine_local(kg, sd, isect, ray, verts);
67   }
68   else
69 #endif /*  __BVH_LOCAL__*/
70   {
71     sd->P = motion_triangle_refine(kg, sd, isect, ray, verts);
72   }
73   /* Compute face normal. */
74   float3 Ng;
75   if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
76     Ng = normalize(cross(verts[2] - verts[0], verts[1] - verts[0]));
77   }
78   else {
79     Ng = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
80   }
81   sd->Ng = Ng;
82   sd->N = Ng;
83   /* Compute derivatives of P w.r.t. uv. */
84 #ifdef __DPDU__
85   sd->dPdu = (verts[0] - verts[2]);
86   sd->dPdv = (verts[1] - verts[2]);
87 #endif
88   /* Compute smooth normal. */
89   if (sd->shader & SHADER_SMOOTH_NORMAL) {
90     /* Find attribute. */
91     AttributeElement elem;
92     int offset = find_attribute_motion(kg, sd->object, ATTR_STD_MOTION_VERTEX_NORMAL, &elem);
93     kernel_assert(offset != ATTR_STD_NOT_FOUND);
94     /* Fetch vertex coordinates. */
95     float3 normals[3], next_normals[3];
96     motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
97     motion_triangle_normals_for_step(
98         kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals);
99     /* Interpolate between steps. */
100     normals[0] = (1.0f - t) * normals[0] + t * next_normals[0];
101     normals[1] = (1.0f - t) * normals[1] + t * next_normals[1];
102     normals[2] = (1.0f - t) * normals[2] + t * next_normals[2];
103     /* Interpolate between vertices. */
104     float u = sd->u;
105     float v = sd->v;
106     float w = 1.0f - u - v;
107     sd->N = (u * normals[0] + v * normals[1] + w * normals[2]);
108   }
109 }
110
111 CCL_NAMESPACE_END