3D ์ฌ์ ๋ฌผ์ฒด๊ฐ 1,000๊ฐ ์๋ค๊ณ ํด๋ด์. ๋งค ํ๋ ์๋ง๋ค "์ด ๋ฌผ์ฒด๋ค์ด ์๋ก ์ถฉ๋ํ๋๊ฐ?"๋ฅผ ํ์ธํ๋ ค๋ฉด, ๋จ์ํ๊ฒ ๋ชจ๋ ์์ ๊ฒ์ฌํ๋ฉด ๋์.
for A in objects: for B in objects: if A != B: check_collision(A, B)์ด ๋ธ๋ฃจํธํฌ์ค ๋ฐฉ์์ ๋ณต์ก๋๋ O(nยฒ). ๋ฌผ์ฒด 1,000๊ฐ โ ์ฝ 500,000๋ฒ ๊ฒ์ฌ, 10,000๊ฐ๋ฉด 5์ฒ๋ง ๋ฒ. 60fps ๊ฒ์์์๋ ํ๋ ์๋น ์ด ์ฐ์ฐ์ ๋ฐ๋ณตํด์ผ ํด์. ๋น์ฐํ ์ค์ฉ์ ์ด์ง ์์์.
ํด๊ฒฐ์ ํต์ฌ ์์ด๋์ด๋ "๊ฒน์น ๊ฐ๋ฅ์ฑ์ด ์๋ ๋ฌผ์ฒด๋ค์ ๊ฒ์ฌ ์์ฒด๋ฅผ ํ์ง ์๋๋ค." ์ด์์
์ฌ๊ธฐ์ ๋ฑ์ฅํ๋ ๊ฒ์ด ๋ฐ์ด๋ฉ ๋ณผ๋ฅจ(BB)์ BVH์์.
๋ณต์กํ ๋ฉ์ ํํ ๊ทธ๋๋ก ์ถฉ๋์ ๊ฒ์ฌํ๋ ๊ฑด ๋๋ฌด ๋น์ธ์. ๋์ ์ถฉ๋์ ํ์ธํ ๋๋ ๋ฌผ์ฒด๋ฅผ ๋จ์ํ ๊ธฐํ ํํ๋ก ๊ฐ์ธ๋ ๋ฐ์ด๋ฉ ๋ณผ๋ฅจ์ ์ฌ์ฉํด์.

์ ๊ทธ๋ฆผ์ด Bounding Box ๋ชจ๋ธ ์์์์.

๊ฐ์ฅ ํํ๊ฒ ์ฐ์ด๋ ๊ฑด AABB(Axis-Aligned Bounding Box)์์. ์ธ๊ณ ์ขํ์ถ์ ์ ๋ ฌ๋ ๋จ์ํ ์ง์ก๋ฉด์ฒด๋ก, ๋ AABB์ ๊ฒน์นจ ๊ฒ์ฌ๋ ๊ฐ ์ถ์ ๊ตฌ๊ฐ ๋น๊ต 6๋ฒ์ผ๋ก ๋๋์. ๋น ๋ฅด์ง๋ง ํ์ ๋ ๋ฌผ์ฒด์๋ ๋ญ๋น๊ฐ ๋ ๋ง์ด ์๊ธฐ๊ธด ํด์. ๊ทธ๋์ OBB์ ๊ฐ์ด ์ถ์ ํ์ด์ ์ฐ๋ ๋ฐ์ด๋ฉ ๋ฐ์ค๋ฅผ ์ฌ์ฉํ ์ ์์ด์.
๋ฐ์ด๋ฉ ๋ณผ๋ฅจ๋ง์ผ๋ก๋ ์์ง ๋ถ์กฑํด์. ์ถฉ๋์ ๋น๊ตํ๊ธฐ ๋ ์ฌ์์ก์ง๋ง ์ฌ์ ํ ๋ชจ๋ ๋ฌผ์ฒด์ ๋ํด์ ๊ฒ์ฌํด์ผํด์. ๊ฒ์์์ ์ฌ์ ๋ชจ๋ ๋ฌผ์ฒด๋ฅผ ์ฌ์ ํ ์ํํด์ผ ํ๋ ๊ฒ๊ณผ ๊ฐ์์. BVH(Bounding Volume Hierarchy)๋ ์ด ๋ฌผ์ฒด๋ค์ ์ด์ง ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ๋ฌถ์ด, "๋ถ๋ชจ ๋ฐ์ค์ ๊ฒน์น์ง ์์ผ๋ฉด ์์ ์ ์ฒด๋ฅผ ์คํต"ํ ์ ์๊ฒ ํด์.

