src/shapes.cc
branchpyrit
changeset 91 9d66d323c354
parent 87 1081e3dd3f3e
child 92 9af5c039b678
equal deleted inserted replaced
90:f6a72eb99631 91:9d66d323c354
    27 #include "shapes.h"
    27 #include "shapes.h"
    28 #include "serialize.h"
    28 #include "serialize.h"
    29 
    29 
    30 bool Sphere::intersect(const Ray &ray, Float &dist) const
    30 bool Sphere::intersect(const Ray &ray, Float &dist) const
    31 {
    31 {
    32 	Vector3 V = ray.o - center;
    32 	Vector V = ray.o - center;
    33 	register Float d = -dot(V, ray.dir);
    33 	register Float d = -dot(V, ray.dir);
    34 	register Float Det = d * d - (dot(V,V) - sqr_radius);
    34 	register Float Det = d * d - (dot(V,V) - sqr_radius);
    35 	register Float t1,t2;
    35 	register Float t1,t2;
    36 	if (Det > 0) {
    36 	if (Det > 0) {
    37 		Det = sqrtf(Det);
    37 		Det = sqrtf(Det);
    52 		}
    52 		}
    53 	}
    53 	}
    54 	return false;
    54 	return false;
    55 }
    55 }
    56 
    56 
       
    57 #ifndef NO_SSE
    57 __m128 Sphere::intersect_packet(const RayPacket &rays, __m128 &dists)
    58 __m128 Sphere::intersect_packet(const RayPacket &rays, __m128 &dists)
    58 {
    59 {
    59 	VectorPacket V = rays.o - VectorPacket(center);
    60 	VectorPacket V = rays.o - VectorPacket(center);
    60 	register __m128 d = _mm_sub_ps(mZero, dot(V, rays.dir));
    61 	register __m128 d = _mm_sub_ps(mZero, dot(V, rays.dir));
    61 	register __m128 Det = _mm_sub_ps(_mm_mul_ps(d, d),
    62 	register __m128 Det = _mm_sub_ps(_mm_mul_ps(d, d),
    77 	const __m128 newdists = _mm_or_ps(_mm_and_ps(cond1, t1), _mm_and_ps(cond2, t2));
    78 	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 	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 	dists = _mm_or_ps(_mm_and_ps(mask, newdists), _mm_andnot_ps(mask, dists));
    80 	return mask;
    81 	return mask;
    81 }
    82 }
       
    83 #endif
    82 
    84 
    83 /* if there should be CSG sometimes, this may be needed... */
    85 /* if there should be CSG sometimes, this may be needed... */
    84 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const
    86 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const
    85 {
    87 {
    86 	//allts = new vector<Float>();
    88 	//allts = new vector<Float>();
    87 
    89 
    88 	Vector3 V = ((Ray)ray).o - center;
    90 	Vector V = ((Ray)ray).o - center;
    89 	Float Vd = - dot(V, ray.dir);
    91 	Float Vd = - dot(V, ray.dir);
    90 	Float Det = Vd * Vd - (dot(V,V) - sqr_radius);
    92 	Float Det = Vd * Vd - (dot(V,V) - sqr_radius);
    91 
    93 
    92 	if (Det > 0) {
    94 	if (Det > 0) {
    93 		Det = sqrtf(Det);
    95 		Det = sqrtf(Det);
   173 		return true;
   175 		return true;
   174 	}
   176 	}
   175 	return false;
   177 	return false;
   176 }
   178 }
   177 
   179 
       
   180 #ifndef NO_SSE
   178 __m128 Box::intersect_packet(const RayPacket &rays, __m128 &dists)
   181 __m128 Box::intersect_packet(const RayPacket &rays, __m128 &dists)
   179 {
   182 {
   180 	register __m128 tnear = mZero;
   183 	register __m128 tnear = mZero;
   181 	register __m128 tfar = mInf;
   184 	register __m128 tfar = mInf;
   182 	register __m128 t1, t2;
   185 	register __m128 t1, t2;
   213 
   216 
   214 	mask = _mm_and_ps(mask, _mm_cmplt_ps(tnear, dists));
   217 	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));
   218 	dists = _mm_or_ps(_mm_and_ps(mask, tnear), _mm_andnot_ps(mask, dists));
   216 	return mask;
   219 	return mask;
   217 }
   220 }
       
   221 #endif
   218 
   222 
   219 bool Box::intersect_bbox(const BBox &bbox) const
   223 bool Box::intersect_bbox(const BBox &bbox) const
   220 {
   224 {
   221 	return (
   225 	return (
   222 	H.x > bbox.L.x && L.x < bbox.H.x &&
   226 	H.x > bbox.L.x && L.x < bbox.H.x &&
   223 	H.y > bbox.L.y && L.y < bbox.H.y &&
   227 	H.y > bbox.L.y && L.y < bbox.H.y &&
   224 	H.z > bbox.L.z && L.z < bbox.H.z);
   228 	H.z > bbox.L.z && L.z < bbox.H.z);
   225 }
   229 }
   226 
   230 
   227 const Vector3 Box::normal(const Vector3 &P) const
   231 const Vector Box::normal(const Vector &P) const
   228 {
   232 {
   229 	register Vector3 l = P - L;
   233 	register Vector l = P - L;
   230 	register Vector3 h = H - P;
   234 	register Vector h = H - P;
   231 
   235 
   232 	if (l.x < h.x)
   236 	if (l.x < h.x)
   233 		h.x = -1;
   237 		h.x = -1;
   234 	else
   238 	else
   235 	{
   239 	{
   271 	}
   275 	}
   272 	return h;
   276 	return h;
   273 }
   277 }
   274 
   278 
   275 #ifdef TRI_PLUCKER
   279 #ifdef TRI_PLUCKER
   276 inline void Plucker(const Vector3 &p, const Vector3 &q, Float* pl)
   280 inline void Plucker(const Vector &p, const Vector &q, Float* pl)
   277 {
   281 {
   278     pl[0] = p.x*q.y - q.x*p.y;
   282     pl[0] = p.x*q.y - q.x*p.y;
   279     pl[1] = p.x*q.z - q.x*p.z;
   283     pl[1] = p.x*q.z - q.x*p.z;
   280     pl[2] = p.x - q.x;
   284     pl[2] = p.x - q.x;
   281     pl[3] = p.y*q.z - q.y*p.z;
   285     pl[3] = p.y*q.z - q.y*p.z;
   292 Triangle::Triangle(Vertex *aA, Vertex *aB, Vertex *aC, Material *amaterial)
   296 Triangle::Triangle(Vertex *aA, Vertex *aB, Vertex *aC, Material *amaterial)
   293 	: A(aA), B(aB), C(aC)
   297 	: A(aA), B(aB), C(aC)
   294 {
   298 {
   295 	material = amaterial;
   299 	material = amaterial;
   296 
   300 
   297 	const Vector3 c = B->P - A->P;
   301 	const Vector c = B->P - A->P;
   298 	const Vector3 b = C->P - A->P;
   302 	const Vector b = C->P - A->P;
   299 
   303 
   300 	N = cross(c, b);
   304 	N = cross(c, b);
   301 	N.normalize();
   305 	N.normalize();
   302 
   306 
   303 #ifdef TRI_PLUCKER
   307 #ifdef TRI_PLUCKER
   361 	return true;
   365 	return true;
   362 #endif
   366 #endif
   363 
   367 
   364 #if defined(TRI_BARI) || defined(TRI_BARI_PRE)
   368 #if defined(TRI_BARI) || defined(TRI_BARI_PRE)
   365 	static const int modulo3[5] = {0,1,2,0,1};
   369 	static const int modulo3[5] = {0,1,2,0,1};
   366 	const Vector3 &O = ray.o;
   370 	const Vector &O = ray.o;
   367 	const Vector3 &D = ray.dir;
   371 	const Vector &D = ray.dir;
   368 	register const int u = modulo3[k+1];
   372 	register const int u = modulo3[k+1];
   369 	register const int v = modulo3[k+2];
   373 	register const int v = modulo3[k+2];
   370 #endif
   374 #endif
   371 #ifdef TRI_BARI_PRE
   375 #ifdef TRI_BARI_PRE
   372 	const Float t = (nd - O[k] - nu * O[u] - nv * O[v]) / (D[k] + nu * D[u] + nv * D[v]);
   376 	const Float t = (nd - O[k] - nu * O[u] - nv * O[v]) / (D[k] + nu * D[u] + nv * D[v]);
   390 #endif
   394 #endif
   391 
   395 
   392 #ifdef TRI_BARI
   396 #ifdef TRI_BARI
   393 	// original barycentric coordinates based intesection
   397 	// original barycentric coordinates based intesection
   394 	// not optimized, just for reference
   398 	// not optimized, just for reference
   395 	const Vector3 c = B - A;
   399 	const Vector c = B - A;
   396 	const Vector3 b = C - A;
   400 	const Vector b = C - A;
   397 	// distance test
   401 	// distance test
   398 	const Float t = - dot( (O-A), N) / dot(D,N);
   402 	const Float t = - dot( (O-A), N) / dot(D,N);
   399 	if (t < Eps || t > dist)
   403 	if (t < Eps || t > dist)
   400 		return false;
   404 		return false;
   401 
   405 
   413 	dist = t;
   417 	dist = t;
   414 	return true;
   418 	return true;
   415 #endif
   419 #endif
   416 }
   420 }
   417 
   421 
   418 #ifdef TRI_BARI_PRE
   422 #if not defined(NO_SSE) and defined(TRI_BARI_PRE)
   419 __m128 Triangle::intersect_packet(const RayPacket &rays, __m128 &dists)
   423 __m128 Triangle::intersect_packet(const RayPacket &rays, __m128 &dists)
   420 {
   424 {
   421 	static const int modulo3[5] = {0,1,2,0,1};
   425 	static const int modulo3[5] = {0,1,2,0,1};
   422 	register const int u = modulo3[k+1];
   426 	register const int u = modulo3[k+1];
   423 	register const int v = modulo3[k+2];
   427 	register const int v = modulo3[k+2];
   461 }
   465 }
   462 #endif
   466 #endif
   463 
   467 
   464 bool Triangle::intersect_bbox(const BBox &bbox) const
   468 bool Triangle::intersect_bbox(const BBox &bbox) const
   465 {
   469 {
   466 	const Vector3 boxcenter = (bbox.L+bbox.H)*0.5;
   470 	const Vector boxcenter = (bbox.L+bbox.H)*0.5;
   467 	const Vector3 boxhalfsize = (bbox.H-bbox.L)*0.5;
   471 	const Vector boxhalfsize = (bbox.H-bbox.L)*0.5;
   468 	const Vector3 v0 = A->P - boxcenter;
   472 	const Vector v0 = A->P - boxcenter;
   469 	const Vector3 v1 = B->P - boxcenter;
   473 	const Vector v1 = B->P - boxcenter;
   470 	const Vector3 v2 = C->P - boxcenter;
   474 	const Vector v2 = C->P - boxcenter;
   471 	const Vector3 e0 = v1-v0;
   475 	const Vector e0 = v1-v0;
   472 	const Vector3 e1 = v2-v1;
   476 	const Vector e1 = v2-v1;
   473 	const Vector3 e2 = v0-v2;
   477 	const Vector e2 = v0-v2;
   474 
   478 
   475 	Float fex = fabsf(e0.x);
   479 	Float fex = fabsf(e0.x);
   476 	Float fey = fabsf(e0.y);
   480 	Float fey = fabsf(e0.y);
   477 	Float fez = fabsf(e0.z);
   481 	Float fez = fabsf(e0.z);
   478 
   482 
   567 	if (v1.z > max) max = v1.z;
   571 	if (v1.z > max) max = v1.z;
   568 	if (v2.z > max) max = v2.z;
   572 	if (v2.z > max) max = v2.z;
   569 	if(min>boxhalfsize.z || max<-boxhalfsize.z) return false;
   573 	if(min>boxhalfsize.z || max<-boxhalfsize.z) return false;
   570 
   574 
   571 	/*  test if the box intersects the plane of the triangle */
   575 	/*  test if the box intersects the plane of the triangle */
   572 	Vector3 vmin,vmax;
   576 	Vector vmin,vmax;
   573 	Float v;
   577 	Float v;
   574 	for(int q=0;q<3;q++)
   578 	for(int q=0;q<3;q++)
   575 	{
   579 	{
   576 		v=v0[q];
   580 		v=v0[q];
   577 		if(N[q]>0.0f)
   581 		if(N[q]>0.0f)