1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
|
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "vec.isph"
#include "quaternion.isph"
struct LinearSpace3f
{
Vec3f vx;
Vec3f vy;
Vec3f vz;
};
struct LinearSpace3fa
{
Vec3fa vx;
Vec3fa vy;
Vec3fa vz;
};
////////////////////////////////////////////////////////////////////////////////
/// Constructors
////////////////////////////////////////////////////////////////////////////////
inline uniform LinearSpace3f make_LinearSpace3f(const uniform Vec3f &x, const uniform Vec3f &y, const uniform Vec3f &z) {
uniform LinearSpace3f l; l.vx = x; l.vy = y; l.vz = z; return l;
}
inline varying LinearSpace3f make_LinearSpace3f(const varying Vec3f &x, const varying Vec3f &y, const varying Vec3f &z) {
varying LinearSpace3f l; l.vx = x; l.vy = y; l.vz = z; return l;
}
inline uniform LinearSpace3f make_LinearSpace3f(const uniform LinearSpace3fa &s) {
uniform LinearSpace3f l; l.vx = make_Vec3f(s.vx); l.vy = make_Vec3f(s.vy); l.vz = make_Vec3f(s.vz); return l;
}
inline varying LinearSpace3f make_LinearSpace3f(const varying LinearSpace3fa &s) {
varying LinearSpace3f l; l.vx = make_Vec3f(s.vx); l.vy = make_Vec3f(s.vy); l.vz = make_Vec3f(s.vz); return l;
}
/*! construction from quaternion */
inline uniform LinearSpace3f make_LinearSpace3f(const uniform Quaternion3f& q)
{
uniform LinearSpace3f l;
l.vx = make_Vec3f(q.r*q.r + q.i*q.i - q.j*q.j - q.k*q.k, 2.0f*(q.i*q.j + q.r*q.k), 2.0f*(q.i*q.k - q.r*q.j));
l.vy = make_Vec3f(2.0f*(q.i*q.j - q.r*q.k), (q.r*q.r - q.i*q.i + q.j*q.j - q.k*q.k), 2.0f*(q.j*q.k + q.r*q.i));
l.vz = make_Vec3f(2.0f*(q.i*q.k + q.r*q.j), 2.0f*(q.j*q.k - q.r*q.i), q.r*q.r - q.i*q.i - q.j*q.j + q.k*q.k);
return l;
}
inline varying LinearSpace3f make_LinearSpace3f(const varying Quaternion3f& q)
{
LinearSpace3f l;
l.vx = make_Vec3f(q.r*q.r + q.i*q.i - q.j*q.j - q.k*q.k, 2.0f*(q.i*q.j + q.r*q.k), 2.0f*(q.i*q.k - q.r*q.j));
l.vy = make_Vec3f(2.0f*(q.i*q.j - q.r*q.k), (q.r*q.r - q.i*q.i + q.j*q.j - q.k*q.k), 2.0f*(q.j*q.k + q.r*q.i));
l.vz = make_Vec3f(2.0f*(q.i*q.k + q.r*q.j), 2.0f*(q.j*q.k - q.r*q.i), q.r*q.r - q.i*q.i - q.j*q.j + q.k*q.k);
return l;
}
inline uniform LinearSpace3f make_LinearSpace3f_identity()
{
return make_LinearSpace3f(make_Vec3f(1.f,0.f,0.f),
make_Vec3f(0.f,1.f,0.f),
make_Vec3f(0.f,0.f,1.f));
}
/*! return scale matrix */
inline uniform LinearSpace3f make_LinearSpace3f_scale(const uniform Vec3f& s)
{
return make_LinearSpace3f( make_Vec3f( s.x, 0.0f, 0.0f),
make_Vec3f(0.0f, s.y, 0.0f),
make_Vec3f(0.0f, 0.0f, s.z));
}
/*! return matrix for rotation around arbitrary axis */
inline uniform LinearSpace3f make_LinearSpace3f_rotate(const uniform Vec3f& _u, const uniform float& r)
{
uniform Vec3f u = normalize(_u);
uniform float s = sin(r), c = cos(r);
return make_LinearSpace3f(make_Vec3f(u.x*u.x+(1-u.x*u.x)*c, u.x*u.y*(1-c)+u.z*s, u.x*u.z*(1-c)-u.y*s),
make_Vec3f(u.x*u.y*(1-c)-u.z*s, u.y*u.y+(1-u.y*u.y)*c, u.y*u.z*(1-c)+u.x*s),
make_Vec3f(u.x*u.z*(1-c)+u.y*s, u.y*u.z*(1-c)-u.x*s, u.z*u.z+(1-u.z*u.z)*c));
}
/*! return matrix for rotation around arbitrary axis */
inline varying LinearSpace3f make_LinearSpace3f_rotate(const varying Vec3f& _u, const varying float& r)
{
varying Vec3f u = normalize(_u);
varying float s = sin(r), c = cos(r);
return make_LinearSpace3f(make_Vec3f(u.x*u.x+(1-u.x*u.x)*c, u.x*u.y*(1-c)+u.z*s, u.x*u.z*(1-c)-u.y*s),
make_Vec3f(u.x*u.y*(1-c)-u.z*s, u.y*u.y+(1-u.y*u.y)*c, u.y*u.z*(1-c)+u.x*s),
make_Vec3f(u.x*u.z*(1-c)+u.y*s, u.y*u.z*(1-c)-u.x*s, u.z*u.z+(1-u.z*u.z)*c));
}
/*! return matrix for rotation around arbitrary axis */
inline varying LinearSpace3f make_LinearSpace3f_rotate(const uniform Vec3f& _u, const varying float& r)
{
varying Vec3f u = normalize(_u);
varying float s = sin(r), c = cos(r);
return make_LinearSpace3f(make_Vec3f(u.x*u.x+(1-u.x*u.x)*c, u.x*u.y*(1-c)+u.z*s, u.x*u.z*(1-c)-u.y*s),
make_Vec3f(u.x*u.y*(1-c)-u.z*s, u.y*u.y+(1-u.y*u.y)*c, u.y*u.z*(1-c)+u.x*s),
make_Vec3f(u.x*u.z*(1-c)+u.y*s, u.y*u.z*(1-c)-u.x*s, u.z*u.z+(1-u.z*u.z)*c));
}
////////////////////////////////////////////////////////////////////////////////
// Unary Operators
////////////////////////////////////////////////////////////////////////////////
inline uniform LinearSpace3f neg(const uniform LinearSpace3f &l) { return make_LinearSpace3f(neg(l.vx),neg(l.vy),neg(l.vz)); }
inline varying LinearSpace3f neg(const varying LinearSpace3f &l) { return make_LinearSpace3f(neg(l.vx),neg(l.vy),neg(l.vz)); }
/*! compute the determinant of the matrix */
inline uniform float det(const uniform LinearSpace3f &l) { return dot(l.vx,cross(l.vy,l.vz)); }
inline varying float det(const varying LinearSpace3f &l) { return dot(l.vx,cross(l.vy,l.vz)); }
/*! compute transposed matrix */
inline uniform LinearSpace3f transposed(const uniform LinearSpace3f &l) {
return make_LinearSpace3f(make_Vec3f(l.vx.x,l.vy.x,l.vz.x),
make_Vec3f(l.vx.y,l.vy.y,l.vz.y),
make_Vec3f(l.vx.z,l.vy.z,l.vz.z));
}
inline varying LinearSpace3f transposed(const varying LinearSpace3f &l) {
return make_LinearSpace3f(make_Vec3f(l.vx.x,l.vy.x,l.vz.x),
make_Vec3f(l.vx.y,l.vy.y,l.vz.y),
make_Vec3f(l.vx.z,l.vy.z,l.vz.z));
}
/*! compute adjoint matrix */
inline uniform LinearSpace3f adjoint(const uniform LinearSpace3f &l) {
return transposed(make_LinearSpace3f(cross(l.vy,l.vz),cross(l.vz,l.vx),cross(l.vx,l.vy)));
}
inline varying LinearSpace3f adjoint(const varying LinearSpace3f &l) {
return transposed(make_LinearSpace3f(cross(l.vy,l.vz),cross(l.vz,l.vx),cross(l.vx,l.vy)));
}
/*! calculates orthogonal coordinate frame with z-Vector pointing towards N */
inline uniform LinearSpace3f frame(const uniform Vec3f &N)
{
const uniform Vec3f dx0 = make_Vec3f(0.0f,N.z,-N.y);
const uniform Vec3f dx1 = make_Vec3f(-N.z,0.0f,N.x);
const uniform Vec3f dx = normalize(dot(dx0,dx0) > dot(dx1,dx1) ? dx0 : dx1);
const uniform Vec3f dy = normalize(cross(N,dx));
return make_LinearSpace3f(dx,dy,N);
}
inline varying LinearSpace3f frame(const varying Vec3f &N)
{
const varying Vec3f dx0 = make_Vec3f(0.0f,N.z,-N.y);
const varying Vec3f dx1 = make_Vec3f(-N.z,0.0f,N.x);
const varying Vec3f dx = normalize(dot(dx0,dx0) > dot(dx1,dx1) ? dx0 : dx1);
const varying Vec3f dy = normalize(cross(N,dx));
return make_LinearSpace3f(dx,dy,N);
}
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
inline uniform LinearSpace3f operator+(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a.vx+b.vx, a.vy+b.vy, a.vz+b.vz); }
inline varying LinearSpace3f operator+(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return make_LinearSpace3f(a.vx+b.vx, a.vy+b.vy, a.vz+b.vz); }
inline uniform LinearSpace3f operator-(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a.vx-b.vx, a.vy-b.vy, a.vz-b.vz); }
inline varying LinearSpace3f operator-(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return make_LinearSpace3f(a.vx-b.vx, a.vy-b.vy, a.vz-b.vz); }
inline uniform Vec3f operator*(const uniform LinearSpace3f &l, const uniform Vec3f &v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
inline varying Vec3f operator*(const uniform LinearSpace3f &l, const varying Vec3f &v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
inline varying Vec3f operator*(const varying LinearSpace3f &l, const varying Vec3f &v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
inline uniform LinearSpace3f operator*(const uniform float &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
inline uniform LinearSpace3f operator*(const uniform LinearSpace3f &a, const uniform float &b) { return make_LinearSpace3f(a.vx*b, a.vy*b, a.vz*b); }
inline uniform LinearSpace3f operator*(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
inline varying LinearSpace3f operator*(const varying float &a, const varying LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
inline varying LinearSpace3f operator*(const varying LinearSpace3f &a, const varying float &b) { return make_LinearSpace3f(a.vx*b, a.vy*b, a.vz*b); }
inline varying LinearSpace3f operator*(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
inline varying LinearSpace3f operator*(const varying float &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
inline varying LinearSpace3f operator*(const uniform LinearSpace3f &a, const varying float &b) { return make_LinearSpace3f(a.vx*b, a.vy*b, a.vz*b); }
inline uniform Vec3f xfmVector(const uniform LinearSpace3f l, const uniform Vec3f v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
inline varying Vec3f xfmVector(const uniform LinearSpace3f l, const varying Vec3f v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
inline varying Vec3f xfmVector(const varying LinearSpace3f l, const varying Vec3f v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators
////////////////////////////////////////////////////////////////////////////////
inline uniform bool eq(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return eq(a.vx,b.vx) & eq(a.vy,b.vy) & eq(a.vz,b.vz); }
inline varying bool eq(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return eq(a.vx,b.vx) & eq(a.vy,b.vy) & eq(a.vz,b.vz); }
inline uniform bool ne(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return ne(a.vx,b.vx) | ne(a.vy,b.vy) | ne(a.vz,b.vz); }
inline varying bool ne(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return ne(a.vx,b.vx) | ne(a.vy,b.vy) | ne(a.vz,b.vz); }
////////////////////////////////////////////////////////////////////////////////
// Unary Operators
////////////////////////////////////////////////////////////////////////////////
/*! compute inverse matrix */
inline uniform LinearSpace3f rcp(const uniform LinearSpace3f &l) { return rcp(det(l))*adjoint(l); }
inline varying LinearSpace3f rcp(const varying LinearSpace3f &l) { return rcp(det(l))*adjoint(l); }
inline uniform Vec3f xfmNormal(const uniform LinearSpace3f l, const uniform Vec3f v) { return xfmVector(transposed(rcp(l)),v); }
inline varying Vec3f xfmNormal(const uniform LinearSpace3f l, const varying Vec3f v) { return xfmVector(transposed(rcp(l)),v); }
inline varying Vec3f xfmNormal(const varying LinearSpace3f l, const varying Vec3f v) { return xfmVector(transposed(rcp(l)),v); }
////////////////////////////////////////////////////////////////////////////////
// Interpolation
////////////////////////////////////////////////////////////////////////////////
inline uniform LinearSpace3f lerp(uniform float factor, const uniform LinearSpace3f& a, const uniform LinearSpace3f& b) {
return make_LinearSpace3f(lerp(factor, a.vx, b.vx), lerp(factor, a.vy, b.vy), lerp(factor, a.vz, b.vz));
}
inline varying LinearSpace3f lerp(varying float factor, const uniform LinearSpace3f& a, const uniform LinearSpace3f& b) {
return make_LinearSpace3f(lerp(factor, a.vx, b.vx), lerp(factor, a.vy, b.vy), lerp(factor, a.vz, b.vz));
}
inline varying LinearSpace3f lerp(varying float factor, const varying LinearSpace3f& a, const varying LinearSpace3f& b) {
return make_LinearSpace3f(lerp(factor, a.vx, b.vx), lerp(factor, a.vy, b.vy), lerp(factor, a.vz, b.vz));
}
////////////////////////////////////////////////////////////////////////////////
// Norms
////////////////////////////////////////////////////////////////////////////////
inline uniform float norm_1(const uniform LinearSpace3f& l)
{
uniform float sum = 0;
sum += reduce_add(abs(l.vx));
sum += reduce_add(abs(l.vy));
sum += reduce_add(abs(l.vz));
return sum / 9.f;
}
inline uniform Quaternion3f make_Quaternion3f(const uniform LinearSpace3f & l)
{
uniform Quaternion3f q;
const uniform float tr = l.vx.x + l.vy.y + l.vz.z;
if (tr > 0)
{
const uniform float S = sqrt(tr+1.0) * 2;
q.r = 0.25 * S;
q.i = (l.vy.z - l.vz.y) / S;
q.j = (l.vz.x - l.vx.z) / S;
q.k = (l.vx.y - l.vy.x) / S;
}
else if ((l.vx.x > l.vy.y)&(l.vx.x > l.vz.z))
{
const uniform float S = sqrt(1.0 + l.vx.x - l.vy.y - l.vz.z) * 2;
q.r = (l.vy.z - l.vz.y) / S;
q.i = 0.25 * S;
q.j = (l.vy.x + l.vx.y) / S;
q.k = (l.vz.x + l.vx.z) / S;
}
else if (l.vy.y > l.vz.z)
{
const uniform float S = sqrt(1.0 + l.vy.y - l.vx.x - l.vz.z) * 2;
q.r = (l.vz.x - l.vx.z) / S;
q.i = (l.vy.x + l.vx.y) / S;
q.j = 0.25 * S;
q.k = (l.vz.y + l.vy.z) / S;
}
else
{
const uniform float S = sqrt(1.0 + l.vz.z - l.vx.x - l.vy.y) * 2;
q.r = (l.vx.y - l.vy.x) / S;
q.i = (l.vz.x + l.vx.z) / S;
q.j = (l.vz.y + l.vy.z) / S;
q.k = 0.25 * S;
}
return q;
}
inline varying Quaternion3f make_Quaternion3f(const varying LinearSpace3f & l)
{
Quaternion3f q;
const float tr = l.vx.x + l.vy.y + l.vz.z;
if (tr > 0)
{
const float S = sqrt(tr+1.0) * 2;
q.r = 0.25 * S;
q.i = (l.vy.z - l.vz.y) / S;
q.j = (l.vz.x - l.vx.z) / S;
q.k = (l.vx.y - l.vy.x) / S;
}
else if ((l.vx.x > l.vy.y)&(l.vx.x > l.vz.z))
{
const float S = sqrt(1.0 + l.vx.x - l.vy.y - l.vz.z) * 2;
q.r = (l.vy.z - l.vz.y) / S;
q.i = 0.25 * S;
q.j = (l.vy.x + l.vx.y) / S;
q.k = (l.vz.x + l.vx.z) / S;
}
else if (l.vy.y > l.vz.z)
{
const float S = sqrt(1.0 + l.vy.y - l.vx.x - l.vz.z) * 2;
q.r = (l.vz.x - l.vx.z) / S;
q.i = (l.vy.x + l.vx.y) / S;
q.j = 0.25 * S;
q.k = (l.vz.y + l.vy.z) / S;
}
else
{
const float S = sqrt(1.0 + l.vz.z - l.vx.x - l.vy.y) * 2;
q.r = (l.vx.y - l.vy.x) / S;
q.i = (l.vz.x + l.vx.z) / S;
q.j = (l.vz.y + l.vy.z) / S;
q.k = 0.25 * S;
}
return q;
}
|