Blender V5.0
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
133template<class T>
135 const ccl_private ShaderData *sd,
136 ccl_private T *P)
137{
138#ifdef __OBJECT_MOTION__
139 if (sd->object_flag & SD_OBJECT_MOTION) {
140 *P = transform_point_auto(&sd->ob_tfm_motion, *P);
141 return;
142 }
143#endif
144
145 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
146 *P = transform_point(&tfm, *P);
147}
148
149/* Transform position from world to object space */
150
152 const ccl_private ShaderData *sd,
154{
155#ifdef __OBJECT_MOTION__
156 if (sd->object_flag & SD_OBJECT_MOTION) {
157 *P = transform_point_auto(&sd->ob_itfm_motion, *P);
158 return;
159 }
160#endif
161
162 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
163 *P = transform_point(&tfm, *P);
164}
165
166/* Transform normal from world to object space */
167
169 const ccl_private ShaderData *sd,
171{
172#ifdef __OBJECT_MOTION__
173 if (sd->object_flag & SD_OBJECT_MOTION) {
174 if (sd->object != OBJECT_NONE) {
175 *N = safe_normalize(transform_direction_transposed_auto(&sd->ob_tfm_motion, *N));
176 }
177 return;
178 }
179#endif
180
181 if (sd->object != OBJECT_NONE) {
182 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
184 }
185}
186
187/* Transform normal from object to world space */
188
190 const ccl_private 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
200 if (sd->object != OBJECT_NONE) {
201 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
203 }
204}
205
207{
208 return ((object_flag & SD_OBJECT_NEGATIVE_SCALE) && (object_flag & SD_OBJECT_TRANSFORM_APPLIED));
209}
210
211/* Transform direction vector from object to world space */
212
214 const ccl_private ShaderData *sd,
216{
217#ifdef __OBJECT_MOTION__
218 if (sd->object_flag & SD_OBJECT_MOTION) {
219 *D = transform_direction_auto(&sd->ob_tfm_motion, *D);
220 return;
221 }
222#endif
223
224 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
225 *D = transform_direction(&tfm, *D);
226}
227
228/* Transform direction vector from world to object space */
229
231 const ccl_private ShaderData *sd,
233{
234#ifdef __OBJECT_MOTION__
235 if (sd->object_flag & SD_OBJECT_MOTION) {
236 *D = transform_direction_auto(&sd->ob_itfm_motion, *D);
237 return;
238 }
239#endif
240
241 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
242 *D = transform_direction(&tfm, *D);
243}
244
245/* Object center position */
246
248{
249 if (sd->object == OBJECT_NONE) {
250 return make_float3(0.0f, 0.0f, 0.0f);
251 }
252
253#ifdef __OBJECT_MOTION__
254 if (sd->object_flag & SD_OBJECT_MOTION) {
255 return make_float3(sd->ob_tfm_motion.x.w, sd->ob_tfm_motion.y.w, sd->ob_tfm_motion.z.w);
256 }
257#endif
258
259 const Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
260 return make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
261}
262
263/* Color of the object */
264
266{
267 if (object == OBJECT_NONE) {
268 return make_float3(0.0f, 0.0f, 0.0f);
269 }
270
271 const ccl_global KernelObject *kobject = &kernel_data_fetch(objects, object);
272 return make_float3(kobject->color[0], kobject->color[1], kobject->color[2]);
273}
274
275/* Alpha of the object */
276
278{
279 if (object == OBJECT_NONE) {
280 return 0.0f;
281 }
282
283 return kernel_data_fetch(objects, object).alpha;
284}
285
286/* Pass ID number of object */
287
289{
290 if (object == OBJECT_NONE) {
291 return 0.0f;
292 }
293
294 return kernel_data_fetch(objects, object).pass_id;
295}
296
297/* Light-group of object. */
298
300{
301 if (object == OBJECT_NONE) {
302 return LIGHTGROUP_NONE;
303 }
304
305 return kernel_data_fetch(objects, object).lightgroup;
306}
307
308/* Per object random number for shader variation */
309
311{
312 if (object == OBJECT_NONE) {
313 return 0.0f;
314 }
315
316 return kernel_data_fetch(objects, object).random_number;
317}
318
319/* Particle ID from which this object was generated */
320
322{
323 if (object == OBJECT_NONE) {
324 return 0;
325 }
326
327 return kernel_data_fetch(objects, object).particle_index;
328}
329
330/* Generated texture coordinate on surface from where object was instanced */
331
333{
334 if (object == OBJECT_NONE) {
335 return make_float3(0.0f, 0.0f, 0.0f);
336 }
337
338 const ccl_global KernelObject *kobject = &kernel_data_fetch(objects, object);
339 return make_float3(
340 kobject->dupli_generated[0], kobject->dupli_generated[1], kobject->dupli_generated[2]);
341}
342
343/* UV texture coordinate on surface from where object was instanced */
344
346{
347 if (object == OBJECT_NONE) {
348 return make_float3(0.0f, 0.0f, 0.0f);
349 }
350
351 const ccl_global KernelObject *kobject = &kernel_data_fetch(objects, object);
352 return make_float3(kobject->dupli_uv[0], kobject->dupli_uv[1], 0.0f);
353}
354
355/* Volume density */
356
358{
359 if (object == OBJECT_NONE) {
360 return 1.0f;
361 }
362
363 return kernel_data_fetch(objects, object).volume_density;
364}
365
366/* Pass ID for shader */
367
369{
370 return kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).pass_id;
371}
372
373/* Cryptomatte ID */
374
376{
377 if (object == OBJECT_NONE) {
378 return 0.0f;
379 }
380
381 return kernel_data_fetch(objects, object).cryptomatte_object;
382}
383
385{
386 if (object == OBJECT_NONE) {
387 return 0;
388 }
389
390 return kernel_data_fetch(objects, object).cryptomatte_asset;
391}
392
393/* Particle data from which object was instanced */
394
396{
397 return kernel_data_fetch(particles, particle).index;
398}
399
400ccl_device float particle_age(KernelGlobals kg, const int particle)
401{
402 return kernel_data_fetch(particles, particle).age;
403}
404
405ccl_device float particle_lifetime(KernelGlobals kg, const int particle)
406{
407 return kernel_data_fetch(particles, particle).lifetime;
408}
409
410ccl_device float particle_size(KernelGlobals kg, const int particle)
411{
412 return kernel_data_fetch(particles, particle).size;
413}
414
416{
417 return kernel_data_fetch(particles, particle).rotation;
418}
419
421{
422 return make_float3(kernel_data_fetch(particles, particle).location);
423}
424
426{
427 return make_float3(kernel_data_fetch(particles, particle).velocity);
428}
429
431{
432 return make_float3(kernel_data_fetch(particles, particle).angular_velocity);
433}
434
435/* Object intersection in BVH */
436
438{
439 const float ooeps = 8.271806E-25f;
440 return make_float3((fabsf(dir.x) > ooeps) ? dir.x : copysignf(ooeps, dir.x),
441 (fabsf(dir.y) > ooeps) ? dir.y : copysignf(ooeps, dir.y),
442 (fabsf(dir.z) > ooeps) ? dir.z : copysignf(ooeps, dir.z));
443}
444
446{
447 return reciprocal(dir);
448}
449
450/* Transform ray into object space to enter static object in BVH */
451
453 const int object,
454 const ccl_private Ray *ray,
456 ccl_private float3 *dir,
457 ccl_private float3 *idir)
458{
460
461 *P = transform_point(&tfm, ray->P);
462
463 *dir = bvh_clamp_direction(transform_direction(&tfm, ray->D));
464 *idir = bvh_inverse_direction(*dir);
465}
466
467#ifdef __OBJECT_MOTION__
468/* Transform ray into object space to enter motion blurred object in BVH */
469
470ccl_device_inline void bvh_instance_motion_push(KernelGlobals kg,
471 const int object,
472 const ccl_private Ray *ray,
474 ccl_private float3 *dir,
475 ccl_private float3 *idir)
476{
477 Transform tfm;
478 object_fetch_transform_motion_test(kg, object, ray->time, &tfm);
479
480 *P = transform_point(&tfm, ray->P);
481
482 *dir = bvh_clamp_direction(transform_direction(&tfm, ray->D));
483 *idir = bvh_inverse_direction(*dir);
484}
485
486#endif
487
488/* Transform ray to exit static object in BVH. */
489
492 ccl_private float3 *dir,
493 ccl_private float3 *idir)
494{
495 *P = ray->P;
496 *dir = bvh_clamp_direction(ray->D);
497 *idir = bvh_inverse_direction(*dir);
498}
499
500/* TODO: This can be removed when we know if no devices will require explicit
501 * address space qualifiers for this case. */
502
503#define object_position_transform_auto object_position_transform
504#define object_dir_transform_auto object_dir_transform
505#define object_normal_transform_auto object_normal_transform
506
#define D
unsigned int uint
#define transform_direction_transposed_auto
#define transform_point_auto
#define kernel_data_fetch(name, index)
#define transform_direction_auto
#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)
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 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 float particle_size(KernelGlobals kg, const int particle)
ccl_device_inline void object_position_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private T *P)
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:36
#define N
#define T
#define fabsf
#define ccl_device
float4 y
Definition transform.h:23
float4 x
Definition transform.h:23
float4 z
Definition transform.h:23
float z
Definition sky_math.h:136
float y
Definition sky_math.h:136
float x
Definition sky_math.h:136
float w
Definition sky_math.h:225
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:591
ccl_device_inline Transform transform_inverse(const Transform tfm)
Definition transform.h:525
ccl_device_inline float3 transform_direction(const ccl_private Transform *t, const float3 a)
Definition transform.h:127
ccl_device_inline float3 transform_direction_transposed(const ccl_private Transform *t, const float3 a)
Definition transform.h:149
ccl_device_inline float3 transform_point(const ccl_private Transform *t, const float3 a)
Definition transform.h:56