src/kdtree.cc
branchpyrit
changeset 86 ce6abe0aeeae
parent 85 907a634e5c02
child 87 1081e3dd3f3e
equal deleted inserted replaced
85:907a634e5c02 86:ce6abe0aeeae
   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