xref: /aosp_15_r20/external/mesa3d/src/intel/vulkan/grl/include/affinespace.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 //
2 // Copyright (C) 2009-2021 Intel Corporation
3 //
4 // SPDX-License-Identifier: MIT
5 //
6 //
7 
8 #pragma once
9 
10 #include "GRLRTASCommon.h"
11 
12 GRL_NAMESPACE_BEGIN(GRL)
GRL_NAMESPACE_BEGIN(RTAS)13 GRL_NAMESPACE_BEGIN(RTAS)
14 inline float3 GRL_OVERLOADABLE cross(const float3 a, const float3 b)
15 {
16     float3 res = { a.y * b.z - a.z * b.y,
17                    a.z * b.x - a.x * b.z,
18                    a.x * b.y - a.y * b.x };
19     return res;
20 }
21 
22 struct LinearSpace3f
23 {
24     float3 vx;
25     float3 vy;
26     float3 vz;
27 };
28 
29 /* compute the determinant of the matrix */
LinearSpace3f_Constructor(const float3 vx,const float3 vy,const float3 vz)30 GRL_INLINE struct LinearSpace3f LinearSpace3f_Constructor(const float3 vx, const float3 vy, const float3 vz)
31 {
32     struct LinearSpace3f xfm;
33     xfm.vx = vx;
34     xfm.vy = vy;
35     xfm.vz = vz;
36     return xfm;
37 }
38 
39 /* compute the determinant of the matrix */
LinearSpace3f_det(struct LinearSpace3f xfm)40 GRL_INLINE float LinearSpace3f_det(struct LinearSpace3f xfm)
41 {
42     return dot(xfm.vx, cross(xfm.vy, xfm.vz));
43 }
44 
45 /* compute transposed matrix */
LinearSpace3f_transpose(struct LinearSpace3f in)46 GRL_INLINE struct LinearSpace3f LinearSpace3f_transpose(struct LinearSpace3f in)
47 {
48     float3 x = { in.vx.x, in.vy.x, in.vz.x };
49     float3 y = { in.vx.y, in.vy.y, in.vz.y };
50     float3 z = { in.vx.z, in.vy.z, in.vz.z };
51 
52     return LinearSpace3f_Constructor(x,
53                                      y,
54                                      z);
55 }
56 
57 /* compute adjoint matrix */
LinearSpace3f_adjoint(struct LinearSpace3f in)58 GRL_INLINE const struct LinearSpace3f LinearSpace3f_adjoint(struct LinearSpace3f in)
59 {
60     return LinearSpace3f_transpose(LinearSpace3f_Constructor(cross(in.vy, in.vz),
61                                                              cross(in.vz, in.vx),
62                                                              cross(in.vx, in.vy)));
63 }
64 
65 /* compute inverse matrix */
LinearSpace3f_invert(struct LinearSpace3f in)66 GRL_INLINE struct LinearSpace3f LinearSpace3f_invert(struct LinearSpace3f in)
67 {
68     const float det = LinearSpace3f_det(in);
69     const struct LinearSpace3f adj = LinearSpace3f_adjoint(in);
70     return LinearSpace3f_Constructor(adj.vx / det, adj.vy / det, adj.vz / det);
71 }
72 
xfmPoint(struct LinearSpace3f xfm,float3 p)73 GRL_INLINE float3 GRL_OVERLOADABLE xfmPoint(struct LinearSpace3f xfm, float3 p)
74 {
75     return xfm.vx * p.x + xfm.vy * p.y + xfm.vz * p.z;
76 }
77 
78 struct AffineSpace3f
79 {
80     struct LinearSpace3f l;
81     float3 p;
82 };
83 
AffineSpace3f_Constructor(struct LinearSpace3f l,float3 p)84 GRL_INLINE struct AffineSpace3f AffineSpace3f_Constructor(struct LinearSpace3f l, float3 p)
85 {
86     struct AffineSpace3f out;
87     out.l = l;
88     out.p = p;
89     return out;
90 }
91 
AffineSpace3f_load_row_major(const float * in)92 GRL_INLINE struct AffineSpace3f AffineSpace3f_load_row_major(const float *in)
93 {
94     struct AffineSpace3f out;
95     out.l.vx.x = in[0];
96     out.l.vx.y = in[4];
97     out.l.vx.z = in[8];
98     out.l.vy.x = in[1];
99     out.l.vy.y = in[5];
100     out.l.vy.z = in[9];
101     out.l.vz.x = in[2];
102     out.l.vz.y = in[6];
103     out.l.vz.z = in[10];
104     out.p.x = in[3];
105     out.p.y = in[7];
106     out.p.z = in[11];
107     return out;
108 }
109 
110 // squared proportion of oriented transformed cube to aa box that would contain it.
111 // the smaller it is the more overhead transformation produces
112 GRL_INLINE
transformation_bbox_surf_overhead(const float * Transform)113 float transformation_bbox_surf_overhead(const float* Transform)
114 {
115     // We use an abs-matrix to transform the AABB extent vector, which is enough to compute the area
116     //     New AABB is center +- Extent.
117     //
118     // For derivation see:
119     //    https://zeux.io/2010/10/17/aabb-from-obb-with-component-wise-abs/
120     //
121 
122 
123     // take the cube of side 1 and see how big aabb containing it transformed is vs just surface of transformed
124     float ex = fabs(Transform[0]) + fabs(Transform[1]) + fabs(Transform[2]);
125     float ey = fabs(Transform[4]) + fabs(Transform[5]) + fabs(Transform[6]);
126     float ez = fabs(Transform[8]) + fabs(Transform[9]) + fabs(Transform[10]);
127 
128     // we will compare squared sizes
129     ex = ex * ex;
130     ey = ey * ey;
131     ez = ez * ez;
132 
133     // surface of aabb containing oriented box;
134     float aabb_sq_half_surf = ex * ey + ey * ez + ez * ex;
135 
136     // ^2 lengths of transformed <1,0,0>, <0,1,0>, <0,0,1>
137     float obx = Transform[0] * Transform[0] + Transform[4] * Transform[4] + Transform[8] * Transform[8];
138     float oby = Transform[1] * Transform[1] + Transform[5] * Transform[5] + Transform[9] * Transform[9];
139     float obz = Transform[2] * Transform[2] + Transform[6] * Transform[6] + Transform[10] * Transform[10];
140 
141     float obb_sq_half_surf = obx * oby + oby * obz + obz * obx;
142 
143     return obb_sq_half_surf / aabb_sq_half_surf;
144 
145     // ex = 2.0
146     // ey = 2.0
147     // ez = 2.0
148     // ex = 4.0
149     // ey = 4.0
150     // ez = 4.0
151     // aabb_half_surf = 16+16 *2.0 +  2.0*2.0+ 2.0*2.0; = 12;
152     // aabb_sq_half_surf = 144;
153     //
154     // obx = 4.0;
155     // oby = 4.0;
156     // obz = 4.0;
157     // obb_sq_half_surf = 16 + 16+ 16;
158     // obb_sq_half_surf = 16.0 *3 = 48
159 }
160 
load_row_major_from_AffineSpace3f(struct AffineSpace3f in,float * out)161 GRL_INLINE void load_row_major_from_AffineSpace3f(struct AffineSpace3f in, float* out)
162 {
163     out[0]  = in.l.vx.x;
164     out[4]  = in.l.vx.y;
165     out[8]  = in.l.vx.z;
166     out[1]  = in.l.vy.x;
167     out[5]  = in.l.vy.y;
168     out[9]  = in.l.vy.z;
169     out[2]  = in.l.vz.x;
170     out[6]  = in.l.vz.y;
171     out[10] = in.l.vz.z;
172 
173     out[3]  = in.p.x;
174     out[7]  = in.p.y;
175     out[11] = in.p.z;
176 }
177 
xfmPoint(struct AffineSpace3f xfm,float3 p)178 GRL_INLINE float3 GRL_OVERLOADABLE xfmPoint(struct AffineSpace3f xfm, float3 p)
179 {
180     return xfmPoint(xfm.l, p) + xfm.p;
181 }
182 
183 /* compute inverse matrix */
AffineSpace3f_invert(struct AffineSpace3f in)184 GRL_INLINE struct AffineSpace3f AffineSpace3f_invert(struct AffineSpace3f in)
185 {
186     const struct LinearSpace3f il = LinearSpace3f_invert(in.l);
187     float3 ip = -xfmPoint(il, in.p);
188     return AffineSpace3f_Constructor(il, ip);
189 }
190 
191 GRL_NAMESPACE_END(RTAS)
192 GRL_NAMESPACE_END(GRL)
193