Advertisement

Picking code, make a ray come from the camera pos

Started by October 01, 2018 11:06 AM
1 comment, last by TommyThree 6 years, 1 month ago

I have some code I got off the net. It finds the direction of a ray when you click the screen. When I set the ray origin to 0,0,0 and direction to the calculated direction (see below code) it detects intersections on objects that are at the origin only. If I set the origin to the camera position, nothing happens. No intersections. The code in the Luna book does the same thing. What am I missing?

 



MousePicker::MousePicker(DirectX::XMMATRIX proj, DirectX::XMMATRIX view)
{
	projectionMatrix = proj;
	viewMatrix = view;
}

MousePicker::MousePicker()
{

}

DirectX::XMFLOAT3 MousePicker::getCurrentRay() { return currentRay; }

DirectX::XMVECTOR MousePicker::getCurrentRayXM() { return DirectX::XMLoadFloat3(&currentRay); }

void MousePicker::update(DirectX::XMMATRIX view, float x, float y, float width, float height)
{
	viewMatrix = view;
	currentRay = calculateMouseRay(x, y, width, height);
}

DirectX::XMFLOAT3 MousePicker::calculateMouseRay(float x, float y, float width, float height)
{
	float mouseX = x;
	float mouseY = y;
	DirectX::XMFLOAT2 normalizedCoords = getNormalizedDeviceCoords(x, y, width, height);
	DirectX::XMFLOAT4 clipCoords = DirectX::XMFLOAT4(normalizedCoords.x, normalizedCoords.y, -1.0f, 1.0f);
	DirectX::XMFLOAT4 eyeCoord = toEyeCoords(clipCoords);
	DirectX::XMFLOAT3 worldRay = toWorldCoords(eyeCoord);

	return worldRay;
}

DirectX::XMFLOAT2 MousePicker::getNormalizedDeviceCoords(float mouseX, float mouseY, float width, float height)
{
	float x = (2.0f*mouseX) / width - 1.0f;
	float y = (2.0f*mouseY) / height - 1.0f;

	return DirectX::XMFLOAT2(x, -y);
}

DirectX::XMFLOAT4 MousePicker::toEyeCoords(DirectX::XMFLOAT4 clipCoords)
{
	DirectX::XMVECTOR clip = DirectX::XMLoadFloat4(&clipCoords);

	DirectX::XMMATRIX invertedProj = DirectX::XMMatrixInverse(nullptr, projectionMatrix);
	DirectX::XMVECTOR eyeCoords = DirectX::XMVector4Transform(clip, invertedProj);
	DirectX::XMFLOAT4 eyeCoord;
	DirectX::XMStoreFloat4(&eyeCoord, eyeCoords);

	return DirectX::XMFLOAT4(eyeCoord.x, eyeCoord.y, -1.0f, 0.0f);
}

DirectX::XMFLOAT3 MousePicker::toWorldCoords(DirectX::XMFLOAT4 eyeCoords)
{
	DirectX::XMVECTOR eyeCoord = DirectX::XMLoadFloat4(&eyeCoords);

	DirectX::XMMATRIX invertedView = DirectX::XMMatrixInverse(nullptr, viewMatrix);
	DirectX::XMVECTOR rayWorld = DirectX::XMVector4Transform(eyeCoord, invertedView);
	DirectX::XMFLOAT4 ray;

	DirectX::XMStoreFloat4(&ray, rayWorld);
	DirectX::XMFLOAT3 mouseRay = DirectX::XMFLOAT3(ray.x, ray.y, ray.z);
	DirectX::XMVECTOR mRay  = DirectX::XMVector3Normalize(DirectX::XMLoadFloat3(&mouseRay));

	DirectX::XMFLOAT3 mouseR;
	DirectX::XMStoreFloat3(&mouseR, mRay);

	return mouseR;
}



MousePicker::~MousePicker()
{
}

 


		float temp;
		XMVECTOR origin = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
		if (meshList[0].AABB_Box.Intersects(origin, mp.getCurrentRayXM(), temp) )
		{
			MessageBoxA(NULL, meshList[0].name.c_str(), "0", MB_OK);
		}

		if (meshList[1].AABB_Box.Intersects(origin, mp.getCurrentRayXM(), temp))
		{
			MessageBoxA(NULL, meshList[1].name.c_str(), "1", MB_OK);
		}

		if (meshList[2].AABB_Box.Intersects(origin, mp.getCurrentRayXM(), temp))
		{
			MessageBoxA(NULL, meshList[2].name.c_str(), "2", MB_OK);
		}

 

I used XMVectorUnproject to pick the screen.


DirectX::XMVECTOR testpick::update(int x, int y, float width, float height, float nearZ, float farZ, DirectX::XMMATRIX projection, DirectX::XMMATRIX view)
{
	DirectX::XMVECTOR mouseNear = DirectX::XMVectorSet((float)x, (float)y, 0.0f, 0.0f);
	DirectX::XMVECTOR mouseFar = DirectX::XMVectorSet((float)x, (float)y, 1.0f, 0.0f);
	DirectX::XMVECTOR unprojectedNear = DirectX::XMVector3Unproject(mouseNear, 0, 0, width, height, nearZ, farZ,
		projection, view, DirectX::XMMatrixIdentity());
	DirectX::XMVECTOR unprojectedFar = DirectX::XMVector3Unproject(mouseFar, 0, 0, width, height, nearZ, farZ,
		projection, view, DirectX::XMMatrixIdentity());
	DirectX::XMVECTOR dir = DirectX::XMVector3Normalize(DirectX::XMVectorSubtract(unprojectedFar, unprojectedNear));
	return dir;
}

		XMVECTOR origin = cam.GetPositionXM();
		XMVECTOR dir = testpkr.update(pt.x, pt.y, Width, Height, 1.0f, 1000.0f, cam.Proj(), cam.View());
		float temp;

		if (meshList[0].AABB_Box.Intersects(origin, dir, temp))
		{
			aLog.AddLog(meshList[0].name.append("\n").c_str());
		}

		if (meshList[1].AABB_Box.Intersects(origin, dir, temp))
		{
			aLog.AddLog(meshList[1].name.append("\n").c_str());
		}

		if (meshList[2].AABB_Box.Intersects(origin, dir, temp))
		{
			aLog.AddLog(meshList[2].name.append("\n").c_str());
		}

 

This topic is closed to new replies.

Advertisement