Skip to content

Commit 1a7412f

Browse files
turns out computing the inverse transform in doubles is what saves our intersection precision
1 parent e552021 commit 1a7412f

File tree

1 file changed

+71
-3
lines changed

1 file changed

+71
-3
lines changed

include/nbl/ext/RadeonRays/RadeonRays.h

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,77 @@ class Manager final : public core::IReferenceCounted
149149
{
150150
core::matrix4SIMD tform(transform);
151151

152-
core::matrix3x4SIMD tmp;
153-
transform.getInverse(tmp);
154-
core::matrix4SIMD tform_inv(tmp);
152+
// TODO: move this stuff
153+
struct dvec3
154+
{
155+
dvec3() : x(0.0), y(0.0), z(0.0) {}
156+
dvec3(const core::vectorSIMDf& p) : x(p.x), y(p.y), z(p.z) {}
157+
158+
dvec3& operator-=(dvec3 other)
159+
{
160+
x -= other.x;
161+
y -= other.y;
162+
z -= other.z;
163+
return *this;
164+
}
165+
dvec3& operator*=(double other)
166+
{
167+
x *= other;
168+
y *= other;
169+
z *= other;
170+
return *this;
171+
}
172+
dvec3 operator*(double other) const
173+
{
174+
dvec3 retval(*this);
175+
retval *= other;
176+
return retval;
177+
}
178+
dvec3& operator/=(double other)
179+
{
180+
x /= other;
181+
y /= other;
182+
z /= other;
183+
return *this;
184+
}
185+
186+
double x,y,z;
187+
};
188+
auto dot = [](const dvec3& a, const dvec3& b) -> double
189+
{
190+
return a.x*b.x+a.y*b.y+a.z*b.z;
191+
};
192+
auto cross = [](const dvec3& a, const dvec3& b) -> dvec3
193+
{
194+
dvec3 retval;
195+
retval.x = a.y*b.z-a.z*b.y;
196+
retval.y = a.z*b.x-a.x*b.z;
197+
retval.z = a.x*b.y-a.y*b.x;
198+
return retval;
199+
};
200+
const dvec3 in_rows[3] = {transform.rows[0],transform.rows[1],transform.rows[2]};
201+
dvec3 out_cols[4];
202+
out_cols[0] = cross(in_rows[1],in_rows[2]);
203+
out_cols[1] = cross(in_rows[2],in_rows[0]);
204+
out_cols[2] = cross(in_rows[0],in_rows[1]);
205+
const double determinant = dot(in_rows[0],out_cols[0]);
206+
out_cols[3] = {};
207+
const auto translation = transform.getTranslation();
208+
for (auto i=0; i<3; i++)
209+
{
210+
out_cols[3] -= out_cols[i]*double(translation.pointer[i]);
211+
out_cols[i] /= determinant;
212+
}
213+
out_cols[3] /= determinant;
214+
215+
core::matrix4SIMD tform_inv;
216+
for (auto i=0; i<4; i++)
217+
{
218+
tform_inv.rows[i].x = out_cols[i].x;
219+
tform_inv.rows[i].y = out_cols[i].y;
220+
tform_inv.rows[i].z = out_cols[i].z;
221+
}
222+
tform_inv = core::transpose(tform_inv);
155223

156224
shape->SetTransform(reinterpret_cast<::RadeonRays::matrix&>(tform),reinterpret_cast<::RadeonRays::matrix&>(tform_inv));
157225
}

0 commit comments

Comments
 (0)