Spurred by a patch by Alex Henrie.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3dx9_36/mesh.c | 19 ++++++++++--------- dlls/d3dx9_36/tests/mesh.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c index 5e0bb98efc77..22f86f10d085 100644 --- a/dlls/d3dx9_36/mesh.c +++ b/dlls/d3dx9_36/mesh.c @@ -2409,20 +2409,21 @@ BOOL WINAPI D3DXIntersectTri(const D3DXVECTOR3 *p0, const D3DXVECTOR3 *p1, const return FALSE; }
-BOOL WINAPI D3DXSphereBoundProbe(const D3DXVECTOR3 *pcenter, float radius, - const D3DXVECTOR3 *prayposition, const D3DXVECTOR3 *praydirection) +BOOL WINAPI D3DXSphereBoundProbe(const D3DXVECTOR3 *center, float radius, + const D3DXVECTOR3 *ray_position, const D3DXVECTOR3 *ray_direction) { - D3DXVECTOR3 difference; - FLOAT a, b, c, d; + D3DXVECTOR3 difference = {0}; + float a, b, c, d;
- a = D3DXVec3LengthSq(praydirection); - if (!D3DXVec3Subtract(&difference, prayposition, pcenter)) return FALSE; - b = D3DXVec3Dot(&difference, praydirection); + D3DXVec3Subtract(&difference, ray_position, center); c = D3DXVec3LengthSq(&difference) - radius * radius; + if (c < 0.0f) + return TRUE; + a = D3DXVec3LengthSq(ray_direction); + b = D3DXVec3Dot(&difference, ray_direction); d = b * b - a * c;
- if ( ( d <= 0.0f ) || ( sqrt(d) <= b ) ) return FALSE; - return TRUE; + return d >= 0.0f && (b <= 0.0f || d > b * b); }
/************************************************************************* diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c index c357200656b0..42deb32b9341 100644 --- a/dlls/d3dx9_36/tests/mesh.c +++ b/dlls/d3dx9_36/tests/mesh.c @@ -435,18 +435,42 @@ static void D3DXBoundProbeTest(void) 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; - rayposition.x = 5.0f; rayposition.y = 5.0f; rayposition.z = 9.0f; result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); - ok(result == TRUE, "expected TRUE, received FALSE\n"); + ok(result == TRUE, "Got unexpected result %#x.\n", result);
rayposition.x = 45.0f; rayposition.y = -75.0f; rayposition.z = 49.0f; result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); - ok(result == FALSE, "expected FALSE, received TRUE\n"); + ok(result == FALSE, "Got unexpected result %#x.\n", result); + + raydirection.x = -2.0f; raydirection.y = 4.0f; raydirection.z = -2.0f; + result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); + ok(result == TRUE, "Got unexpected result %#x.\n", result);
rayposition.x = 5.0f; rayposition.y = 11.0f; rayposition.z = 9.0f; result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); - ok(result == FALSE, "expected FALSE, received TRUE\n"); + ok(result == FALSE, "Got unexpected result %#x.\n", result); + + raydirection.x = 2.0f; raydirection.y = -4.0f; raydirection.z = 2.0f; + result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); + ok(result == FALSE, "Got unexpected result %#x.\n", result); + + radius = 1.0f; + rayposition.x = 2.0f; rayposition.y = 2.0f; rayposition.z = 3.0f; + result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); + ok(result == FALSE, "Got unexpected result %#x.\n", result); + + raydirection.x = 0.0f; raydirection.y = 0.0f; raydirection.z = 1.0f; + result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection); + ok(result == TRUE, "Got unexpected result %#x.\n", result); + + if (0) + { + /* All these crash on native. */ + D3DXSphereBoundProbe(¢er, radius, &rayposition, NULL); + D3DXSphereBoundProbe(¢er, radius, NULL, &raydirection); + D3DXSphereBoundProbe(NULL, radius, &rayposition, &raydirection); + } }
static void D3DXComputeBoundingBoxTest(void)