Blender V4.5
kernel/geom/object.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5/* Object Primitive
6 *
7 * All mesh and curve primitives are part of an object. The same mesh and curves
8 * may be instanced multiple times by different objects.
9 *
10 * If the mesh is not instanced multiple times, the object will not be explicitly
11 * stored as a primitive in the BVH, rather the bare triangles are curved are
12 * directly primitives in the BVH with world space locations applied, and the object
13 * ID is looked up afterwards. */
14
15#pragma once
16
17#include "kernel/globals.h"
18#include "kernel/types.h"
19
21
22/* Object attributes, for now a fixed size and contents */
23
28
30
31/* Object to world space transformation */
32
34 const int object,
35 enum ObjectTransform type)
36{
37 if (type == OBJECT_INVERSE_TRANSFORM) {
38 return kernel_data_fetch(objects, object).itfm;
39 }
40 return kernel_data_fetch(objects, object).tfm;
41}
42
43/* Object to world space transformation for motion vectors */
44
46 const int object,
47 enum ObjectVectorTransform type)
48{
49 const int offset = object * OBJECT_MOTION_PASS_SIZE + (int)type;
50 return kernel_data_fetch(object_motion_pass, offset);
51}
52
53/* Motion blurred object transformations */
54
55#ifdef __OBJECT_MOTION__
56ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals kg,
57 const int object,
58 const float time)
59{
60 const uint motion_offset = kernel_data_fetch(objects, object).motion_offset;
61 const ccl_global DecomposedTransform *motion = &kernel_data_fetch(object_motion, motion_offset);
62 const uint num_steps = kernel_data_fetch(objects, object).num_tfm_steps;
63
64 Transform tfm;
65 transform_motion_array_interpolate(&tfm, motion, num_steps, time);
66
67 return tfm;
68}
69#endif /* __OBJECT_MOTION__ */
70
72 const int object,
73 const float time,
75{
76#ifdef __OBJECT_MOTION__
77 const int object_flag = kernel_data_fetch(object_flag, object);
78 if (object_flag & SD_OBJECT_MOTION) {
79 /* if we do motion blur */
80 Transform tfm = object_fetch_transform_motion(kg, object, time);
81
82 if (itfm) {
83 *itfm = transform_inverse(tfm);
84 }
85
86 return tfm;
87 }
88
89#endif /* __OBJECT_MOTION__ */
90
92 if (itfm) {
94 }
95
96 return tfm;
97}
98
99/* Get transform matrix for shading point. */
100
102 const ccl_private ShaderData *sd)
103{
104#ifdef __OBJECT_MOTION__
105 return (sd->object_flag & SD_OBJECT_MOTION) ?
106 sd->ob_tfm_motion :
108#else
109 return object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
110#endif
111}
112
114 const ccl_private ShaderData *sd)
115{
116#ifdef __OBJECT_MOTION__
117 return (sd->object_flag & SD_OBJECT_MOTION) ?
118 sd->ob_itfm_motion :
120#else
121 return object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
122#endif
123}
124
130
131/* Transform position from object to world space */
132
134 const ccl_private ShaderData *sd,
136{
137#ifdef __OBJECT_MOTION__
138 if (sd->object_flag & SD_OBJECT_MOTION) {
139 *P = transform_point_auto(&sd->ob_tfm_motion, *P);
140 return;
141 }
142#endif
143
144 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
145 *P = transform_point(&tfm, *P);
146}
147
148/* Transform position from world to object space */
149
151 const ccl_private ShaderData *sd,
153{
154#ifdef __OBJECT_MOTION__
155 if (sd->object_flag & SD_OBJECT_MOTION) {
156 *P = transform_point_auto(&sd->ob_itfm_motion, *P);
157 return;
158 }
159#endif
160
161 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
162 *P = transform_point(&tfm, *P);
163}
164
165/* Transform normal from world to object space */
166
168 const ccl_private ShaderData *sd,
170{
171#ifdef __OBJECT_MOTION__
172 if (sd->object_flag & SD_OBJECT_MOTION) {
173 if (sd->object != OBJECT_NONE) {
174 *N = safe_normalize(transform_direction_transposed_auto(&sd->ob_tfm_motion, *N));
175 }
176 return;
177 }
178#endif
179
180 if (sd->object != OBJECT_NONE) {
181 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
183 }
184}
185
186/* Transform normal from object to world space */
187
189 const ccl_private ShaderData *sd,
191{
192#ifdef __OBJECT_MOTION__
193 if (sd->object_flag & SD_OBJECT_MOTION) {
194 *N = normalize(transform_direction_transposed_auto(&sd->ob_itfm_motion, *N));
195 return;
196 }
197#endif
198
199 if (sd->object != OBJECT_NONE) {
200 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
202 }
203}
204
206{
207 return ((object_flag & SD_OBJECT_NEGATIVE_SCALE) && (object_flag & SD_OBJECT_TRANSFORM_APPLIED));
208}
209
210/* Transform direction vector from object to world space */
211
213 const ccl_private ShaderData *sd,
215{
216#ifdef __OBJECT_MOTION__
217 if (sd->object_flag & SD_OBJECT_MOTION) {
218 *D = transform_direction_auto(&sd->ob_tfm_motion, *D);
219 return;
220 }
221#endif
222
223 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
224 *D = transform_direction(&tfm, *D);
225}
226
227/* Transform direction vector from world to object space */
228
230 const ccl_private ShaderData *sd,
232{
233#ifdef __OBJECT_MOTION__
234 if (sd->object_flag & SD_OBJECT_MOTION) {
235 *D = transform_direction_auto(&sd->ob_itfm_motion, *D);
236 return;
237 }
238#endif
239
240 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
241 *D = transform_direction(&tfm, *D);
242}
243
244/* Object center position */
245
247{
248 if (sd->object == OBJECT_NONE) {
249 return make_float3(0.0f, 0.0f, 0.0f);
250 }
251
252#ifdef __OBJECT_MOTION__
253 if (sd->object_flag & SD_OBJECT_MOTION) {
254 return make_float3(sd->ob_tfm_motion.x.w, sd->ob_tfm_motion.y.w, sd->ob_tfm_motion.z.w);
255 }
256#endif
257
258 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
259 return make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
260}
261
262/* Color of the object */
263
265{
266 if (object == OBJECT_NONE) {
267 return make_float3(0.0f, 0.0f, 0.0f);
268 }
269
270 const ccl_global KernelObject *kobject = &kernel_data_fetch(objects, object);
271 return make_float3(kobject->color[0], kobject->color[1], kobject->color[2]);
272}
273
274/* Alpha of the object */
275
277{
278 if (object == OBJECT_NONE) {
279 return 0.0f;
280 }
281
282 return kernel_data_fetch(objects, object).alpha;
283}
284
285/* Pass ID number of object */
286
288{
289 if (object == OBJECT_NONE) {
290 return 0.0f;
291 }
292
293 return kernel_data_fetch(objects, object).pass_id;
294}
295
296/* Light-group of object. */
297
299{
300 if (object == OBJECT_NONE) {
301 return LIGHTGROUP_NONE;
302 }
303
304 return kernel_data_fetch(objects, object).lightgroup;
305}
306
307/* Per object random number for shader variation */
308
310{
311 if (object == OBJECT_NONE) {
312 return 0.0f;
313 }
314
315 return kernel_data_fetch(objects, object).random_number;
316}
317
318/* Particle ID from which this object was generated */
319
321{
322 if (object == OBJECT_NONE) {
323 return 0;
324 }
325
326 return kernel_data_fetch(objects, object).particle_index;
327}
328
329/* Generated texture coordinate on surface from where object was instanced */
330
332{
333 if (object == OBJECT_NONE) {
334 return make_float3(0.0f, 0.0f, 0.0f);
335 }
336
337 const ccl_global KernelObject *kobject = &kernel_data_fetch(objects, object);
338 return make_float3(
339 kobject->dupli_generated[0], kobject->dupli_generated[1], kobject->dupli_generated[2]);
340}
341
342/* UV texture coordinate on surface from where object was instanced */
343
345{
346 if (object == OBJECT_NONE) {
347 return make_float3(0.0f, 0.0f, 0.0f);
348 }
349
350 const ccl_global KernelObject *kobject = &kernel_data_fetch(objects, object);
351 return make_float3(kobject->dupli_uv[0], kobject->dupli_uv[1], 0.0f);
352}
353
354/* Volume step size */
355
357{
358 if (object == OBJECT_NONE) {
359 return 1.0f;
360 }
361
362 return kernel_data_fetch(objects, object).volume_density;
363}
364
366{
367 if (object == OBJECT_NONE) {
368 return kernel_data.background.volume_step_size;
369 }
370
371 return kernel_data_fetch(object_volume_step, object);
372}
373
374/* Pass ID for shader */
375
377{
378 return kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).pass_id;
379}
380
381/* Cryptomatte ID */
382
384{
385 if (object == OBJECT_NONE) {
386 return 0.0f;
387 }
388
389 return kernel_data_fetch(objects, object).cryptomatte_object;
390}
391
393{
394 if (object == OBJECT_NONE) {
395 return 0;
396 }
397
398 return kernel_data_fetch(objects, object).cryptomatte_asset;
399}
400
401/* Particle data from which object was instanced */
402
404{
405 return kernel_data_fetch(particles, particle).index;
406}
407
408ccl_device float particle_age(KernelGlobals kg, const int particle)
409{
410 return kernel_data_fetch(particles, particle).age;
411}
412
413ccl_device float particle_lifetime(KernelGlobals kg, const int particle)
414{
415 return kernel_data_fetch(particles, particle).lifetime;
416}
417
418ccl_device float particle_size(KernelGlobals kg, const int particle)
419{
420 return kernel_data_fetch(particles, particle).size;
421}
422
424{
425 return kernel_data_fetch(particles, particle).rotation;
426}
427
429{
430 return make_float3(kernel_data_fetch(particles, particle).location);
431}
432
434{
435 return make_float3(kernel_data_fetch(particles, particle).velocity);
436}
437
439{
440 return make_float3(kernel_data_fetch(particles, particle).angular_velocity);
441}
442
443/* Object intersection in BVH */
444
446{
447 const float ooeps = 8.271806E-25f;
448 return make_float3((fabsf(dir.x) > ooeps) ? dir.x : copysignf(ooeps, dir.x),
449 (fabsf(dir.y) > ooeps) ? dir.y : copysignf(ooeps, dir.y),
450 (fabsf(dir.z) > ooeps) ? dir.z : copysignf(ooeps, dir.z));
451}
452
454{
455 return reciprocal(dir);
456}
457
458/* Transform ray into object space to enter static object in BVH */
459
461 const int object,
462 const ccl_private Ray *ray,
464 ccl_private float3 *dir,
465 ccl_private float3 *idir)
466{
468
469 *P = transform_point(&tfm, ray->P);
470
471 *dir = bvh_clamp_direction(transform_direction(&tfm, ray->D));
472 *idir = bvh_inverse_direction(*dir);
473}
474
475#ifdef __OBJECT_MOTION__
476/* Transform ray into object space to enter motion blurred object in BVH */
477
478ccl_device_inline void bvh_instance_motion_push(KernelGlobals kg,
479 const int object,
480 const ccl_private Ray *ray,
482 ccl_private float3 *dir,
483 ccl_private float3 *idir)
484{
485 Transform tfm;
486 object_fetch_transform_motion_test(kg, object, ray->time, &tfm);
487
488 *P = transform_point(&tfm, ray->P);
489
490 *dir = bvh_clamp_direction(transform_direction(&tfm, ray->D));
491 *idir = bvh_inverse_direction(*dir);
492}
493
494#endif
495
496/* Transform ray to exit static object in BVH. */
497
500 ccl_private float3 *dir,
501 ccl_private float3 *idir)
502{
503 *P = ray->P;
504 *dir = bvh_clamp_direction(ray->D);
505 *idir = bvh_inverse_direction(*dir);
506}
507
508/* TODO: This can be removed when we know if no devices will require explicit
509 * address space qualifiers for this case. */
510
511#define object_position_transform_auto object_position_transform
512#define object_dir_transform_auto object_dir_transform
513#define object_normal_transform_auto object_normal_transform
514
#define D
unsigned int uint
#define kernel_data
#define transform_direction_transposed_auto
#define transform_point_auto
#define kernel_data_fetch(name, index)
#define transform_direction_auto
#define ccl_device
#define OBJECT_NONE
#define OBJECT_MOTION_PASS_SIZE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define LIGHTGROUP_NONE
#define ccl_global
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define copysignf(x, y)
#define fabsf(x)
VecBase< float, 4 > float4
VecBase< float, D > normalize(VecOp< float, D >) RET
ccl_device_inline float3 object_dupli_uv(KernelGlobals kg, const int object)
ccl_device_inline int object_particle_id(KernelGlobals kg, const int object)
ccl_device int shader_pass_id(KernelGlobals kg, const ccl_private ShaderData *sd)
ObjectTransform
@ OBJECT_INVERSE_TRANSFORM
@ OBJECT_TRANSFORM
ccl_device_inline Transform object_get_inverse_transform(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device_inline float object_volume_density(KernelGlobals kg, const int object)
ccl_device_inline Transform lamp_get_inverse_transform(KernelGlobals kg, const ccl_global KernelLight *klight)
ccl_device_inline float object_cryptomatte_id(KernelGlobals kg, const int object)
ccl_device_inline void object_inverse_position_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private float3 *P)
ccl_device_inline void object_dir_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private float3 *D)
ccl_device float4 particle_rotation(KernelGlobals kg, const int particle)
ccl_device_inline int object_lightgroup(KernelGlobals kg, const int object)
ccl_device_inline void bvh_instance_push(KernelGlobals kg, const int object, const ccl_private Ray *ray, ccl_private float3 *P, ccl_private float3 *dir, ccl_private float3 *idir)
ccl_device_inline bool object_negative_scale_applied(const int object_flag)
ccl_device_inline void object_position_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private float3 *P)
ccl_device float3 particle_location(KernelGlobals kg, const int particle)
ccl_device_inline void object_normal_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private float3 *N)
ccl_device float particle_lifetime(KernelGlobals kg, const int particle)
ccl_device float particle_age(KernelGlobals kg, const int particle)
ccl_device_inline uint particle_index(KernelGlobals kg, const int particle)
ccl_device_inline Transform object_fetch_transform(KernelGlobals kg, const int object, enum ObjectTransform type)
ccl_device_inline float3 object_color(KernelGlobals kg, const int object)
ccl_device_inline float3 bvh_inverse_direction(const float3 dir)
ccl_device_inline Transform object_get_transform(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device float3 particle_velocity(KernelGlobals kg, const int particle)
ccl_device_inline float3 bvh_clamp_direction(const float3 dir)
ccl_device_inline float object_alpha(KernelGlobals kg, const int object)
ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals kg, const int object, enum ObjectVectorTransform type)
ccl_device float3 particle_angular_velocity(KernelGlobals kg, const int particle)
ccl_device_inline float object_cryptomatte_asset_id(KernelGlobals kg, const int object)
ccl_device_inline float3 object_dupli_generated(KernelGlobals kg, const int object)
ccl_device_inline float object_pass_id(KernelGlobals kg, const int object)
ccl_device_inline float object_volume_step_size(KernelGlobals kg, const int object)
ccl_device float particle_size(KernelGlobals kg, const int particle)
ccl_device_inline void object_inverse_dir_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private float3 *D)
ccl_device_inline void object_inverse_normal_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private float3 *N)
ObjectVectorTransform
@ OBJECT_PASS_MOTION_PRE
@ OBJECT_PASS_MOTION_POST
ccl_device_inline float3 object_location(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals kg, const int object, const float time, ccl_private Transform *itfm)
ccl_device_inline void bvh_instance_pop(const ccl_private Ray *ray, ccl_private float3 *P, ccl_private float3 *dir, ccl_private float3 *idir)
ccl_device_inline float object_random_number(KernelGlobals kg, const int object)
@ SHADER_MASK
@ SD_OBJECT_MOTION
@ SD_OBJECT_NEGATIVE_SCALE
@ SD_OBJECT_TRANSFORM_APPLIED
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float3 reciprocal(const float3 a)
Definition math_float3.h:34
#define N
float4 y
Definition transform.h:23
float4 x
Definition transform.h:23
float4 z
Definition transform.h:23
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
ccl_device void transform_motion_array_interpolate(ccl_private Transform *tfm, const ccl_global DecomposedTransform *motion, const uint numsteps, const float time)
Definition transform.h:558
ccl_device_inline Transform transform_inverse(const Transform tfm)
Definition transform.h:492
ccl_device_inline float3 transform_direction(const ccl_private Transform *t, const float3 a)
Definition transform.h:87
ccl_device_inline float3 transform_direction_transposed(const ccl_private Transform *t, const float3 a)
Definition transform.h:116
ccl_device_inline float3 transform_point(const ccl_private Transform *t, const float3 a)
Definition transform.h:56