Blender V4.3
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
22/* Time interpolation of vertex positions and normals */
23
25 uint3 tri_vindex,
26 int offset,
27 int numverts,
28 int numsteps,
29 int step,
30 float3 verts[3])
31{
32 if (step == numsteps) {
33 /* center step: regular vertex location */
34 verts[0] = kernel_data_fetch(tri_verts, tri_vindex.x);
35 verts[1] = kernel_data_fetch(tri_verts, tri_vindex.y);
36 verts[2] = kernel_data_fetch(tri_verts, tri_vindex.z);
37 }
38 else {
39 /* center step not store in this array */
40 if (step > numsteps) {
41 step--;
42 }
43
44 offset += step * numverts;
45
46 verts[0] = kernel_data_fetch(attributes_float3, offset + tri_vindex.x);
47 verts[1] = kernel_data_fetch(attributes_float3, offset + tri_vindex.y);
48 verts[2] = kernel_data_fetch(attributes_float3, offset + tri_vindex.z);
49 }
50}
51
53 uint3 tri_vindex,
54 int offset,
55 int numverts,
56 int numsteps,
57 int step,
58 float3 normals[3])
59{
60 if (step == numsteps) {
61 /* center step: regular vertex location */
62 normals[0] = kernel_data_fetch(tri_vnormal, tri_vindex.x);
63 normals[1] = kernel_data_fetch(tri_vnormal, tri_vindex.y);
64 normals[2] = kernel_data_fetch(tri_vnormal, tri_vindex.z);
65 }
66 else {
67 /* center step is not stored in this array */
68 if (step > numsteps) {
69 step--;
70 }
71
72 offset += step * numverts;
73
74 normals[0] = kernel_data_fetch(attributes_float3, offset + tri_vindex.x);
75 normals[1] = kernel_data_fetch(attributes_float3, offset + tri_vindex.y);
76 normals[2] = kernel_data_fetch(attributes_float3, offset + tri_vindex.z);
77 }
78}
79
81 int object,
82 float time,
83 int prim,
84 ccl_private uint3 *tri_vindex,
85 ccl_private int *numsteps,
86 ccl_private int *step,
87 ccl_private float *t)
88{
89 /* Get object motion info. */
90 *numsteps = kernel_data_fetch(objects, object).numsteps;
91
92 /* Figure out which steps we need to fetch and their interpolation factor. */
93 int maxstep = *numsteps * 2;
94 *step = min((int)(time * maxstep), maxstep - 1);
95 *t = time * maxstep - *step;
96
97 /* Get triangle indices. */
98 *tri_vindex = kernel_data_fetch(tri_vindex, prim);
99}
100
102 int object,
103 uint3 tri_vindex,
104 int numsteps,
105 int numverts,
106 int step,
107 float t,
108 float3 verts[3])
109{
110 /* Find attribute. */
113
114 /* Fetch vertex coordinates. */
115 float3 next_verts[3];
116 motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
117 motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
118
119 /* Interpolate between steps. */
120 verts[0] = (1.0f - t) * verts[0] + t * next_verts[0];
121 verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
122 verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
123}
124
126 KernelGlobals kg, int object, int prim, float time, float3 verts[3])
127{
128 int numsteps, step;
129 float t;
130 uint3 tri_vindex;
131 motion_triangle_compute_info(kg, object, time, prim, &tri_vindex, &numsteps, &step, &t);
132
133 const int numverts = kernel_data_fetch(objects, object).numverts;
134 motion_triangle_vertices(kg, object, tri_vindex, numsteps, numverts, step, t, verts);
135}
136
138 int object,
139 uint3 tri_vindex,
140 int numsteps,
141 int numverts,
142 int step,
143 float t,
144 float3 normals[3])
145{
146 /* Find attribute. */
149
150 /* Fetch normals. */
151 float3 next_normals[3];
152 motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
154 kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals);
155
156 /* Interpolate between steps. */
157 normals[0] = normalize((1.0f - t) * normals[0] + t * next_normals[0]);
158 normals[1] = normalize((1.0f - t) * normals[1] + t * next_normals[1]);
159 normals[2] = normalize((1.0f - t) * normals[2] + t * next_normals[2]);
160}
161
163 KernelGlobals kg, int object, int prim, float time, float3 verts[3], float3 normals[3])
164{
165 int numsteps, step;
166 float t;
167 uint3 tri_vindex;
168 motion_triangle_compute_info(kg, object, time, prim, &tri_vindex, &numsteps, &step, &t);
169
170 const int numverts = kernel_data_fetch(objects, object).numverts;
171 motion_triangle_vertices(kg, object, tri_vindex, numsteps, numverts, step, t, verts);
172 motion_triangle_normals(kg, object, tri_vindex, numsteps, numverts, step, t, normals);
173}
174
176 float3 Ng,
177 int object,
178 uint3 tri_vindex,
179 int numsteps,
180 int step,
181 float t,
182 float u,
183 float v)
184{
185 float3 normals[3];
186 const int numverts = kernel_data_fetch(objects, object).numverts;
187 motion_triangle_normals(kg, object, tri_vindex, numsteps, numverts, step, t, normals);
188
189 /* Interpolate between normals. */
190 float w = 1.0f - u - v;
191 float3 N = safe_normalize(w * normals[0] + u * normals[1] + v * normals[2]);
192
193 return is_zero(N) ? Ng : N;
194}
195
197 KernelGlobals kg, float3 Ng, int object, int prim, float u, float v, float time)
198{
199 int numsteps, step;
200 float t;
201 uint3 tri_vindex;
202 motion_triangle_compute_info(kg, object, time, prim, &tri_vindex, &numsteps, &step, &t);
203
204 return motion_triangle_smooth_normal(kg, Ng, object, tri_vindex, numsteps, step, t, u, v);
205}
206
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
ccl_device_inline int intersection_find_attribute(KernelGlobals kg, const int object, const uint id)
#define kernel_assert(cond)
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_private
#define ccl_device_inline
#define CCL_NAMESPACE_END
static float verts[][3]
@ 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_and_normals(KernelGlobals kg, int object, int prim, float time, float3 verts[3], float3 normals[3])
ccl_device_inline float3 motion_triangle_smooth_normal(KernelGlobals kg, float3 Ng, int object, uint3 tri_vindex, int numsteps, int step, float t, float u, float v)
ccl_device_inline void motion_triangle_normals(KernelGlobals kg, int object, uint3 tri_vindex, int numsteps, int numverts, int step, float t, float3 normals[3])
ccl_device_inline void motion_triangle_vertices(KernelGlobals kg, int object, uint3 tri_vindex, int numsteps, int numverts, int step, float t, float3 verts[3])
CCL_NAMESPACE_BEGIN ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals kg, uint3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 verts[3])
ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals kg, uint3 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3])
ccl_device_inline void motion_triangle_compute_info(KernelGlobals kg, int object, float time, int prim, ccl_private uint3 *tri_vindex, ccl_private int *numsteps, ccl_private int *step, ccl_private float *t)
#define min(a, b)
Definition sort.c:32
uint y
Definition types_uint3.h:15
uint z
Definition types_uint3.h:15
uint x
Definition types_uint3.h:15