[ Cloth Simulation & Collision ] 03. 충돌 (History-Based Collisions)

2023. 7. 19. 20:30·물리 기반 시뮬레이션/Cloth Simulation

💥 History-Based Collision

이전의 Level Set Based Collision을 보완한 충돌 처리 방법으로, 다음 위치를 충돌 법선 방향으로 투영하여 제한하던 이전 방법과는 다르게, 이는 원래의 속도를 그대로 투영하여 계산한다.

 

이는 다음 두 단계에 걸쳐 계산된다.

현재 위치 - 충돌 물체의 표면 - 다음 위치


🔎 충돌 감지 (Collision Detection)

앞에서 언급했듯이, 현재 속도를 법선 방향으로 투영하여 거리를 계산하는 이전 방법과는 다르게, 속도에 따른 다음 위치를 계산한 뒤, 이것과 표면으로부터의 수직 거리를 계산한다.

➡️ 이때, 계산한 거리 값이 음수라면 충돌을 의미한다.


📌 충돌 처리 (Collision Response)

충돌이 감지되면 다음과 같이 두 단계에 걸쳐 충돌 처리를 진행한다:

이때, $\theta$ 는 다음과 같이 표현된다:

이는 아래의 그림에서, 가중치를 나타내는 것을 확인할 수 있다:

따라서, 각 과정에선 다음과 같은 연산을 수행한다:

1. 첫 번째 과정 (현재 위치 - 충돌 물체의 표면)은 현재 속도에 현재 수직 거리만큼의 가중치를 주어 표면까지의 변위로 변환한다.

2. 두 번째 과정 (충돌 물체의 표면 - 다음 위치)은 속도에 남은 가중치인 (1- $\theta$)를 곱하여 변위를 계산한다. 이때, 두 번째 과정에서 사용되는 속도는 원래의 속도가 아닌, $\Gamma$ 함수를 적용하여 충돌 후의 마찰과 법선 방향 상대 속도를 제거한 속도 $v_{\star}$이다.

이때,  $\Gamma$ 함수는 Level Set 기반 방법에서 계산하는 속도와 동일하며 식은 다음과 같다:

또한, $v_{\star}$ 는 아래와 같이 법선 방향 속도와 접선 방향 속도로 나누어 생각할 수 있다:

이때, 법선 방향 성분 $v_{\star N}$ 은 충돌 물체의 법선 방향 속도와 정점의 법선 방향 속도 중 더 큰 값을 선택하여 상대속도와 관련해서 더이상 가까워지지 않도록 계산한다:

접선 방향 성분 $v_{\star T}$ 은 마찰력을 고려하여, 두 번째 과정의 변위를 계산한다:

최종적으로 Level Set Based Collision 과 History-Based Collision 을 비교해보면 다음과 같다.


📌 충돌 처리 이후

추가적으로, 충돌 처리가 끝난 이후에 trapezoidal rule (사다리꼴 규칙)에서의 사용을 위해 앞에서 사용한 $\Gamma$ 함수를 사용해 새로운 속도 $v_{\star}$ 를 반환하며, 충돌 처리 도중에 적용되는 법선 방향의 힘은 모두 0이 되어야 한다.

 

법선 방향의 힘을 제거하여 힘을 적용하는 과정은 다음과 같다:

이때, $F_i$ 는 속도와 독립적인 힘이고 $F_d$는 속도에 선형 의존하는 감쇠 힘이다. 또한 $P$는 법선 방향의 힘을 제거하며, 다음과 같은 행렬 계산을 이용한다:

이는 힘에 의해 계산된 속도를 법선 방향으로 투영하여 원래의 속도에서 빼주는 과정을 거친다.


💻 구현 (Implement)

정점의 외부 힘에 의한 위치 계산은 이전에 다뤘던 PBD 방법으로 구현하였으며, 마지막에 속도를 다음과 같은 함수를 추가하여 구현하였다.

void PBD_PlaneCloth::HistoryBasedCollision(void) //평면은 정지 상태
{
	double deltaT = 0.01f;
	double h = 0.1f;
	double coefficientFriction = 0.6f; //마찰 계수

	for (int i = 0; i < _res[0]; i++) { //width
		for (int j = 0; j < _res[1]; j++) { //height 모든 정점에 대하여 실행
			int index = j * _res[0] + i;

			double x = _pos[index].x();
			double y = _pos[index].y();
			double z = _pos[index].z();

			vec3 N(PlaneCalPI(x + h, y, z) - PlaneCalPI(x, y, z),
				   PlaneCalPI(x, y + h, z) - PlaneCalPI(x, y, z),
				   PlaneCalPI(x, y, z + h) - PlaneCalPI(x, y, z));
			N /= h; //법선 벡터 계산 (오일러 방법 이용) = Gradient PI
			N.normalize();

			double PI = PlaneCalPI(x, y, z); //PI, newPI 계산
			vec3 newPos = _pos[index] + (_vel[index] * deltaT);
			double newPI = PlaneCalPI(newPos);
			
			if (newPI < 0)
			{
				double weight = PlaneCalPI(_pos[index]) / (PlaneCalPI(_pos[index]) - PlaneCalPI(newPos));

				vec3 beforeV = _vel[index] * weight; //현재 위치 ~ 접촉면까지의 속도 (v~n+1/2)
				vec3 xc = _pos[index] + beforeV * deltaT;
				_vel[index] = beforeV; //업데이트
				_pos[index] = xc; 

				// V star n+1/2 계산
				double vpN = _vel[index].dot(N); //원래의 법선 방향 속력
				vec3 vpNN = N * vpN; //원래의 법선 방향 속도
				vec3 vpT = _vel[index] - vpNN; //원래의 접선 방향 속도

				double newVpN = max(vpN, 0); //새로운 법선 방향 속력 (평면 속도 = 0 정지)
				vec3 newVpNN = N * newVpN; // 새로운 법선 방향 속도

				double friction = (coefficientFriction * (newVpN - vpN) / vpT.getNorm()); //마찰 계산
				vec3 newVpT = vpT * (1 - friction);

				if (1 - friction < 0)
					newVpT.set(0, 0, 0);

				vec3 Vnew = newVpNN + newVpT;
				vec3 afterV = Vnew * (1 - weight);

				_vel[index] = afterV; //업데이트
				//_pos[index] = xc + afterV * deltaT;

			}
		}
	}
}

