d3dx8: Implement D3DXBoxBoundProbe.

This commit is contained in:
David Adam 2008-08-19 20:11:58 +02:00 committed by Alexandre Julliard
parent 517462cf9a
commit 5bb6e4ab8c
4 changed files with 120 additions and 4 deletions

View File

@ -109,7 +109,7 @@
@ stub D3DXWeldVertices
@ stub D3DXIntersect
@ stdcall D3DXSphereBoundProbe(ptr long ptr ptr)
@ stub D3DXBoxBoundProbe
@ stdcall D3DXBoxBoundProbe(ptr ptr ptr ptr)
@ stub D3DXCreatePolygon
@ stub D3DXCreateBox
@ stub D3DXCreateCylinder

View File

@ -24,6 +24,76 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
BOOL WINAPI D3DXBoxBoundProbe(CONST D3DXVECTOR3 *pmin, CONST D3DXVECTOR3 *pmax, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
/* Algorithm taken from the article: An Efficient and Robust Ray-Box Intersection Algoritm
Amy Williams University of Utah
Steve Barrus University of Utah
R. Keith Morley University of Utah
Peter Shirley University of Utah
International Conference on Computer Graphics and Interactive Techniques archive
ACM SIGGRAPH 2005 Courses
Los Angeles, California
This algorithm is free of patents or of copyrights, as confirmed by Peter Shirley himself.
Algorithm: Consider the box as the intersection of three slabs. Clip the ray
against each slab, if there's anything left of the ray after we're
done we've got an intersection of the ray with the box.
*/
{
FLOAT div, tmin, tmax, tymin, tymax, tzmin, tzmax;
div = 1.0f / praydirection->x;
if ( div >= 0.0f )
{
tmin = ( pmin->x - prayposition->x ) * div;
tmax = ( pmax->x - prayposition->x ) * div;
}
else
{
tmin = ( pmax->x - prayposition->x ) * div;
tmax = ( pmin->x - prayposition->x ) * div;
}
if ( tmax < 0.0f ) return FALSE;
div = 1.0f / praydirection->y;
if ( div >= 0.0f )
{
tymin = ( pmin->y - prayposition->y ) * div;
tymax = ( pmax->y - prayposition->y ) * div;
}
else
{
tymin = ( pmax->y - prayposition->y ) * div;
tymax = ( pmin->y - prayposition->y ) * div;
}
if ( ( tymax < 0.0f ) || ( tmin > tymax ) || ( tymin > tmax ) ) return FALSE;
if ( tymin > tmin ) tmin = tymin;
if ( tymax < tmax ) tmax = tymax;
div = 1.0f / praydirection->z;
if ( div >= 0.0f )
{
tzmin = ( pmin->z - prayposition->z ) * div;
tzmax = ( pmax->z - prayposition->z ) * div;
}
else
{
tzmin = ( pmax->z - prayposition->z ) * div;
tzmax = ( pmin->z - prayposition->z ) * div;
}
if ( (tzmax < 0.0f ) || ( tmin > tzmax ) || ( tzmin > tmax ) ) return FALSE;
return TRUE;
}
BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
{
D3DXVECTOR3 difference;

View File

@ -22,12 +22,57 @@
static void D3DXBoundProbeTest(void)
{
/*____________Test the Sphere case________________________*/
BOOL result;
D3DXVECTOR3 center, raydirection, rayposition;
D3DXVECTOR3 bottom_point, center, top_point, raydirection, rayposition;
FLOAT radius;
/*____________Test the Box case___________________________*/
bottom_point.x = -3.0f; bottom_point.y = -2.0f; bottom_point.z = -1.0f;
top_point.x = 7.0f; top_point.y = 8.0f; top_point.z = 9.0f;
raydirection.x = -4.0f; raydirection.y = -5.0f; raydirection.z = -6.0f;
rayposition.x = 5.0f; rayposition.y = 5.0f; rayposition.z = 11.0f;
result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
ok(result == TRUE, "expected TRUE, received FALSE\n");
raydirection.x = 4.0f; raydirection.y = 5.0f; raydirection.z = 6.0f;
rayposition.x = 5.0f; rayposition.y = 5.0f; rayposition.z = 11.0f;
result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
ok(result == FALSE, "expected FALSE, received TRUE\n");
rayposition.x = -4.0f; rayposition.y = 1.0f; rayposition.z = -2.0f;
result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
ok(result == TRUE, "expected TRUE, received FALSE\n");
bottom_point.x = 1.0f; bottom_point.y = 0.0f; bottom_point.z = 0.0f;
top_point.x = 1.0f; top_point.y = 0.0f; top_point.z = 0.0f;
rayposition.x = 0.0f; rayposition.y = 1.0f; rayposition.z = 0.0f;
raydirection.x = 0.0f; raydirection.y = 3.0f; raydirection.z = 0.0f;
result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
ok(result == FALSE, "expected FALSE, received TRUE\n");
bottom_point.x = 1.0f; bottom_point.y = 2.0f; bottom_point.z = 3.0f;
top_point.x = 10.0f; top_point.y = 15.0f; top_point.z = 20.0f;
raydirection.x = 7.0f; raydirection.y = 8.0f; raydirection.z = 9.0f;
rayposition.x = 3.0f; rayposition.y = 7.0f; rayposition.z = -6.0f;
result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
ok(result == TRUE, "expected TRUE, received FALSE\n");
bottom_point.x = 0.0f; bottom_point.y = 0.0f; bottom_point.z = 0.0f;
top_point.x = 1.0f; top_point.y = 1.0f; top_point.z = 1.0f;
raydirection.x = 0.0f; raydirection.y = 1.0f; raydirection.z = .0f;
rayposition.x = -3.0f; rayposition.y = 0.0f; rayposition.z = 0.0f;
result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
ok(result == FALSE, "expected FALSE, received TRUE\n");
raydirection.x = 1.0f; raydirection.y = 0.0f; raydirection.z = .0f;
rayposition.x = -3.0f; rayposition.y = 0.0f; rayposition.z = 0.0f;
result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
ok(result == TRUE, "expected TRUE, received FALSE\n");
/*____________Test the Sphere case________________________*/
radius = sqrt(77.0f);
center.x = 1.0f; center.y = 2.0f; center.z = 3.0f;
raydirection.x = 2.0f; raydirection.y = -4.0f; raydirection.z = 2.0f;

View File

@ -28,6 +28,7 @@ extern "C" {
HRESULT WINAPI D3DXCreateBuffer(DWORD,LPD3DXBUFFER*);
UINT WINAPI D3DXGetFVFVertexSize(DWORD);
BOOL WINAPI D3DXBoxBoundProbe(CONST D3DXVECTOR3 *, CONST D3DXVECTOR3 *, CONST D3DXVECTOR3 *, CONST D3DXVECTOR3 *);
BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *,FLOAT,CONST D3DXVECTOR3 *,CONST D3DXVECTOR3 *);
#ifdef __cplusplus