Picking
Picking
- 
마우스 클릭을 통해 Object를 고를 때 사실 화면에서 보여지는 것은 2D로 변환된 Screen Space이다.
 - 
따라서 우린 Ray Casting을 사용해 레이저를 쏘듯 카메라에서 Object까지 가상의 선을 그어 Object와의 HIT여부를 검사한다.
 - 
Collider Component를 만들어 Ray cast 충돌 검사에 사용한다.
 
shared_ptr<GameObject> SceneManager::Pick(int32 screenX, int32 screenY)
{
	shared_ptr<Camera> camera = GetActiveScene()->GetMainCamera();
	float width = static_cast<float>(GEngine->GetWindow().width);
	float height = static_cast<float>(GEngine->GetWindow().height);
	Matrix projectionMatrix = camera->GetProjectionMatrix();
	// ViewSpace에서 Picking 진행
	float viewX = (+2.0f * screenX / width - 1.0f) / projectionMatrix(0, 0);
	float viewY = (-2.0f * screenY / height + 1.0f) / projectionMatrix(1, 1);
	Matrix viewMatrix = camera->GetViewMatrix();
	Matrix viewMatrixInv = viewMatrix.Invert();
	auto& gameObjects = GET_SINGLE(SceneManager)->GetActiveScene()->GetGameObjects();
	float minDistance = FLT_MAX;
	shared_ptr<GameObject> picked;
	for (auto& gameObject : gameObjects)
	{
		if (gameObject->GetCollider() == nullptr)
			continue;
		// ViewSpace에서의 Ray 정의
		Vec4 rayOrigin = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
		Vec4 rayDir = Vec4(viewX, viewY, 1.0f, 0.0f);
		// WorldSpace에서의 Ray 정의
		rayOrigin = XMVector3TransformCoord(rayOrigin, viewMatrixInv);
		rayDir = XMVector3TransformNormal(rayDir, viewMatrixInv);
		rayDir.Normalize();
		// WorldSpace에서 연산
		float distance = 0.f;
		if (gameObject->GetCollider()->Intersects(rayOrigin, rayDir, OUT distance) == false)
			continue;
		if (distance < minDistance)
		{
			minDistance = distance;
			picked = gameObject;
		}
	}
	return picked;
}
- 
스크린의 높이와 너비와 마우스의 클릭 위치를 가져와 ViewSpace에서 Picking을 한다.
 - 
World Space에서 충돌검사를 하기 위해 view Matrix의 역행렬을 이용해 View Space에서의 Ray를 WorldSpace로 변환.
 - 
WorldSpace에서 Ray와 Collider사이의 충돌 여부 계산.
 
결과
- 디버깅을 통해 구체가 클릭되면 HIT ! 이 출력되게 설정하였다.
 
Author And Source
이 문제에 관하여(Picking), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sansam41/Picking저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)