지난시간 정리
- dop network 안에서 오브젝트는 '그릇'이다.
- rigid body 시뮬레이션에서 제일 중요한 것은 충돌조건이다.
- RBD / Bullet 방식 중, 우리는 Bullet에 좀 더 집중할 예정이다.
Rigid Body 시뮬레이션에서 제일 까다롭고, 중요한 포인트인 개념
- 얼마나 완벽하게 Proxy Geometry와 고해상도 결과물을 치환시키느냐
- 시뮬레이션이 안정적이고 빠르게 작동하기 위해서는 가벼운 충돌조건들이 필요하다. 우리가 사용한 충돌조건을 기준으로 디테일이 높은 자료를 완벽하게 치환시킬줄 알아야한다.
- 이 과정이 instancing이다.
instancing을 직접할 수 있어야 시간을 많이 아낄 수 있다.
Proxy geo로 가볍게 시뮬레이션을 하는데 익숙해져야하는 또다른 이유
- 가볍게 시뮬레이션을 돌릴 수 있어야 tweak의 횟수를 늘릴 수 있다.
- 마음에 드는 디테일을 찾으려면 시드값도 계속 바꿔보고 이니셜 값들도 계속 바꿔보고 해야하는데 무거운 자료로는 몇번 해보질 못한다.
- 가벼운 자료로 tweak을 진행한다면, 수백번도 시도해볼 수 있다.
Proxy geo로 시뮬레이션을 진행하고, 디테일이 높은 물체로 치환해주는 이러한 작업을 올바르게 진행하기 위해서, 그리고 후디니가 제안하는 표준적인 방법을 잘 따르기 위해서는 결국 pack 된 자료를 바탕으로 시뮬레이션을 진행해줘야한다.
그리고 자연스럽게 bullet solver를 신뢰하고 사용하게 될 것이다.
학습의 순서
- Packed Object로 시뮬레이션 발생시키기
- Pack된 자료를 Dop Network에 넣기 전에 미리 준비해야할 내용들
- 시뮬레이션 자료 분석
- 치환(transform Physics) 기본 개념
일단 세가지 경우를 만들었다.
just : 약간 틀어준 지오메트리를 transform 노드로 일정높이만큼 이동했다.
pack_A : 약간 틀어준 지오메트리에 pack을 적용해준 뒤 transform 노드로 일정높이만큼 이동했다.
pack_B : 약간 틀어준 지오메트리를 transform 노드로 일정높이만큼 이동해준 뒤 pack을 적용해줬다.
위 세가지 경우는 틀어준 각도가 같고(동일한 각도) 이동해준 높이 또한 같다(동일한 위치)
dop network를 구성해준다.
(내가 집에서 시뮬레이션 돌린 결과는 Pack_A 와 Pack_B의 시뮬레이션 결과가 동일하게 나왔다. 선생님 예제는 다르게 나왔기 때문에, 일단 공부 정리는 선생님 강의 내용을 중심으로 진행한다.)
Pack 된 자료와 그렇지 않은 자료는 완벽히 동일한 위치에서 동일한 각도로 떨어지게 되어도 서로 결과가 다르게 나타났다.
심지어는 0,0,0의 위치에 있는 자료를 Pack해준 뒤 transform으로 위치를 이동해준 결과와 0,0,0의 위치에 있는 자료를 transform으로 위치를 이동하고 pack 해준 결과의 시뮬레이션 계산결과 또한 다르게 나타난다.
그 이유로는 각각의 자료들의 위치와 방향을 불러오고 저장하는 방식에서 오차가 발생하고 있기 때문에 표면적으로는 동일한 자료를 넣어도 서로 다른 결과가 반환되는 것이다.
물체를 회전시키기 위해서 우리가 많이 사용하는 것은?
- transform 노드이다.
transform 노드는 사용자가 편하게 작업할 수 있도록 후디니가 360도 기준의 각도로 계산하기 쉽게 만들어준 것이다.
- 실제 후디니가 각도를 인식하기 위해서는 @orient 정보가 필요하다.
- @orient는 'x, y, z를 기준으로 회전한다' 이런 느낌이 아니고, vector4 정보이다.
- 직관적인 숫자는 아니다.
orient 각도 방식은 물체의 instancing에 도움을 준다.(후디니가 판단하기에도 훨씬 빠르다.)
RBD Object를 활용해서 시뮬레이션을 진행할 때 Pack 과정이 있을까? 없을까?
- 실제 시뮬레이션 공정에서는 순간적으로 pack을 한 뒤 시뮬레이션을 진행하고 다시 unpack해서 결과로 사용자가 볼 수 있게 해주는 것이다.
RBD Object의 경우, 최초에 어떠한 collision 데이터를 사용할지 변환하는 과정이 있고, 이 때의 충돌 데이터는 packing된다.
packing된 뒤에는 pivot, 중심이 생기고, 방향을 나타내는 orient와 위치정보 P를 가지게 된다.
그러면 collision 정보가 어느 한 점에 pack된 상태로 instancing 된 것이다.
이제 이 자료를 가지고 시뮬레이션이 발생한다.
그리고 시뮬레이션의 결과로 다음 프레임에서의 위치(P)와 방향(Orient)이 정해졌다면, 사용자에게 최종적으로 결과를 보여주기 위해 위치가 바뀐 collision에 원본을 치환해서 돌려주게 된다.
만약에, 위와 같은 과정(packing)을 거치지 않고, 주어진 오브젝트를 가지고 시뮬레이션을 진행하면 어떻게 될까?
- 물체가 가진 각각의 포인트들의 위치가 시뮬레이션 되면서 오차에 의해 변형이 발생하고 원본을 보존하지 못할 수 있다.
- 시간이 지남에 따라 원본의 손상이 가해질 수 있다는 것을 의미한다.
시뮬레이션을 진행한다고 해서 각각의 조각의 모양이 변할 수는 없으니 다른 값으로써 시뮬레이션 결과를 얻어내고 마지막에 위치에 대체해주는 과정이 필요하다.
Packed Object의 경우는 이미 packing된 지오메트리가 들어오기 때문에, 따로 packing, unpacking의 converting 단계가 없다.
- 이미 회전중심(pivot)과 위치(P), 방향(Orient)이 정해진 상태로써 시뮬레이션에 들어가게 되는 것이다.
시뮬레이션을 통해 나온 결과는 위치(P)와 방향(Orient)이 바뀐 상태이다.
그리고 결과로 반환받게 될 정보는 packing된 상태 그대로이다.
최종적으로 시뮬레이션된 결과를 이용하고 싶다면, 그 때 unpacking을 진행하고 작업을 하면 된다.
pack 되지 않은 물체를 packing / unpacking 해주는 convert 단계에서 발생하는 오차로 인해 RBD Object와 Packed Object의 시뮬레이션의 결과가 다르게 나타난다.
그렇다면, Packed Object 두 경우는 결과가 다른 이유가 무엇일까?
- 두 케이스의 pivot의 위치가 다르기 때문이다.
- box에 pack을 해주고 transform으로 이동시킨 경우(pack_A)와 box를 transform으로 이동시켜주고 pack을 해준 경우(pack_B)는 pivot을 확인해보면 서로 다른 pivot 좌표를 가지고 있는 것을 확인할 수 있다.
위의 이미지와 같이 pivot이 다르기 때문에 표현되는 orient 또한 달라지게 된다.
- pivot의 정보가 다르기 때문에 방향(orientation)을 구해줄 때에도 다른 정보가 쓰이게 된다.
결론은... 주어진 정보가 동일해보이는 물체도 시뮬레이션 결과는 다를 수 있다.
Initial State
초기에 들어오는 지오메트리의 위치, 회전, 속도 등을 바꿔줄 수 있다.
Dop Network 밖에서 Transform 노드를 활용해서 물체의 위치를 이동시켜줄 수도 있지만, RBD Packed Object의 Initial State의 Position을 조절하는 것으로도 물체의 초기 위치를 변경시켜줄 수 있다.
- 이것은 우리가 불러온 물체를 Position 값만큼 이동시켜서 시뮬레이션을 시작시키겠다는 의미이다.
이제는 선택을 해야한다.
시뮬레이션 시킬 물체의 위치를 dop network 밖에서 정해줄 것인지, dop network 안의 RBD Packed Object의 initial state에서 정해줄 것인지 정해야한다.
Attribute wrangle로도 물체의 위치를 바꿀 수 있다.
- 이것이 가능한 이유는 pack된 물체의 point 위치정보는 pack된 물체가 어디에 놓이느냐 를 뜻하는 것이기 때문에 포인트의 위치정보에 임의의 vector 정보를 연산해줘서 위치를 바꿔줄 수 있다.
- '임의의 위치에 물체를 두겠다.' 이 의미보다는, 'pack된 물체를 임의의 위치만큼 이동시키겠다.' 로 이해하면 된다.
이번에는 rotation에 대해 이야기해보자.
시작단계에서 불러온 물체가 x축 방향으로 40도 만큼 회전해서 시뮬레이션이 시작되었으면 좋겠다.
두 물체의 초기 회전을 다르게 주고 시뮬레이션을 걸어보자.
Rigid Body 초보 상태인 지금은, Initial state에서 position이나 rotation을 바꾸지 말고, dop network 밖에서 미리 준비해주는 방식을 사용하자.
그 이유로는, 현재 RBD Pacekd Object라는 '그릇'에는 각각 단일 오브젝트가 담겨있어서 initial state의 값을 변경해준 결과가 우리의 예측에서 크게 벗어나지 않는다.
하지만, 이 '그릇'에 여러 물체가 담기기 시작하면 이야기가 달라지게 된다.
현재 세가지의 rubber toy를 만들어줬다.
그리고 각각 RBD Packed Object 노드를 하나씩 할당해서 시뮬레이션을 적용했다.
이제 여기에 변화를 줘보자.
세개의 rubber toy를 하나로 묶어주면 결과가 어떻게 나올까?
이 세 토이들은 하나로 묶여서 움직일까? 아니면 따로 움직일까?
답은 '따로 움직인다' 이다.
RBD Packed Object 라는 '그릇'에는 현재 pack된 물체 3개가 담겨있는 것이다.
수십개의 물체가 있다고 해도, 그것들이 '서로 다른 packing'과정에 의해 pack되고 묶여서 들어온다면, 시뮬레이션은 각각의 pack 된 물체들이 따로 움직이게 된다.
만약, 하나의 packing 과정을 통해 pack된 물체가 들어오면 어떻게 될까?
위의 이미지처럼 merge를 사용해 하나로 묶어준 세개의 토이를 packing 해준 것을 시뮬레이션 해보자.
모두 묶인 상태로 시뮬레이션이 진행된다.
각각 따로 packing된 물체와 동시에 한번에 packing된 물체의 시뮬레이션 차이를 알아보았다.
그렇다면 위의 두 경우(따로 packing된 경우 / 한번에 packing된 경우) initial state를 변경해준다면?
rotation에 한해서는 initial state에서 손을 보지 말자. 각각의 pack된 물체들에 대해 동일한 회전값이 적용되기 때문이다.
이제 초기에 불러온 물체에 velocity에 대해서 이야기해보자.
순서상, rotation이 적용된 방향을 기준으로 velocity가 적용된다(local)
하지만 결과는 월드축 방향이 아닌, 오브젝트의 로컬축을 기준으로 y축 방향으로 10만큼의 속도로 튕겨져나갔다.
이것은 조금 직관적이지 않아보인다.
우리가 바라는 것은 rotation은 rotation대로 적용되고, velocity는 velocity대로 적용되는 것인데, 위의 결과는 그것이 아니다.
그렇기 때문에 rotation을 dop network 밖에서 세팅해주는 것을 선호하는 것이다.
이번에는 dop network 밖에서 B에 회전을 적용해줬다.
이번에는 angular velocity에 대해 알아보자.
(각속도 개념인듯)
회전에 대한 초기 속도이다.
이것 또한 local축을 따라가는지라, rotation에 종속되어서 축이 회전하고, 그 축을 기준으로 회전 속도를 부여한다.
C(분홍 토이)의 초기 rotation을 z축으로 60으로 하고, y축 방향으로 angular velocity를 400으로 주었을 때,
위의 이미지처럼 z축으로 회전한 축을 기준으로 하여 y축 방향으로 400의 속도로 회전하게 된다.
정리
initial state의 rotation은 velocity와 angular velocity에 영향을 많이 준다.
쿼터니언 방식으로 회전이 발생하고 있는 것이다.
- 쿼터니언 방식 : 방향이 정해져있다면, 방향을 축으로해서 회전이 정해지는 것
지금 당장 joy of VEX로 가서 쿼터니언, orient를 공부하고 오겠다고 시간쓰지 말자.
현재로서는
- dop network 안에서 initial 세팅을 잡는다면, rotation에 따라 축이 바뀌고, velocity(속도)와 angular velocity(회전속도)에 영향을 준다는 것,
- dop network 밖에서 initial 세팅을 잡는다면, global하게 방향과 회전을 줄 수 있다.
정도만 기억하자.
dop network 밖에서 초기 속도와 초기 회전속도를 세팅해보자.
초기 속도에 대한 attribute는 @v이고, 초기 회전속도에 대한 attribute는 @w이다.
초기 속도와 회전속도를 dop network 밖에서 세팅할 경우에는 RBD Packed Object의 initial state 하단의 'Inherit Velocity from Point Velocity'를 체크해줘야한다.
그렇다면, 현재는 RBD Packed Object '그릇' 하나당 하나의 오브젝트가 들어가있는데, 하나의 그릇에 pack된 물체 세개를 한꺼번에 넣으면 어떻게 될까?
상황에 따라 object 그릇에 담는 물체는 여러개를 담을 수도 있고, 단일 물체를 담아줄 수도 있다.
이것은 사용자의 니즈에 따라 그릇을 잘 분류만 해줄 수 있으면 된다.
이제 물체들의 물리값에 대해 다뤄보자.
Physical
- 얼마나 무거울지(Density / Mass), 얼마나 튀기는 정도(탄성)가 클지(Bounce), 얼마나 마찰이 심할지(Friction)
물리법칙에 사용되는 값들도 Dop network 밖에서 initial state 정하듯이 미리 정해줄 수 있다.
- 이 때 사용되는 Attribute만 잘 알고 있으면 된다.
sphere에 friction(마찰) / bounce(탄성)을 적용해보자.
일단 여기에서 한번 끊어가자.
스스로 만들 수 있으니, 여러 박스에 부딪히는 공, 도미노도 만들어보기 바란다.
오늘도 즐거운 강의였다.
Joy of VEX를 완강하지 못하고 듣고 있어서 가끔씩 뜨끔뜨끔할 때가 있는데,
쿼터니언과 오리엔트 이야기가 나올 때 또 뜨끔!!
수업이 다 마무리되면 꼭 조오벡도 마스터해야지...
이제 뚝딱뚝딱 뭔가 얼추 그림이 나오도록은 만들어볼 수도 있을꺼라는 생각이 들긴 하는데...
이게 문제가 아니야... 그럴싸하고, 이뻐보이고... 결국 tweak과 감의 싸움이 시작되나보다 :(