Picking From Distance DirectX11

Started by
0 comments, last by vinterberg 8 years, 7 months ago
I want to pick objects from distance(whenever it's visible to the camera) but i have problem with it.
here what i'v done so far:

 DirectX::XMFLOAT4X4 projection;
     DirectX::XMStoreFloat4x4(&projection,AngelSubSystemResources::BaseCameraProperties::BCamera.GetProjection());
     float vx = (((2 * this->m_mouseX) / AngelSubSystemResources::WindowProperties::GetWidth()) - 1)/projection._11;
     float vy = (((-2 * this->m_mouseY) / AngelSubSystemResources::WindowProperties::GetHeight()) + 1) / projection._22;
     DirectX::XMVECTOR rayOrigin = XMVectorSet(0.0f,0.0f,0.0f,1.0f);
     
     DirectX::XMVECTOR rayDir = DirectX::XMVectorSet(vx, vy, 1.0f, 0.0f);
    
     DirectX::XMMATRIX view = AngelSubSystemResources::BaseCameraProperties::BCamera.GetView();
    
     DirectX::XMMATRIX toWorld = DirectX::XMMatrixInverse(&DirectX::XMMatrixDeterminant(view), view);
    
     rayOrigin = DirectX::XMVector3TransformCoord(rayOrigin, toWorld);
     rayDir = DirectX::XMVector3TransformNormal(rayDir, toWorld);
     rayDir = DirectX::XMVector3Normalize(rayDir);
     XMVECTOR ray = rayOrigin + (rayDir * 100);
     float x = DirectX::XMVectorGetX(rayDir);
     float y = DirectX::XMVectorGetY(rayDir);
     float z = DirectX::XMVectorGetZ(rayDir);
    
     
    
     /*OutputDebugStringA("\nX:");
     OutputDebugStringA(std::to_string(x).c_str());
     OutputDebugStringA("\nY:");
     OutputDebugStringA(std::to_string(y).c_str());
     OutputDebugStringA("\nZ:");
     OutputDebugStringA(std::to_string(z).c_str());*/
     float f = 0;
     for (auto const & member : allAABB)
     {
     if (IntersectRayAxisAlignedBox(rayOrigin, rayDir, member->boundingBox, &f))
     {
     //if (member->name == "Plant")
     {
     OutputDebugStringA("\n++++Intersect with:");
     OutputDebugStringA(std::to_string(f).c_str());
     OutputDebugStringA("+++++++++\n\n");
     }
     
     }
     OutputDebugStringA("\n++++NOT INTERSECTIGN+++++++");
     }
in this function i check for intersection between mouse and mesh, and here is the function that checks it:

 static inline BOOL XMVector3AnyTrue(FXMVECTOR V)
    {
     XMVECTOR C;
    
     // Duplicate the fourth element from the first element.
     C = XMVectorSwizzle(V, 0, 1, 2, 0);
    
     return XMComparisonAnyTrue(XMVector4EqualIntR(C, XMVectorTrueInt()));
    }
    
    
    BOOL IntersectRayAxisAlignedBox(FXMVECTOR Origin, FXMVECTOR Direction, BoundingBox pVolume, FLOAT* pDist)
    {
     static const XMVECTOR Epsilon =
     {
     1e-20f, 1e-20f, 1e-20f, 1e-20f
     };
     static const XMVECTOR FltMin =
     {
     -FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX
     };
     static const XMVECTOR FltMax =
     {
     FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX
     };
    
     // Load the box.
     XMVECTOR Center = XMLoadFloat3(&pVolume.Center);
     XMVECTOR Extents = XMLoadFloat3(&pVolume.Extents);
    
     // Adjust ray origin to be relative to center of the box.
     XMVECTOR TOrigin = Center - Origin;
    
     // Compute the dot product againt each axis of the box.
     // Since the axii are (1,0,0), (0,1,0), (0,0,1) no computation is necessary.
     XMVECTOR AxisDotOrigin = TOrigin;
     XMVECTOR AxisDotDirection = Direction;
    
     // if (fabs(AxisDotDirection) <= Epsilon) the ray is nearly parallel to the slab.
     XMVECTOR IsParallel = XMVectorLessOrEqual(XMVectorAbs(AxisDotDirection), Epsilon);
    
     // Test against all three axii simultaneously.
     XMVECTOR InverseAxisDotDirection = XMVectorReciprocal(AxisDotDirection);
     XMVECTOR t1 = (AxisDotOrigin - Extents) * InverseAxisDotDirection;
     XMVECTOR t2 = (AxisDotOrigin + Extents) * InverseAxisDotDirection;
    
     // Compute the max of min(t1,t2) and the min of max(t1,t2) ensuring we don't
     // use the results from any directions parallel to the slab.
     XMVECTOR t_min = XMVectorSelect(XMVectorMin(t1, t2), FltMin, IsParallel);
     XMVECTOR t_max = XMVectorSelect(XMVectorMax(t1, t2), FltMax, IsParallel);
    
     // t_min.x = maximum( t_min.x, t_min.y, t_min.z );
     // t_max.x = minimum( t_max.x, t_max.y, t_max.z );
     t_min = XMVectorMax(t_min, XMVectorSplatY(t_min));  // x = max(x,y)
     t_min = XMVectorMax(t_min, XMVectorSplatZ(t_min));  // x = max(max(x,y),z)
     t_max = XMVectorMin(t_max, XMVectorSplatY(t_max));  // x = min(x,y)
     t_max = XMVectorMin(t_max, XMVectorSplatZ(t_max));  // x = min(min(x,y),z)
    
     // if ( t_min > t_max ) return FALSE;
     XMVECTOR NoIntersection = XMVectorGreater(XMVectorSplatX(t_min), XMVectorSplatX(t_max));
    
     // if ( t_max < 0.0f ) return FALSE;
     NoIntersection = XMVectorOrInt(NoIntersection, XMVectorLess(XMVectorSplatX(t_max), XMVectorZero()));
    
     // if (IsParallel && (-Extents > AxisDotOrigin || Extents < AxisDotOrigin)) return FALSE;
     XMVECTOR ParallelOverlap = XMVectorInBounds(AxisDotOrigin, Extents);
     NoIntersection = XMVectorOrInt(NoIntersection, XMVectorAndCInt(IsParallel, ParallelOverlap));
    
    
     if (!XMVector3AnyTrue(NoIntersection))
     {
     // Store the x-component to *pDist
     XMStoreFloat(pDist, t_min);
     return TRUE;
     }
    
     return FALSE;
    }
But the result is when i come very close to the mesh it shows that i'v got an intersection but as i mention i want to pick this mesh whenever player can see the mesh no matter how far it is!
anyone can help me please?
Advertisement

rayDir = DirectX::XMVector3Normalize(rayDir);
XMVECTOR ray = rayOrigin + (rayDir * 100);

if (IntersectRayAxisAlignedBox(rayOrigin, rayDir, member->boundingBox, &f))

Seems like you pass a normalized rayDir to IntersectRayAxisAlignedBox() - maybe you could try scaling that by those 100 (though this should probably be maxdist in your world, or whatever maximum distance you want - hardcoded constants can get messy if you alter other things elsewhere that are related to that constant in an abstract way) like in the ray calculation (which goes unused btw ^^)?

.:vinterberg:.

This topic is closed to new replies.

Advertisement