Blender V5.0
motion_triangle_intersect.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/* Motion Triangle Primitive
6 *
7 * These are stored as regular triangles, plus extra positions and normals at
8 * times other than the frame center. Computing the triangle vertex positions
9 * or normals at a given ray time is a matter of interpolation of the two steps
10 * between which the ray time lies.
11 *
12 * The extra positions and normals are stored as ATTR_STD_MOTION_VERTEX_POSITION
13 * and ATTR_STD_MOTION_VERTEX_NORMAL mesh attributes.
14 */
15
16#pragma once
17
18#include "kernel/globals.h"
19#include "kernel/types.h"
20
23#include "kernel/geom/object.h"
24
25#include "util/math_intersect.h"
26
28
33 ccl_private ShaderData *sd,
34 const float u,
35 const float v,
36 const float3 verts[3])
37{
38 /* This appears to give slightly better precision than interpolating with w = (1 - u - v). */
39 float3 P = verts[0] + u * (verts[1] - verts[0]) + v * (verts[2] - verts[0]);
40
41 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
42 const Transform tfm = object_get_transform(kg, sd);
43 P = transform_point(&tfm, P);
44 }
45
46 return P;
47}
48
49/* Ray intersection. We simply compute the vertex positions at the given ray
50 * time and do a ray intersection with the resulting triangle.
51 */
52
55 const float3 P,
56 const float3 dir,
57 const float tmin,
58 const float tmax,
59 const float time,
60 const uint visibility,
61 const int object,
62 const int prim,
63 const int prim_addr)
64{
65 /* Get vertex locations for intersection. */
66 float3 verts[3];
67 motion_triangle_vertices(kg, object, prim, time, verts);
68 /* Ray-triangle intersection, unoptimized. */
69 float t;
70 float u;
71 float v;
72 if (ray_triangle_intersect(P, dir, tmin, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
73#ifdef __VISIBILITY_FLAG__
74 /* Visibility flag test. we do it here under the assumption
75 * that most triangles are culled by node flags.
76 */
77 if (kernel_data_fetch(prim_visibility, prim_addr) & visibility)
78#endif
79 {
80 isect->t = t;
81 isect->u = u;
82 isect->v = v;
83 isect->prim = prim;
84 isect->object = object;
85 isect->type = PRIMITIVE_MOTION_TRIANGLE;
86 return true;
87 }
88 }
89 return false;
90}
91
92/* Special ray intersection routines for local intersections. In that case we
93 * only want to intersect with primitives in the same object, and if case of
94 * multiple hits we pick a single random primitive as the intersection point.
95 * Returns whether traversal should be stopped.
96 */
97#ifdef __BVH_LOCAL__
98ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals kg,
99 ccl_private LocalIntersection *local_isect,
100 const float3 P,
101 const float3 dir,
102 const float time,
103 const int object,
104 const int prim,
105 const float tmin,
106 const float tmax,
107 ccl_private uint *lcg_state,
108 const int max_hits)
109{
110 /* Get vertex locations for intersection. */
111 float3 verts[3];
112 motion_triangle_vertices(kg, object, prim, time, verts);
113 /* Ray-triangle intersection, unoptimized. */
114 float t;
115 float u;
116 float v;
117 if (!ray_triangle_intersect(P, dir, tmin, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
118 return false;
119 }
120
121 /* If no actual hit information is requested, just return here. */
122 if (max_hits == 0) {
123 return true;
124 }
125
126 const int hit_index = local_intersect_get_record_index(local_isect, t, lcg_state, max_hits);
127 if (hit_index == -1) {
128 return false;
129 }
130
131 /* Record intersection. */
132 ccl_private Intersection *isect = &local_isect->hits[hit_index];
133 isect->t = t;
134 isect->u = u;
135 isect->v = v;
136 isect->prim = prim;
137 isect->object = object;
138 isect->type = PRIMITIVE_MOTION_TRIANGLE;
139
140 /* Record geometric normal. */
141 local_isect->Ng[hit_index] = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
142
143 return false;
144}
145#endif /* __BVH_LOCAL__ */
146
unsigned int uint
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define kernel_data_fetch(name, index)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
static float verts[][3]
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
ccl_device_inline Transform object_get_transform(KernelGlobals kg, const ccl_private ShaderData *sd)
@ PRIMITIVE_MOTION_TRIANGLE
@ SD_OBJECT_TRANSFORM_APPLIED
ccl_device_forceinline bool ray_triangle_intersect(const float3 ray_P, const float3 ray_D, const float ray_tmin, const float ray_tmax, const float3 tri_a, const float3 tri_b, const float3 tri_c, ccl_private float *isect_u, ccl_private float *isect_v, ccl_private float *isect_t)
ccl_device_inline void motion_triangle_vertices(KernelGlobals kg, const int object, const uint3 tri_vindex, const int numsteps, const int numverts, const int step, const float t, float3 verts[3])
CCL_NAMESPACE_BEGIN ccl_device_inline float3 motion_triangle_point_from_uv(KernelGlobals kg, ccl_private ShaderData *sd, const float u, const float v, const float3 verts[3])
ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg, ccl_private Intersection *isect, const float3 P, const float3 dir, const float tmin, const float tmax, const float time, const uint visibility, const int object, const int prim, const int prim_addr)
ccl_device_inline float3 transform_point(const ccl_private Transform *t, const float3 a)
Definition transform.h:56