Blender  V2.93
geom_motion_triangle.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* Motion Triangle Primitive
18  *
19  * These are stored as regular triangles, plus extra positions and normals at
20  * times other than the frame center. Computing the triangle vertex positions
21  * or normals at a given ray time is a matter of interpolation of the two steps
22  * between which the ray time lies.
23  *
24  * The extra positions and normals are stored as ATTR_STD_MOTION_VERTEX_POSITION
25  * and ATTR_STD_MOTION_VERTEX_NORMAL mesh attributes.
26  */
27 
29 
30 /* Time interpolation of vertex positions and normals */
31 
33  int object,
34  uint id,
35  AttributeElement *elem)
36 {
37  /* todo: find a better (faster) solution for this, maybe store offset per object */
38  uint attr_offset = object_attribute_map_offset(kg, object);
39  uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
40 
41  while (attr_map.x != id) {
42  if (UNLIKELY(attr_map.x == ATTR_STD_NONE)) {
43  if (UNLIKELY(attr_map.y == 0)) {
44  return (int)ATTR_STD_NOT_FOUND;
45  }
46  else {
47  /* Chain jump to a different part of the table. */
48  attr_offset = attr_map.z;
49  }
50  }
51  else {
52  attr_offset += ATTR_PRIM_TYPES;
53  }
54  attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
55  }
56 
57  *elem = (AttributeElement)attr_map.y;
58 
59  /* return result */
60  return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
61 }
62 
64  uint4 tri_vindex,
65  int offset,
66  int numverts,
67  int numsteps,
68  int step,
69  float3 verts[3])
70 {
71  if (step == numsteps) {
72  /* center step: regular vertex location */
73  verts[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 0));
74  verts[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 1));
75  verts[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w + 2));
76  }
77  else {
78  /* center step not store in this array */
79  if (step > numsteps)
80  step--;
81 
82  offset += step * numverts;
83 
84  verts[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x));
85  verts[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y));
86  verts[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z));
87  }
88 }
89 
91  uint4 tri_vindex,
92  int offset,
93  int numverts,
94  int numsteps,
95  int step,
96  float3 normals[3])
97 {
98  if (step == numsteps) {
99  /* center step: regular vertex location */
100  normals[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
101  normals[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
102  normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
103  }
104  else {
105  /* center step is not stored in this array */
106  if (step > numsteps)
107  step--;
108 
109  offset += step * numverts;
110 
111  normals[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x));
112  normals[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y));
113  normals[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z));
114  }
115 }
116 
118  KernelGlobals *kg, int object, int prim, float time, float3 verts[3])
119 {
120  /* get motion info */
121  int numsteps, numverts;
122  object_motion_info(kg, object, &numsteps, &numverts, NULL);
123 
124  /* figure out which steps we need to fetch and their interpolation factor */
125  int maxstep = numsteps * 2;
126  int step = min((int)(time * maxstep), maxstep - 1);
127  float t = time * maxstep - step;
128 
129  /* find attribute */
130  AttributeElement elem;
131  int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem);
133 
134  /* fetch vertex coordinates */
135  float3 next_verts[3];
136  uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
137 
138  motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
139  motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
140 
141  /* interpolate between steps */
142  verts[0] = (1.0f - t) * verts[0] + t * next_verts[0];
143  verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
144  verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
145 }
146 
148  KernelGlobals *kg, float3 Ng, int object, int prim, float u, float v, float time)
149 {
150  /* get motion info */
151  int numsteps, numverts;
152  object_motion_info(kg, object, &numsteps, &numverts, NULL);
153 
154  /* figure out which steps we need to fetch and their interpolation factor */
155  int maxstep = numsteps * 2;
156  int step = min((int)(time * maxstep), maxstep - 1);
157  float t = time * maxstep - step;
158 
159  /* find attribute */
160  AttributeElement elem;
161  int offset = find_attribute_motion(kg, object, ATTR_STD_MOTION_VERTEX_NORMAL, &elem);
163 
164  /* fetch normals */
165  float3 normals[3], next_normals[3];
166  uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
167 
168  motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
170  kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals);
171 
172  /* interpolate between steps */
173  normals[0] = (1.0f - t) * normals[0] + t * next_normals[0];
174  normals[1] = (1.0f - t) * normals[1] + t * next_normals[1];
175  normals[2] = (1.0f - t) * normals[2] + t * next_normals[2];
176 
177  /* interpolate between vertices */
178  float w = 1.0f - u - v;
179  float3 N = safe_normalize(u * normals[0] + v * normals[1] + w * normals[2]);
180 
181  return is_zero(N) ? Ng : N;
182 }
183 
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNLIKELY(x)
_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
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
double time
static float verts[][3]
static float normals[][3]
ccl_device_inline uint object_attribute_map_offset(KernelGlobals *kg, int object)
ccl_device_inline void motion_triangle_vertices(KernelGlobals *kg, int object, int prim, float time, float3 verts[3])
CCL_NAMESPACE_BEGIN ccl_device_inline int find_attribute_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals *kg, uint4 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3])
ccl_device_inline float3 motion_triangle_smooth_normal(KernelGlobals *kg, float3 Ng, int object, int prim, float u, float v, float time)
ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg, uint4 tri_vindex, int offset, int numverts, int numsteps, int step, float3 verts[3])
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_MOTION_VERTEX_NORMAL
Definition: kernel_types.h:757
@ ATTR_STD_NOT_FOUND
Definition: kernel_types.h:773
@ ATTR_STD_NONE
Definition: kernel_types.h:745
@ 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
params N
#define min(a, b)
Definition: sort.c:51
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition: util_math.h:415
ccl_device_inline float2 safe_normalize(const float2 &a)
ccl_device_inline bool is_zero(const float2 &a)