src/scene.cc
branchpyrit
changeset 86 ce6abe0aeeae
parent 78 9569e9f35374
child 91 9d66d323c354
--- a/src/scene.cc	Sun Apr 27 14:19:37 2008 +0200
+++ b/src/scene.cc	Sun Apr 27 19:56:23 2008 +0200
@@ -107,3 +107,45 @@
 	b = tfar;
 	return true;
 }
+
+// rewrite of BBox::intersect for ray packets
+__m128 BBox::intersect_packet(const RayPacket &rays, __m128 &a, __m128 &b)
+{
+	register __m128 tnear = mZero;
+	register __m128 tfar = mInf;
+	register __m128 t1, t2;
+	register __m128 mask = mAllSet;
+
+	for (int i = 0; i < 3; i++)
+	{
+		const __m128 mL = _mm_set_ps1(L[i]);
+		const __m128 mH = _mm_set_ps1(H[i]);
+		mask = _mm_and_ps(mask,
+		_mm_or_ps(
+		_mm_or_ps(_mm_cmplt_ps(rays.dir.ma[i], mMEps), _mm_cmpgt_ps(rays.dir.ma[i], mEps)),
+		_mm_and_ps(_mm_cmpge_ps(rays.o.ma[i], mL), _mm_cmple_ps(rays.o.ma[i], mH))
+		));
+		if (!_mm_movemask_ps(mask))
+			return mask;
+
+		/* compute the intersection distance of the planes */
+		t1 = _mm_div_ps(_mm_sub_ps(mL, rays.o.ma[i]), rays.dir.ma[i]);
+		t2 = _mm_div_ps(_mm_sub_ps(mH, rays.o.ma[i]), rays.dir.ma[i]);
+
+		__m128 t = _mm_min_ps(t1, t2);
+		t2 = _mm_max_ps(t1, t2);
+		t1 = t;
+
+		tnear = _mm_max_ps(tnear, t1);	/* want largest Tnear */
+		tfar = _mm_min_ps(tfar, t2);	/* want smallest Tfar */
+
+		mask = _mm_and_ps(mask,
+			_mm_and_ps(_mm_cmple_ps(tnear, tfar), _mm_cmpge_ps(tfar, mZero)));
+		if (!_mm_movemask_ps(mask))
+			return mask;
+	}
+
+	a = tnear;
+	b = tfar;
+	return mask;
+}