Blender  V2.93
geom_motion_curve.h
Go to the documentation of this file.
1 /*
2  * Licensed under the Apache License, Version 2.0 (the "License");
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 
16 
17 /* Motion Curve Primitive
18  *
19  * These are stored as regular curves, plus extra positions and radii at times
20  * other than the frame center. Computing the curve keys at a given ray time is
21  * a matter of interpolation of the two steps between which the ray time lies.
22  *
23  * The extra curve keys are stored as ATTR_STD_MOTION_VERTEX_POSITION.
24  */
25 
26 #ifdef __HAIR__
27 
28 ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg,
29  int object,
30  uint id,
31  AttributeElement *elem)
32 {
33  /* todo: find a better (faster) solution for this, maybe store offset per object.
34  *
35  * NOTE: currently it's not a bottleneck because in test scenes the loop below runs
36  * zero iterations and rendering is really slow with motion curves. For until other
37  * areas are speed up it's probably not so crucial to optimize this out.
38  */
39  uint attr_offset = object_attribute_map_offset(kg, object) + ATTR_PRIM_GEOMETRY;
40  uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
41 
42  while (attr_map.x != id) {
43  attr_offset += ATTR_PRIM_TYPES;
44  attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
45  }
46 
47  *elem = (AttributeElement)attr_map.y;
48 
49  /* return result */
50  return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
51 }
52 
53 ccl_device_inline void motion_curve_keys_for_step_linear(KernelGlobals *kg,
54  int offset,
55  int numkeys,
56  int numsteps,
57  int step,
58  int k0,
59  int k1,
60  float4 keys[2])
61 {
62  if (step == numsteps) {
63  /* center step: regular key location */
64  keys[0] = kernel_tex_fetch(__curve_keys, k0);
65  keys[1] = kernel_tex_fetch(__curve_keys, k1);
66  }
67  else {
68  /* center step is not stored in this array */
69  if (step > numsteps)
70  step--;
71 
72  offset += step * numkeys;
73 
74  keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
75  keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
76  }
77 }
78 
79 /* return 2 curve key locations */
80 ccl_device_inline void motion_curve_keys_linear(
81  KernelGlobals *kg, int object, int prim, float time, int k0, int k1, float4 keys[2])
82 {
83  /* get motion info */
84  int numsteps, numkeys;
85  object_motion_info(kg, object, &numsteps, NULL, &numkeys);
86 
87  /* figure out which steps we need to fetch and their interpolation factor */
88  int maxstep = numsteps * 2;
89  int step = min((int)(time * maxstep), maxstep - 1);
90  float t = time * maxstep - step;
91 
92  /* find attribute */
93  AttributeElement elem;
94  int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
96 
97  /* fetch key coordinates */
98  float4 next_keys[2];
99 
100  motion_curve_keys_for_step_linear(kg, offset, numkeys, numsteps, step, k0, k1, keys);
101  motion_curve_keys_for_step_linear(kg, offset, numkeys, numsteps, step + 1, k0, k1, next_keys);
102 
103  /* interpolate between steps */
104  keys[0] = (1.0f - t) * keys[0] + t * next_keys[0];
105  keys[1] = (1.0f - t) * keys[1] + t * next_keys[1];
106 }
107 
108 ccl_device_inline void motion_curve_keys_for_step(KernelGlobals *kg,
109  int offset,
110  int numkeys,
111  int numsteps,
112  int step,
113  int k0,
114  int k1,
115  int k2,
116  int k3,
117  float4 keys[4])
118 {
119  if (step == numsteps) {
120  /* center step: regular key location */
121  keys[0] = kernel_tex_fetch(__curve_keys, k0);
122  keys[1] = kernel_tex_fetch(__curve_keys, k1);
123  keys[2] = kernel_tex_fetch(__curve_keys, k2);
124  keys[3] = kernel_tex_fetch(__curve_keys, k3);
125  }
126  else {
127  /* center step is not stored in this array */
128  if (step > numsteps)
129  step--;
130 
131  offset += step * numkeys;
132 
133  keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
134  keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
135  keys[2] = kernel_tex_fetch(__attributes_float3, offset + k2);
136  keys[3] = kernel_tex_fetch(__attributes_float3, offset + k3);
137  }
138 }
139 
140 /* return 2 curve key locations */
141 ccl_device_inline void motion_curve_keys(KernelGlobals *kg,
142  int object,
143  int prim,
144  float time,
145  int k0,
146  int k1,
147  int k2,
148  int k3,
149  float4 keys[4])
150 {
151  /* get motion info */
152  int numsteps, numkeys;
153  object_motion_info(kg, object, &numsteps, NULL, &numkeys);
154 
155  /* figure out which steps we need to fetch and their interpolation factor */
156  int maxstep = numsteps * 2;
157  int step = min((int)(time * maxstep), maxstep - 1);
158  float t = time * maxstep - step;
159 
160  /* find attribute */
161  AttributeElement elem;
162  int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
164 
165  /* fetch key coordinates */
166  float4 next_keys[4];
167 
168  motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys);
169  motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step + 1, k0, k1, k2, k3, next_keys);
170 
171  /* interpolate between steps */
172  keys[0] = (1.0f - t) * keys[0] + t * next_keys[0];
173  keys[1] = (1.0f - t) * keys[1] + t * next_keys[1];
174  keys[2] = (1.0f - t) * keys[2] + t * next_keys[2];
175  keys[3] = (1.0f - t) * keys[3] + t * next_keys[3];
176 }
177 
178 #endif
179 
unsigned int uint
Definition: BLI_sys_types.h:83
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
return(oflags[bm->toolflag_index].f &oflag) !=0
double time
ccl_device_inline uint object_attribute_map_offset(KernelGlobals *kg, int object)
ccl_device_inline void object_motion_info(KernelGlobals *kg, int object, int *numsteps, int *numverts, int *numkeys)
Definition: geom_object.h:293
#define kernel_assert(cond)
#define kernel_tex_fetch(tex, index)
#define ccl_device_inline
#define CCL_NAMESPACE_END
@ ATTR_STD_NOT_FOUND
Definition: kernel_types.h:773
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel_types.h:756
AttributeElement
Definition: kernel_types.h:729
@ ATTR_ELEMENT_NONE
Definition: kernel_types.h:730
@ ATTR_PRIM_TYPES
Definition: kernel_types.h:726
@ ATTR_PRIM_GEOMETRY
Definition: kernel_types.h:723
#define min(a, b)
Definition: sort.c:51