struct BVHNode: aabb: AABB // ์ด ๋
ธ๋๋ฅผ ๊ฐ์ธ๋ ๋ฐ์ด๋ฉ ๋ฐ์ค left: BVHNode // ์ผ์ชฝ ์์ (null์ด๋ฉด ๋ฆฌํ) right: BVHNode // ์ค๋ฅธ์ชฝ ์์ (null์ด๋ฉด ๋ฆฌํ) object: Object // ๋ฆฌํ ๋
ธ๋์ผ ๋๋ง ์ ํจfunction buildBVH(objects): node.aabb = computeAABB(objects) // ์ ์ฒด๋ฅผ ๊ฐ์ธ๋ ๋ฐ์ค if len(objects) == 1: node.object = objects[0] // ๋ฆฌํ ๋
ธ๋ return node axis = longestAxis(node.aabb) // ๊ฐ์ฅ ๊ธด ์ถ์ผ๋ก ๋ถํ (๋ฌผ์ฒด๊ฐ ๊ฐ์ฅ ๊ธด ๋ฐฉํฅ) sorted = sortByAxis(objects, axis) mid = len(sorted) / 2 node.left = buildBVH(sorted[:mid]) node.right = buildBVH(sorted[mid:]) return nodefunction rayIntersect(node, ray): if not intersects(node.aabb, ray): return null // ์ด ์๋ธํธ๋ฆฌ ์ ์ฒด ์คํต if isLeaf(node): return preciseIntersect(node.object, ray) hitLeft = rayIntersect(node.left, ray) hitRight = rayIntersect(node.right, ray) return closest(hitLeft, hitRight)> SAH(Surface Area Heuristic): ๋จ์ํ ์ค๊ฐ๊ฐ์ผ๋ก ๋ถํ ํ๋ ๋์ , ๊ฐ ๋ถํ ํ๋ณด์ ํ๋ฉด์ ๋น์จ๋ก ์์ ํ์ ๋น์ฉ์ ๊ณ์ฐํด ๊ฐ์ฅ ํจ์จ์ ์ธ ๋ถํ ์ถ์ ์ ํํด์. ๋ ์ดํธ๋ ์ด์ฑ ์์ง์์ ํ์์ ์ด๋ผ๊ณ ํด์. ์๋ ๊ทธ๋ฆผ์ด ์ค๊ฐ๊ฐ์ผ๋ก ๋ถํ ํ๋ ๊ฒ๊ณผ SAH๋ก ๋ถํ ํ๋ ์ฐจ์ด๋ฅผ ๋ณด์ฌ์ค์.

BVH ํ๋๋ก๋ "๋ ์ด(๊ด์ , ๋น)์ด ์ด๋ค ๋ฌผ์ฒด์ ๋ง๋๊ฐ"๋ฅผ ์ฐพ์ ์ ์์ด์. ํ์ง๋ง "์บ๋ฆญํฐ A์ ์บ๋ฆญํฐ B๊ฐ ์ถฉ๋ํ๋๊ฐ?" ์ฒ๋ผ ๋ ๋ณต์กํ ์ค๋ธ์ ํธ ์ฌ์ด์ ์ถฉ๋์ ์ฐพ์ผ๋ ค๋ฉด ๋ฌ๋ผ์.
๊ฐ ์ค๋ธ์ ํธ๊ฐ ์์ฒด BVH๋ฅผ ๊ฐ๊ณ ์์ ๋, BVTT(Bounding Volume Traversal Tree)๋ ๋ BVH๋ฅผ ๋์์ ์ฌ๊ท ์ํํ๋ฉฐ ์ถฉ๋ ์์ ์ขํ๊ฐ์.

function traverseBVTT(nodeA, nodeB, results): // ๋ ๋
ธ๋์ AABB๊ฐ ๊ฒน์น์ง ์์ผ๋ฉด ์ด ์ ์ ์ฒด ์คํต if not overlaps(nodeA.aabb, nodeB.aabb): return // ๋ ๋ค ๋ฆฌํ๋ฉด ์ ๋ฐ ์ถฉ๋ ๊ฒ์ฌ if isLeaf(nodeA) and isLeaf(nodeB): results.add(preciseCheck(nodeA.object, nodeB.object)) return // ๋ ํฐ ๋
ธ๋๋ฅผ ๋จผ์ ๋ถํ (๋น์ฉ ์ต์ํ) if volume(nodeA) >= volume(nodeB): traverseBVTT(nodeA.left, nodeB, results) traverseBVTT(nodeA.right, nodeB, results) else: traverseBVTT(nodeA, nodeB.left, results) traverseBVTT(nodeA, nodeB.right, results)ํต์ฌ์ ๋จ์ํด์. ๋ ๋ ธ๋์ AABB๊ฐ ๊ฒน์น์ง ์์ผ๋ฉด, ๊ทธ ์๋ ์์ ์์ ์ ๋๋ก ์ถฉ๋ํ ์ ์์ด์. ๊ทธ๋์ ์๋ธํธ๋ฆฌ ์ ์ฒด๋ฅผ ๊ฐ์ง์น๊ธฐํ๋ ๊ฑฐ์์. ๋ณต์ก๋๋ O(log n ยท log m)๊ฐ ๋์.

