Initial commit.

This commit is contained in:
hal8174 2024-04-23 10:14:24 +02:00
commit d3bb49b3f5
1073 changed files with 484757 additions and 0 deletions

View file

@ -0,0 +1,12 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../../../common/math/affinespace.h"
namespace embree
{
__forceinline bool eq (const AffineSpace3fa& a, const AffineSpace3fa& b) { return a == b; }
}

View file

@ -0,0 +1,135 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "linearspace.isph"
struct AffineSpace3f
{
LinearSpace3f l;
Vec3f p;
};
struct AffineSpace3fa
{
LinearSpace3fa l;
Vec3fa p;
};
////////////////////////////////////////////////////////////////////////////////
/// Constructors
////////////////////////////////////////////////////////////////////////////////
inline uniform AffineSpace3f make_AffineSpace3f(const uniform LinearSpace3f l) {
uniform AffineSpace3f xfm; xfm.l = l; xfm.p = make_Vec3f(0,0,0); return xfm;
}
inline varying AffineSpace3f make_AffineSpace3f(const varying LinearSpace3f l) {
varying AffineSpace3f xfm; xfm.l = l; xfm.p = make_Vec3f(0,0,0); return xfm;
}
inline uniform AffineSpace3f make_AffineSpace3f(const uniform LinearSpace3f l, const uniform Vec3f p) {
uniform AffineSpace3f xfm; xfm.l = l; xfm.p = p; return xfm;
}
inline varying AffineSpace3f make_AffineSpace3f(const varying LinearSpace3f l, const varying Vec3f p) {
varying AffineSpace3f xfm; xfm.l = l; xfm.p = p; return xfm;
}
inline uniform AffineSpace3f make_AffineSpace3f(const uniform AffineSpace3fa l) {
uniform AffineSpace3f xfm; xfm.l = make_LinearSpace3f(l.l); xfm.p = make_Vec3f(l.p); return xfm;
}
inline varying AffineSpace3f make_AffineSpace3f(const varying AffineSpace3fa l) {
varying AffineSpace3f xfm; xfm.l = make_LinearSpace3f(l.l); xfm.p = make_Vec3f(l.p); return xfm;
}
inline uniform AffineSpace3f make_AffineSpace3f(const uniform Vec3f x, const uniform Vec3f y, const uniform Vec3f z, const uniform Vec3f p) {
uniform AffineSpace3f xfm; xfm.l.vx = x; xfm.l.vy = y; xfm.l.vz = z; xfm.p = p; return xfm;
}
inline varying AffineSpace3f make_AffineSpace3f(const varying Vec3f x, const varying Vec3f y, const varying Vec3f z, const varying Vec3f p) {
varying AffineSpace3f xfm; xfm.l.vx = x; xfm.l.vy = y; xfm.l.vz = z; xfm.p = p; return xfm;
}
////////////////////////////////////////////////////////////////////////////////
// Unary Operators
////////////////////////////////////////////////////////////////////////////////
inline uniform AffineSpace3f neg(const uniform AffineSpace3f a) { return make_AffineSpace3f(neg(a.l),neg(a.p)); }
inline varying AffineSpace3f neg(const varying AffineSpace3f a) { return make_AffineSpace3f(neg(a.l),neg(a.p)); }
inline uniform AffineSpace3f rcp( const uniform AffineSpace3f a) { uniform LinearSpace3f il = rcp(a.l); return make_AffineSpace3f(il,neg(il*a.p)); }
inline varying AffineSpace3f rcp( const varying AffineSpace3f a) { varying LinearSpace3f il = rcp(a.l); return make_AffineSpace3f(il,neg(il*a.p)); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
inline uniform AffineSpace3f operator+(const uniform AffineSpace3f a, const uniform AffineSpace3f b) { return make_AffineSpace3f(a.l+b.l, a.p+b.p); }
inline varying AffineSpace3f operator+(const varying AffineSpace3f a, const varying AffineSpace3f b) { return make_AffineSpace3f(a.l+b.l, a.p+b.p); }
inline uniform AffineSpace3f operator-(const uniform AffineSpace3f a, const uniform AffineSpace3f b) { return make_AffineSpace3f(a.l-b.l, a.p-b.p); }
inline varying AffineSpace3f operator-(const varying AffineSpace3f a, const varying AffineSpace3f b) { return make_AffineSpace3f(a.l-b.l, a.p-b.p); }
inline uniform AffineSpace3f operator*( const uniform float a, const uniform AffineSpace3f b ) { return make_AffineSpace3f(a*b.l,a*b.p); }
inline uniform AffineSpace3f operator*( const uniform AffineSpace3f a, const uniform float b ) { return make_AffineSpace3f(a.l*b,a.p*b); }
inline uniform AffineSpace3f operator*( const uniform AffineSpace3f a, const uniform AffineSpace3f b ) { return make_AffineSpace3f(a.l*b.l,a.l*b.p+a.p); }
inline varying AffineSpace3f operator*( const varying float a, const varying AffineSpace3f b ) { return make_AffineSpace3f(a*b.l,a*b.p); }
inline varying AffineSpace3f operator*( const varying AffineSpace3f a, const varying float b ) { return make_AffineSpace3f(a.l*b,a.p*b); }
inline varying AffineSpace3f operator*( const varying AffineSpace3f a, const varying AffineSpace3f b ) { return make_AffineSpace3f(a.l*b.l,a.l*b.p + a.p); }
inline varying AffineSpace3f operator*( const varying float a, const uniform AffineSpace3f b ) { return make_AffineSpace3f(a*b.l,a*b.p); }
inline varying AffineSpace3f operator*( const uniform AffineSpace3f a, const varying float b ) { return make_AffineSpace3f(a.l*b,a.p*b); }
inline uniform Vec3f xfmPoint (const uniform AffineSpace3f a, const uniform Vec3f v) { return xfmVector(a.l,v)+a.p; }
inline varying Vec3f xfmPoint (const uniform AffineSpace3f a, const varying Vec3f v) { return xfmVector(a.l,v)+a.p; }
inline varying Vec3f xfmPoint (const varying AffineSpace3f a, const varying Vec3f v) { return xfmVector(a.l,v)+a.p; }
inline uniform Vec3f xfmVector(const uniform AffineSpace3f a, const uniform Vec3f v) { return xfmVector(a.l,v); }
inline varying Vec3f xfmVector(const uniform AffineSpace3f a, const varying Vec3f v) { return xfmVector(a.l,v); }
inline varying Vec3f xfmVector(const varying AffineSpace3f a, const varying Vec3f v) { return xfmVector(a.l,v); }
inline uniform Vec3f xfmNormal(const uniform AffineSpace3f a, const uniform Vec3f v) { return xfmNormal(a.l,v); }
inline varying Vec3f xfmNormal(const uniform AffineSpace3f a, const varying Vec3f v) { return xfmNormal(a.l,v); }
inline varying Vec3f xfmNormal(const varying AffineSpace3f a, const varying Vec3f v) { return xfmNormal(a.l,v); }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators
////////////////////////////////////////////////////////////////////////////////
inline uniform bool eq(const uniform AffineSpace3f a, const uniform AffineSpace3f b) { return eq(a.l,b.l) & eq(a.p,b.p); }
inline varying bool eq(const varying AffineSpace3f a, const varying AffineSpace3f b) { return eq(a.l,b.l) & eq(a.p,b.p); }
inline uniform bool ne(const uniform AffineSpace3f a, const uniform AffineSpace3f b) { return ne(a.l,b.l) | ne(a.p,b.p); }
inline varying bool ne(const varying AffineSpace3f a, const varying AffineSpace3f b) { return ne(a.l,b.l) | ne(a.p,b.p); }
////////////////////////////////////////////////////////////////////////////////
// Interpolation
////////////////////////////////////////////////////////////////////////////////
inline uniform AffineSpace3f lerp(uniform float factor, const uniform AffineSpace3f& a, const uniform AffineSpace3f& b) {
return make_AffineSpace3f(lerp(factor, a.l, b.l), lerp(factor, a.p, b.p));
}
inline varying AffineSpace3f lerp(varying float factor, const uniform AffineSpace3f& a, const uniform AffineSpace3f& b) {
return make_AffineSpace3f(lerp(factor, a.l, b.l), lerp(factor, a.p, b.p));
}
/*! return scale matrix */
inline uniform AffineSpace3f make_AffineSpace3f_scale(const uniform Vec3f& s) {
return make_AffineSpace3f(make_LinearSpace3f_scale(s));
}
/*! return translation matrix */
inline uniform AffineSpace3f make_AffineSpace3f_translate(const uniform Vec3f& p) {
return make_AffineSpace3f(make_Vec3f(1,0,0),make_Vec3f(0,1,0),make_Vec3f(0,0,1),p);
}
/*! return translation matrix */
inline AffineSpace3f make_AffineSpace3f_translate(const Vec3f& p) {
return make_AffineSpace3f(make_Vec3f(1,0,0),make_Vec3f(0,1,0),make_Vec3f(0,0,1),p);
}
/*! return matrix for rotation around arbitrary axis and point */
inline uniform AffineSpace3f make_AffineSpace3f_rotate (const uniform Vec3f& p, const uniform Vec3f& u, const uniform float& r) {
return (make_AffineSpace3f_translate(+p) * make_AffineSpace3f(make_LinearSpace3f_rotate(u,r))) * make_AffineSpace3f_translate(neg(p));
}

View file

@ -0,0 +1,56 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/vec.h"
namespace embree
{
Vec3fa closestPointTriangle(Vec3fa const& p, Vec3fa const& a, Vec3fa const& b, Vec3fa const& c)
{
const Vec3fa ab = b - a;
const Vec3fa ac = c - a;
const Vec3fa ap = p - a;
const float d1 = dot(ab, ap);
const float d2 = dot(ac, ap);
if (d1 <= 0.f && d2 <= 0.f) return a;
const Vec3fa bp = p - b;
const float d3 = dot(ab, bp);
const float d4 = dot(ac, bp);
if (d3 >= 0.f && d4 <= d3) return b;
const Vec3fa cp = p - c;
const float d5 = dot(ab, cp);
const float d6 = dot(ac, cp);
if (d6 >= 0.f && d5 <= d6) return c;
const float vc = d1 * d4 - d3 * d2;
if (vc <= 0.f && d1 >= 0.f && d3 <= 0.f)
{
const float v = d1 / (d1 - d3);
return a + v * ab;
}
const float vb = d5 * d2 - d1 * d6;
if (vb <= 0.f && d2 >= 0.f && d6 <= 0.f)
{
const float v = d2 / (d2 - d6);
return a + v * ac;
}
const float va = d3 * d6 - d5 * d4;
if (va <= 0.f && (d4 - d3) >= 0.f && (d5 - d6) >= 0.f)
{
const float v = (d4 - d3) / ((d4 - d3) + (d5 - d6));
return b + v * (c - b);
}
const float denom = 1.f / (va + vb + vc);
const float v = vb * denom;
const float w = vc * denom;
return a + v * ab + w * ac;
}
}

View file

@ -0,0 +1,100 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/vec.isph"
Vec3f closestPointTriangle(Vec3f const& p, Vec3f const& a, Vec3f const& b, Vec3f const& c)
{
const Vec3f ab = b - a;
const Vec3f ac = c - a;
const Vec3f ap = p - a;
const float d1 = dot(ab, ap);
const float d2 = dot(ac, ap);
if (d1 <= 0.f && d2 <= 0.f) return a;
const Vec3f bp = p - b;
const float d3 = dot(ab, bp);
const float d4 = dot(ac, bp);
if (d3 >= 0.f && d4 <= d3) return b;
const Vec3f cp = p - c;
const float d5 = dot(ab, cp);
const float d6 = dot(ac, cp);
if (d6 >= 0.f && d5 <= d6) return c;
const float vc = d1 * d4 - d3 * d2;
if (vc <= 0.f && d1 >= 0.f && d3 <= 0.f)
{
const float v = d1 / (d1 - d3);
return a + v * ab;
}
const float vb = d5 * d2 - d1 * d6;
if (vb <= 0.f && d2 >= 0.f && d6 <= 0.f)
{
const float v = d2 / (d2 - d6);
return a + v * ac;
}
const float va = d3 * d6 - d5 * d4;
if (va <= 0.f && (d4 - d3) >= 0.f && (d5 - d6) >= 0.f)
{
const float v = (d4 - d3) / ((d4 - d3) + (d5 - d6));
return b + v * (c - b);
}
const float denom = 1.f / (va + vb + vc);
const float v = vb * denom;
const float w = vc * denom;
return a + v * ab + w * ac;
}
uniform Vec3f closestPointTriangle(uniform Vec3f& p, uniform Vec3f& a, uniform Vec3f& b, uniform Vec3f& c)
{
const uniform Vec3f ab = b - a;
const uniform Vec3f ac = c - a;
const uniform Vec3f ap = p - a;
const uniform float d1 = dot(ab, ap);
const uniform float d2 = dot(ac, ap);
if (d1 <= 0.f && d2 <= 0.f) return a;
const uniform Vec3f bp = p - b;
const uniform float d3 = dot(ab, bp);
const uniform float d4 = dot(ac, bp);
if (d3 >= 0.f && d4 <= d3) return b;
const uniform Vec3f cp = p - c;
const uniform float d5 = dot(ab, cp);
const uniform float d6 = dot(ac, cp);
if (d6 >= 0.f && d5 <= d6) return c;
const uniform float vc = d1 * d4 - d3 * d2;
if (vc <= 0.f && d1 >= 0.f && d3 <= 0.f)
{
const uniform float v = d1 / (d1 - d3);
return a + v * ab;
}
const uniform float vb = d5 * d2 - d1 * d6;
if (vb <= 0.f && d2 >= 0.f && d6 <= 0.f)
{
const uniform float v = d2 / (d2 - d6);
return a + v * ac;
}
const uniform float va = d3 * d6 - d5 * d4;
if (va <= 0.f && (d4 - d3) >= 0.f && (d5 - d6) >= 0.f)
{
const uniform float v = (d4 - d3) / ((d4 - d3) + (d5 - d6));
return b + v * (c - b);
}
const uniform float denom = 1.f / (va + vb + vc);
const uniform float v = vb * denom;
const uniform float w = vc * denom;
return a + v * ab + w * ac;
}

View file

@ -0,0 +1,7 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../../../common/math/linearspace3.h"

View file

@ -0,0 +1,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;
}

