Blender V5.0
motion_curve.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#pragma once
6
7#include "kernel/globals.h"
8
9#include "kernel/bvh/util.h"
10
12
13/* Motion Curve Primitive
14 *
15 * These are stored as regular curves, plus extra positions and radii at times
16 * other than the frame center. Computing the curve keys at a given ray time is
17 * a matter of interpolation of the two steps between which the ray time lies.
18 *
19 * The extra curve keys are stored as ATTR_STD_MOTION_VERTEX_POSITION.
20 */
21
22#ifdef __HAIR__
23
24ccl_device_inline void motion_curve_keys_for_step_linear(KernelGlobals kg,
25 int offset,
26 const int numverts,
27 const int numsteps,
28 int step,
29 const int k0,
30 const int k1,
31 float4 keys[2])
32{
33 if (step == numsteps) {
34 /* center step: regular key location */
35 keys[0] = kernel_data_fetch(curve_keys, k0);
36 keys[1] = kernel_data_fetch(curve_keys, k1);
37 }
38 else {
39 /* center step is not stored in this array */
40 if (step > numsteps) {
41 step--;
42 }
43
44 offset += step * numverts;
45
46 keys[0] = kernel_data_fetch(attributes_float4, offset + k0);
47 keys[1] = kernel_data_fetch(attributes_float4, offset + k1);
48 }
49}
50
51/* return 2 curve key locations */
52ccl_device_inline void motion_curve_keys_linear(KernelGlobals kg,
53 const int object,
54 const float time,
55 const int k0,
56 const int k1,
57 float4 keys[2])
58{
59 /* get motion info */
60 const int numsteps = kernel_data_fetch(objects, object).num_geom_steps;
61 const int numverts = kernel_data_fetch(objects, object).numverts;
62
63 /* figure out which steps we need to fetch and their interpolation factor */
64 const int maxstep = numsteps * 2;
65 const int step = min((int)(time * maxstep), maxstep - 1);
66 const float t = time * maxstep - step;
67
68 /* find attribute */
71
72 /* fetch key coordinates */
73 float4 next_keys[2];
74
75 motion_curve_keys_for_step_linear(kg, offset, numverts, numsteps, step, k0, k1, keys);
76 motion_curve_keys_for_step_linear(kg, offset, numverts, numsteps, step + 1, k0, k1, next_keys);
77
78 /* interpolate between steps */
79 keys[0] = (1.0f - t) * keys[0] + t * next_keys[0];
80 keys[1] = (1.0f - t) * keys[1] + t * next_keys[1];
81}
82
83ccl_device_inline void motion_curve_keys_for_step(KernelGlobals kg,
84 int offset,
85 const int numverts,
86 const int numsteps,
87 int step,
88 const int k0,
89 const int k1,
90 const int k2,
91 const int k3,
92 float4 keys[4])
93{
94 if (step == numsteps) {
95 /* center step: regular key location */
96 keys[0] = kernel_data_fetch(curve_keys, k0);
97 keys[1] = kernel_data_fetch(curve_keys, k1);
98 keys[2] = kernel_data_fetch(curve_keys, k2);
99 keys[3] = kernel_data_fetch(curve_keys, k3);
100 }
101 else {
102 /* center step is not stored in this array */
103 if (step > numsteps) {
104 step--;
105 }
106
107 offset += step * numverts;
108
109 keys[0] = kernel_data_fetch(attributes_float4, offset + k0);
110 keys[1] = kernel_data_fetch(attributes_float4, offset + k1);
111 keys[2] = kernel_data_fetch(attributes_float4, offset + k2);
112 keys[3] = kernel_data_fetch(attributes_float4, offset + k3);
113 }
114}
115
116/* return 2 curve key locations */
117ccl_device_inline void motion_curve_keys(KernelGlobals kg,
118 const int object,
119 const float time,
120 const int k0,
121 const int k1,
122 const int k2,
123 const int k3,
124 float4 keys[4])
125{
126 /* get motion info */
127 const int numsteps = kernel_data_fetch(objects, object).num_geom_steps;
128 const int numverts = kernel_data_fetch(objects, object).numverts;
129
130 /* figure out which steps we need to fetch and their interpolation factor */
131 const int maxstep = numsteps * 2;
132 const int step = min((int)(time * maxstep), maxstep - 1);
133 const float t = time * maxstep - step;
134
135 /* find attribute */
136 const int offset = intersection_find_attribute(kg, object, ATTR_STD_MOTION_VERTEX_POSITION);
138
139 /* fetch key coordinates */
140 float4 next_keys[4];
141
142 motion_curve_keys_for_step(kg, offset, numverts, numsteps, step, k0, k1, k2, k3, keys);
143 motion_curve_keys_for_step(kg, offset, numverts, numsteps, step + 1, k0, k1, k2, k3, next_keys);
144
145 /* interpolate between steps */
146 keys[0] = (1.0f - t) * keys[0] + t * next_keys[0];
147 keys[1] = (1.0f - t) * keys[1] + t * next_keys[1];
148 keys[2] = (1.0f - t) * keys[2] + t * next_keys[2];
149 keys[3] = (1.0f - t) * keys[3] + t * next_keys[3];
150}
151
152#endif
153
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)
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
@ ATTR_STD_NOT_FOUND
@ ATTR_STD_MOTION_VERTEX_POSITION
#define min(a, b)
Definition sort.cc:36