# 사용자 정의 힘과 충돌 처리

#### 사용자 정의 힘 적용

물리 엔진 내에서 사용자 정의 힘을 적용하는 것은 복잡한 시뮬레이션 시나리오를 만드는 핵심 요소이다. 기본적인 중력과 마찰력 외에도 다양한 힘을 정의하고 적용할 수 있다.

**힘의 정의**

사용자 정의 힘은 어떤 대상(object)에 대해 시뮬레이션 단계마다 계산하고 적용할 수 있다. 정의된 힘은 벡터로 나타내며, 이는 대상에 적용되는 힘의 방향과 크기를 명시한다. 힘의 식은 다음과 같은 형태로 일반화할 수 있다:

$$
\mathbf{F} = m\mathbf{a}
$$

여기서 $\mathbf{F}$는 힘 벡터, $m$은 질량, $\mathbf{a}$는 가속도이다.

**힘의 예**

다음은 몇 가지 사용자 정의 힘의 예시이다.

1. **드래그(공기 저항)** 드래그는 대상의 속도에 반비례하는 힘으로 속도를 감소시키는 역할을 한다. 드래그 힘은 다음과 같이 정의할 수 있다:

$$
\mathbf{F}\_{d} = -c\_d |\mathbf{v}| \mathbf{v}
$$

```
여기서 $c_d$는 드래그 계수, $\mathbf{v}$는 속도 벡터이다.
```

2\. **흐름에 의한 힘(유체 저항)** 유체 및 기체 내를 이동하는 객체에 작용하는 힘을 정의할 수 있다:

$$
\mathbf{F}\_{f} = \frac{1}{2} \rho v^2 A C\_d \mathbf{\hat{v}}
$$

```
여기서 $\rho$는 유체 밀도, $v$는 유체 속도, $A$는 단면적, $C_d$는 저항 계수, $\mathbf{\hat{v}}$는 속도의 단위 벡터이다.
```

#### 사용자 정의 충돌 처리

**충돌 감지**

충돌 감지는 두 물체 간의 상호작용을 계산하는 데 필수적인 단계이다. 충돌 감지를 구현하는 방법에는 여러 가지가 있으며, 가장 대표적인 방법은 AABB (Axis-Aligned Bounding Box)와 OBB (Oriented Bounding Box)이다.

* **AABB** 물체를 둘러싼 축 정렬 경계 상자는 계산이 간단하며 빠르다. 두 AABB가 충돌하는지 확인하는 방법은 다음과 같다:

  ```python
  def aabb_collision(box1, box2):
      return (box1.max_x > box2.min_x and
              box1.min_x < box2.max_x and
              box1.max_y > box2.min_y and
              box1.min_y < box2.max_y and
              box1.max_z > box2.min_z and
              box1.min_z < box2.max_z)
  ```
* **OBB** 오리엔티드 바운딩 박스는 AABB보다 더 정교하지만 계산 비용이 높다. OBB의 충돌 여부를 판단하는 방법은 Separating Axis Theorem(SAT)을 사용할 수 있다.

**충돌 응답**

충돌 감지 후에는 물체 간의 실제 상호작용을 계산해야 한다. 주로 두 가지 방법을 사용한다:

1. **반사력 기반 충돌 응답** 탄성 충돌에서 물체는 충돌 전의 속도와 충돌 후의 속도가 대칭적으로 변화한다. 필요한 속도의 변화를 계산한다:

$$
\mathbf{v}*{1} = \mathbf{v}*{1} - \left(1 + e\right) \frac{\left(\mathbf{v}*{1} - \mathbf{v}*{2}\right) \cdot \mathbf{n}}{\left(\mathbf{n} \cdot \mathbf{n}\right)} \mathbf{n}
$$

```
여기서 $e$는 계수 반발계수, $\mathbf{n}$은 충돌 면의 법선 벡터이다.
```

2\. **감쇠 기반 충돌 응답** 충돌 후 속도를 감소시키는 식으로 감쇠력을 적용할 수 있다:

$$
\mathbf{v}' = \mathbf{v} - d\mathbf{v}
$$

```
여기서 $d$는 감쇠 계수이다.
```

### 고급 사용자 정의 요소

#### 다루기 어려운 물리적 특성

**비탄성 충돌**

비탄성 충돌의 경우, 충돌 후 물체들이 병합되거나 운동 에너지가 손실된다. 운동 에너지의 손실을 고려하여 새로운 속도를 계산한다:

$$
\mathbf{v}\_{new} = \frac{m\_1 \mathbf{v}\_1 + m\_2 \mathbf{v}\_2}{m\_1 + m\_2}
$$

여기서 $v\_{new}$는 병합 후의 공통 속도이다.

**점성 및 유체 역학**

유체 시뮬레이션은 물리 엔진에서 매우 중요한 요소이다. SPH(Smoothed Particle Hydrodynamics)와 같은 알고리즘은 유체의 점성 및 밀도 변화를 효율적으로 모델링할 수 있다.

$$
\mathbf{F}*i = - \sum*{j} m\_j \left( P\_i + P\_j \right) \frac{\nabla W\_{ij}}{\rho\_j}
$$

여기서 $W\_{ij}$는 커널 함수, $\rho\_j$는 입자의 밀도이다.

#### 사용자 정의 물체의 행태

**유연체 및 나일론**

유연체(soft body)와 다른 변형 가능한 물체는 정확한 물리 엔진 커스터마이징이 필요하다. 유연체 시뮬레이션은 주로 스프링-매스 모형이나 FEM(Finite Element Method)을 사용한다.

* **스프링-매스 모형**: 점과 점을 연결하는 스프링으로 구성된 모델
* **유한 요소법(FEM)**: 응력과 변형을 모델링하여 물체의 거동을 더 정확히 예측

**파괴 및 파편화**

파괴 시뮬레이션은 물체가 충돌하거나 힘을 받을 때 어떻게 분해되는지를 예측하며, 고급 충돌 처리 알고리즘과 결합하여 효과적으로 구현된다.

### 최적화와 퍼포먼스 조정

#### 병렬 처리와 비동기 처리

병렬 처리와 비동기 처리는 물리 엔진의 성능을 대폭 향상시킨다.

* **GPU 가속**: GPU의 병렬 처리를 통해 많은 양의 물리 계산을 효율적으로 처리
* **멀티스레딩**: 서로 다른 스레드에서 물리 연산을 분산 수행하여 CPU 사용량 최적화

#### 최적화 기법

**단순화된 충돌 감지**

성능을 높이기 위해 충돌 감지에서 몇 가지 주의 사항을 고려한다.

* **Broad-phase와 Narrow-phase** 충돌 감지: 충돌 가능성을 좁히고 세밀한 충돌 감지를 수행
* **공간 분할**: 구역을 설정하여 각 구역 내에서 충돌을 감지

**리소스 관리를 통한 최적화**

리소스 효율적인 메모리 관리와 캐싱 기술을 적용한다. 예를 들어, 상시 캐싱을 통해 계산 비용을 줄이다.
