340 void KdTree::packet_intersection(const Shape **origin_shapes, const RayPacket &rays, |
340 void KdTree::packet_intersection(const Shape **origin_shapes, const RayPacket &rays, |
341 Float *nearest_distances, Shape **nearest_shapes) |
341 Float *nearest_distances, Shape **nearest_shapes) |
342 { |
342 { |
343 __m128 a, b; /* entry/exit signed distance */ |
343 __m128 a, b; /* entry/exit signed distance */ |
344 __m128 t; /* signed distance to the splitting plane */ |
344 __m128 t; /* signed distance to the splitting plane */ |
345 __m128 mask = zeros; |
345 __m128 mask = mZero; |
346 |
346 |
347 /* if we have no tree, fall back to naive test */ |
347 /* if we have no tree, fall back to naive test */ |
348 if (!built) |
348 if (!built) |
349 Container::packet_intersection(origin_shapes, rays, nearest_distances, nearest_shapes); |
349 Container::packet_intersection(origin_shapes, rays, nearest_distances, nearest_shapes); |
350 |
350 |
351 nearest_shapes[0] = NULL; |
351 // nearest_shapes[0..4] = NULL |
352 nearest_shapes[1] = NULL; |
352 memset(nearest_shapes, 0, 4*sizeof(Shape*)); |
353 nearest_shapes[2] = NULL; |
353 |
354 nearest_shapes[3] = NULL; |
354 mask = bbox.intersect_packet(rays, a, b); |
355 |
|
356 //bbox.intersect_packet(rays, a, b) |
|
357 if (bbox.intersect(rays[0], ((float*)&a)[0], ((float*)&b)[0])) |
|
358 ((int*)&mask)[0] = -1; |
|
359 if (bbox.intersect(rays[1], ((float*)&a)[1], ((float*)&b)[1])) |
|
360 ((int*)&mask)[1] = -1; |
|
361 if (bbox.intersect(rays[2], ((float*)&a)[2], ((float*)&b)[2])) |
|
362 ((int*)&mask)[2] = -1; |
|
363 if (bbox.intersect(rays[3], ((float*)&a)[3], ((float*)&b)[3])) |
|
364 ((int*)&mask)[3] = -1; |
|
365 |
|
366 if (!_mm_movemask_ps(mask)) |
355 if (!_mm_movemask_ps(mask)) |
367 return; |
356 return; |
368 |
357 |
369 /* pointers to the far child node and current node */ |
358 /* pointers to the far child node and current node */ |
370 KdNode *farchild, *node; |
359 KdNode *farchild, *node; |
394 /* loop, traverse through the whole kd-tree, |
383 /* loop, traverse through the whole kd-tree, |
395 until an object is intersected or ray leaves the scene */ |
384 until an object is intersected or ray leaves the scene */ |
396 __m128 splitVal; |
385 __m128 splitVal; |
397 int axis; |
386 int axis; |
398 static const int mod3[] = {0,1,2,0,1}; |
387 static const int mod3[] = {0,1,2,0,1}; |
399 const VectorPacket invdirs = ones / rays.dir; |
388 const VectorPacket invdirs = mOne / rays.dir; |
400 while (node) |
389 while (node) |
401 { |
390 { |
402 /* loop until a leaf is found */ |
391 /* loop until a leaf is found */ |
403 while (!node->isLeaf()) |
392 while (!node->isLeaf()) |
404 { |
393 { |
492 |
481 |
493 /* current node is the leaf . . . empty or full */ |
482 /* current node is the leaf . . . empty or full */ |
494 __m128 dists = stack[exit].t; |
483 __m128 dists = stack[exit].t; |
495 ShapeList::iterator shape; |
484 ShapeList::iterator shape; |
496 __m128 results; |
485 __m128 results; |
|
486 __m128 newmask = mask; |
497 for (shape = node->getShapes()->begin(); shape != node->getShapes()->end(); shape++) |
487 for (shape = node->getShapes()->begin(); shape != node->getShapes()->end(); shape++) |
498 { |
488 { |
499 results = (*shape)->intersect_packet(rays, dists); |
489 results = (*shape)->intersect_packet(rays, dists); |
500 int valid = _mm_movemask_ps( |
490 int valid = _mm_movemask_ps( |
501 _mm_and_ps(mask, _mm_and_ps(results, _mm_cmpge_ps(dists, _mm_sub_ps(stack[entry].t, mEps))))); |
491 _mm_and_ps(mask, _mm_and_ps(results, _mm_cmpge_ps(dists, _mm_sub_ps(stack[entry].t, mEps))))); |
503 { |
493 { |
504 if (*shape != origin_shapes[i] && ((valid>>i)&1)) |
494 if (*shape != origin_shapes[i] && ((valid>>i)&1)) |
505 { |
495 { |
506 nearest_shapes[i] = *shape; |
496 nearest_shapes[i] = *shape; |
507 nearest_distances[i] = ((float*)&dists)[i]; |
497 nearest_distances[i] = ((float*)&dists)[i]; |
|
498 ((int*)&newmask)[i] = 0; |
508 } |
499 } |
509 } |
500 } |
510 } |
501 } |
511 |
502 |
512 for (int i = 0; i < 4; i++) |
503 mask = newmask; |
513 if (nearest_shapes[i]) |
|
514 ((int*)&mask)[i] = 0; |
|
515 |
|
516 if (!_mm_movemask_ps(mask)) |
504 if (!_mm_movemask_ps(mask)) |
517 return; |
505 return; |
518 |
506 |
519 entry = exit; |
507 entry = exit; |
520 |
508 |