View file

@ -0,0 +1,6 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../../../common/math/emath.h"

View file

@ -0,0 +1,184 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../common.isph"
// ------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------
#define inf (1e100f)
#define pos_inf (1e100f)
#define neg_inf (-1e100f)
#define M_PI 3.14159265358979323846f
#define pi 3.14159265358979323846f
#define two_pi 6.283185307179586232f
#define four_pi 12.566370614359172464f
#define one_over_pi 0.31830988618379069122f
#define one_over_two_pi 0.15915494309189534561f
#define one_over_four_pi 0.079577471545947672804f
#define one_over_two_pi_sqr 0.050660591821168885722f
/*! c-style reciprocal. required since ispc 1.7 due to type changes in this version */
inline float rcpf(const float f) { return rcp(f); }
/*! c-style reciprocal. required since ispc 1.7 due to type changes in this version */
inline uniform float rcpf(const uniform float f) { return rcp(f); }
/*! c-style square root. */
inline float sqrtf(const float f) { return sqrt(f); }
/*! c-style square root */
inline uniform float sqrtf(const uniform float f) { return sqrt(f); }
/*! c-style reciprocal square root. */
inline float rsqrtf(const float f) { return rsqrt(f); }
/*! c-style reciprocal square root */
inline uniform float rsqrtf(const uniform float f) { return rsqrt(f); }
/*! square. */
inline float sqr(const float f) { return f*f; }
/*! square. */
inline uniform float sqr(const uniform float f) { return f*f; }
/*! c-style square. */
inline float sqrf(const float f) { return f*f; }
/*! c-style square */
inline uniform float sqrf(const uniform float f) { return f*f; }
/*! c-style pow function. */
inline float powf(const float a, const float b) { return pow(a,b); }
/*! c-style pow function */
inline uniform float powf(const uniform float a, const uniform float b) { return pow(a,b); }
/*! c-style cos. */
inline float cosf(const float f) { return cos(f); }
/*! c-style cos */
inline uniform float cosf(const uniform float f) { return cos(f); }
/*! c-style sin. */
inline float sinf(const float f) { return sin(f); }
/*! c-style sin */
inline uniform float sinf(const uniform float f) { return sin(f); }
/*! c-style exp. */
inline float expf(const float f) { return exp(f); }
/*! c-style exp */
inline uniform float expf(const uniform float f) { return exp(f); }
/*! c-style log. */
inline float logf(const float f) { return log(f); }
/*! c-style log */
inline uniform float logf(const uniform float f) { return log(f); }
/*! c-style abs. */
inline float absf(const float f) { return abs(f); }
/*! c-style abs */
inline uniform float absf(const uniform float f) { return abs(f); }
// inline float clamp(const float f) { return max(min(1.f,f),0.f); }
inline uniform float rcp_safe(uniform float f) { return rcpf((abs(f) < 1e-8f) ? 1e-8f : f); }
inline varying float rcp_safe(varying float f) { return rcpf((abs(f) < 1e-8f) ? 1e-8f : f); }
inline uniform float sqrt_safe(uniform float f) { return sqrt(max(f, 0.0f)); }
inline varying float sqrt_safe(varying float f) { return sqrt(max(f, 0.0f)); }
inline uniform float clamp (const uniform float v) { return max(0.0f,min(v,1.0f)); }
inline varying float clamp (const varying float v) { return max(0.0f,min(v,1.0f)); }
inline uniform float clamp (const uniform float v, const uniform float lower, const uniform float upper) { return max(lower,min(v,upper)); }
inline varying float clamp (const varying float v, const varying float lower, const varying float upper) { return max(lower,min(v,upper)); }
inline uniform int clamp (const uniform int v, const uniform int lower, const uniform int upper) { return max(lower,min(v,upper)); }
inline varying int clamp (const varying int v, const varying int lower, const varying int upper) { return max(lower,min(v,upper)); }
inline uniform float frac(const uniform float x) { return x - floor(x); }
inline varying float frac(const varying float x) { return x - floor(x); }
inline uniform float deg2rad (const uniform float x) { return x * 1.74532925199432957692e-2f; }
inline varying float deg2rad (const varying float x) { return x * 1.74532925199432957692e-2f; }
inline uniform float rad2deg (const uniform float x) { return x * 5.72957795130823208768e1f; }
inline varying float rad2deg (const varying float x) { return x * 5.72957795130823208768e1f; }
inline float cos2sin(const float f) { return sqrt(max(0.f, 1.f - sqr(f))); }
inline float sin2cos(const float f) { return cos2sin(f); }
inline uniform float nextafter(const uniform float a, const uniform float b)
{
//! Match the behavior of the C99 math.h function.
if (a == b) return(b);
//! We will compute the smallest representable floating increment or decrement around 'a'.
uniform float delta = (b > a) ? 1.0f : -1.0f;
//! Iteratively compute the positive or negative increment.
while (a + 0.5f * delta != a) delta *= 0.5f;
//! Return the smallest number greater than 'a' or the largest number smaller than 'a'.
return(a + delta);
}
#define __define_lerp(TYPE) \
inline TYPE lerp(float factor, TYPE a, TYPE b) \
{ \
return (1-factor)* a + factor * b; \
} \
inline uniform TYPE lerp(uniform float factor, uniform TYPE a, uniform TYPE b) \
{ \
return (1-factor)* a + factor * b; \
}
__define_lerp(int8)
__define_lerp(int32)
__define_lerp(float)
__define_lerp(uint8)
__define_lerp(uint32)
#undef __define_lerp
// ------------------------------------------------------------------
// min4/max4, for all types
// ------------------------------------------------------------------
#define __define_op4T(MM,TYPE) \
inline uniform TYPE MM##4(uniform TYPE a, uniform TYPE b, \
uniform TYPE c, uniform TYPE d) \
{ \
return MM(a, MM(b, MM(c, d))); \
} \
inline varying TYPE MM##4(varying TYPE a, varying TYPE b, \
varying TYPE c, varying TYPE d) \
{ \
return MM(a, MM(b, MM(c, d))); \
}
#define __define_op4(MM) \
__define_op4T(MM,int8) \
__define_op4T(MM,int32) \
__define_op4T(MM,uint8) \
__define_op4T(MM,uint32) \
__define_op4T(MM,float) \
__define_op4T(MM,double)
__define_op4(min)
__define_op4(max)
#undef __define_op4T
#undef __define_op4
#define SIMILAR_EPSILON .00001f
inline float similar(float a, float b)
{
return absf(a - b) <= SIMILAR_EPSILON;
}
inline uniform float similar(uniform float a, uniform float b)
{
return absf(a - b) <= SIMILAR_EPSILON;
}
#undef SIMILAR_EPSILON

View file

@ -0,0 +1,7 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../../../common/math/quaternion.h"

View file

