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?