src/scene.cc
branchpyrit
changeset 92 9af5c039b678
parent 91 9d66d323c354
child 93 96d65f841791
equal deleted inserted replaced
91:9d66d323c354 92:9af5c039b678
    71 {
    71 {
    72 	eye = eye + fw*p + left*u + up*v;
    72 	eye = eye + fw*p + left*u + up*v;
    73 }
    73 }
    74 
    74 
    75 /* http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm */
    75 /* http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm */
    76 bool BBox::intersect(const Ray &ray, Float &a, Float &b)
    76 bool BBox::intersect(const Ray &ray, Float &a, Float &b) const
    77 {
    77 {
    78 	register Float tnear = -Inf;
    78 	register Float tnear = -Inf;
    79 	register Float tfar = Inf;
    79 	register Float tfar = Inf;
    80 	register Float t1, t2;
    80 	register Float t1, t2;
    81 
    81 
   106 	a = tnear;
   106 	a = tnear;
   107 	b = tfar;
   107 	b = tfar;
   108 	return true;
   108 	return true;
   109 }
   109 }
   110 
   110 
   111 #ifndef NO_SSE
   111 #ifndef NO_SIMD
   112 // rewrite of BBox::intersect for ray packets
   112 // rewrite of BBox::intersect for ray packets
   113 __m128 BBox::intersect_packet(const RayPacket &rays, __m128 &a, __m128 &b)
   113 mfloat4 BBox::intersect_packet(const RayPacket &rays, mfloat4 &a, mfloat4 &b) const
   114 {
   114 {
   115 	register __m128 tnear = mZero;
   115 	mfloat4 origin = rays.o.ma[0];
   116 	register __m128 tfar = mInf;
   116 	mfloat4 invdir = rays.invdir.ma[0];
   117 	register __m128 t1, t2;
   117 	mfloat4 t1 = mmul(msub(mset1(L[0]), origin), invdir);
   118 	register __m128 mask = mAllSet;
   118 	mfloat4 t2 = mmul(msub(mset1(H[0]), origin), invdir);
       
   119 	mfloat4 tmin = mmin(t1, t2);
       
   120 	mfloat4 tmax = mmax(t1, t2);
   119 
   121 
   120 	for (int i = 0; i < 3; i++)
   122 	origin = rays.o.ma[1];
   121 	{
   123 	invdir = rays.invdir.ma[1];
   122 		const __m128 mL = _mm_set_ps1(L[i]);
   124 	t1 = mmul(msub(mset1(L[1]), origin), invdir);
   123 		const __m128 mH = _mm_set_ps1(H[i]);
   125 	t2 = mmul(msub(mset1(H[1]), origin), invdir);
   124 		mask = _mm_and_ps(mask,
   126 	tmin = mmax(mmin(t1, t2), tmin);
   125 		_mm_or_ps(
   127 	tmax = mmin(mmax(t1, t2), tmax);
   126 		_mm_or_ps(_mm_cmplt_ps(rays.dir.ma[i], mMEps), _mm_cmpgt_ps(rays.dir.ma[i], mEps)),
       
   127 		_mm_and_ps(_mm_cmpge_ps(rays.o.ma[i], mL), _mm_cmple_ps(rays.o.ma[i], mH))
       
   128 		));
       
   129 		if (!_mm_movemask_ps(mask))
       
   130 			return mask;
       
   131 
   128 
   132 		/* compute the intersection distance of the planes */
   129 	origin = rays.o.ma[2];
   133 		t1 = _mm_div_ps(_mm_sub_ps(mL, rays.o.ma[i]), rays.dir.ma[i]);
   130 	invdir = rays.invdir.ma[2];
   134 		t2 = _mm_div_ps(_mm_sub_ps(mH, rays.o.ma[i]), rays.dir.ma[i]);
   131 	t1 = mmul(msub(mset1(L[2]), origin), invdir);
       
   132 	t2 = mmul(msub(mset1(H[2]), origin), invdir);
       
   133 	tmin = mmax(mmin(t1, t2), tmin);
       
   134 	tmax = mmin(mmax(t1, t2), tmax);
   135 
   135 
   136 		__m128 t = _mm_min_ps(t1, t2);
   136 	a = tmin;
   137 		t2 = _mm_max_ps(t1, t2);
   137 	b = tmax;
   138 		t1 = t;
   138 	return mand(mcmplt(tmin, tmax), mcmpgt(tmax, mZero));
   139 
       
   140 		tnear = _mm_max_ps(tnear, t1);	/* want largest Tnear */
       
   141 		tfar = _mm_min_ps(tfar, t2);	/* want smallest Tfar */
       
   142 
       
   143 		mask = _mm_and_ps(mask,
       
   144 			_mm_and_ps(_mm_cmple_ps(tnear, tfar), _mm_cmpge_ps(tfar, mZero)));
       
   145 		if (!_mm_movemask_ps(mask))
       
   146 			return mask;
       
   147 	}
       
   148 
       
   149 	a = tnear;
       
   150 	b = tfar;
       
   151 	return mask;
       
   152 }
   139 }
   153 #endif
   140 #endif