@ -0,0 +1,124 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "vec.isph"
struct Quaternion3f
{
float r, i, j, k;
};
////////////////////////////////////////////////////////////////////////////////
/// Constructors
////////////////////////////////////////////////////////////////////////////////
inline uniform Quaternion3f make_Quaternion3f(const uniform Vec4f& v) {
uniform Quaternion3f q; q.r = v.x; q.i = v.y; q.j = v.z; q.k = v.w; return q;
}
inline varying Quaternion3f make_Quaternion3f(const varying Vec4f& v) {
Quaternion3f q; q.r = v.x; q.i = v.y; q.j = v.z; q.k = v.w; return q;
}
/*! return quaternion for rotation around arbitrary axis */
inline varying Quaternion3f make_Quaternion3f_rotate(const varying Vec3f& u, const varying float r) {
Quaternion3f q;
Vec3f uu = sin(0.5*r)*normalize(u);
q.r = cos(0.5*r);
q.i = uu.x;
q.j = uu.y;
q.k = uu.z;
return q;
}
/*! return quaternion for rotation around arbitrary axis */
inline uniform Quaternion3f make_Quaternion3f_rotate(const uniform Vec3f& u, const uniform float r) {
uniform Quaternion3f q;
uniform Vec3f uu = sin(0.5*r)*normalize(u);
q.r = cos(0.5*r);
q.i = uu.x;
q.j = uu.y;
q.k = uu.z;
return q;
}
////////////////////////////////////////////////////////////////////////////////
// Unary Operators
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
inline uniform Quaternion3f operator*(const uniform float a, const uniform Quaternion3f& q) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
inline uniform Quaternion3f operator*(const uniform Quaternion3f& q, const uniform float a) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
inline varying Quaternion3f operator*(const varying float a, const uniform Quaternion3f& q) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
inline varying Quaternion3f operator*(const uniform Quaternion3f& q, const varying float a) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
inline varying Quaternion3f operator*(const varying float a, const varying Quaternion3f& q) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
inline varying Quaternion3f operator*(const varying Quaternion3f& q, const varying float a) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
inline uniform Quaternion3f operator+(const uniform Quaternion3f& q0, const uniform Quaternion3f& q1) { return make_Quaternion3f(make_Vec4f(q0.r+q1.r, q0.i+q1.i, q0.j+q1.j, q0.k+q1.k)); }
inline uniform Quaternion3f operator-(const uniform Quaternion3f& q0, const uniform Quaternion3f& q1) { return make_Quaternion3f(make_Vec4f(q0.r-q1.r, q0.i-q1.i, q0.j-q1.j, q0.k-q1.k)); }
inline varying Quaternion3f operator+(const varying Quaternion3f& q0, const varying Quaternion3f& q1) { return make_Quaternion3f(make_Vec4f(q0.r+q1.r, q0.i+q1.i, q0.j+q1.j, q0.k+q1.k)); }
inline varying Quaternion3f operator-(const varying Quaternion3f& q0, const varying Quaternion3f& q1) { return make_Quaternion3f(make_Vec4f(q0.r-q1.r, q0.i-q1.i, q0.j-q1.j, q0.k-q1.k)); }
inline uniform float dot(const uniform Quaternion3f& q0, const uniform Quaternion3f& q1) { return q0.r*q1.r + q0.i*q1.i + q0.j*q1.j + q0.k*q1.k; }
inline varying float dot(const varying Quaternion3f& q0, const varying Quaternion3f& q1) { return q0.r*q1.r + q0.i*q1.i + q0.j*q1.j + q0.k*q1.k; }
inline uniform Quaternion3f normalize(const uniform Quaternion3f& q) { uniform const float len = sqrt(dot(q, q)); return make_Quaternion3f(make_Vec4f(q.r/len, q.i/len, q.j/len, q.k/len)); }
inline varying Quaternion3f normalize(const varying Quaternion3f& q) { varying const float len = sqrt(dot(q, q)); return make_Quaternion3f(make_Vec4f(q.r/len, q.i/len, q.j/len, q.k/len)); }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Interpolation
////////////////////////////////////////////////////////////////////////////////
inline uniform Quaternion3f lerp(const uniform factor, const uniform Quaternion3f& a, const uniform Quaternion3f& b) {
return make_Quaternion3f(lerp(factor, make_Vec4f(a.r, a.i, a.j, a.k), make_Vec4f(b.r, b.i, b.j, b.k)));
}
inline varying Quaternion3f lerp(const varying factor, const uniform Quaternion3f& a, const uniform Quaternion3f& b) {
return make_Quaternion3f(lerp(factor, make_Vec4f(a.r, a.i, a.j, a.k), make_Vec4f(b.r, b.i, b.j, b.k)));
}
inline uniform Quaternion3f slerp(const uniform float factor, const uniform Quaternion3f& q1, const uniform Quaternion3f& q2)
{
uniform const float cosTheta = dot(q1, q2);
if (cosTheta > .9995f)
return normalize((1 - factor) * q1 + factor * q2);
else {
uniform const float theta = acos(clamp(cosTheta, -1.f, 1.f));
uniform const float thetap = theta * factor;
uniform Quaternion3f qperp = normalize(q2 - q1 * cosTheta);
return q1 * cos(thetap) + qperp * sin(thetap);
}
}
inline varying Quaternion3f slerp(const varying float factor, const uniform Quaternion3f& q1, const uniform Quaternion3f& q2)
{
uniform const float cosTheta = dot(q1, q2);
if (cosTheta > .9995f)
return normalize((1 - factor) * q1 + factor * q2);
else {
const float theta = acos(clamp(cosTheta, -1.f, 1.f));
const float thetap = theta * factor;
Quaternion3f qperp = normalize(q2 - q1 * cosTheta);
return q1 * cos(thetap) + qperp * sin(thetap);
}
}
inline varying Quaternion3f slerp(const varying float factor, const varying Quaternion3f& q1, const varying Quaternion3f& q2)
{
const float cosTheta = dot(q1, q2);
if (cosTheta > .9995f)
return normalize((1 - factor) * q1 + factor * q2);
else {
const float theta = acos(clamp(cosTheta, -1.f, 1.f));
const float thetap = theta * factor;
Quaternion3f qperp = normalize(q2 - q1 * cosTheta);
return q1 * cos(thetap) + qperp * sin(thetap);
}
}

View file

@ -0,0 +1,114 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/vec.h"
namespace embree {
struct RandomSampler
{
unsigned int s;
};
__forceinline unsigned int MurmurHash3_mix(unsigned int hash, unsigned int k)
{
const unsigned int c1 = 0xcc9e2d51;
const unsigned int c2 = 0x1b873593;
const unsigned int r1 = 15;
const unsigned int r2 = 13;
const unsigned int m = 5;
const unsigned int n = 0xe6546b64;
k *= c1;
k = (k << r1) | (k >> (32 - r1));
k *= c2;
hash ^= k;
hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
return hash;
}
__forceinline unsigned int MurmurHash3_finalize(unsigned int hash)
{
hash ^= hash >> 16;
hash *= 0x85ebca6b;
hash ^= hash >> 13;
hash *= 0xc2b2ae35;
hash ^= hash >> 16;
return hash;
}
__forceinline unsigned int LCG_next(unsigned int value)
{
const unsigned int m = 1664525;
const unsigned int n = 1013904223;
return value * m + n;
}
__forceinline void RandomSampler_init(RandomSampler& self, int id)
{
unsigned int hash = 0;
hash = MurmurHash3_mix(hash, id);
hash = MurmurHash3_finalize(hash);
self.s = hash;
}
__forceinline void RandomSampler_init(RandomSampler& self, int pixelId, int sampleId)
{
unsigned int hash = 0;
hash = MurmurHash3_mix(hash, pixelId);
hash = MurmurHash3_mix(hash, sampleId);
hash = MurmurHash3_finalize(hash);
self.s = hash;
}
__forceinline void RandomSampler_init(RandomSampler& self, int x, int y, int sampleId)
{
RandomSampler_init(self, x | (y << 16), sampleId);
}
__forceinline int RandomSampler_getInt(RandomSampler& self) {
self.s = LCG_next(self.s); return self.s >> 1;
}
__forceinline unsigned int RandomSampler_getUInt(RandomSampler& self) {
self.s = LCG_next(self.s); return self.s;
}
__forceinline float RandomSampler_getFloat(RandomSampler& self) {
return (float)RandomSampler_getInt(self) * 4.656612873077392578125e-10f;
}
__forceinline float RandomSampler_get1D(RandomSampler& self) {
return RandomSampler_getFloat(self);
}
__forceinline Vec2f RandomSampler_get2D(RandomSampler& self)
{
const float u = RandomSampler_get1D(self);
const float v = RandomSampler_get1D(self);
return Vec2f(u,v);
}
__forceinline Vec3fa RandomSampler_get3D(RandomSampler& self)
{
/*
const float u = RandomSampler_get1D(self);
const float v = RandomSampler_get1D(self);
const float w = RandomSampler_get1D(self);
return Vec3fa(u,v,w);
*/
const int u = RandomSampler_getUInt(self);
const int v = RandomSampler_getUInt(self);
const int w = RandomSampler_getUInt(self);
return Vec3fa(srl(Vec3ia(u,v,w), 1)) * 4.656612873077392578125e-10f;
}
} // namespace embree

View file

@ -0,0 +1,104 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../math/vec.isph"
struct RandomSampler
{
unsigned int s;
};
inline unsigned int MurmurHash3_mix(unsigned int hash, unsigned int k)
{
const unsigned int c1 = 0xcc9e2d51;
const unsigned int c2 = 0x1b873593;
const unsigned int r1 = 15;
const unsigned int r2 = 13;
const unsigned int m = 5;
const unsigned int n = 0xe6546b64;
k *= c1;
k = (k << r1) | (k >> (32 - r1));
k *= c2;
hash ^= k;
hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
return hash;
}
inline unsigned int MurmurHash3_finalize(unsigned int hash)
{
hash ^= hash >> 16;
hash *= 0x85ebca6b;
hash ^= hash >> 13;
hash *= 0xc2b2ae35;
hash ^= hash >> 16;
return hash;
}
inline unsigned int LCG_next(unsigned int value)
{
const unsigned int m = 1664525;
const unsigned int n = 1013904223;
return value * m + n;
}
inline void RandomSampler_init(RandomSampler& self, int id)
{
unsigned int hash = 0;
hash = MurmurHash3_mix(hash, id);
hash = MurmurHash3_finalize(hash);
self.s = hash;
}
inline void RandomSampler_init(RandomSampler& self, int pixelId, int sampleId)
{
unsigned int hash = 0;
hash = MurmurHash3_mix(hash, pixelId);
hash = MurmurHash3_mix(hash, sampleId);
hash = MurmurHash3_finalize(hash);
self.s = hash;
}
inline void RandomSampler_init(RandomSampler& self, int x, int y, int sampleId)
{
RandomSampler_init(self, x | (y << 16), sampleId);
}
inline int RandomSampler_getInt(RandomSampler& self) {
self.s = LCG_next(self.s); return self.s >> 1;
}
inline unsigned int RandomSampler_getUInt(RandomSampler& self) {
self.s = LCG_next(self.s); return self.s;
}
inline float RandomSampler_getFloat(RandomSampler& self) {
return (float)RandomSampler_getInt(self) * 4.656612873077392578125e-10f;
}
inline float RandomSampler_get1D(RandomSampler& self) {
return RandomSampler_getFloat(self);
}
inline Vec2f RandomSampler_get2D(RandomSampler& self)
{
const float u = RandomSampler_get1D(self);
const float v = RandomSampler_get1D(self);
return make_Vec2f(u,v);
}
inline Vec3fa RandomSampler_get3D(RandomSampler& self)
{
const float u = RandomSampler_get1D(self);
const float v = RandomSampler_get1D(self);
const float w = RandomSampler_get1D(self);
return make_Vec3fa(u,v,w);
}