double PBD_PlaneCloth::PlaneCalPI(double x0, double y0, double z0)
{
	//ax + by + cz + d = 0 평면 방정식
	double a = 0;
	double b = 2;
	double c = 3;
	double d = 1;
	
	return (a * x0 + b * y0 + c * z0 + d) / sqrt(pow(a, 2) + pow(b, 2) + pow(c, 2));
}

double PBD_PlaneCloth::PlaneCalPI(vec3 v)
{
	//ax + by + cz + d = 0 평면 방정식
	double a = 0;
	double b = 2;
	double c = 3;
	double d = 1; 

	return (a * v.x() + b * v.y() + c * v.z() + d) / sqrt(pow(a, 2) + pow(b, 2) + pow(c, 2));
}

이는 위에서 설명했던 과정을 단순히 코드로 구현한 것으로, 중간의 첫 번째 과정의 위치 및 속도를 업데이트 하는 과정을 거쳤으며, 최종적으로 두 번째 단계의 속도를 업데이트 해주었다. 결과는 다음과 같다.

 

Level Set Based Collision

 

History-Based Collision

Level Set Based 방법과 History-Based 방법을 비교했다.

History Based Collision 방식이 좀 더 자연스러운 움직임을 보이는 것을 확인할 수 있다.


참고 자료 :

Robust High-Resolution Cloth Using Parallelism, History-Based Collisions and Accurate Friction - Andrew Selle, Jonathan Su, Geoffrey Irving, Ronald Fedkiw


깃허브:

https://github.com/qkrdmstn/pbd-cloth-simulation.git

 

GitHub - qkrdmstn/pbd-cloth-simulation

Contribute to qkrdmstn/pbd-cloth-simulation development by creating an account on GitHub.

github.com

 

'물리 기반 시뮬레이션 > Cloth Simulation' 카테고리의 다른 글

[ Cloth Simulation & Collision ] 06. SDF 생성  (0) 2025.05.15
[ Cloth Simulation & Collision ] 05. Local Optimization for SDF  (0) 2024.01.17
[ Cloth Simulation & Collision ] 04. 천 자가 충돌 (Cloth Self-Collision)  (0) 2023.09.06
[ Cloth Simulation & Collision ] 02. 레벨 셋 충돌 (Level Set Collision)  (0) 2023.07.13
[ Cloth Simulation & Collision ] 01. 천 시뮬레이션 (Cloth Simulation)  (0) 2023.07.06
'물리 기반 시뮬레이션/Cloth Simulation' 카테고리의 다른 글
  • [ Cloth Simulation & Collision ] 05. Local Optimization for SDF
  • [ Cloth Simulation & Collision ] 04. 천 자가 충돌 (Cloth Self-Collision)
  • [ Cloth Simulation & Collision ] 02. 레벨 셋 충돌 (Level Set Collision)
  • [ Cloth Simulation & Collision ] 01. 천 시뮬레이션 (Cloth Simulation)
coding-l7
coding-l7
  • coding-l7
    coding-l7rl0
    coding-l7
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 기타
      • 유니티
        • OfficeWorkerRunning
      • 프로그래밍 언어 N
        • C N
        • C#
        • C++
      • CS
        • 컴퓨터 구조
        • 운영체제
      • 물리 기반 시뮬레이션
        • 기초
        • Cloth Simulation
        • Fluid Simulation
      • 코딩 테스트
        • 프로그래머스
        • 백준
      • 독서
        • [ 뇌를 자극하는 윈도우즈 시스템 프로그래밍 ]
        • [ 혼자 공부하는 컴퓨터 구조 + 운영체제 ]
        • [ CUDA 기반 GPU 병렬 처리 프로그래밍 ]
      • 영어
        • Basic Grammar In Use
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
    • 포트폴리오
  • 공지사항

  • 인기 글

  • 태그

    상수
    RAM
    position based dynamics
    C언어
    screen space fluid rendering
    screen-space rendering
    유체 시뮬레이션
    bilateral blur
    시스템 프로그래밍
    명령어
    cloth simulation
    그리드 기반 방법
    jump table
    surface turbulence
    wave simulation
    pbd
    GLSL
    컴퓨터 구조
    액체 시뮬레이션
    collision
    실수
    OpenGL
    정수 승격
    파동 난류
    Flip
    물리 기반 시뮬레이션
    fluid implicit particle
    narrow range filter screen-space fluid rendering
    fluid simulation
    입자 기반 방법
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
coding-l7
[ Cloth Simulation & Collision ] 03. 충돌 (History-Based Collisions)
글쓰기
상단으로

티스토리툴바