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 |