105 |
105 |
106 a = tnear; |
106 a = tnear; |
107 b = tfar; |
107 b = tfar; |
108 return true; |
108 return true; |
109 } |
109 } |
|
110 |
|
111 // rewrite of BBox::intersect for ray packets |
|
112 __m128 BBox::intersect_packet(const RayPacket &rays, __m128 &a, __m128 &b) |
|
113 { |
|
114 register __m128 tnear = mZero; |
|
115 register __m128 tfar = mInf; |
|
116 register __m128 t1, t2; |
|
117 register __m128 mask = mAllSet; |
|
118 |
|
119 for (int i = 0; i < 3; i++) |
|
120 { |
|
121 const __m128 mL = _mm_set_ps1(L[i]); |
|
122 const __m128 mH = _mm_set_ps1(H[i]); |
|
123 mask = _mm_and_ps(mask, |
|
124 _mm_or_ps( |
|
125 _mm_or_ps(_mm_cmplt_ps(rays.dir.ma[i], mMEps), _mm_cmpgt_ps(rays.dir.ma[i], mEps)), |
|
126 _mm_and_ps(_mm_cmpge_ps(rays.o.ma[i], mL), _mm_cmple_ps(rays.o.ma[i], mH)) |
|
127 )); |
|
128 if (!_mm_movemask_ps(mask)) |
|
129 return mask; |
|
130 |
|
131 /* compute the intersection distance of the planes */ |
|
132 t1 = _mm_div_ps(_mm_sub_ps(mL, rays.o.ma[i]), rays.dir.ma[i]); |
|
133 t2 = _mm_div_ps(_mm_sub_ps(mH, rays.o.ma[i]), rays.dir.ma[i]); |
|
134 |
|
135 __m128 t = _mm_min_ps(t1, t2); |
|
136 t2 = _mm_max_ps(t1, t2); |
|
137 t1 = t; |
|
138 |
|
139 tnear = _mm_max_ps(tnear, t1); /* want largest Tnear */ |
|
140 tfar = _mm_min_ps(tfar, t2); /* want smallest Tfar */ |
|
141 |
|
142 mask = _mm_and_ps(mask, |
|
143 _mm_and_ps(_mm_cmple_ps(tnear, tfar), _mm_cmpge_ps(tfar, mZero))); |
|
144 if (!_mm_movemask_ps(mask)) |
|
145 return mask; |
|
146 } |
|
147 |
|
148 a = tnear; |
|
149 b = tfar; |
|
150 return mask; |
|
151 } |