์ค๋ฌด์์ ๋์ ๋ณดํต ํจ๊ป ์ฐ์ฌ์. ์ฌ ์ ์ฒด BVH๋ก "์ถฉ๋ ํ๋ณด ์"์ ์ถ๋ ค๋ด๊ณ (broad phase), ๊ทธ ์์ ๋ํด ๊ฐ ์ค๋ธ์ ํธ์ BVH๋ฅผ BVTT๋ก ์ ๋ฐ ๊ฒ์ฌํด์(narrow phase)
- Unity Physics / PhysX: ์ฌ BVH(DBVT)๋ก broad phase, ๊ฐ ์ค๋ธ์ ํธ convex hull BVH๋ก narrow phase
- Unreal Engine: `FBVHTree` ํด๋์ค๊ฐ BVH ๊ด๋ฆฌ, `FChaosPhysics`์์ BVTT ๊ธฐ๋ฐ ์ถฉ๋ ์ ์์ง
- ๋ ์ดํธ๋ ์ด์ฑ (DXR, NVIDIA OptiX): GPU ๊ฐ์ BVH ํ์, RTX BVH ํ๋์จ์ด ์ ๋์ผ๋ก ์ฒ๋ฆฌ
- FCL (Flexible Collision Library): ๋ก๋ณดํฑ์ค/์๋ฎฌ๋ ์ด์ ์ฉ ์คํ์์ค, BVTT ๊ธฐ๋ฐ ์ถฉ๋ ์ฟผ๋ฆฌ ์ ๊ณต
BVH์ BVTT๋ ๊ฒฐ๊ตญ ๊ฐ์ ํต์ฌ ์์ด๋์ด์ ๋ ๊ฐ์ง ์ ์ฉ์ด์์. "๊ฒน์น ์ ์๋ ๊ณต๊ฐ์ ์ผ์ฐ ๋ฒ๋ฆฐ๋ค." BVH๊ฐ ์ฌ๊ณผ ๋ ์ด ์ฌ์ด์ ๋ฌธ์ ๋ฅผ ํ์๋ค๋ฉด, BVTT๋ ๊ทธ ์์ด๋์ด๋ฅผ ๋ ๋ณต์กํ ์ค๋ธ์ ํธ ์ฌ์ด์ ๋ฌธ์ ๋ก ํ์ฅํ๊ฑฐ์์.

์ ์ฌ์ง์ ์ ๊ฐ VTK๋ก ์ฌ๋ฌ ๋ฌผ์ฒด๊ฐ Intersection๋๋ ๋ถ๋ถ์ ๊ฐ์กฐํ์ฌ ๋ ๋๋ง ํ๋ ์ฌ์ง์ด์์. vtk๋ฅผ ํ์ฉํ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ฐ๊ปด๋ ๋น ๋ฅด๊ฒ ๋ฆฌ๋ ๋๋ง ๊ฐ๋ฅํ๋๋ก ๋ง๋ค์์ด์. ์ฒ์์๋ Vertex๊ฐ ๊ฒน์น๋ฉด ๋๊ฒ ์ง๋ผ๋ ๋จ์ํ ์๊ฐ์ ํ๋๋ฐ, ์๊ฐํด๋ณด๋ ๋ฉด(face)๊ฐ ๊ต์ฐจํด์ผ๋ง ์๋ก ์ถฉ๋ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ณต์กํด์ง๋๋ผ๊ณ ์. ๊ทธ๋์ ์ถฉ๋์ง์ ์ ๋น ๋ฅด๊ฒ ์ฐพ๋ ๋ฐฉ๋ฒ๋ค์ ์ฐพ๋ค๊ฐ BVH์ BVTT๊น์ง ๊ณต๋ถํ๊ฒ ๋์์ด์.