sweep and pruneμ κ΅μλκ»μ νΉμ λ Όλ¬Έμ μ½μΌλΌκ³ νμ ¨μ λ λ³Έ λ°©λ²μ λλ€
νμ§λ§ νκΈ ν΄μμ΄ λ ν¬μ€ν μ΄ μμ΄μ κ°λ¨νκ² λ²μνμ¬ λκ³ μ μ μΆκ° λ° λ³΄μν μμ μ λλ€
ν΄λΉ ν¬μ€ν μ https://github.com/mattleibow/jitterphysics/wiki/Sweep-and-Prune μ νκ΅μ΄λ‘ ν΄μν ν¬μ€ν μΌλ‘ λ¬Έμ κ°λ μ μμ νλλ‘ νκ² μ΅λλ€
κ΄μ μΆ©λ μμ€ν μ λͺ¨λ 물리 μμ§μ ν΅μ¬ κ³Όμ μ€ νλμ λλ€.
μ΄λ―Έ κ΄μ μΆ©λμ λν΄ λμΉ κ² μλ€λ©΄ κ΄μ μΆ©λμμ€ν μ μ΅μ ννλ μ½λλ₯Ό μ§μ 볡ꡬνκΈ°λ μ΄λ ΅μ΅λλ€.
물리 μμ§μμ μΆ©λ λ¨κ³μλ 3κ°μ§κ° μμ΅λλ€.
1. Broadphase : κ΄λν λ²μ
- μ¬κΈ°μ μ΄λ€ μΆ©λμ΄ μ€μ λ‘ μΌμ΄λ μ μλμ§λ₯Ό κ°μ§νκ³ , μΆ©λν μ μλ μΆ©λμ νκΈ°ν©λλ€.
μ°Έκ³ ν λ§ν μ¬μ΄νΈ : https://developer.nvidia.com/gpugems/gpugems3/part-v-physics-simulation/chapter-32-broad-phase-collision-detection-cuda
2. Midphase : μ€κ° λ²μ
- ꡬλ μ² λ¬Όμ²΄ κ°μ κΈ°ννμ λ¨κ³μμμ μΆ©λμ λ§ν©λλ€.
3. Narrowphase : μ’μ λ²μ
- μ΄ λ¨κ³μμ μ€μ μΆ©λ κ°μ§λ₯Ό μνν©λλ€. κ΅μ°¨μ , μΆ©λ λ²μ λλ μΉ¨ν¬ κΉμ΄μ κ°μ μΆ©λ λ°μ΄ν°λ₯Ό κ²μνλ μμ μ ν©λλ€.
κ±°μ λͺ¨λ κ΄μ μμ€ν μ κ°μ²΄μ μΆ μ λ ¬λ κ²½κ³ μμ(aabb)λ₯Ό μ¬μ©ν©λλ€.
aabbλ κ½€ 빨리 κ³μ°λ μ μμΌλ©° κ΅μ°¨μ μ νμΈνλ κ²λ λͺ μ€μ μ½λλ‘ μνλ©λλ€.
μ°Έκ³ ν λ§ν μ¬μ΄νΈ : https://blog.naver.com/mycode333/50031266282
κ·Έλ λ€λ©΄, μ΄λ»κ² νλ©΄ "κ²ΉμΉμ§ μλ μμ μ λ ¬ κ³Όμ "μ κ°μν ν μ μμκΉμ?
μΆ©λμ κ°μ§νκΈ° μν μμ μ μ κ·Όλ°©μμ λν΄ λͺ κ°μ§λ₯Ό μμλ΄ μλ€.
for (int i = 0; I < rigidBodies.Count; i++)
{
for (int e = i; e < rigidBodies.Count; e++)
{
if (CheckBoundingBoxForOverlap(i, e))
DetectNarrowPhase(i,e);
}
}
λ€λ₯Έ λͺ¨λ κ²λ€μ λν΄ μ²« λ²μ§Έ Rigidbodyλ₯Ό κ°μ§νκ³ , 첫 λ²μ§Έ Rigidbodyλ₯Ό μ μΈν λ€λ₯Έ λͺ¨λ κ²λ€μ λν΄ λ λ²μ§Έ Rigidbodyλ₯Ό κ°μ§ν©λλ€.
κ·Έλ κ² λμμ§λ μμ§λ§..
λ§μ½ 10x10x10 μΆ©λ κ°μ§ λλ νλΈκ° μλ€λ©΄, μ΅μμ κ²½μ° μμ² κ°μ μΆ©λ κ°λ₯ν μμ νμΈνμ¬ μμ μ½λλ₯Ό μνν΄μΌ ν©λλ€. μ’μ λ²μμ μΆ©λ 체ν¬λ 0.25λ°±λ§ κ°λ₯Ό 체ν¬ν΄μΌν©λλ€.
μμ°μ μΌλ‘ κ΄μ λ²μλ O(n^2) λ¬Έμ κ° μκΈ°λλ° μ΄μ λν΄ λ¬΄μμ ν μ μμκΉμ?
λ°μ΄ν° ꡬ쑰λ₯Ό κ°μνν΄μΌ ν©λλ€.
μΉμμ "κ΄μμ μΆ©λ νμ§"λ₯Ό κ²μνλ©΄ Sweep And Prune(SAP)μ κ·Όλ²μ λ°κ²¬νκ² λ©λλ€.
λ§μ λ³νλ ꡬνλ€μ΄ μμ§λ§ λΆλ₯ν λ€μ λ€λ¬λλ€(Prune)λ 곡ν΅μ μ΄ μμ΅λλ€.
SAP μκ³ λ¦¬μ¦μμ κ°μ₯ κ°λ¨ν "flavor"λ₯Ό μ§μλμ§ μλ λ¨μΌ μΆ SAPμμ μ¬μ©νλ€λ κ²μ΄ 무μμ μλ―Ένλμ§ μμλ΄ μλ€.
1. κ³΅κ° μμ λͺ¨λ 물체λ€μ "AxisList"λΌλ λͺ©λ‘ μμ λ€μ΄μμ΅λλ€. κ²½κ³μμμ μμμ μ΄μ©ν΄ ν κ°μ μΆ(μ¬κΈ°μλ XμΆ)μΌλ‘ 리μ€νΈλ₯Ό μ λ ¬ν©λλ€. λ°λΌμ 물체 5μ κ°μ₯ μΌμͺ½ μ§μ μ΄ XμΆμ μ§μ λ³Ό λ 물체 6μ κ°μ₯ μΌμͺ½ μ§μ λ³΄λ€ λ μΌμͺ½μ μλ€λ κ²μ μ μ μμ΅λλ€.
2. "ActiveList"λΌλ μλ‘μ΄ μμ 리μ€νΈλ₯Ό λ§λ€μ. μ΄μ "AxisList"μ λ€μ νλͺ©μ λ³΄κ³ "ActiveList"μ λͺ¨λ νλͺ©κ³Ό λΉκ΅ν©λλ€.(νμ¬λ λ¨ νλ) λ§μ½ μ νλͺ©μ μΌμͺ½μ΄ λ ν¬λ©΄ νμ¬ "ActiveList"μ μ€λ₯Έμͺ½ νλͺ©μ΄ μ κ±°λκ³ "ActiveList"μμ νμ¬ "ActiveList" μμ΄ν μ΄ μ κ±°λ©λλ€. κ·Έλ μ§ μμΌλ©΄ μ "AxisList" νλͺ©κ³Ό νμ¬ "ActiveList" νλͺ© κ°μ μΆ©λ κ°λ₯μ±μ΄ μκΉλλ€. μ νλͺ© μ체λ₯Ό "ActiveList"μ μΆκ°νκ³ "AxisList"μ λ€μ νλͺ©μ κ³μν©λλ€.
μ΄ μ κ·Όλ²μ΄ μ§μμ μ΄μ§ μλ€λ κ²μ μκ²λ©λλ€.
μ λ ¬μ μ²μλΆν° λͺ¨λ νλ μμμ μνλλ©°(quicksort μ±λ₯μ΄ μ’λ€) ν μΆ(μ¬κΈ°μμλ XμΆ)μ λν΄ μ λ ¬λλ€.
μ°λ¦¬λ μ₯λ©΄μ μΌκ΄μ±μ μ΄μ©νμ§ μλλ€.(ν νλ μμμ μ₯λ©΄μ΄ λ§μ΄ λ³νμ§ μμ κ°λ₯μ±μ΄ μλ€)
μλ ν₯μμ μ΄λμ λ°μνλκ²μΌκΉ?
μ λ΅μ μΆ©λ νμ§λ κ²μ λ¬Έμ μ΄κΈ° λλ¬Έμ λλ€. κ·Έλ¦¬κ³ μ¬μ λΆλ₯λ λͺ©λ‘μ κ²μμ O(nlog(n)) λ³΄λ€ λΉ λ¦ λλ€.
μ΄ μ¬μ΄ μ κ·Όλ²μ ꡬννλ©΄ λ¬΄μ°¨λ³ ν μκ³ λ¦¬μ¦(brute force algorithm)μ λΉν΄ μμ²λ μλ ν₯μμ΄ κ°λ₯ν©λλ€.
JigLib (Danny Chapmanμ΄ λ§λ μ½λ)μμ C # (JigLibX)λ‘ μ΄μλμμ λ, JigLibμ μλ λ²μ μ 무차λ³μ μΈ νκ³Ό λ§€μ° κΈ°λ³Έμ μΈ κ·Έλ¦¬λ μ κ·Όλ²μ ν¬ν¨νκ³ μμμ΅λλ€.
μ‘΄ μνΈλ μμμ μ€λͺ
ν μ½λλ₯Ό μ ννκ² μ¬μ©νλ νλ‘μ νΈμ SAP μκ³ λ¦¬μ¦μ μ μ©νλλ°, μ΄λ 볡μ‘ν 그리λ μ κ·Όλ²μ μ½κ² 극볡νμ΅λλ€.
λ°λΌμ μ΄ μ½λλ μ΄λ―Έ κ½€ μ μνλμ§λ§, κ·ΈλΌμλ λΆκ΅¬νκ³ XμΆμμ λͺ¨λ λ¬Όμ²΄κ° κ²ΉμΉλ©΄ λ°νμμ λ€μ O (n *2)μ΄λ€.
(λ°λΌμ, λλΆλΆμ λ¬Όμ²΄κ° κ·Έκ³³μμ κ²ΉμΉκΈ° λλ¬Έμ, λΆλ¦¬ μΆμΌλ‘ up-μΆμ μ¬μ©νμ§ μμμΌ ν©λλ€)
Sweep and Pruneμ νκΈ° μν λ 볡μ‘ν(κ·Έλ¦¬κ³ λ λΉ λ₯Έ) μ κ·Όλ²μ μμ ν 3μΆ κ²μ¬λ₯Ό νλ κ²μ λλ€.
λ λ¬Όμ²΄κ° μΆ©λνλ©΄ μΈ μΆ λͺ¨λ κ²ΉμΉλ κ²½μ°μλ§ μΆ©λν©λλ€ (λΆλ¦¬ μΆ μ 리).
μ§μμ 3Axis SAPλ λ€μκ³Ό κ°μ΄ μμ½νμ¬ μλν©λλ€.
μ°λ¦¬λ μΈ κ°μ λͺ©λ‘ (κ° μΆ 1μ λν΄)μ μ¬μ©νκ³ μ½μ μ λ ¬μ μ¬μ©νμ¬ μ λ ¬λ λͺ©λ‘μ μ μ§ν©λλ€.
μ½μ μ λ ¬μ κ±°μ μ λ ¬λ λͺ©λ‘μμ O(n)μ λλ€.
μ½μ μ λ ¬ μκ³ λ¦¬μ¦μ μ€μμ κ°μ²΄κ° λ€λ₯Έ 본체μ μ€μ²©λκΈ° μμ/μ€μ§νλ κ²μ μλ―Έν©λλ€.
κ·Έλμ ν κ°μ ν΄μ ν μ΄λΈμ κ²Ήμ³μ 보κ΄νκ³ , κ° νλ μμ μ½μ ꡬμμ νκ³ , ν΄μ ν μ΄λΈ ꡬ쑰λ₯Ό μ λ°μ΄νΈνλ λ° μ¬μ©νλ λ³κ²½μ¬νλ§ λ³΄κ³ λ°μ΅λλ€.
Jitterμ μ μ°¨
private void SortAxis(List<SweepPoint> axis)
{
for (int j = 1; j < axis.Count; j++)
{
SweepPoint keyelement = axis[j];
float key = keyelement.Value;
int i = j - 1;
while (i >= 0 && axis[i].Value > key)
{
SweepPoint swapper = axis[i];
if (keyelement.Begin && !swapper.Begin)
{
if (CheckBoundingBoxes(swapper.Body, keyelement.Body))
{
lock (fullOverlaps)
{
fullOverlaps.Add(new BroadphasePair(swapper.Body, keyelement.Body));
}
}
}
if (!keyelement.Begin && swapper.Begin)
{
lock (fullOverlaps)
{
fullOverlaps.Remove(new BroadphasePair(swapper.Body, keyelement.Body));
}
}
axis[i + 1] = swapper;
i = i - 1;
}
axis[i + 1] = keyelement;
}
}
λ§μ½ λΉμ μ΄ μ νμ μΈ SAP λ°μ΄ν° ꡬ쑰μ λͺ¨λ μΈλΆμ¬νμ κ΄μ¬μ΄ μλ€λ©΄, λλ νΌμλ₯΄ ν λ₯΄λλ§μ΄ μ΄ νλ₯ν κΈ°μ¬λ₯Ό μ½μ κ²μ μΆμ²ν©λλ€.
κ·Έλ μ§ μλ€λ©΄ κ° νλ μμ "Aκ° μΆ Cμμ Bμ κ²ΉμΉλ€"λ μ 보λ "Aκ° μΆ Cμμ Bμ μ€μ²©μ μ€μ§νλ€"λ μ λ³΄λ§ μ λ¬λ°μΌλ©΄ X, Y λλ ZμΆμ΄ λ μ μμ΅λλ€.
μ²μ μ΄κ²μ μννμ λ, λλ λ΄κ° λ°λ κ°μΌ κ²°κ³Όμ λ§€μ° λ§μ‘±νκ³ , κ·Έλ¦¬κ³ λμ μ€μλ₯Ό νμ΅λλ€.
κ°κ°μ μμ΄ μΌλ§λ μ€λ³΅λλμ§λ₯Ό κΈ°μ΅νλ λ°μ΄ν° ꡬ쑰λ₯Ό ꡬννμ΅λλ€.
κ²ΉμΉλ νμκ° 3ν(λͺ¨λ μΆμμ κ²ΉμΉλ νμκ° 1νμμ μλ―Έ)μΈ κ²½μ°, 물체λ μΆ©λν©λλ€.
μ΄κ²μ ν¨κ³Όκ° μμ§λ§ λμ°ν©λλ€.
ν μΆμ κ²ΉμΉλ μμ μλ λ§€μ° λμ μ μμΌλ―λ‘ μ€λ³΅ κ³μ = 1μΈ μμ² κ°μ μ μ¬μ κ²ΉμΉλ μμ μ μ₯ν΄μΌ νλ€. λ¨μ§ λͺ κ°λ§ λ λ²μ§Έ μΆμ κ²ΉμΉκ³ κ²ΉμΉλ νμκ° 2μ΄κ³ , μΈ λ²μ§Έ μΆμ κ²ΉμΉλ νμλ 3μ΄λΌλ κ²μ κΉ¨λ¬μμ΅λλ€.
κ²°κ΅ λ°νμμ O(nlogn)μμ§λ§ λ©λͺ¨λ¦¬ μ¬μ©λμ O(n^2)μ΄μλ€(λ΄ μ¬μ ꡬ쑰λ₯Ό μ£½μ΄λ κ²)
μ΄ λ¬Έμ μ ν΄κ²°μ± μ κ°λ¨ν©λλ€. μ무κ²λ μ μ₯νμ§ λ§λΌ.
ν μΆμ΄ μ€μ²©μ λ³΄κ³ νλ κ²½μ° μ λ ΄ν μ 체 κ²½κ³ μμ νμΈ – μμμΌ κ²½μ° ν΄λΉ μμ νμ€λ²λ©μ μΆκ°νμμμ€.
ν μΆμ λ κ°μ λͺΈμ²΄κ° λΆλ¦¬λμ΄ μλ€κ³ λ³΄κ³ λ κ²½μ°, νμ€λ²λ©μμ μμ μ κ±°νμμμ€. (μ΄κ²μ μμ μ½λλ‘ νν΄μ§λ€.) λ°λΌμ SAPμ μ¬μ©λλ λ©λͺ¨λ¦¬λ λ€μ O(n)μ μ§λμ§ μμ΅λλ€.
("CollisionSystemPersistent"μμ Jitterμ ꡬνμ μ°Ύμ μ μμ) SAP.cs".)
μ§μμ μΈ Sweep and Prune μκ³ λ¦¬μ¦μ λ¨μ μ€ νλλ λ§μ λΉνμ± κ°μ²΄λ₯Ό κ°μ§ μ λ§ ν° μΈκ³λ₯Ό κ²½ννλ€λ κ²μ΄λ€.
μ΄μμ΄ μ μ μΈ λ¬Όμ²΄κ° λ§μ λ§μμ κ΄ν΅νλ κ²μ μμν΄λ³΄λΌ.
κ° λ¬Όμ²΄(μ΄νμΌλ‘λΆν° μλ§μΌ λ¨μ΄μ Έ μμ΄λ)μ νν μ체 μ¬μ΄μ κ΅νμ΄ μλ€
μ΄ λ¬Έμ λ 그리λ(κ΄λ²μ λ¨κ³)λ₯Ό ꡬμ±νλ μ¬λ¬ κ°μ μν SAPλ₯Ό μ¬μ©νμ¬ ν΄κ²°ν μ μλ€.
λ΄κ° μμμ°¨λ¦° λ λ€λ₯Έ λ¬Έμ λ κ΄μ κ³Ό κ²½κ³ μμ μ§μκ° ν¨μ¨μ μΌλ‘ μνλ μ μλ€λ κ²μ΄λ€.
λ μ΄μΊμ€ν μ κ²½μ°, μ λ ¬λ μΈ κ°μ λͺ©λ‘μ κ· μΌνμ§ μμ 볡μ 그리λλ‘ ν΄μλ μ μμΌλ―λ‘, μ£Όλ¬Έν λ μ΄ μΏΌλ¦¬λ₯Ό μ»μ μ μλ€.
μ΄κ²μ μ€μ λ‘λ λ€μ λ리λ€.
μλνλ©΄ λ§μ 볡μ 그리λκ° λΉμ΄ μκ³ μ΄κΈ° ν격μ λ°μ κ΄μ μ λν ν΄κ²°μ± μΌ λΏμ΄κΈ° λλ¬Έμ΄λ€.
λ¨μ§ κ° λ¬Όμ²΄μ λν΄ κ±°μΉ ν κ²μ¬λ₯Ό νλ κ²μ΄ μ’ μ’ λ λΉ λ₯΄κΈ° λλ¬Έμ΄λ€.
λ λ€λ₯Έ λ¬Έμ λ μ₯λ©΄μ νλμ ν° λ¬Όμ²΄(λκ° μ§λ©΄μ΄λ λ 벨)κ° ν¬ν¨λμ΄ μλ€λ κ²μ΄λ€.
μ΄ κ°μ²΄μ λμ μ μμ ν μΌμͺ½μ μκ³ λͺ©λ‘ μ€λ₯Έμͺ½μ μλ€.
μ€μν ν¬μΈνΈμ μ μ₯λ μΆκ° μ λ³΄κ° μμΌλ©΄ κ°μ²΄κ° ν¨μ¬ λ ν° μν°ν°μ λμ μ μν΄ λλ¬μΈμ΄λμ§ μ¬λΆλ₯Ό ν¨μ¨μ μΌλ‘ κ°μ§ν μ μλ λ°©λ²μ΄ μλ€.