Original Post
Hello there boys and ghouls, I'm having an offset issue with ray picking, specifically ray-sphere intersection. I'm using a D3DX supplied Sphere and positioning it at origin. The offset is in -Y and is very small, so the picking works but it's not centered :(. Here's the (presumably) relevant code: I've tried converting screen-to-client coordinates, using all sorts of different algorithms for ray picking/intersection, and it still seems to be off by a few units.
void IsometricCamera::ComputePickingRay( WORD x, WORD y, Ray &ray ) {
D3DVIEWPORT9 viewport;
pD3DDevice->GetViewport( &viewport );
// Convert and scale
float pX = ( ( ( 2.0f * x ) / viewport.Width ) - 1.0f ) / ( projMatrix( 0, 0 ) );
float pY = ( ( (-2.0f * y ) / viewport.Height ) + 1.0f ) / ( projMatrix( 1, 1 ) );
ray.origin = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
ray.direction = D3DXVECTOR3( pX, pY, 1.0f );
// Transfer to world coords
D3DXMATRIX inverseViewMatrix;
D3DXMatrixInverse( &inverseViewMatrix, NULL, &viewMatrix );
D3DXVec3TransformCoord( &ray.origin, &ray.origin, &inverseViewMatrix );
D3DXVec3TransformNormal( &ray.direction, &ray.direction, &inverseViewMatrix );
D3DXVec3Normalize( &ray.direction, &ray.direction );
}
bool SelectableEntity::SphericalModel::Evaluate( const Ray &mouseRay, const WorldEntity::EntityOrientation &orientation ) {
/*
* Taken from Frank D. Luna's book -- might need optimizing
*/
D3DXVECTOR3 vec = mouseRay.origin - orientation.position;
// Quadratic equation variables
float b = 2.0f * D3DXVec3Dot( &mouseRay.direction, &vec );
float c = D3DXVec3Dot( &vec, &vec ) - ( radius * radius );
float discriminant = ( b * b ) - ( 4.0f * c );
// Imaginary check
if( discriminant < 0.0f )
return false;
discriminant = sqrtf( discriminant );
if( ( ( -b + discriminant ) / 2.0f ) >= 0.0f ||
( ( -b - discriminant ) / 2.0f ) >= 0.0f )
return true;
return false;
}