각 Vertex에 대한 cotangent weight를 구하여 Laplace smooting를 적용해보자
Vec3<double> v1 = pos - vertices[i]->neighbor_vertices[p_prev]->pos;
Vec3<double> v2 = vertices[i]->neighbor_vertices[j]->pos - vertices[i]->neighbor_vertices[p_prev]->pos;
Vec3<double> v3 = pos - vertices[i]->neighbor_vertices[p_next]->pos;
Vec3<double> v4 = vertices[i]->neighbor_vertices[j]->pos - vertices[i]->neighbor_vertices[p_next]->pos;
double cotan_a = (v1.Dot(v2)) / ( (v1.Cross(v2)).GetNorm());
double cotan_b = (v3.Dot(v4)) / ( (v3.Cross(v4)).GetNorm());
double weight = (cotan_a + cotan_b) * 0.5;
sum += vertices[i]->neighbor_vertices[j]->pos * weight;
N += weight;
Mesh의 모든 Vertex의 neighber vertex에 대해 Cotangent weight를 구한 뒤 sum vector에 더해준 뒤
weight의 총합인 N으로 나누어 주었다.
smooting 작업을 진행 할 수록 Vertex가 사라지는 문제가 생겼다.
Vertex가 타노스 당하는 이 문제를 해결하기 위해 다른 분들이 작성한 코드를 염탐해보았는데 전부 같은 방법으로 Weight를 구하거나 내가 이해할 수 없는 고등기술을 사용하지만 brainexcerpts라는 분이 작성한 weight를 구하는 방법을 살펴보자.
double cotan_a = (v1.Dot(v2)) / ( (v1.Cross(v2)).GetNorm());
double cotan_b = (v3.Dot(v4)) / ( (v3.Cross(v4)).GetNorm());
->
double cotan_a = (v1.Dot(v2)) / ( 1e-6 + (v1.Cross(v2)).GetNorm());
double cotan_b = (v3.Dot(v4)) / ( 1e-6 + (v3.Cross(v4)).GetNorm());
의 방식으로 부동소수점을 더한 뒤 나누기 연산을 해주어서 weight 값이 nan이 되는 것을 방지한다.
정상적으로 Cotangent Weight Smooting이 되는 것을 확인할 수 있다.
'C++' 카테고리의 다른 글
[C++] 백준/Gold/15486. 퇴사 2 (0) | 2025.03.18 |
---|---|
[C++] 텍스트 기반 RPG 게임 제작 프로젝트 회고록 (0) | 2025.01.17 |
[OPEN GL] 프로젝트 시작 전 사용 설정 (0) | 2021.12.05 |
[Open GL] v/vt/vn 형식 OBJ 읽어오기 (0) | 2021.12.05 |
Laplace equation in c++ (1) | 2021.10.08 |