Blender  V3.3
kernel/geom/object.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 /* Object Primitive
5  *
6  * All mesh and curve primitives are part of an object. The same mesh and curves
7  * may be instanced multiple times by different objects.
8  *
9  * If the mesh is not instanced multiple times, the object will not be explicitly
10  * stored as a primitive in the BVH, rather the bare triangles are curved are
11  * directly primitives in the BVH with world space locations applied, and the object
12  * ID is looked up afterwards. */
13 
14 #pragma once
15 
17 
18 /* Object attributes, for now a fixed size and contents */
19 
23 };
24 
26 
27 /* Object to world space transformation */
28 
30  int object,
31  enum ObjectTransform type)
32 {
34  return kernel_data_fetch(objects, object).itfm;
35  }
36  else {
37  return kernel_data_fetch(objects, object).tfm;
38  }
39 }
40 
41 /* Lamp to world space transformation */
42 
44 {
45  if (inverse) {
46  return kernel_data_fetch(lights, lamp).itfm;
47  }
48  else {
49  return kernel_data_fetch(lights, lamp).tfm;
50  }
51 }
52 
53 /* Object to world space transformation for motion vectors */
54 
56  int object,
58 {
59  int offset = object * OBJECT_MOTION_PASS_SIZE + (int)type;
60  return kernel_data_fetch(object_motion_pass, offset);
61 }
62 
63 /* Motion blurred object transformations */
64 
65 #ifdef __OBJECT_MOTION__
66 ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals kg, int object, float time)
67 {
68  const uint motion_offset = kernel_data_fetch(objects, object).motion_offset;
69  ccl_global const DecomposedTransform *motion = &kernel_data_fetch(object_motion, motion_offset);
70  const uint num_steps = kernel_data_fetch(objects, object).numsteps * 2 + 1;
71 
72  Transform tfm;
73  transform_motion_array_interpolate(&tfm, motion, num_steps, time);
74 
75  return tfm;
76 }
77 
78 ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals kg,
79  int object,
80  float time,
81  ccl_private Transform *itfm)
82 {
83  int object_flag = kernel_data_fetch(object_flag, object);
84  if (object_flag & SD_OBJECT_MOTION) {
85  /* if we do motion blur */
86  Transform tfm = object_fetch_transform_motion(kg, object, time);
87 
88  if (itfm)
89  *itfm = transform_inverse(tfm);
90 
91  return tfm;
92  }
93  else {
95  if (itfm)
97 
98  return tfm;
99  }
100 }
101 #endif
102 
103 /* Get transform matrix for shading point. */
104 
106  ccl_private const ShaderData *sd)
107 {
108 #ifdef __OBJECT_MOTION__
109  return (sd->object_flag & SD_OBJECT_MOTION) ?
110  sd->ob_tfm_motion :
111  object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
112 #else
113  return object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
114 #endif
115 }
116 
118  ccl_private const ShaderData *sd)
119 {
120 #ifdef __OBJECT_MOTION__
121  return (sd->object_flag & SD_OBJECT_MOTION) ?
122  sd->ob_itfm_motion :
124 #else
125  return object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
126 #endif
127 }
128 /* Transform position from object to world space */
129 
131  ccl_private const ShaderData *sd,
133 {
134 #ifdef __OBJECT_MOTION__
135  if (sd->object_flag & SD_OBJECT_MOTION) {
136  *P = transform_point_auto(&sd->ob_tfm_motion, *P);
137  return;
138  }
139 #endif
140 
141  Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
142  *P = transform_point(&tfm, *P);
143 }
144 
145 /* Transform position from world to object space */
146 
148  ccl_private const ShaderData *sd,
150 {
151 #ifdef __OBJECT_MOTION__
152  if (sd->object_flag & SD_OBJECT_MOTION) {
153  *P = transform_point_auto(&sd->ob_itfm_motion, *P);
154  return;
155  }
156 #endif
157 
159  *P = transform_point(&tfm, *P);
160 }
161 
162 /* Transform normal from world to object space */
163 
165  ccl_private const ShaderData *sd,
167 {
168 #ifdef __OBJECT_MOTION__
169  if (sd->object_flag & SD_OBJECT_MOTION) {
170  if ((sd->object != OBJECT_NONE) || (sd->type == PRIMITIVE_LAMP)) {
171  *N = normalize(transform_direction_transposed_auto(&sd->ob_tfm_motion, *N));
172  }
173  return;
174  }
175 #endif
176 
177  if (sd->object != OBJECT_NONE) {
178  Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
180  }
181  else if (sd->type == PRIMITIVE_LAMP) {
182  Transform tfm = lamp_fetch_transform(kg, sd->lamp, false);
184  }
185 }
186 
187 /* Transform normal from object to world space */
188 
190  ccl_private const ShaderData *sd,
192 {
193 #ifdef __OBJECT_MOTION__
194  if (sd->object_flag & SD_OBJECT_MOTION) {
195  *N = normalize(transform_direction_transposed_auto(&sd->ob_itfm_motion, *N));
196  return;
197  }
198 #endif
199 
202 }
203 
204 /* Transform direction vector from object to world space */
205 
207  ccl_private const ShaderData *sd,
209 {
210 #ifdef __OBJECT_MOTION__
211  if (sd->object_flag & SD_OBJECT_MOTION) {
212  *D = transform_direction_auto(&sd->ob_tfm_motion, *D);
213  return;
214  }
215 #endif
216 
217  Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
218  *D = transform_direction(&tfm, *D);
219 }
220 
221 /* Transform direction vector from world to object space */
222 
224  ccl_private const ShaderData *sd,
226 {
227 #ifdef __OBJECT_MOTION__
228  if (sd->object_flag & SD_OBJECT_MOTION) {
229  *D = transform_direction_auto(&sd->ob_itfm_motion, *D);
230  return;
231  }
232 #endif
233 
234  const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
235  *D = transform_direction(&tfm, *D);
236 }
237 
238 /* Object center position */
239 
241 {
242  if (sd->object == OBJECT_NONE)
243  return make_float3(0.0f, 0.0f, 0.0f);
244 
245 #ifdef __OBJECT_MOTION__
246  if (sd->object_flag & SD_OBJECT_MOTION) {
247  return make_float3(sd->ob_tfm_motion.x.w, sd->ob_tfm_motion.y.w, sd->ob_tfm_motion.z.w);
248  }
249 #endif
250 
251  Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
252  return make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
253 }
254 
255 /* Color of the object */
256 
258 {
259  if (object == OBJECT_NONE)
260  return make_float3(0.0f, 0.0f, 0.0f);
261 
262  ccl_global const KernelObject *kobject = &kernel_data_fetch(objects, object);
263  return make_float3(kobject->color[0], kobject->color[1], kobject->color[2]);
264 }
265 
266 /* Alpha of the object */
267 
269 {
270  if (object == OBJECT_NONE)
271  return 0.0f;
272 
273  return kernel_data_fetch(objects, object).alpha;
274 }
275 
276 /* Pass ID number of object */
277 
279 {
280  if (object == OBJECT_NONE)
281  return 0.0f;
282 
283  return kernel_data_fetch(objects, object).pass_id;
284 }
285 
286 /* Lightgroup of lamp */
287 
289 {
290  if (lamp == LAMP_NONE)
291  return LIGHTGROUP_NONE;
292 
293  return kernel_data_fetch(lights, lamp).lightgroup;
294 }
295 
296 /* Lightgroup of object */
297 
299 {
300  if (object == OBJECT_NONE)
301  return LIGHTGROUP_NONE;
302 
303  return kernel_data_fetch(objects, object).lightgroup;
304 }
305 
306 /* Per lamp random number for shader variation */
307 
309 {
310  if (lamp == LAMP_NONE)
311  return 0.0f;
312 
313  return kernel_data_fetch(lights, lamp).random;
314 }
315 
316 /* Per object random number for shader variation */
317 
319 {
320  if (object == OBJECT_NONE)
321  return 0.0f;
322 
323  return kernel_data_fetch(objects, object).random_number;
324 }
325 
326 /* Particle ID from which this object was generated */
327 
329 {
330  if (object == OBJECT_NONE)
331  return 0;
332 
333  return kernel_data_fetch(objects, object).particle_index;
334 }
335 
336 /* Generated texture coordinate on surface from where object was instanced */
337 
339 {
340  if (object == OBJECT_NONE)
341  return make_float3(0.0f, 0.0f, 0.0f);
342 
343  ccl_global const KernelObject *kobject = &kernel_data_fetch(objects, object);
344  return make_float3(
345  kobject->dupli_generated[0], kobject->dupli_generated[1], kobject->dupli_generated[2]);
346 }
347 
348 /* UV texture coordinate on surface from where object was instanced */
349 
351 {
352  if (object == OBJECT_NONE)
353  return make_float3(0.0f, 0.0f, 0.0f);
354 
355  ccl_global const KernelObject *kobject = &kernel_data_fetch(objects, object);
356  return make_float3(kobject->dupli_uv[0], kobject->dupli_uv[1], 0.0f);
357 }
358 
359 /* Information about mesh for motion blurred triangles and curves */
360 
362  int object,
363  ccl_private int *numsteps,
364  ccl_private int *numverts,
365  ccl_private int *numkeys)
366 {
367  if (numkeys) {
368  *numkeys = kernel_data_fetch(objects, object).numkeys;
369  }
370 
371  if (numsteps)
372  *numsteps = kernel_data_fetch(objects, object).numsteps;
373  if (numverts)
374  *numverts = kernel_data_fetch(objects, object).numverts;
375 }
376 
377 /* Offset to an objects patch map */
378 
380 {
381  if (object == OBJECT_NONE)
382  return 0;
383 
384  return kernel_data_fetch(objects, object).patch_map_offset;
385 }
386 
387 /* Volume step size */
388 
390 {
391  if (object == OBJECT_NONE) {
392  return 1.0f;
393  }
394 
395  return kernel_data_fetch(objects, object).volume_density;
396 }
397 
399 {
400  if (object == OBJECT_NONE) {
401  return kernel_data.background.volume_step_size;
402  }
403 
404  return kernel_data_fetch(object_volume_step, object);
405 }
406 
407 /* Pass ID for shader */
408 
410 {
411  return kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).pass_id;
412 }
413 
414 /* Cryptomatte ID */
415 
417 {
418  if (object == OBJECT_NONE)
419  return 0.0f;
420 
421  return kernel_data_fetch(objects, object).cryptomatte_object;
422 }
423 
425 {
426  if (object == OBJECT_NONE)
427  return 0;
428 
429  return kernel_data_fetch(objects, object).cryptomatte_asset;
430 }
431 
432 /* Particle data from which object was instanced */
433 
435 {
436  return kernel_data_fetch(particles, particle).index;
437 }
438 
439 ccl_device float particle_age(KernelGlobals kg, int particle)
440 {
441  return kernel_data_fetch(particles, particle).age;
442 }
443 
445 {
446  return kernel_data_fetch(particles, particle).lifetime;
447 }
448 
449 ccl_device float particle_size(KernelGlobals kg, int particle)
450 {
451  return kernel_data_fetch(particles, particle).size;
452 }
453 
455 {
456  return kernel_data_fetch(particles, particle).rotation;
457 }
458 
460 {
461  return float4_to_float3(kernel_data_fetch(particles, particle).location);
462 }
463 
465 {
466  return float4_to_float3(kernel_data_fetch(particles, particle).velocity);
467 }
468 
470 {
471  return float4_to_float3(kernel_data_fetch(particles, particle).angular_velocity);
472 }
473 
474 /* Object intersection in BVH */
475 
477 {
478  const float ooeps = 8.271806E-25f;
479  return make_float3((fabsf(dir.x) > ooeps) ? dir.x : copysignf(ooeps, dir.x),
480  (fabsf(dir.y) > ooeps) ? dir.y : copysignf(ooeps, dir.y),
481  (fabsf(dir.z) > ooeps) ? dir.z : copysignf(ooeps, dir.z));
482 }
483 
485 {
486  return rcp(dir);
487 }
488 
489 /* Transform ray into object space to enter static object in BVH */
490 
492  int object,
493  ccl_private const Ray *ray,
495  ccl_private float3 *dir,
496  ccl_private float3 *idir)
497 {
499 
500  *P = transform_point(&tfm, ray->P);
501 
502  *dir = bvh_clamp_direction(transform_direction(&tfm, ray->D));
503  *idir = bvh_inverse_direction(*dir);
504 }
505 
506 #ifdef __OBJECT_MOTION__
507 /* Transform ray into object space to enter motion blurred object in BVH */
508 
509 ccl_device_inline void bvh_instance_motion_push(KernelGlobals kg,
510  int object,
511  ccl_private const Ray *ray,
513  ccl_private float3 *dir,
514  ccl_private float3 *idir)
515 {
516  Transform tfm;
517  object_fetch_transform_motion_test(kg, object, ray->time, &tfm);
518 
519  *P = transform_point(&tfm, ray->P);
520 
521  *dir = bvh_clamp_direction(transform_direction(&tfm, ray->D));
522  *idir = bvh_inverse_direction(*dir);
523 }
524 
525 #endif
526 
527 /* Transform ray to exit static object in BVH. */
528 
531  ccl_private float3 *dir,
532  ccl_private float3 *idir)
533 {
534  *P = ray->P;
535  *dir = bvh_clamp_direction(ray->D);
536  *idir = bvh_inverse_direction(*dir);
537 }
538 
539 /* TODO: This can be removed when we know if no devices will require explicit
540  * address space qualifiers for this case. */
541 
542 #define object_position_transform_auto object_position_transform
543 #define object_dir_transform_auto object_dir_transform
544 #define object_normal_transform_auto object_normal_transform
545 
unsigned int uint
Definition: BLI_sys_types.h:67
_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 type
float float4[4]
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btTransform.h:182
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_inline
Definition: cuda/compat.h:34
#define ccl_global
Definition: cuda/compat.h:43
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
double time
Light lamp
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
ccl_device void transform_motion_array_interpolate(ccl_private Transform *tfm, ccl_global const DecomposedTransform *motion, uint numsteps, float time)
#define transform_direction_transposed_auto
#define transform_point_auto
#define transform_direction_auto
ccl_device_inline Transform transform_inverse(const Transform tfm)
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
ccl_device_inline float3 transform_direction_transposed(ccl_private const Transform *t, const float3 a)
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_device_inline void bvh_instance_push(KernelGlobals kg, int object, ccl_private const Ray *ray, ccl_private float3 *P, ccl_private float3 *dir, ccl_private float3 *idir)
ccl_device_inline float3 bvh_clamp_direction(float3 dir)
ccl_device_inline float object_pass_id(KernelGlobals kg, int object)
ccl_device_inline void bvh_instance_pop(ccl_private const Ray *ray, ccl_private float3 *P, ccl_private float3 *dir, ccl_private float3 *idir)
ccl_device_inline float object_alpha(KernelGlobals kg, int object)
ObjectTransform
@ OBJECT_INVERSE_TRANSFORM
@ OBJECT_TRANSFORM
ccl_device float particle_age(KernelGlobals kg, int particle)
ccl_device float4 particle_rotation(KernelGlobals kg, int particle)
ccl_device_inline uint particle_index(KernelGlobals kg, int particle)
ccl_device_inline void object_motion_info(KernelGlobals kg, int object, ccl_private int *numsteps, ccl_private int *numverts, ccl_private int *numkeys)
ccl_device_inline float3 object_location(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device_inline float object_volume_density(KernelGlobals kg, int object)
ccl_device_inline float3 bvh_inverse_direction(float3 dir)
ccl_device_inline float object_random_number(KernelGlobals kg, int object)
ccl_device float particle_lifetime(KernelGlobals kg, int particle)
ccl_device_inline void object_position_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *P)
ccl_device float3 particle_angular_velocity(KernelGlobals kg, int particle)
ccl_device_inline int object_particle_id(KernelGlobals kg, int object)
ccl_device_inline float3 object_color(KernelGlobals kg, int object)
ccl_device_inline float object_cryptomatte_asset_id(KernelGlobals kg, int object)
ccl_device_inline void object_inverse_dir_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *D)
ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals kg, int object, enum ObjectVectorTransform type)
ccl_device_inline Transform object_get_transform(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device_inline float lamp_random_number(KernelGlobals kg, int lamp)
ccl_device_inline uint object_patch_map_offset(KernelGlobals kg, int object)
ccl_device_inline void object_inverse_position_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *P)
ccl_device int shader_pass_id(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device_inline Transform object_fetch_transform(KernelGlobals kg, int object, enum ObjectTransform type)
ccl_device_inline int lamp_lightgroup(KernelGlobals kg, int lamp)
ccl_device float3 particle_velocity(KernelGlobals kg, int particle)
ccl_device_inline float object_cryptomatte_id(KernelGlobals kg, int object)
ccl_device float3 particle_location(KernelGlobals kg, int particle)
ccl_device_inline void object_dir_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *D)
ccl_device float particle_size(KernelGlobals kg, int particle)
ccl_device_inline Transform lamp_fetch_transform(KernelGlobals kg, int lamp, bool inverse)
ccl_device_inline float object_volume_step_size(KernelGlobals kg, int object)
ccl_device_inline float3 object_dupli_generated(KernelGlobals kg, int object)
ccl_device_inline void object_inverse_normal_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *N)
ccl_device_inline float3 object_dupli_uv(KernelGlobals kg, int object)
ccl_device_inline int object_lightgroup(KernelGlobals kg, int object)
ObjectVectorTransform
@ OBJECT_PASS_MOTION_PRE
@ OBJECT_PASS_MOTION_POST
ccl_device_inline void object_normal_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *N)
ccl_device_inline Transform object_get_inverse_transform(KernelGlobals kg, ccl_private const ShaderData *sd)
@ PRIMITIVE_LAMP
Definition: kernel/types.h:556
#define OBJECT_NONE
Definition: kernel/types.h:40
#define OBJECT_MOTION_PASS_SIZE
Definition: kernel/types.h:25
ShaderData
Definition: kernel/types.h:925
@ SHADER_MASK
Definition: kernel/types.h:449
@ SD_OBJECT_MOTION
Definition: kernel/types.h:806
#define LIGHTGROUP_NONE
Definition: kernel/types.h:45
#define LAMP_NONE
Definition: kernel/types.h:42
ccl_device_inline float3 rcp(const float3 &a)
Definition: math_float3.h:377
static float P(float k)
Definition: math_interp.c:25
#define N
#define copysignf(x, y)
Definition: metal/compat.h:220
#define fabsf(x)
Definition: metal/compat.h:219
#define make_float3(x, y, z)
Definition: metal/compat.h:204
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
float z
float y
float x
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition: util/math.h:500
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:13