Blender V5.0
motion_triangle.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5/* Motion Triangle Primitive
6 *
7 * These are stored as regular triangles, plus extra positions and normals at
8 * times other than the frame center. Computing the triangle vertex positions
9 * or normals at a given ray time is a matter of interpolation of the two steps
10 * between which the ray time lies.
11 *
12 * The extra positions and normals are stored as ATTR_STD_MOTION_VERTEX_POSITION
13 * and ATTR_STD_MOTION_VERTEX_NORMAL mesh attributes.
14 */
15
16#pragma once
17
18#include "kernel/bvh/util.h"
19
21
23
24/* Time interpolation of vertex positions and normals */
25
27 const uint3 tri_vindex,
28 int offset,
29 const int numverts,
30 const int numsteps,
31 int step,
32 float3 verts[3])
33{
34 if (step == numsteps) {
35 /* center step: regular vertex location */
36 verts[0] = kernel_data_fetch(tri_verts, tri_vindex.x);
37 verts[1] = kernel_data_fetch(tri_verts, tri_vindex.y);
38 verts[2] = kernel_data_fetch(tri_verts, tri_vindex.z);
39 }
40 else {
41 /* center step not store in this array */
42 if (step > numsteps) {
43 step--;
44 }
45
46 offset += step * numverts;
47
48 verts[0] = kernel_data_fetch(attributes_float3, offset + tri_vindex.x);
49 verts[1] = kernel_data_fetch(attributes_float3, offset + tri_vindex.y);
50 verts[2] = kernel_data_fetch(attributes_float3, offset + tri_vindex.z);
51 }
52}
53
55 const uint3 tri_vindex,
56 int offset,
57 const int numverts,
58 const int numsteps,
59 int step,
60 float3 normals[3])
61{
62 if (step == numsteps) {
63 /* center step: regular vertex location */
64 normals[0] = kernel_data_fetch(tri_vnormal, tri_vindex.x);
65 normals[1] = kernel_data_fetch(tri_vnormal, tri_vindex.y);
66 normals[2] = kernel_data_fetch(tri_vnormal, tri_vindex.z);
67 }
68 else {
69 /* center step is not stored in this array */
70 if (step > numsteps) {
71 step--;
72 }
73
74 offset += step * numverts;
75
76 normals[0] = kernel_data_fetch(attributes_float3, offset + tri_vindex.x);
77 normals[1] = kernel_data_fetch(attributes_float3, offset + tri_vindex.y);
78 normals[2] = kernel_data_fetch(attributes_float3, offset + tri_vindex.z);
79 }
80}
81
83 const int object,
84 const float time,
85 const int prim,
86 ccl_private uint3 *tri_vindex,
87 ccl_private int *numsteps,
88 ccl_private int *step,
89 ccl_private float *t)
90{
91 /* Get object motion info. */
92 *numsteps = kernel_data_fetch(objects, object).num_geom_steps;
93
94 /* Figure out which steps we need to fetch and their interpolation factor. */
95 const int maxstep = *numsteps * 2;
96 *step = min((int)(time * maxstep), maxstep - 1);
97 *t = time * maxstep - *step;
98
99 /* Get triangle indices. */
100 *tri_vindex = kernel_data_fetch(tri_vindex, prim);
101}
102
104 const int object,
105 const uint3 tri_vindex,
106 const int numsteps,
107 const int numverts,
108 const int step,
109 const float t,
110 float3 verts[3])
111{
112 /* Find attribute. */
113 const int offset = intersection_find_attribute(kg, object, ATTR_STD_MOTION_VERTEX_POSITION);
115
116 /* Fetch vertex coordinates. */
117 float3 next_verts[3];
118 motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
119 motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
120
121 /* Interpolate between steps. */
122 verts[0] = (1.0f - t) * verts[0] + t * next_verts[0];
123 verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
124 verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
125}
126
128 KernelGlobals kg, const int object, const int prim, const float time, float3 verts[3])
129{
130 int numsteps;
131 int step;
132 float t;
133 uint3 tri_vindex;
134 motion_triangle_compute_info(kg, object, time, prim, &tri_vindex, &numsteps, &step, &t);
135
136 const int numverts = kernel_data_fetch(objects, object).numverts;
137 motion_triangle_vertices(kg, object, tri_vindex, numsteps, numverts, step, t, verts);
138}
139
141 const int object,
142 const uint3 tri_vindex,
143 const int numsteps,
144 const int numverts,
145 const int step,
146 const float t,
147 float3 normals[3])
148{
149 /* Find attribute. */
150 const int offset = intersection_find_attribute(kg, object, ATTR_STD_MOTION_VERTEX_NORMAL);
152
153 /* Fetch normals. */
154 float3 next_normals[3];
155 motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
157 kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals);
158
159 /* Interpolate between steps. */
160 normals[0] = normalize((1.0f - t) * normals[0] + t * next_normals[0]);
161 normals[1] = normalize((1.0f - t) * normals[1] + t * next_normals[1]);
162 normals[2] = normalize((1.0f - t) * normals[2] + t * next_normals[2]);
163}
164
166 const int object,
167 const int prim,
168 const float time,
169 float3 verts[3],
170 float3 normals[3])
171{
172 int numsteps;
173 int step;
174 float t;
175 uint3 tri_vindex;
176 motion_triangle_compute_info(kg, object, time, prim, &tri_vindex, &numsteps, &step, &t);
177
178 const int numverts = kernel_data_fetch(objects, object).numverts;
179 motion_triangle_vertices(kg, object, tri_vindex, numsteps, numverts, step, t, verts);
180 motion_triangle_normals(kg, object, tri_vindex, numsteps, numverts, step, t, normals);
181}
182
184 const float3 Ng,
185 const int object,
186 const uint3 tri_vindex,
187 const int numsteps,
188 const int step,
189 const float t,
190 const float u,
191 const float v)
192{
193 float3 normals[3];
194 const int numverts = kernel_data_fetch(objects, object).numverts;
195 motion_triangle_normals(kg, object, tri_vindex, numsteps, numverts, step, t, normals);
196
197 /* Interpolate between normals. */
198 const float w = 1.0f - u - v;
199 const float3 N = safe_normalize(w * normals[0] + u * normals[1] + v * normals[2]);
200
201 return is_zero(N) ? Ng : N;
202}
203
205 const float3 Ng,
206 const int object,
207 const int prim,
208 const float u,
209 float v,
210 const float time)
211{
212 int numsteps;
213 int step;
214 float t;
215 uint3 tri_vindex;
216 motion_triangle_compute_info(kg, object, time, prim, &tri_vindex, &numsteps, &step, &t);
217
218 return motion_triangle_smooth_normal(kg, Ng, object, tri_vindex, numsteps, step, t, u, v);
219}
220
221/* Compute motion triangle normals at the hit position, and offsetted positions in x and y
222 * direction for bump mapping. */
224 const float3 Ng,
225 const int object,
226 const int prim,
227 const float time,
228 const float u,
229 const float v,
230 const differential du,
231 const differential dv,
232 ccl_private float3 &N_x,
233 ccl_private float3 &N_y)
234{
235 int numsteps, step;
236 float t;
237 uint3 tri_vindex;
238 motion_triangle_compute_info(kg, object, time, prim, &tri_vindex, &numsteps, &step, &t);
239
240 float3 n[3];
241 const int numverts = kernel_data_fetch(objects, object).numverts;
242 motion_triangle_normals(kg, object, tri_vindex, numsteps, numverts, step, t, n);
243
244 const float3 N = safe_normalize(triangle_interpolate(u, v, n[0], n[1], n[2]));
245 N_x = safe_normalize(triangle_interpolate(u + du.dx, v + dv.dx, n[0], n[1], n[2]));
246 N_y = safe_normalize(triangle_interpolate(u + du.dy, v + dv.dy, n[0], n[1], n[2]));
247
248 N_x = is_zero(N_x) ? Ng : N_x;
249 N_y = is_zero(N_y) ? Ng : N_y;
250 return is_zero(N) ? Ng : N;
251}
252
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
ccl_device_inline int intersection_find_attribute(KernelGlobals kg, const int object, const uint id)
#define kernel_assert(cond)
#define kernel_data_fetch(name, index)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
CCL_NAMESPACE_BEGIN ccl_device_inline T triangle_interpolate(const float u, const float v, const T f0, const T f1, const T f2)
static float verts[][3]
static float normals[][3]
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
@ ATTR_STD_MOTION_VERTEX_NORMAL
@ ATTR_STD_NOT_FOUND
@ ATTR_STD_MOTION_VERTEX_POSITION
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float2 safe_normalize(const float2 a)
#define N
ccl_device_inline void motion_triangle_vertices(KernelGlobals kg, const int object, const uint3 tri_vindex, const int numsteps, const int numverts, const int step, const float t, float3 verts[3])
ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals kg, const uint3 tri_vindex, int offset, const int numverts, const int numsteps, int step, float3 normals[3])
ccl_device_inline void motion_triangle_compute_info(KernelGlobals kg, const int object, const float time, const int prim, ccl_private uint3 *tri_vindex, ccl_private int *numsteps, ccl_private int *step, ccl_private float *t)
CCL_NAMESPACE_BEGIN ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals kg, const uint3 tri_vindex, int offset, const int numverts, const int numsteps, int step, float3 verts[3])
ccl_device_inline void motion_triangle_vertices_and_normals(KernelGlobals kg, const int object, const int prim, const float time, float3 verts[3], float3 normals[3])
ccl_device_inline void motion_triangle_normals(KernelGlobals kg, const int object, const uint3 tri_vindex, const int numsteps, const int numverts, const int step, const float t, float3 normals[3])
ccl_device_inline float3 motion_triangle_smooth_normal(KernelGlobals kg, const float3 Ng, const int object, const uint3 tri_vindex, const int numsteps, const int step, const float t, const float u, const float v)
#define min(a, b)
Definition sort.cc:36
uint y
Definition types_uint3.h:13
uint z
Definition types_uint3.h:13
uint x
Definition types_uint3.h:13