• 티스토리 홈
  • 프로필사진
    유니얼
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
유니얼
  • 프로필사진
    유니얼
    • 분류 전체보기 (295)
      • Unity (17)
        • 게임 개발 (5)
      • Unreal (24)
        • 게임 개발 (20)
      • DirectX (36)
      • 코딩테스트 (91)
        • 프로그래머스 (25)
        • 백준 (66)
      • Google Workspace (1)
      • Programing (102)
        • C# (68)
        • C++ (24)
        • JavaScript (10)
      • 게임 서버 프로그래밍 (17)
      • Web (6)
        • 슈퍼코딩 (6)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
    등록된 댓글이 없습니다.
  • 최근 공지
    등록된 공지가 없습니다.
# Home
# 공지사항
#
# 태그
# 검색결과
# 방명록
  • [DirectX11] Triangle의 Point Test,Interaction,Raycast
    2024년 03월 14일
    • 유니얼
    • 작성자
    • 2024.03.14.:14
    728x90

    DirectX 11로 게임 엔진 아키텍처 만들기

    3D 그래픽스와 게임 개발에서 삼각형은 가장 기본적인 구성 단위 중 하나입니다. 복잡한 메시(mesh)와 모델들은 수천, 수백만 개의 삼각형으로 이루어져 있으며, 이러한 삼각형들과의 상호작용은 게임 엔진과 물리 엔진에서 중요한 역할을 합니다. 이 글에서는 삼각형과 점의 관계, 삼각형과 레이(ray)의 교차 검사 방법 등을 포함하여 삼각형과 관련된 다양한 계산 방법들을 탐구합니다.

    참고강의 링크:

    https://www.inflearn.com/course/directx11-%EA%B2%8C%EC%9E%84%EA%B0%9C%EB%B0%9C-%EB%8F%84%EC%95%BD%EB%B0%98/dashboard

     

    [게임 프로그래머 도약반] DirectX11 입문 강의 - 인프런

    게임 프로그래머 공부에 있어서 필수적인 DirectX 11 지식을 초보자들의 눈높이에 맞춰 설명하는 강의입니다., [사진][사진] [사진] 게임 개발자는 Unreal, Unity만 사용할 줄 알면 되는 거 아닌가요? 엔

    www.inflearn.com

    점이 삼각형 내부에 있는지 검사하기

    점이 주어진 삼각형 내부에 있는지 확인하는 방법 중 하나는 삼각형을 구성하는 벡터들을 사용하여 교차 벡터(cross vector)를 계산하고, 이들의 내적(dot product)을 검사하는 것입니다. 이 방법은 간단하면서도 효율적으로 점의 위치를 삼각형에 대해 판단할 수 있게 해줍니다.

     

    // 점이 삼각형 내부에 있는지 판단하는 함수
    bool MathUtils::PointInTriangle(const Point3D& p, const Triangle3D& t)
    {
    	Vec3 a = t.a - p; // 점 p에서 삼각형의 꼭짓점 a로의 벡터
    	Vec3 b = t.b - p; // 점 p에서 삼각형의 꼭짓점 b로의 벡터
    	Vec3 c = t.c - p; // 점 p에서 삼각형의 꼭짓점 c로의 벡터
    
    	// 삼각형의 각 변에 대해 점 p를 포함하는 평면의 법선 벡터 계산
    	Vec3 normPBC = b.Cross(c); // PBC의 법선 벡터 (u)
    	Vec3 normPCA = c.Cross(a); // PCA의 법선 벡터 (v)
    	Vec3 normPAB = a.Cross(b); // PAB의 법선 벡터 (w)
    
    	// 법선 벡터들의 방향이 모두 같은지 확인하여 점이 삼각형 내부에 있는지 판단
    	if (normPBC.Dot(normPCA) < 0.0f)
    		return false; // PBC와 PCA 법선 벡터가 서로 반대 방향이면 점은 삼각형 내부에 없음
    
    	else if (normPBC.Dot(normPAB) < 0.0f)
    		return false; // PBC와 PAB 법선 벡터가 서로 반대 방향이면 점은 삼각형 내부에 없음
    
    	return true; // 그 외의 경우 점은 삼각형 내부에 있음
    }

    삼각형으로부터 평면 생성하기

    삼각형을 구성하는 점들로부터 평면의 방정식을 생성할 수 있습니다. 이는 삼각형의 두 벡터를 교차하여 법선 벡터(normal vector)를 얻고, 이를 통해 평면의 방정식을 도출하는 과정을 포함합니다. 평면의 방정식은 다양한 충돌 검사와 물리 계산에 사용될 수 있습니다.

    // 삼각형으로부터 평면을 생성하는 함수
    Plane3D MathUtils::FromTriangle(const Triangle3D& t)
    {
    	Plane3D result;
    
    	// 삼각형의 두 변의 벡터를 외적하여 평면의 법선 벡터를 계산
    	result.normal = (t.b - t.a).Cross(t.c - t.a);
    	result.normal.Normalize(); // 법선 벡터를 정규화
    
    	// 평면의 거리 계산 (법선 벡터와 삼각형의 한 꼭짓점의 내적으로 계산)
    	result.distance = result.normal.Dot(t.a);
    
    	return result;
    }

    삼각형과 레이의 교차 검사

    삼각형과 레이의 교차 검사는 레이 트레이싱(ray tracing), 충돌 검사, 가시성 판단 등 다양한 분야에서 중요합니다. 평면과 레이의 교차 점을 찾고, 이 점이 실제로 삼각형 내부에 있는지를 판단하여 교차 여부를 결정합니다.

     

    // 미구현된 함수, 삼각형 내의 점에 대한 바리센트릭 좌표를 계산
    Vec3 MathUtils::Barycentric(const Point3D& p, const Triangle3D& t)
    {
    	// 이 함수는 여기에서 구현되지 않았습니다.
    	return Vec3();
    }
    
    // 레이와 삼각형의 충돌 검사
    bool MathUtils::Raycast(const Triangle3D& triangle, const Ray3D& ray, OUT float& distance)
    {
    	Plane3D plane = FromTriangle(triangle); // 삼각형으로부터 평면 생성
    
    	float t = 0;
    	// 레이와 평면의 충돌 검사
    	if (!Raycast(plane, ray, OUT t))
    		return false; // 충돌하지 않으면 false 반환
    
    	// 충돌 지점 계산
    	Point3D result = ray.origin + ray.direction * t;
    
    	// 충돌 지점에 대한 바리센트릭 좌표 계산
    	Vec3 barycentric = Barycentric(result, triangle);
    
    	// 바리센트릭 좌표를 사용하여 충돌 지점이 삼각형 내부에 있는지 확인
    	if (barycentric.x >= 0.0f && barycentric.x <= 1.0f &&
    		barycentric.y >= 0.0f && barycentric.y <= 1.0f &&
    		barycentric.z >= 0.0f && barycentric.z <= 1.0f)
    	{
    		distance = t; // 충돌 거리 설정
    		return true; // 충돌 발생
    	}
    	return false; // 충돌하지 않음
    }

    벡터의 투영

    벡터를 다른 벡터에 투영하는 연산은 광선 추적, 반사, 굴절 등의 계산에서 유용하게 사용됩니다. 특정 벡터를 다른 벡터에 정사영(projection)하면, 두 벡터 간의 상대적인 위치와 방향을 파악할 수 있습니다.

    // 벡터 a를 벡터 b에 투영하는 함수
    Vec3 MathUtils::ProjectVecOnVec(Vec3 a, Vec3 b)
    {
    	b.Normalize(); // 벡터 b를 정규화
    
    	float dist = a.Dot(b); // 벡터 a와 정규화된 벡터 b의 내적 계산
    
    	return b * dist; // 투영된 벡터 반환
    }

    결론

    이러한 기본적인 수학적 개념과 계산 방법들은 3D 그래픽스 프로그래밍과 게임 엔진 개발의 기초를 이룹니다. 복잡한 3D 환경을 정확하게 모델링하고, 가상 세계 내의 객체들 사이의 상호작용을 구현하는 데 있어서, 이러한 기법들은 필수적인 도구입니다. 개발자들은 이러한 수학적 기반 위에 구축하여, 사용자에게 현실감 넘치는 가상 환경과 경험을 제공할 수 있습니다.

    반응형
    다음글
    다음 글이 없습니다.
    이전글
    이전 글이 없습니다.
    댓글
조회된 결과가 없습니다.
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
목차
표시할 목차가 없습니다.
    • 안녕하세요
    • 감사해요
    • 잘있어요

    티스토리툴바