blender/intern/cycles/kernel/geom/motion_curve.h
Brecht Van Lommel 9cfc7967dd Cycles: use SPDX license headers
* Replace license text in headers with SPDX identifiers.
* Remove specific license info from outdated readme.txt, instead leave details
  to the source files.
* Add list of SPDX license identifiers used, and corresponding license texts.
* Update copyright dates while we're at it.

Ref D14069, T95597
2022-02-11 17:47:34 +01:00

145 lines
5.2 KiB
C

/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#pragma once
CCL_NAMESPACE_BEGIN
/* Motion Curve Primitive
*
* These are stored as regular curves, plus extra positions and radii at times
* other than the frame center. Computing the curve keys at a given ray time is
* a matter of interpolation of the two steps between which the ray time lies.
*
* The extra curve keys are stored as ATTR_STD_MOTION_VERTEX_POSITION.
*/
#ifdef __HAIR__
ccl_device_inline void motion_curve_keys_for_step_linear(KernelGlobals kg,
int offset,
int numkeys,
int numsteps,
int step,
int k0,
int k1,
float4 keys[2])
{
if (step == numsteps) {
/* center step: regular key location */
keys[0] = kernel_tex_fetch(__curve_keys, k0);
keys[1] = kernel_tex_fetch(__curve_keys, k1);
}
else {
/* center step is not stored in this array */
if (step > numsteps)
step--;
offset += step * numkeys;
keys[0] = kernel_tex_fetch(__attributes_float4, offset + k0);
keys[1] = kernel_tex_fetch(__attributes_float4, offset + k1);
}
}
/* return 2 curve key locations */
ccl_device_inline void motion_curve_keys_linear(
KernelGlobals kg, int object, int prim, float time, int k0, int k1, float4 keys[2])
{
/* get motion info */
int numsteps, numkeys;
object_motion_info(kg, object, &numsteps, NULL, &numkeys);
/* figure out which steps we need to fetch and their interpolation factor */
const int maxstep = numsteps * 2;
const int step = min((int)(time * maxstep), maxstep - 1);
const float t = time * maxstep - step;
/* find attribute */
const int offset = intersection_find_attribute(kg, object, ATTR_STD_MOTION_VERTEX_POSITION);
kernel_assert(offset != ATTR_STD_NOT_FOUND);
/* fetch key coordinates */
float4 next_keys[2];
motion_curve_keys_for_step_linear(kg, offset, numkeys, numsteps, step, k0, k1, keys);
motion_curve_keys_for_step_linear(kg, offset, numkeys, numsteps, step + 1, k0, k1, next_keys);
/* interpolate between steps */
keys[0] = (1.0f - t) * keys[0] + t * next_keys[0];
keys[1] = (1.0f - t) * keys[1] + t * next_keys[1];
}
ccl_device_inline void motion_curve_keys_for_step(KernelGlobals kg,
int offset,
int numkeys,
int numsteps,
int step,
int k0,
int k1,
int k2,
int k3,
float4 keys[4])
{
if (step == numsteps) {
/* center step: regular key location */
keys[0] = kernel_tex_fetch(__curve_keys, k0);
keys[1] = kernel_tex_fetch(__curve_keys, k1);
keys[2] = kernel_tex_fetch(__curve_keys, k2);
keys[3] = kernel_tex_fetch(__curve_keys, k3);
}
else {
/* center step is not stored in this array */
if (step > numsteps)
step--;
offset += step * numkeys;
keys[0] = kernel_tex_fetch(__attributes_float4, offset + k0);
keys[1] = kernel_tex_fetch(__attributes_float4, offset + k1);
keys[2] = kernel_tex_fetch(__attributes_float4, offset + k2);
keys[3] = kernel_tex_fetch(__attributes_float4, offset + k3);
}
}
/* return 2 curve key locations */
ccl_device_inline void motion_curve_keys(KernelGlobals kg,
int object,
int prim,
float time,
int k0,
int k1,
int k2,
int k3,
float4 keys[4])
{
/* get motion info */
int numsteps, numkeys;
object_motion_info(kg, object, &numsteps, NULL, &numkeys);
/* figure out which steps we need to fetch and their interpolation factor */
const int maxstep = numsteps * 2;
const int step = min((int)(time * maxstep), maxstep - 1);
const float t = time * maxstep - step;
/* find attribute */
const int offset = intersection_find_attribute(kg, object, ATTR_STD_MOTION_VERTEX_POSITION);
kernel_assert(offset != ATTR_STD_NOT_FOUND);
/* fetch key coordinates */
float4 next_keys[4];
motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys);
motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step + 1, k0, k1, k2, k3, next_keys);
/* interpolate between steps */
keys[0] = (1.0f - t) * keys[0] + t * next_keys[0];
keys[1] = (1.0f - t) * keys[1] + t * next_keys[1];
keys[2] = (1.0f - t) * keys[2] + t * next_keys[2];
keys[3] = (1.0f - t) * keys[3] + t * next_keys[3];
}
#endif
CCL_NAMESPACE_END