View file

@ -0,0 +1,159 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
/*! \brief utility library containing sampling functions */
// convention is to return the sample (Vec3fa) generated from given Vec2f 's'ample as last parameter
// sampling functions often come in pairs: sample and pdf (needed later for MIS)
// good reference is "Total Compendium" by Philip Dutre http://people.cs.kuleuven.be/~philip.dutre/GI/
#include "../math/vec.h"
#include "../math/linearspace.h"
namespace embree {
struct Sample3f
{
Vec3fa v;
float pdf;
};
inline Sample3f make_Sample3f(const Vec3fa& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#if defined(ISPC)
inline Sample3f make_Sample3f(const Vec3fa& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#endif
inline Vec3fa cartesian(const float phi, const float sinTheta, const float cosTheta)
{
const float sinPhi = sinf(phi);
const float cosPhi = cosf(phi);
//sincosf(phi, &sinPhi, &cosPhi);
return Vec3fa(cosPhi * sinTheta,
sinPhi * sinTheta,
cosTheta);
}
inline Vec3fa cartesian(const float phi, const float cosTheta)
{
return cartesian(phi, cos2sin(cosTheta), cosTheta);
}
/// cosine-weighted sampling of hemisphere oriented along the +z-axis
////////////////////////////////////////////////////////////////////////////////
inline Vec3fa cosineSampleHemisphere(const Vec2f s)
{
const float phi = 2.0f * float(M_PI) * s.x;
const float cosTheta = sqrt(s.y);
const float sinTheta = sqrt(1.0f - s.y);
return cartesian(phi, sinTheta, cosTheta);
}
inline float cosineSampleHemispherePDF(const Vec3fa &dir)
{
return dir.z / float(M_PI);
}
inline float cosineSampleHemispherePDF(float cosTheta)
{
return cosTheta / float(M_PI);
}
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3fa& N)
{
Vec3fa localDir = cosineSampleHemisphere(Vec2f(u,v));
Sample3f s;
s.v = frame(N) * localDir;
s.pdf = cosineSampleHemispherePDF(localDir);
return s;
}
/// power cosine-weighted sampling of hemisphere oriented along the +z-axis
////////////////////////////////////////////////////////////////////////////////
inline Vec3fa powerCosineSampleHemisphere(const float n, const Vec2f &s)
{
const float phi =float(two_pi) * s.x;
const float cosTheta = pow(s.y, 1.0f / (n + 1.0f));
return cartesian(phi, cosTheta);
}
inline float powerCosineSampleHemispherePDF(const float cosTheta, const float n) // TODO: order of arguments
{
return (n + 1.0f) * (0.5f / float(M_PI)) * pow(cosTheta, n);
}
inline float powerCosineSampleHemispherePDF(const Vec3fa& dir, const float n) // TODO: order of arguments
{
return (n + 1.0f) * (0.5f / float(M_PI)) * pow(dir.z, n);
}
/// sampling of cone of directions oriented along the +z-axis
////////////////////////////////////////////////////////////////////////////////
inline Vec3fa uniformSampleCone(const float cosAngle, const Vec2f &s)
{
const float phi =float(two_pi) * s.x;
const float cosTheta = 1.0f - s.y * (1.0f - cosAngle);
return cartesian(phi, cosTheta);
}
inline float uniformSampleConePDF(const float cosAngle)
{
return rcp(float(two_pi)*(1.0f - cosAngle));
}
inline float _uniformSampleConePDF(const float cosAngle)
{
return rcp(float(two_pi)*(1.0f - cosAngle));
}
/// sampling of disk
////////////////////////////////////////////////////////////////////////////////
inline Vec3fa uniformSampleDisk(const float radius, const Vec2f &s)
{
const float r = sqrtf(s.x) * radius;
const float phi =float(two_pi) * s.y;
const float sinPhi = sinf(phi);
const float cosPhi = cosf(phi);
//sincosf(phi, &sinPhi, &cosPhi);
return Vec3fa(r * cosPhi, r * sinPhi, 0.f);
}
inline float uniformSampleDiskPDF(const float radius)
{
return rcp(float(M_PI) * sqr(radius));
}
inline float _uniformSampleDiskPDF(const float radius)
{
return rcp(float(M_PI) * sqr(radius));
}
/// sampling of triangle abc
////////////////////////////////////////////////////////////////////////////////
inline Vec3fa uniformSampleTriangle(const Vec3fa &a, const Vec3fa &b, const Vec3fa &c, const Vec2f &s)
{
const float su = sqrtf(s.x);
return c + (1.0f - su) * (a-c) + (s.y*su) * (b-c);
}
inline float uniformSampleTrianglePDF(const Vec3fa &a, const Vec3fa &b, const Vec3fa &c)
{
return 2.0f * rcp(abs(length(cross(a-c, b-c))));
}
} // namespace embree

View file

@ -0,0 +1,155 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
/*! \brief utility library containing sampling functions */
// convention is to return the sample (Vec3f) generated from given Vec2f 's'ample as last parameter
// sampling functions often come in pairs: sample and pdf (needed later for MIS)
// good reference is "Total Compendium" by Philip Dutre http://people.cs.kuleuven.be/~philip.dutre/GI/
#include "../math/vec.isph"
#include "../math/linearspace.isph"
struct Sample3f
{
Vec3f v;
float pdf;
};
inline uniform Sample3f make_Sample3f(const uniform Vec3f& v, const uniform float pdf) {
uniform Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#if defined(ISPC)
inline Sample3f make_Sample3f(const Vec3f& v, const float pdf) {
Sample3f s; s.v = v; s.pdf = pdf; return s;
}
#endif
inline Vec3f cartesian(const float phi, const float sinTheta, const float cosTheta)
{
const float sinPhi = sinf(phi);
const float cosPhi = cosf(phi);
//sincos(phi, &sinPhi, &cosPhi);
return make_Vec3f(cosPhi * sinTheta,
sinPhi * sinTheta,
cosTheta);
}
inline Vec3f cartesian(const float phi, const float cosTheta)
{
return cartesian(phi, cos2sin(cosTheta), cosTheta);
}
/// cosine-weighted sampling of hemisphere oriented along the +z-axis
////////////////////////////////////////////////////////////////////////////////
inline Vec3f cosineSampleHemisphere(const Vec2f s)
{
const float phi = 2.0f * M_PI * s.x;
const float cosTheta = sqrt(s.y);
const float sinTheta = sqrt(1.0f - s.y);
return cartesian(phi, sinTheta, cosTheta);
}
inline float cosineSampleHemispherePDF(const Vec3f &dir)
{
return dir.z / M_PI;
}
inline float cosineSampleHemispherePDF(float cosTheta)
{
return cosTheta / M_PI;
}
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3f& N)
{
Vec3f localDir = cosineSampleHemisphere(make_Vec2f(u,v));
Sample3f s;
s.v = frame(N) * localDir;
s.pdf = cosineSampleHemispherePDF(localDir);
return s;
}
/// power cosine-weighted sampling of hemisphere oriented along the +z-axis
////////////////////////////////////////////////////////////////////////////////
inline Vec3f powerCosineSampleHemisphere(const float n, const Vec2f &s)
{
const float phi = two_pi * s.x;
const float cosTheta = pow(s.y, 1.0f / (n + 1.0f));
return cartesian(phi, cosTheta);
}
inline float powerCosineSampleHemispherePDF(const float cosTheta, const float n) // TODO: order of arguments
{
return (n + 1.0f) * (0.5f / M_PI) * pow(cosTheta, n);
}
inline float powerCosineSampleHemispherePDF(const Vec3f& dir, const float n) // TODO: order of arguments
{
return (n + 1.0f) * (0.5f / M_PI) * pow(dir.z, n);
}
/// uniform sampling of cone of directions oriented along the +z-axis
////////////////////////////////////////////////////////////////////////////////
inline Vec3f uniformSampleCone(const float cosAngle, const Vec2f &s)
{
const float phi = two_pi * s.x;
const float cosTheta = 1.0f - s.y * (1.0f - cosAngle);
return cartesian(phi, cosTheta);
}
inline float uniformSampleConePDF(const float cosAngle)
{
return rcp(two_pi*(1.0f - cosAngle));
}
inline uniform float uniformSampleConePDF(const uniform float cosAngle)
{
return rcp(two_pi*(1.0f - cosAngle));
}
/// uniform sampling of disk
////////////////////////////////////////////////////////////////////////////////
inline Vec3f uniformSampleDisk(const float radius, const Vec2f &s)
{
const float r = sqrtf(s.x) * radius;
const float phi = two_pi * s.y;
const float sinPhi = sinf(phi);
const float cosPhi = cosf(phi);
//sincos(phi, &sinPhi, &cosPhi);
return make_Vec3f(r * cosPhi, r * sinPhi, 0.f);
}
inline float uniformSampleDiskPDF(const float radius)
{
return rcp(M_PI * sqr(radius));
}
inline uniform float uniformSampleDiskPDF(const uniform float radius)
{
return rcp(M_PI * sqr(radius));
}
/// uniform sampling of triangle abc
////////////////////////////////////////////////////////////////////////////////
inline Vec3f uniformSampleTriangle(const Vec3f &a, const Vec3f &b, const Vec3f &c, const Vec2f &s)
{
const float su = sqrtf(s.x);
return c + (1.0f - su) * (a-c) + (s.y*su) * (b-c);
}
inline float uniformSampleTrianglePDF(const Vec3f &a, const Vec3f &b, const Vec3f &c)
{
return 2.0f * rcp(abs(length(cross(a-c, b-c))));
}

View file

@ -0,0 +1,87 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "../../../common/math/vec2.h"
#include "../../../common/math/vec3.h"
#include "../../../common/math/vec4.h"
namespace embree {
__forceinline Vec3f neg(const Vec3f& a ) { return -a; }
__forceinline Vec3fa neg(const Vec3fa& a) { return -a; }
__forceinline bool eq (const Vec3fa& a, const Vec3fa& b) { return a == b; }
__forceinline bool ne (const Vec3fa& a, const Vec3fa& b) { return a != b; }
// FIXME: change order of lerp arguments, then remove this function
template<typename V>
__forceinline V lerpr(float t, const V& v0, const V& v1) {
return (1.0f-t)*v0 + t*v1;
}
// -------------------------------------------------------
// sRGB conversion functions
// -------------------------------------------------------
#define APPROXIMATE_SRGB
inline float linear_to_srgb(const float f)
{
const float c = max(f, 0.f);
#ifdef APPROXIMATE_SRGB
return pow(c, 1.f/2.2f);
#else
return c <= 0.0031308f ? 12.92f*c : pow(c, 1.f/2.4f)*1.055f - 0.055f;
#endif
}
inline Vec4f linear_to_srgba(const Vec4f c)
{
return Vec4f(linear_to_srgb(c.x),
linear_to_srgb(c.y),
linear_to_srgb(c.z),
max(c.w, 0.f)); // alpha is never gamma-corrected
}
inline uint32_t linear_to_srgba8(const Vec4f c)
{
#if 1
Vec4f l = 255.f * min(linear_to_srgba(c), Vec4f(1.f));
return
((uint32_t)l.x << 0) |
((uint32_t)l.y << 8) |
((uint32_t)l.z << 16) |
((uint32_t)l.w << 24);
#else
// TODO use ISPC's float_to_srgb8 once it is fixed (issue #1198)
return
(float_to_srgb8(c.x) << 0) |
(float_to_srgb8(c.y) << 8) |
(float_to_srgb8(c.z) << 16) |
((uint32_t)clamp(c.w, 0.f, 1.f) << 24); // alpha is never gamma-corrected
#endif
}
inline float srgb_to_linear(const float f)
{
const float c = max(f, 0.f);
#ifdef APPROXIMATE_SRGB
return pow(c, 2.2f);
#else
return c <= 0.04045f ? c/12.92f : pow((c + 0.055f)/1.055f, 2.4f);
#endif
}
inline Vec4f srgba_to_linear(const Vec4f c)
{
return Vec4f(srgb_to_linear(c.x),
srgb_to_linear(c.y),
srgb_to_linear(c.z),
max(c.w, 0.f)); // alpha is never gamma-corrected
}
// TODO implement srgba8_to_linear with a 256 entry LUT
#undef APPROXIMATE_SRGB
} // namespace embree

View file

@ -0,0 +1,986 @@
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "math.isph"
#define __define_ispc_vector2(TYPE,ABB) \
struct Vec2##ABB { \
TYPE x; TYPE y; \
}; \
#define __define_ispc_vector3(TYPE,ABB) \
struct Vec3##ABB { \
TYPE x,y,z; \
}; \
struct Vec3##ABB##a { \
TYPE x,y,z,w; \
}; \
#define __define_ispc_vector4(TYPE,ABB) \
struct Vec4##ABB { \
TYPE x,y,z,w; \
}; \
__define_ispc_vector2(int,i);
__define_ispc_vector2(unsigned int,ui);
__define_ispc_vector2(unsigned int8,uc);
__define_ispc_vector2(float,f);
__define_ispc_vector3(int,i);
__define_ispc_vector3(unsigned int,ui);
__define_ispc_vector3(unsigned int8,uc);
__define_ispc_vector3(float,f);
__define_ispc_vector4(int,i);
__define_ispc_vector4(unsigned int,ui);
__define_ispc_vector4(unsigned int8,uc);
__define_ispc_vector4(float,f);
#undef __define_ispc_vector2
#undef __define_ispc_vector3
#undef __define_ispc_vector4
/*! defines all constructors "make_Vec2[T]" for 2-vector type */
#define __define_ispc_constructors2(UV,TYPE,ABB,ITYPE,IABB) \
inline UV Vec2##ABB make_Vec2##ABB(const UV ITYPE x, \
const UV ITYPE y) \
{ \
UV Vec2##ABB ret; \
ret.x = x; \
ret.y = y; \
return ret; \
} \
inline UV Vec2##ABB make_Vec2##ABB(const UV ITYPE x) \
{ \
UV Vec2##ABB ret; \
ret.x = x; \
ret.y = x; \
return ret; \
} \
/*! defines all constructors "make_Vec3[T]" and "make_Vec3[T]a" for
3-vector type */
#define __define_ispc_constructors3(UV,TYPE,ABB,ITYPE,IABB) \
inline UV Vec3##ABB make_Vec3##ABB(const UV ITYPE x) \
{ \
UV Vec3##ABB ret; \
ret.x = x; \
ret.y = x; \
ret.z = x; \
return ret; \
} \
inline UV Vec3##ABB make_Vec3##ABB(const UV Vec3##IABB v) \
{ \
UV Vec3##ABB ret; \
ret.x = v.x; \
ret.y = v.y; \
ret.z = v.z; \
return ret; \
} \
inline UV Vec3##ABB make_Vec3##ABB(const UV Vec3##IABB##a v) \
{ \
UV Vec3##ABB ret; \
ret.x = v.x; \
ret.y = v.y; \
ret.z = v.z; \
return ret; \
} \
inline UV Vec3##ABB make_Vec3##ABB(const UV ITYPE x, \
const UV ITYPE y, \
const UV ITYPE z) \
{ \
UV Vec3##ABB ret; \
ret.x = x; \
ret.y = y; \
ret.z = z; \
return ret; \
} \
inline UV Vec3##ABB make_Vec3##ABB(const UV Vec4##IABB v) \
{ \
UV Vec3##ABB ret; \
ret.x = v.x; \
ret.y = v.y; \
ret.z = v.z; \
return ret; \
} \
/* the '3a' variants */ \
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV ITYPE x) \
{ \
UV Vec3##ABB##a ret; \
ret.x = x; \
ret.y = x; \
ret.z = x; \
ret.w = 0; \
return ret; \
} \
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV Vec3##IABB &v) \
{ \
UV Vec3##ABB##a ret; \
ret.x = v.x; \
ret.y = v.y; \
ret.z = v.z; \
ret.w = 0; \
return ret; \
} \
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV Vec3##IABB##a v) \
{ \
UV Vec3##ABB##a ret; \
ret.x = v.x; \
ret.y = v.y; \
ret.z = v.z; \
ret.w = v.w; \
return ret; \
} \
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV ITYPE x, \
const UV ITYPE y, \
const UV ITYPE z) \
{ \
UV Vec3##ABB##a ret; \
ret.x = x; \
ret.y = y; \
ret.z = z; \
ret.w = 0; \
return ret; \
} \
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV ITYPE x, \
const UV ITYPE y, \
const UV ITYPE z, \
const UV ITYPE w) \
{ \
UV Vec3##ABB##a ret; \
ret.x = x; \
ret.y = y; \
ret.z = z; \
ret.w = w; \
return ret; \
} \
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV Vec3##IABB &v, \
const UV ITYPE w) \
{ \
UV Vec3##ABB##a ret; \
ret.x = v.x; \
ret.y = v.y; \
ret.z = v.z; \
ret.w = w; \
return ret; \
} \
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV Vec4##IABB v) \
{ \
UV Vec3##ABB##a ret; \
ret.x = v.x; \
ret.y = v.y; \
ret.z = v.z; \
ret.w = v.w; \
return ret; \
} \
/*! defines all constructors "make_Vec4[T]" for 4-vector type */
#define __define_ispc_constructors4(UV,TYPE,ABB,ITYPE,IABB) \
/*! construct Vec4 from a single scalar */ \
inline UV Vec4##ABB make_Vec4##ABB(const UV ITYPE f) \
{ \
UV Vec4##ABB ret; \
ret.x = f; \
ret.y = f; \
ret.z = f; \
ret.w = f; \
return ret; \
} \
/*! construct Vec4 from a 4 scalars */ \
inline UV Vec4##ABB make_Vec4##ABB(const UV ITYPE x, \
const UV ITYPE y, \
const UV ITYPE z, \
const UV ITYPE w) \
{ \
UV Vec4##ABB ret; \
ret.x = x; \
ret.y = y; \
ret.z = z; \
ret.w = w; \
return ret; \
} \
/*! construct Vec4 from another Vec4 (of another type) */ \
inline UV Vec4##ABB make_Vec4##ABB(const UV Vec4##IABB v) \
{ \
UV Vec4##ABB ret; \
ret.x = v.x; \
ret.y = v.y; \
ret.z = v.z; \
ret.w = v.w; \
return ret; \
} \
#define __define_ispc_lift_constructors4(UV,TYPE,ABB) \
/*! lift Vec4 from Vec3; fill in with 0es */ \
inline UV Vec4##ABB make_Vec4##ABB(const UV Vec3##ABB v) \
{ \
UV Vec4##ABB ret; \
ret.x = (TYPE)v.x; \
ret.y = (TYPE)v.y; \
ret.z = (TYPE)v.z; \
ret.w = (TYPE)0; \
return ret; \
} \
#define __define_ispc_constructors_uv_t(UV,OTYPE,OABB,ITYPE,IABB) \
__define_ispc_constructors2(UV,OTYPE,OABB,ITYPE,IABB) \
__define_ispc_constructors3(UV,OTYPE,OABB,ITYPE,IABB) \
__define_ispc_constructors4(UV,OTYPE,OABB,ITYPE,IABB) \
#define __define_ispc_constructors_uv(UV,TYPE,ABB) \
__define_ispc_constructors_uv_t(UV,TYPE,ABB,int,i) \
__define_ispc_constructors_uv_t(UV,TYPE,ABB,unsigned int,ui) \
__define_ispc_constructors_uv_t(UV,TYPE,ABB,unsigned int8,uc) \
__define_ispc_constructors_uv_t(UV,TYPE,ABB,float,f) \
__define_ispc_lift_constructors4(UV,TYPE,ABB) \
#define __define_ispc_constructors(UV) \
__define_ispc_constructors_uv(UV,unsigned int,ui) \
__define_ispc_constructors_uv(UV,unsigned int8,uc) \
__define_ispc_constructors_uv(UV,int,i) \
__define_ispc_constructors_uv(UV,float,f) \
__define_ispc_constructors(uniform);
__define_ispc_constructors(varying);
#undef __define_ispc_constructors2
#undef __define_ispc_constructors3
#undef __define_ispc_constructors3a
#undef __define_ispc_constructors4
#undef __define_ispc_lift_constructors4
#undef __define_ispc_constructors_uv
#undef __define_ispc_constructors
// =======================================================
// define 'lifted' binary operators (min/max/...)
#define __lift_binaryFct(FCT,T) \
/* ********************************************************* */ \
/* ---- Vec2 ---- */ \
/* ********************************************************* */ \
/* uniform Vec2 FCT(uniform Vec2, uniform Vec2) */ \
inline uniform Vec2##T FCT(const uniform Vec2##T a, \
const uniform Vec2##T b) \
{ return make_Vec2##T(FCT(a.x,b.x),FCT(a.y,b.y)); } \
/* Vec2 FCT(Vec2, Vec2) */ \
inline varying Vec2##T FCT(const varying Vec2##T a, \
const varying Vec2##T b) \
{ return make_Vec2##T(FCT(a.x,b.x),FCT(a.y,b.y)); } \
/* Vec2 FCT(Vec2, uniform Vec2) */ \
inline varying Vec2##T FCT(const varying Vec2##T a, \
const uniform Vec2##T b) \
{ return make_Vec2##T(FCT(a.x,b.x),FCT(a.y,b.y)); } \
/* Vec2 FCT(uniform Vec2, Vec2) */ \
inline varying Vec2##T FCT(const uniform Vec2##T a, \
const varying Vec2##T b) \
{ return make_Vec2##T(FCT(a.x,b.x),FCT(a.y,b.y)); } \
\
/* ********************************************************* */ \
/* ---- Vec3 ---- */ \
/* ********************************************************* */ \
/* uniform Vec3 FCT(uniform Vec3, uniform Vec3) */ \
inline uniform Vec3##T FCT(const uniform Vec3##T a, \
const uniform Vec3##T b) \
{ return make_Vec3##T(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
/* Vec3 FCT(Vec3, Vec3) */ \
inline varying Vec3##T FCT(const varying Vec3##T a, \
const varying Vec3##T b) \
{ return make_Vec3##T(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
/* Vec3 FCT(uniformVec3, Vec3) */ \
inline varying Vec3##T FCT(const uniform Vec3##T a, \
const varying Vec3##T b) \
{ return make_Vec3##T(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
/* Vec3 FCT(Vec3, uniformVec3) */ \
inline varying Vec3##T FCT(const varying Vec3##T a, \
const uniform Vec3##T b) \
{ return make_Vec3##T(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
\
/* ********************************************************* */ \
/* ---- Vec3a (from 3a and 3a) ---- */ \
/* ********************************************************* */ \
/* uniform Vec3a FCT(uniform Vec3a, uniform Vec3a) */ \
inline uniform Vec3##T##a FCT(const uniform Vec3##T##a a, \
const uniform Vec3##T##a b) \
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z),FCT(a.w,b.w)); } \
/* Vec3a FCT(Vec3a, Vec3a) */ \
inline varying Vec3##T##a FCT(const varying Vec3##T##a a, \
const varying Vec3##T##a b) \
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z),FCT(a.w,b.w)); } \
\
/* ********************************************************* */ \
/* ---- Vec3a (from 3 and 3a) ---- */ \
/* ********************************************************* */ \
/* uniform Vec3a FCT(uniform Vec3a, uniform Vec3a) */ \
inline uniform Vec3##T##a FCT(const uniform Vec3##T a, \
const uniform Vec3##T##a b) \
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
/* Vec3a FCT(Vec3a, Vec3a) */ \
inline varying Vec3##T##a FCT(const varying Vec3##T a, \
const varying Vec3##T##a b) \
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
\
/* ********************************************************* */ \
/* ---- Vec3a (from 3a and 3) ---- */ \
/* ********************************************************* */ \
/* uniform Vec3a FCT(uniform Vec3a, uniform Vec3a) */ \
inline uniform Vec3##T##a FCT(const uniform Vec3##T##a a, \
const uniform Vec3##T b) \
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
/* Vec3a FCT(Vec3a, Vec3a) */ \
inline varying Vec3##T##a FCT(const varying Vec3##T##a a, \
const varying Vec3##T b) \
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
\
/* ********************************************************* */ \
/* ---- Vec4 ---- */ \
/* ********************************************************* */ \
/* uniform Vec4 FCT(uniform Vec4, uniform Vec4) */ \
inline uniform Vec4##T FCT(const uniform Vec4##T a, \
const uniform Vec4##T b) \
{ return make_Vec4##T(FCT(a.x,b.x),FCT(a.y,b.y), \
FCT(a.z,b.z),FCT(a.w,b.w)); } \
/* Vec4 FCT(Vec4, Vec4) */ \
inline varying Vec4##T FCT(const varying Vec4##T a, \
const varying Vec4##T b) \
{ return make_Vec4##T(FCT(a.x,b.x),FCT(a.y,b.y), \
FCT(a.z,b.z),FCT(a.w,b.w)); } \
__lift_binaryFct(min,f)
__lift_binaryFct(max,f)
__lift_binaryFct(min,i)
__lift_binaryFct(max,i)
__lift_binaryFct(min,ui)
__lift_binaryFct(max,ui)
#undef __lift_binaryFct
// =======================================================
// for now, let's implement those manually - should eventually do those via a macro!
inline uniform Vec3f neg(const uniform Vec3f v)
{ return make_Vec3f(-v.x,-v.y,-v.z); }
inline Vec3f neg(const Vec3f v)
{ return make_Vec3f(-v.x,-v.y,-v.z); }
inline uniform Vec3f negate(const uniform Vec3f &a)
{ return(make_Vec3f(-a.x, -a.y, -a.z)); }
inline varying Vec3f negate(const varying Vec3f &a)
{ return(make_Vec3f(-a.x, -a.y, -a.z)); }
#define __define_binary_operator_typed(opname,op,abb,type) \
/* Vec2##abb */ \
inline uniform Vec2##abb opname (const uniform Vec2##abb a, \
const uniform Vec2##abb b) { \
return make_Vec2##abb(a.x op b.x, a.y op b.y); \
} \
inline Vec2##abb opname (const Vec2##abb a, const Vec2##abb b) { \
return make_Vec2##abb(a.x op b.x, a.y op b.y); \
} \
inline uniform Vec2##abb opname (const uniform Vec2##abb a, \
const uniform type b) { \
return make_Vec2##abb(a.x op b, a.y op b); \
} \
inline Vec2##abb opname (const Vec2##abb a, const type b) { \
return make_Vec2##abb(a.x op b, a.y op b); \
} \
inline uniform Vec2##abb opname (const uniform type a, \
const uniform Vec2##abb b) { \
return make_Vec2##abb(a op b.x, a op b.y); \
} \
inline Vec2##abb opname (const type a, const Vec2##abb b) { \
return make_Vec2##abb(a op b.x, a op b.y); \
} \
/* Vec3##abb */ \
inline uniform Vec3##abb opname (const uniform Vec3##abb a, \
const uniform Vec3##abb b) { \
return make_Vec3##abb(a.x op b.x, a.y op b.y, a.z op b.z); \
} \
inline Vec3##abb opname (const Vec3##abb a, const Vec3##abb b) { \
return make_Vec3##abb(a.x op b.x, a.y op b.y, a.z op b.z); \
} \
inline uniform Vec3##abb opname (const uniform Vec3##abb a, \
const uniform type b) { \
return make_Vec3##abb(a.x op b, a.y op b, a.z op b); \
} \
inline Vec3##abb opname (const Vec3##abb a, const type b) { \
return make_Vec3##abb(a.x op b, a.y op b, a.z op b); \
} \
inline uniform Vec3##abb opname (const uniform type a, \
const uniform Vec3##abb b) { \
return make_Vec3##abb(a op b.x, a op b.y, a op b.z); \
} \
inline Vec3##abb opname (const type a, const Vec3##abb b) { \
return make_Vec3##abb(a op b.x, a op b.y, a op b.z); \
} \
/* Vec3##abb##a */ \
inline uniform Vec3##abb##a opname (const uniform Vec3##abb##a a, \
const uniform Vec3##abb##a b) { \
return make_Vec3##abb##a(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \
} \
inline Vec3##abb##a opname (const Vec3##abb##a a, const Vec3##abb##a b) { \
return make_Vec3##abb##a(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \
} \
inline uniform Vec3##abb##a opname (const uniform Vec3##abb##a a, \
const uniform type b) { \
return make_Vec3##abb##a(a.x op b, a.y op b, a.z op b, a.w op b); \
} \
inline Vec3##abb##a opname (const Vec3##abb##a a, const type b) { \
return make_Vec3##abb##a(a.x op b, a.y op b, a.z op b, a.w op b); \
} \
inline uniform Vec3##abb##a opname (const uniform type a, \
const uniform Vec3##abb##a b) { \
return make_Vec3##abb##a(a op b.x, a op b.y, a op b.z, a op b.w); \
} \
inline Vec3##abb##a opname (const type a, const Vec3##abb##a b) { \
return make_Vec3##abb##a(a op b.x, a op b.y, a op b.z, a op b.w); \
} \
/* Vec4##abb */ \
inline uniform Vec4##abb opname (const uniform Vec4##abb a, \
const uniform Vec4##abb b) { \
return make_Vec4##abb(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \
} \
inline Vec4##abb opname (const Vec4##abb a, const Vec4##abb b) { \
return make_Vec4##abb(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \
} \
inline uniform Vec4##abb opname (const uniform Vec4##abb a, \
const uniform type b) { \
return make_Vec4##abb(a.x op b, a.y op b, a.z op b, a.w op b); \
} \
inline Vec4##abb opname (const Vec4##abb a, const type b) { \
return make_Vec4##abb(a.x op b, a.y op b, a.z op b, a.w op b); \
} \
inline uniform Vec4##abb opname (const uniform type a, \
const uniform Vec4##abb b) { \
return make_Vec4##abb(a op b.x, a op b.y, a op b.z, a op b.w); \
} \
inline Vec4##abb opname (const type a, const Vec4##abb b) { \
return make_Vec4##abb(a op b.x, a op b.y, a op b.z, a op b.w); \
}
#define __define_binary_operator(opname,op) \
__define_binary_operator_typed(opname,op,f,float) \
__define_binary_operator_typed(opname,op,i,int32) \
__define_binary_operator_typed(opname,op,ui,uint32)
// define 'regular' operators
__define_binary_operator( operator+, + );
__define_binary_operator( operator-, - );
__define_binary_operator( operator*, * );
__define_binary_operator( operator/, / );
// define old functional operators as used in the embree path tracer, deprecated
__define_binary_operator( add, + );
__define_binary_operator( sub, - );
__define_binary_operator( mul, * );
#undef __define_binary_operator
inline float reduce_mul(const Vec3f v)
{ return v.x * v.y * v.z; }
inline uniform float reduce_mul(const uniform Vec3f v)
{ return v.x * v.y * v.z; }
inline float reduce_max(const Vec3f v)
{ return max(max(v.x,v.y),v.z); }
inline float reduce_add(const Vec3f v)
{ return v.x+v.y+v.z; }
inline uniform float reduce_add(const uniform Vec3f v)
{ return v.x+v.y+v.z; }
inline float reduce_avg(const Vec3f v)
{ return (v.x+v.y+v.z)*(1.0f/3.0f); }
inline float luminance(const Vec3f& c)
{ return 0.212671f*c.x + 0.715160f*c.y + 0.072169f*c.z; }
inline uniform bool eq(const uniform Vec2f a, const uniform Vec2f b)
{ return a.x==b.x && a.y==b.y; }
inline bool eq(const Vec2f a, const Vec2f b)
{ return a.x==b.x & a.y==b.y; }
inline uniform bool eq(const uniform Vec3f a, const uniform Vec3f b)
{ return a.x==b.x && a.y==b.y && a.z==b.z; }
inline bool eq(const Vec3f a, const Vec3f b)
{ return a.x==b.x & a.y==b.y & a.z==b.z; }
inline uniform bool eq(const uniform Vec3fa a, const uniform Vec3fa b)
{ return a.x==b.x && a.y==b.y && a.z==b.z; }
inline bool eq(const Vec3fa a, const Vec3fa b)
{ return a.x==b.x & a.y==b.y & a.z==b.z; }
inline uniform bool ne(const uniform Vec2f a, const uniform Vec2f b)
{ return !eq(a,b); }
inline bool ne(const Vec2f a, const Vec2f b)
{ return !eq(a,b); }
inline uniform bool ne(const uniform Vec3f a, const uniform Vec3f b)
{ return !eq(a,b); }
inline bool ne(const Vec3f a, const Vec3f b)
{ return !eq(a,b); }
inline uniform bool ne(const uniform Vec3fa a, const uniform Vec3fa b)
{ return !eq(a,b); }
inline bool ne(const Vec3fa a, const Vec3fa b)
{ return !eq(a,b); }
// ------------------------------------------------------------------
// dot product
// ------------------------------------------------------------------
/*! computes 3D dot product for *all-uniform* Vec3fs */
inline uniform float dot(const uniform Vec3f a, const uniform Vec3f b)
{ return a.x*b.x+a.y*b.y+a.z*b.z; }
/*! computes 3D dot product for Vec3fs that produce varying results */
inline float dot(const Vec3f a, const Vec3f b)
{ return a.x*b.x+a.y*b.y+a.z*b.z; }
inline uniform float length(const uniform Vec3f a) { return sqrtf(dot(a,a)); }
inline varying float length(const varying Vec3f a) { return sqrtf(dot(a,a)); }
inline uniform float distance(const uniform Vec3f a, const uniform Vec3f b) { return length(a - b); }
inline varying float distance(const varying Vec3f a, const varying Vec3f b) { return length(a - b); }
inline uniform float dot(const uniform Vec3fa a, const uniform Vec3fa b) { return a.x*b.x+a.y*b.y+a.z*b.z; }
inline varying float dot(const varying Vec3fa a, const varying Vec3fa b) { return a.x*b.x+a.y*b.y+a.z*b.z; }
inline uniform float length(const uniform Vec3fa a) { return sqrtf(dot(a,a)); }
inline varying float length(const varying Vec3fa a) { return sqrtf(dot(a,a)); }
inline uniform float distance(const uniform Vec3fa a, const uniform Vec3fa b) { return length(a - b); }
inline varying float distance(const varying Vec3fa a, const varying Vec3fa b) { return length(a - b); }
// ------------------------------------------------------------------
// cross product
// ------------------------------------------------------------------
/*! computes 3D cross product for *all-uniform* Vec3fs */
inline uniform Vec3f cross(const uniform Vec3f &a, const uniform Vec3f &b)
{ return make_Vec3f(a.y*b.z-a.z*b.y,
a.z*b.x-a.x*b.z,
a.x*b.y-a.y*b.x); }
/*! computes 3D cross product for Vec3fs that produce varying results */
inline Vec3f cross(const Vec3f &a, const Vec3f &b)
{ return make_Vec3f(a.y*b.z-a.z*b.y,
a.z*b.x-a.x*b.z,
a.x*b.y-a.y*b.x); }
// ------------------------------------------------------------------
// normalize
// ------------------------------------------------------------------
/*! compute and return normalized version of uniform Vec3f passed to this fct */
inline uniform Vec3f normalize(const uniform Vec3f &v)
{ return v * (1.f/sqrt(dot(v,v))); }
/*! compute and return normalized version of varying Vec3f passed to this fct */
inline Vec3f normalize(const Vec3f v)
{ return v * (1.f/sqrt(dot(v,v))); }
/*! compute and return normalized version of varying Vec3f passed to this fct */
inline Vec3f normalize(const Vec3f v, float &len)
{ len = sqrtf(dot(v,v)); return v * rcpf(len); }
inline Vec3f safe_normalize(const Vec3f v)
{ return v * (1.f/sqrt(max(1e-6f,dot(v,v)))); }
/*! differentiated normalization */
inline varying Vec3f dnormalize(const varying Vec3f& p, const varying Vec3f& dp)
{
const float pp = dot(p,p);
const float pdp = dot(p,dp);
return (pp*dp-pdp*p)*rcp(pp)*rsqrt(pp);
}
inline uniform Vec3fa normalize(const uniform Vec3fa &v) { return v * (1.f/sqrt(dot(v,v))); }
inline varying Vec3fa normalize(const varying Vec3fa v) { return v * (1.f/sqrt(dot(v,v))); }
inline varying Vec3fa dnormalize(const varying Vec3fa& p, const varying Vec3fa& dp)
{
const float pp = dot(p,p);
const float pdp = dot(p,dp);
return (pp*dp-pdp*p)*rcp(pp)*rsqrt(pp);
}
#define __lift_unary_fct(F) \
inline uniform Vec2f F(const uniform Vec2f v) \
{ return make_Vec2f(F(v.x),F(v.y)); } \
inline Vec2f F(const Vec2f v) \
{ return make_Vec2f(F(v.x),F(v.y)); } \
inline uniform Vec3f F(const uniform Vec3f v) \
{ return make_Vec3f(F(v.x),F(v.y),F(v.z)); } \
inline Vec3f F(const Vec3f v) \
{ return make_Vec3f(F(v.x),F(v.y),F(v.z)); } \
inline uniform Vec3fa F(const uniform Vec3fa v) \
{ return make_Vec3fa(F(v.x),F(v.y),F(v.z),F(v.w)); } \
inline Vec3fa F(const Vec3fa v) \
{ return make_Vec3fa(F(v.x),F(v.y),F(v.z),F(v.w)); } \
inline uniform Vec4f F(const uniform Vec4f v) \
{ return make_Vec4f(F(v.x),F(v.y),F(v.z),F(v.w)); } \
inline Vec4f F(const Vec4f v) \
{ return make_Vec4f(F(v.x),F(v.y),F(v.z),F(v.w)); }
__lift_unary_fct(absf)
__lift_unary_fct(rcpf)
__lift_unary_fct(expf)
__lift_unary_fct(logf)
__lift_unary_fct(floor)
__lift_unary_fct(abs)
__lift_unary_fct(rcp)
__lift_unary_fct(exp)
__lift_unary_fct(frac)
__lift_unary_fct(sqr)
#undef __lift_unary_fct
/*! make RGBA from RGB */
inline Vec4f make_Vec4f(const Vec3f rgb, const float a)
{ return make_Vec4f(rgb.x,rgb.y,rgb.z,a); }
/*! make RGBA from RGB */
inline uniform Vec4f make_Vec4f(const uniform Vec3f rgb, const uniform float a)
{ return make_Vec4f(rgb.x,rgb.y,rgb.z,a); }
// // ------------------------------------------------------------------
// // vector functions (abs,rcp,...):
// // ------------------------------------------------------------------
// /*! return vector of absolute values of input vector */
// inline uniform Vec3f abs(const uniform Vec3f v)
// { return make_Vec3f(abs(v.x),abs(v.y),abs(v.z)); }
// /*! return vector of absolute values of input vector */
// inline Vec3f abs(const Vec3f v)
// { return make_Vec3f(abs(v.x),abs(v.y),abs(v.z)); }
// /*! return vector of reciprocals of input vector */
// inline uniform Vec3f rcp(const uniform Vec3f v)
// { return make_Vec3f(rcp(v.x),rcp(v.y),rcp(v.z)); }
// /*! return vector of reciprocals of input vector */
// inline Vec3f rcp(const Vec3f v)
// { return make_Vec3f(rcp(v.x),rcp(v.y),rcp(v.z)); }
#define __define_lerp2(ABB) \
inline uniform Vec2##ABB lerp(uniform float factor, const uniform Vec2##ABB a, const uniform Vec2##ABB b) \
{ \
return make_Vec2##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y)); \
} \
inline Vec2##ABB lerp(float factor, const Vec2##ABB a, const Vec2##ABB b) \
{ \
return make_Vec2##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y)); \
}
#define __define_lerp3(ABB) \
inline uniform Vec3##ABB lerp(uniform float factor, const uniform Vec3##ABB a, const uniform Vec3##ABB b) \
{ \
return make_Vec3##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z)); \
} \
inline Vec3##ABB lerp(float factor, const Vec3##ABB a, const Vec3##ABB b) \
{ \
return make_Vec3##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z)); \
} \
#define __define_lerp3a(ABB) \
inline uniform Vec3##ABB##a lerp(uniform float factor, const uniform Vec3##ABB##a a, const uniform Vec3##ABB##a b) \
{ \
return make_Vec3##ABB##a(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z), lerp(factor, a.w, b.w)); \
} \
inline Vec3##ABB##a lerp(float factor, const Vec3##ABB##a a, const Vec3##ABB##a b) \
{ \
return make_Vec3##ABB##a(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z), lerp(factor, a.w, b.w)); \
}
#define __define_lerp4(ABB) \
inline uniform Vec4##ABB lerp(uniform float factor, const uniform Vec4##ABB a, const uniform Vec4##ABB b) \
{ \
return make_Vec4##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z), lerp(factor, a.w, b.w)); \
} \
inline Vec4##ABB lerp(float factor, const Vec4##ABB a, const Vec4##ABB b) \
{ \
return make_Vec4##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z), lerp(factor, a.w, b.w)); \
}
__define_lerp2(f)
__define_lerp2(i)
__define_lerp2(ui)
__define_lerp2(uc)
__define_lerp3(f)
__define_lerp3(i)
__define_lerp3(ui)
__define_lerp3(uc)
//__define_lerp3a(i)
//__define_lerp3a(ui)
//__define_lerp3a(uc)
__define_lerp4(f)
__define_lerp4(i)
__define_lerp4(ui)
__define_lerp4(uc)
#undef __define_lerp2
#undef __define_lerp3
#undef __define_lerp4
inline Vec2i make_Vec2i(const Vec2f &a)
{ return make_Vec2i((int)a.x, (int)a.y); }
inline Vec2i integer_cast(const Vec2f &a)
{ return make_Vec2i(a); }
inline Vec2f clamp(const Vec2f &a, const uniform Vec2f &b, const uniform Vec2f &c)
{ return(make_Vec2f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y))); }
inline uniform Vec3i operator*(const uniform Vec3i &a, const uniform int b)
{ return(make_Vec3i(a.x * b, a.y * b, a.z * b)); }
inline uniform Vec3i operator+(const uniform Vec3i &a, const uniform Vec3i &b)
{ return(make_Vec3i(a.x + b.x, a.y + b.y, a.z + b.z)); }
inline Vec3i operator+(const varying Vec3i &a, const varying Vec3i &b)
{ return(make_Vec3i(a.x + b.x, a.y + b.y, a.z + b.z)); }
// Workaround for compiler bug.
inline Vec3i operator+(const uniform Vec3i &a, const varying Vec3i &b)
{ return(make_Vec3i(a.x + b.x, a.y + b.y, a.z + b.z)); }
inline Vec3i operator+(const varying Vec3i &a, const varying int32 b)
{ return(make_Vec3i(a.x + b, a.y + b, a.z + b)); }
inline uniform Vec3i operator+(const uniform Vec3i &a, const uniform int b)
{ return(make_Vec3i(a.x + b, a.y + b, a.z + b)); }
inline uniform Vec3i operator-(const uniform Vec3i &a, const uniform int b)
{ return(make_Vec3i(a.x - b, a.y - b, a.z - b)); }
inline Vec3i operator-(const varying Vec3i &a, const uniform Vec3i &b)
{ return(make_Vec3i(a.x - b.x, a.y - b.y, a.z - b.z)); }
inline Vec3i operator-(const varying Vec3i &a, const varying Vec3i &b)
{ return(make_Vec3i(a.x - b.x, a.y - b.y, a.z - b.z)); }
inline Vec3i operator-(const varying Vec3i &a, const varying int32 b)
{ return(make_Vec3i(a.x - b, a.y - b, a.z - b)); }
inline uniform Vec3i operator/(const uniform Vec3i &a, const uniform int b)
{ return(make_Vec3i(a.x / b, a.y / b, a.z / b)); }
inline Vec3f float_cast(const Vec3i &a)
{ return make_Vec3f(a); }
inline Vec3i integer_cast(const Vec3f &a)
{ return make_Vec3i(a); }
inline Vec3i operator>>(const Vec3i &a, const int b)
{ return(make_Vec3i(a.x >> b, a.y >> b, a.z >> b)); }
inline Vec3i operator<<(const Vec3i &a, const int b)
{ return(make_Vec3i(a.x << b, a.y << b, a.z << b)); }
inline Vec3i bitwise_AND(const Vec3i &a, const int b)
{ return(make_Vec3i(a.x & b, a.y & b, a.z &b)); }
inline Vec3f powf(const Vec3f v, const float f)
{ return make_Vec3f(powf(v.x,f),powf(v.y,f),powf(v.z,f)); }
inline uniform Vec3f powf(const uniform Vec3f v, const uniform float f)
{ return make_Vec3f(powf(v.x,f),powf(v.y,f),powf(v.z,f)); }
inline Vec3f clamp(const Vec3f &a, const uniform Vec3f &b, const uniform Vec3f &c)
{ return(make_Vec3f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); }
inline Vec3f clamp(const Vec3f &a, const Vec3f &b, const Vec3f &c)
{ return(make_Vec3f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); }
inline Vec3i clamp(const Vec3i &a, const uniform Vec3i &b, const uniform Vec3i &c)
{ return(make_Vec3i(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); }
//! The next machine representable number from 'a' in the direction of 'b'.
inline uniform Vec3f nextafter(const uniform Vec3i &a, const uniform Vec3i &b)
{ return(make_Vec3f(nextafter(a.x, b.x), nextafter(a.y, b.y), nextafter(a.z, b.z))); }
inline varying float reduce_min(const varying Vec3f &a)
{ return min(min(a.x, a.y), a.z); }
inline uniform float reduce_min(const uniform Vec3f &a)
{ return min(min(a.x, a.y), a.z); }
inline uniform float reduce_min(const uniform Vec3i &a)
{ return min(min(a.x, a.y), a.z); }
inline varying float reduce_min(const varying Vec3i &a)
{ return min(min(a.x, a.y), a.z); }
inline varying float reduce_min(const varying Vec4f &a)
{ return min(min(a.x, a.y), min(a.z, a.w)); }
inline uniform float reduce_min(const uniform Vec4f &a)
{ return min(min(a.x, a.y), min(a.z, a.w)); }
inline uniform float reduce_max(const uniform Vec3i &a)
{ return max(max(a.x, a.y), a.z); }
inline varying float reduce_max(const varying Vec3i &a)
{ return max(max(a.x, a.y), a.z); }
inline varying float reduce_max(const varying Vec3f &a)
{ return max(max(a.x, a.y), a.z); }
inline uniform float reduce_max(const uniform Vec3f &a)
{ return max(max(a.x, a.y), a.z); }
inline varying float reduce_max(const varying Vec4f &a)
{ return max(max(a.x, a.y), max(a.z, a.w)); }
inline uniform float reduce_max(const uniform Vec4f &a)
{ return max(max(a.x, a.y), max(a.z, a.w)); }
inline uniform float reduce_add(const uniform Vec3f &a)
{ return a.x+a.y+a.z; }
inline uniform float reduce_avg(const uniform Vec3f &a)
{ return reduce_add(a)*(1.0f/3.0f); }
inline uniform float luminance(const uniform Vec3f& c)
{ return 0.212671f*c.x + 0.715160f*c.y + 0.072169f*c.z; }
inline varying Vec3f pow(const varying Vec3f &a, const varying float b)
{ return make_Vec3f(pow(a.x, b), pow(a.y, b), pow(a.z, b)); }
inline varying Vec4f pow(const varying Vec4f &a, const varying float b)
{ return make_Vec4f(pow(a.x, b), pow(a.y, b), pow(a.z, b), pow(a.w, b)); }
inline uniform bool isnan(uniform Vec3f v)
{ return isnan(v.x+v.y+v.z); }
inline bool isnan(Vec3f v)
{ return isnan(v.x+v.y+v.z); }
inline uniform bool isnan(uniform Vec3fa v)
{ return isnan(v.x+v.y+v.z); }
inline bool isnan(Vec3fa v)
{ return isnan(v.x+v.y+v.z); }
typedef Vec3fa Vec3ff;
typedef Vec3f Vec3f_;
inline uniform Vec3f make_Vec3f_(uniform float w) { uniform Vec3f r; r.x = w; r.y = w; r.z = w; return r; }
inline varying Vec3f make_Vec3f_(varying float w) { varying Vec3f r; r.x = w; r.y = w; r.z = w; return r; }
inline uniform Vec3f make_Vec3f_(uniform Vec3f v) { uniform Vec3f r; r.x = v.x; r.y = v.y; r.z = v.z; return r; }
inline varying Vec3f make_Vec3f_(varying Vec3f v) { varying Vec3f r; r.x = v.x; r.y = v.y; r.z = v.z; return r; }
inline uniform Vec3f make_Vec3f_(uniform Vec3fa v) { uniform Vec3f r; r.x = v.x; r.y = v.y; r.z = v.z; return r; }
inline varying Vec3f make_Vec3f_(varying Vec3fa v) { varying Vec3f r; r.x = v.x; r.y = v.y; r.z = v.z; return r; }
inline uniform Vec3ff make_Vec3ff(uniform float w) { uniform Vec3ff r; r.x = w; r.y = w; r.z = w; r.w = w; return r; }
inline varying Vec3ff make_Vec3ff(varying float w) { varying Vec3ff r; r.x = w; r.y = w; r.z = w; r.w = w; return r; }
inline uniform Vec3ff make_Vec3ff(uniform Vec3f v) { uniform Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = 0.0f; return r; }
inline varying Vec3ff make_Vec3ff(varying Vec3f v) { varying Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = 0.0f; return r; }
inline uniform Vec3ff make_Vec3ff(uniform Vec3fa v) { uniform Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = 0.0f; return r; }
inline varying Vec3ff make_Vec3ff(varying Vec3fa v) { varying Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = 0.0f; return r; }
inline uniform Vec3ff make_Vec3ff(uniform Vec3f v, uniform float w) { uniform Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r; }
inline varying Vec3ff make_Vec3ff(varying Vec3f v, varying float w) { varying Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r; }
inline uniform Vec3ff make_Vec3ff(uniform Vec3fa v, uniform float w) { uniform Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r; }
inline varying Vec3ff make_Vec3ff(varying Vec3fa v, varying float w) { varying Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r; }
inline uniform Vec3ff make_Vec3ff(uniform float x, uniform float y, uniform float z, uniform float w) { uniform Vec3ff r; r.x = x; r.y = y; r.z = z; r.w = w; return r; }
inline varying Vec3ff make_Vec3ff(varying float x, varying float y, varying float z, varying float w) { varying Vec3ff r; r.x = x; r.y = y; r.z = z; r.w = w; return r; }
inline void out(uniform Vec3f v) { print("(%,%,%)",v.x,v.y,v.z); }
inline void out(Vec3f v) { print("\n(%\n %\n %)",v.x,v.y,v.z); }
inline void out(uniform Vec3i v) { print("(%,%,%)",v.x,v.y,v.z); }
inline void out(Vec3i v) { print("\n(%\n %\n %)",v.x,v.y,v.z); }
// -------------------------------------------------------
// set/get functions for vectors
// should eventually get moved to macros so they work for all types
// -------------------------------------------------------
/*! set vector 'v's value in dimension 'd' to 'f' */
inline void set(uniform Vec3f &v, const uniform uint32 dim, const uniform float f)
{ (&v.x)[dim] = f; }
/*! get vector 'v's value in dimension 'd' */
inline uniform float get(const uniform Vec3f &v, const uniform uint32 dim)
{ return (&v.x)[dim]; }
inline float get(const Vec3f &v, const uniform uint32 dim)
{ return (&v.x)[dim]; }
// -------------------------------------------------------
// sRGB conversion functions
// -------------------------------------------------------
#define APPROXIMATE_SRGB
inline float linear_to_srgb(const float f)
{
const float c = max(f, 0.f);
#ifdef APPROXIMATE_SRGB
return pow(c, 1.f/2.2f);
#else
return c <= 0.0031308f ? 12.92f*c : pow(c, 1.f/2.4f)*1.055f - 0.055f;
#endif
}
inline Vec4f linear_to_srgba(const Vec4f c)
{
return make_Vec4f(linear_to_srgb(c.x),
linear_to_srgb(c.y),
linear_to_srgb(c.z),
max(c.w, 0.f)); // alpha is never gamma-corrected
}
inline uint32 linear_to_srgba8(const Vec4f c)
{
#if 1
Vec4f l = 255.f * min(linear_to_srgba(c), make_Vec4f(1.f));
return
((uint32)l.x << 0) |
((uint32)l.y << 8) |
((uint32)l.z << 16) |
((uint32)l.w << 24);
#else
// TODO use ISPC's float_to_srgb8 once it is fixed (issue #1198)
return
(float_to_srgb8(c.x) << 0) |
(float_to_srgb8(c.y) << 8) |
(float_to_srgb8(c.z) << 16) |
((uint32)clamp(c.w, 0.f, 1.f) << 24); // alpha is never gamma-corrected
#endif
}
inline float srgb_to_linear(const float f)
{
const float c = max(f, 0.f);
#ifdef APPROXIMATE_SRGB
return pow(c, 2.2f);
#else
return c <= 0.04045f ? c/12.92f : pow((c + 0.055f)/1.055f, 2.4f);
#endif
}
inline Vec4f srgba_to_linear(const Vec4f c)
{
return make_Vec4f(srgb_to_linear(c.x),
srgb_to_linear(c.y),
srgb_to_linear(c.z),
max(c.w, 0.f)); // alpha is never gamma-corrected
}
// TODO implement srgba8_to_linear with a 256 entry LUT
#undef APPROXIMATE_SRGB