src/shapes.cc
branchpyrit
changeset 87 1081e3dd3f3e
parent 86 ce6abe0aeeae
child 91 9d66d323c354
equal deleted inserted replaced
86:ce6abe0aeeae 87:1081e3dd3f3e
    52 		}
    52 		}
    53 	}
    53 	}
    54 	return false;
    54 	return false;
    55 }
    55 }
    56 
    56 
       
    57 __m128 Sphere::intersect_packet(const RayPacket &rays, __m128 &dists)
       
    58 {
       
    59 	VectorPacket V = rays.o - VectorPacket(center);
       
    60 	register __m128 d = _mm_sub_ps(mZero, dot(V, rays.dir));
       
    61 	register __m128 Det = _mm_sub_ps(_mm_mul_ps(d, d),
       
    62 		_mm_sub_ps(dot(V,V), _mm_set_ps1(sqr_radius)));
       
    63 	register __m128 t1, t2, mask;
       
    64 
       
    65 	mask = _mm_cmpgt_ps(Det, mZero);
       
    66 	if (!_mm_movemask_ps(mask))
       
    67 		return mask;
       
    68 
       
    69 	Det = _mm_sqrt_ps(Det);
       
    70 	t1 = _mm_sub_ps(d, Det);
       
    71 	t2 = _mm_add_ps(d, Det);
       
    72 
       
    73 	mask = _mm_and_ps(mask, _mm_cmpgt_ps(t2, mZero));
       
    74 
       
    75 	const __m128 cond1 = _mm_and_ps(_mm_cmpgt_ps(t1, mZero), _mm_cmplt_ps(t1, dists));
       
    76 	const __m128 cond2 = _mm_and_ps(_mm_cmple_ps(t1, mZero), _mm_cmplt_ps(t2, dists));
       
    77 	const __m128 newdists = _mm_or_ps(_mm_and_ps(cond1, t1), _mm_and_ps(cond2, t2));
       
    78 	mask = _mm_and_ps(mask, _mm_or_ps(cond1, cond2));
       
    79 	dists = _mm_or_ps(_mm_and_ps(mask, newdists), _mm_andnot_ps(mask, dists));
       
    80 	return mask;
       
    81 }
       
    82 
    57 /* if there should be CSG sometimes, this may be needed... */
    83 /* if there should be CSG sometimes, this may be needed... */
    58 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const
    84 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const
    59 {
    85 {
    60 	//allts = new vector<Float>();
    86 	//allts = new vector<Float>();
    61 
    87 
   147 		return true;
   173 		return true;
   148 	}
   174 	}
   149 	return false;
   175 	return false;
   150 }
   176 }
   151 
   177 
       
   178 __m128 Box::intersect_packet(const RayPacket &rays, __m128 &dists)
       
   179 {
       
   180 	register __m128 tnear = mZero;
       
   181 	register __m128 tfar = mInf;
       
   182 	register __m128 t1, t2;
       
   183 	register __m128 mask = mAllSet;
       
   184 
       
   185 	for (int i = 0; i < 3; i++)
       
   186 	{
       
   187 		const __m128 mL = _mm_set_ps1(L[i]);
       
   188 		const __m128 mH = _mm_set_ps1(H[i]);
       
   189 		mask = _mm_and_ps(mask,
       
   190 		_mm_or_ps(
       
   191 		_mm_or_ps(_mm_cmplt_ps(rays.dir.ma[i], mMEps), _mm_cmpgt_ps(rays.dir.ma[i], mEps)),
       
   192 		_mm_and_ps(_mm_cmpge_ps(rays.o.ma[i], mL), _mm_cmple_ps(rays.o.ma[i], mH))
       
   193 		));
       
   194 		if (!_mm_movemask_ps(mask))
       
   195 			return mask;
       
   196 
       
   197 		/* compute the intersection distance of the planes */
       
   198 		t1 = _mm_div_ps(_mm_sub_ps(mL, rays.o.ma[i]), rays.dir.ma[i]);
       
   199 		t2 = _mm_div_ps(_mm_sub_ps(mH, rays.o.ma[i]), rays.dir.ma[i]);
       
   200 
       
   201 		__m128 t = _mm_min_ps(t1, t2);
       
   202 		t2 = _mm_max_ps(t1, t2);
       
   203 		t1 = t;
       
   204 
       
   205 		tnear = _mm_max_ps(tnear, t1);	/* want largest Tnear */
       
   206 		tfar = _mm_min_ps(tfar, t2);	/* want smallest Tfar */
       
   207 
       
   208 		mask = _mm_and_ps(mask,
       
   209 			_mm_and_ps(_mm_cmple_ps(tnear, tfar), _mm_cmpge_ps(tfar, mZero)));
       
   210 		if (!_mm_movemask_ps(mask))
       
   211 			return mask;
       
   212 	}
       
   213 
       
   214 	mask = _mm_and_ps(mask, _mm_cmplt_ps(tnear, dists));
       
   215 	dists = _mm_or_ps(_mm_and_ps(mask, tnear), _mm_andnot_ps(mask, dists));
       
   216 	return mask;
       
   217 }
       
   218 
   152 bool Box::intersect_bbox(const BBox &bbox) const
   219 bool Box::intersect_bbox(const BBox &bbox) const
   153 {
   220 {
   154 	return (
   221 	return (
   155 	H.x > bbox.L.x && L.x < bbox.H.x &&
   222 	H.x > bbox.L.x && L.x < bbox.H.x &&
   156 	H.y > bbox.L.y && L.y < bbox.H.y &&
   223 	H.y > bbox.L.y && L.y < bbox.H.y &&
   387 	mask = _mm_and_ps(mask, _mm_and_ps(_mm_cmpge_ps(gamma, mZero),
   454 	mask = _mm_and_ps(mask, _mm_and_ps(_mm_cmpge_ps(gamma, mZero),
   388 		_mm_cmple_ps(_mm_add_ps(beta, gamma), mOne)));
   455 		_mm_cmple_ps(_mm_add_ps(beta, gamma), mOne)));
   389 	if (!_mm_movemask_ps(mask))
   456 	if (!_mm_movemask_ps(mask))
   390 		return mask;
   457 		return mask;
   391 
   458 
   392 	for (int i = 0; i < 4; i++)
   459 	dists = _mm_or_ps(_mm_andnot_ps(mask, dists), _mm_and_ps(mask, t));
   393 		if ((_mm_movemask_ps(mask)>>i)&1)
       
   394 			((float*)&dists)[i] = ((float*)&t)[i];
       
   395 	return mask;
   460 	return mask;
   396 }
   461 }
   397 #endif
   462 #endif
   398 
   463 
   399 bool Triangle::intersect_bbox(const BBox &bbox) const
   464 bool Triangle::intersect_bbox(const BBox &bbox) const