Blender  V3.3
motion_triangle.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 /* Motion Triangle Primitive
5  *
6  * These are stored as regular triangles, plus extra positions and normals at
7  * times other than the frame center. Computing the triangle vertex positions
8  * or normals at a given ray time is a matter of interpolation of the two steps
9  * between which the ray time lies.
10  *
11  * The extra positions and normals are stored as ATTR_STD_MOTION_VERTEX_POSITION
12  * and ATTR_STD_MOTION_VERTEX_NORMAL mesh attributes.
13  */
14 
15 #pragma once
16 
17 #include "kernel/bvh/util.h"
18 
20 
21 /* Time interpolation of vertex positions and normals */
22 
24  uint4 tri_vindex,
25  int offset,
26  int numverts,
27  int numsteps,
28  int step,
29  float3 verts[3])
30 {
31  if (step == numsteps) {
32  /* center step: regular vertex location */
33  verts[0] = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
34  verts[1] = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
35  verts[2] = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
36  }
37  else {
38  /* center step not store in this array */
39  if (step > numsteps)
40  step--;
41 
42  offset += step * numverts;
43 
44  verts[0] = kernel_data_fetch(attributes_float3, offset + tri_vindex.x);
45  verts[1] = kernel_data_fetch(attributes_float3, offset + tri_vindex.y);
46  verts[2] = kernel_data_fetch(attributes_float3, offset + tri_vindex.z);
47  }
48 }
49 
51  uint4 tri_vindex,
52  int offset,
53  int numverts,
54  int numsteps,
55  int step,
56  float3 normals[3])
57 {
58  if (step == numsteps) {
59  /* center step: regular vertex location */
60  normals[0] = kernel_data_fetch(tri_vnormal, tri_vindex.x);
61  normals[1] = kernel_data_fetch(tri_vnormal, tri_vindex.y);
62  normals[2] = kernel_data_fetch(tri_vnormal, tri_vindex.z);
63  }
64  else {
65  /* center step is not stored in this array */
66  if (step > numsteps)
67  step--;
68 
69  offset += step * numverts;
70 
71  normals[0] = kernel_data_fetch(attributes_float3, offset + tri_vindex.x);
72  normals[1] = kernel_data_fetch(attributes_float3, offset + tri_vindex.y);
73  normals[2] = kernel_data_fetch(attributes_float3, offset + tri_vindex.z);
74  }
75 }
76 
78  KernelGlobals kg, int object, int prim, float time, float3 verts[3])
79 {
80  /* get motion info */
81  int numsteps, numverts;
82  object_motion_info(kg, object, &numsteps, &numverts, NULL);
83 
84  /* figure out which steps we need to fetch and their interpolation factor */
85  int maxstep = numsteps * 2;
86  int step = min((int)(time * maxstep), maxstep - 1);
87  float t = time * maxstep - step;
88 
89  /* find attribute */
92 
93  /* fetch vertex coordinates */
94  float3 next_verts[3];
95  uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
96 
97  motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
98  motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
99 
100  /* interpolate between steps */
101  verts[0] = (1.0f - t) * verts[0] + t * next_verts[0];
102  verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
103  verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
104 }
105 
107  KernelGlobals kg, int object, int prim, float time, float3 verts[3], float3 normals[3])
108 {
109  /* get motion info */
110  int numsteps, numverts;
111  object_motion_info(kg, object, &numsteps, &numverts, NULL);
112 
113  /* Figure out which steps we need to fetch and their interpolation factor. */
114  int maxstep = numsteps * 2;
115  int step = min((int)(time * maxstep), maxstep - 1);
116  float t = time * maxstep - step;
117 
118  /* Find attribute. */
121 
122  /* Fetch vertex coordinates. */
123  float3 next_verts[3];
124  uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
125 
126  motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
127  motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
128 
129  /* Interpolate between steps. */
130  verts[0] = (1.0f - t) * verts[0] + t * next_verts[0];
131  verts[1] = (1.0f - t) * verts[1] + t * next_verts[1];
132  verts[2] = (1.0f - t) * verts[2] + t * next_verts[2];
133 
134  /* Compute smooth normal. */
135 
136  /* Find attribute. */
139 
140  /* Fetch vertex coordinates. */
141  float3 next_normals[3];
142  motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
144  kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals);
145 
146  /* Interpolate between steps. */
147  normals[0] = (1.0f - t) * normals[0] + t * next_normals[0];
148  normals[1] = (1.0f - t) * normals[1] + t * next_normals[1];
149  normals[2] = (1.0f - t) * normals[2] + t * next_normals[2];
150 }
151 
153  KernelGlobals kg, float3 Ng, int object, int prim, float u, float v, float time)
154 {
155  /* get motion info */
156  int numsteps, numverts;
157  object_motion_info(kg, object, &numsteps, &numverts, NULL);
158 
159  /* figure out which steps we need to fetch and their interpolation factor */
160  int maxstep = numsteps * 2;
161  int step = min((int)(time * maxstep), maxstep - 1);
162  float t = time * maxstep - step;
163 
164  /* find attribute */
167 
168  /* fetch normals */
169  float3 normals[3], next_normals[3];
170  uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
171 
172  motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
174  kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals);
175 
176  /* interpolate between steps */
177  normals[0] = (1.0f - t) * normals[0] + t * next_normals[0];
178  normals[1] = (1.0f - t) * normals[1] + t * next_normals[1];
179  normals[2] = (1.0f - t) * normals[2] + t * next_normals[2];
180 
181  /* interpolate between vertices */
182  float w = 1.0f - u - v;
183  float3 N = safe_normalize(u * normals[0] + v * normals[1] + w * normals[2]);
184 
185  return is_zero(N) ? Ng : N;
186 }
187 
_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
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
#define kernel_assert(cond)
Definition: cpu/compat.h:34
#define ccl_device_inline
Definition: cuda/compat.h:34
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
ccl_device_inline int intersection_find_attribute(KernelGlobals kg, const int object, const uint id)
double time
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
static float verts[][3]
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_device_inline void object_motion_info(KernelGlobals kg, int object, ccl_private int *numsteps, ccl_private int *numverts, ccl_private int *numkeys)
@ ATTR_STD_MOTION_VERTEX_NORMAL
Definition: kernel/types.h:625
@ ATTR_STD_NOT_FOUND
Definition: kernel/types.h:647
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel/types.h:624
ccl_device_inline float2 safe_normalize(const float2 &a)
Definition: math_float2.h:201
#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_NAMESPACE_BEGIN 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 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_normals_for_step(KernelGlobals kg, uint4 tri_vindex, int offset, int numverts, int numsteps, int step, float3 normals[3])
ccl_device_inline void motion_triangle_vertices(KernelGlobals kg, int object, int prim, float time, float3 verts[3])
bool is_zero(const T &a)
MutableSpan< float3 > normals
#define min(a, b)
Definition: sort.c:35
uint x
Definition: types_uint4.h:15
uint y
Definition: types_uint4.h:15
uint z
Definition: types_uint4.h:15
uint w
Definition: types_uint4.h:15