STARTER09_고난주간 6일차_Point Gravity (2차 수정)
목차
- point gravity
- 중간고사 문제
- 일기
규칙을 말로 쓰고 풀어서 쓸 수만 있다면 이번 과제, 할만 했을 것이다.
오늘 작업할 solver의 세팅은 기존에 해오던 것에서 출발하는 것이 아니라, 백지 상태인 빈 지오메트리에서부터 다시 시작해볼 것이다. 5일차, 6일차, 7일차 모두 solver를 통한 점의 움직임을 다루지만 세팅이 조금씩 다르다. 간혹 오해할 수 있는데, 1일차에서 7일차로 갈수록, 더 올바르고 완벽한 세팅이다 라고 생각할 수 있다. 그런데 절대 그렇지 않다. 지금 우리가 가져야할 목표는 유연하게 '이럴 때는 이렇게 하자', '이럴 때 이런 세팅은 필요가 없구나' 하면서 작업하면 된다.
이런건 이렇게 잡는 것이 정답입니다. 이런것은 옳지 않다. 정해진 하나의 정답, 후디니에는 없다. 논리적으로 말이 되고, 구현이 된다면, 방식은 달라도 모든 방법이 솔루션이 될 수 있다. (이것이 후디니스러운 것이라고 선생님은 생각하고 있다고 한다.)
모든 랭글러를 위하여!
후디니 만쉐!
과제 영상에서 관찰할 수 있는걸 모두 말로 표현해보자.
- 포인트가 생성되자마자 움직이기 시작했다.
- 점들이 아래로 향하는 중력에는 영향받지 않는다.
- 움직임의 방향이 계속 변한다.
- @vel이 계속 업데이트 된다.
- 중력이 빨간점을 향해서 작용하고 있다.
어떤 attribute wrangle이 필요할지에 대해 만들어보자.
새로운 지오메트리를 만들고, 이것저것 노드들을 꺼내서 늘어놓아보자.
- 일단 add 노드를 꺼내주고, 아래 null 노드를 달아준 뒤, 이름을 source라고 적는다.
- 우리가 source로 활용할 점이 solver에 의해서 애니메이션이 발생한다.
- 또 다른 점을 add로 만들어준다.
- 이 점은 어떠한 내용을 운반해주는 역할을 한다.
- 그 아래에는 null 노드를 달아주고 이름을 setting이라고 적는다.
- 지금은 별다른 것은 없다. 이쪽으로 세팅이 잡혀서 solver에 들어간다는 것을 의미한다.
solver 안에서는 어떠한 이야기를 해줘야할까?
- 먼저 속도에 대한 이야기를 해줘야한다. attribute wrangle을 만들어주자.(이름은 vel update)
- 속도는 중력에 영향을 받을 예정이기에 그것을 표현하기 위한 attribute wrangle을 만들어주자.
- solver는 결과적으로 포인트의 위치정보를 속도를 가지고 바꿔준다. 이것을 표현하기 위한 attribute wrangle을 만들어주자.
- 마지막에 꼭 OUTPUT 노드를 달아주자.
solver에 의해 포인트가 움직이는 애니메이션을 간단하게 그림으로 표현할것이다..
- 이 상황을 묘사하기 위해 어떤 내용과 세팅이 필요할지, solver 안팎에서 이야기해보자.
가정을 해보자. make it move 노드가 살아있고, 그 내용이 아래와 같다면,
@P += @vel;
우리가 가진 위치정보 @P가 @P + @vel로 갱신되는 형태라면, 소스로 제공받고있는 @vel에 의해 움직임이 발생할 것이다.
만약에, prev_frame - vel_update - make it move - OUTPUT 의 연결이 활성화되어있고, vel update의 내용이 아래와 같다면,
@vel = @vel x 0.5;
어떤식으로 애니메이션이 되겠는가?
처음에 들어온 @vel이 있고, 프레임이 바뀜에 따라 0.5씩 줄어들것이다. 줄어들고 줄어들다가 어느순간 멈춘다.
이번에는 중력이 적용되도록 해주고, 앞에서 받은 @vel에 약간의 노이즈를 추가해보도록 하겠다.
vel update는 상수를 곱해주거나 하는 것이 아닌, 임의의 노이즈를 더해주도록 한다.
- 노이즈라 함은 약간의 랜덤함을 표현해주기 위해 노이즈를 적용시켰다 정도로 이해하면 된다. ex) wind
@vel = @vel + noise;
gravity는 아래와 같이 입력해서 @vel을 갱신해준다.
@vel = @vel + @gravity;
gravity에 대한 정보는 어디에서 받아오겠는가? input 2,3,4 어디에선가 받아올 것이다.(지금은 input 2에서 받아오는것으로 가정하자)
- 받아오는 gravity에 대한 정보는 어트리뷰트가 아닌, vector gravity와 같은 변수에 point 함수를 이용해서 받게 될 것이다.
노이즈에 대한 내용은 중력하고는 관계없이 vel update에서 표현이 가능하다.
필요하다면, attribute wrangle을 vel update 위쪽에 더 달아서 wind에 대한 표현, noise에 대한 표현 등을 추가해 줄 수도 있다.
오늘의 셋팅에서 vel update에 대해서는 많이 사용하지 않을 것이다. 하지만, 7일차 수업에 쓰게 될 내용이 있을 것 같기에 attribute wrangle은 남겨두고 작업을 진행하기로 하겠다.
Input 2에서는 gravity에 대한 정보를 받아와서 속도에 적용하도록 한다.
그렇게 만들어진 @vel이 포지션의 정보에 더해짐으로써 위치변화를 만들어낼 예정이다.
소스부터 만들어보자.
점 하나를 가지고 만들것은 아니기 때문에, 처음에 만들어줬던 add1 노드를 지워주자.
그리고 sphere를 꺼내준다.
- primitive type은 polygon, frequency는 적당히 올려준다.
점을 좀 많이 만들어줄 것인데, 기본적으로는 scatter 노드를 활용해서 표면에 점을 뿌려주는 방법이 있을 것이다.
틀린 방법은 아니지만, 현재 원하는 것은 sphere 내부에 꽉 찬 점들을 만드는 것이다.
이럴때는 어떻게 하면 될까?
- volume을 활용해보자.
vdb라는 것이 이용할 것인데, 아직 우리가 구체적으로 다뤄보진 않았지만, 앞으로 volume 때문에 고통을 받을 것이다. 지금은 이런게 있구나 정도로만 따라와도 충분하다.
- vdb from polygon 노드를 활용하자.
우리가 이번에 활용할 것은 Distance VDB가 아닌, Fog VDB이다.
sphere의 안쪽에 안개가 낀 것처럼 보인다.
volume에 대한 해상도는 Voxel Size를 조절하는것으로 바꿔줄 수 있다.
- 값이 작을수록 해상도가 높아진다.
아래에 VDB Visualize Tree 노드를 달아준다.
우리가 활용할 것은 Active Voxels이다. 활성화해주자.
색에 대한 정보는 필요없기 때문에, attribute delete를 활용해서 색을 날려준다.
점이 너무 많은듯 하니, voxel size를 조금 더 키워주자(0.2)
그리고 점이 너무 고르게 분포하고 있는듯 하기에, Point Jitter 노드를 활용해서 흩어준다.
Scale 값에 따라 흩어놓는 강도를 조절할 수 있다.
- 0 : Jitter 적용 전의 모습 / 0 이상 : 점점 흩어놓는 강도가 높아진다.
이제 jitter가 적용된 포인트들을 source 노드에 연결해준다.
지금은 solver 내부에 아무런 작업을 진행하지 않았기 때문에, 플레이를 해봐도 점이 출력되기만 한다.
이제 solver 밖에서 초기속도 @vel을 만들어주자.
이 속도 @vel에 의해 solver 안에서 위치가 변하게 될 것이다.
point jitter 아래에 attribute wrangle을 추가해준다.
우리가 기대하는 것은 초기 속도가 0.1만큼 y축 방향으로 올라가는 것이기 때문에, solver가 시작되면 점들이 동시에 위로 올라가면 되는 것이다.
solver 내부로 들어가보자.
일단 vel update 노드에서는 vector attribute vel을 활용하겠다는 의미로 선언만 해준다.
make it move 노드에서는 @vel을 사용하기 위해 선언을 해주고, 모든 점들의 포지션 @P에 대해 @vel이 더해짐으로써 갱신된다는 것을 적어준다.
초기 속도를 {0, 0.1, 0}으로 설정했기 때문에 solver의 세팅이 작동함에 따라 올라가는 것이다.(매우 당연하다)
초기 속도를 {0.1, 0.1, 0}으로 바꿔줘도 잘 작동한다.
이번에는 중력에 대해서 작업을 해보자.
기왕이면 v@vel; type casting을 꼭 적어주자. 굳이 solver 안에서 type casting을 해주는 이유는 type casting을 해주지 않으면, 원하는 정보가 제대로 불러와지지 않는 경우가 종종 생기기 때문이다.
우리가 얻은 경로를 가지고 포인트들을 선으로 만들어주자.
이렇게 기본적인 세팅이 끝났다.
초기속도가 있고, 중력이 존재한다.
중력이 속도에 영향을 주기 때문에 자유낙하운동처럼 움직이는 것을 확인할 수 있다.
이제 Point gravity를 만들어볼 것인데, 어디를 어떻게 바꿔야할까? 그리고 어느정도의 힘이 어떻게 작용하는 것일까?
- 이 부분에 대한 고민을 정말 많이 해봤어야 한다.
우리가 결론적으로는 포인트의 위치 정보를 얻고 싶은 것이다.
이 위치 정보에 영향을 주는 것은 속도이다.
속도가 있음으로 위치의 변화가 발생한다.
속도에 변화가 없다면(속도가 일정하다면) 위치의 변화 또한 일정하다.
속도가 변한다면, 위와는 다른 결과를 얻게 된다.
속도가 변화하지 않는다면, 위치는 등속도 운동을 한다고 가정할 수 있다.
속도가 바뀐다면, 위치는 가속도 운동을 한다고 가정할 수 있다.
이때 속도가 바뀜에 있어서도 등가속도 운동 / 가속도 운동으로 나뉠 수 있다.
중력은 등가속도 운동이다.
- 등가속도 운동 : 속도가 일정하게 바뀌는 것
- 가속도 운동 : 속도의 변화가 일정하지 않다.
우리가 고난주간 처음에 배운 것은 속도가 일정했을 때의 위치변화에 대해 배웠다.
그 다음 속도가 일정하지 않을 때의 위치변화를 확인했다.
- 이 때 속도가 받은 힘은 일정했다. 위치의 변화는 점점 큰 폭으로 변화했다.
이제 우리가 하려는 것은 힘이 일정하지 않은 케이스에 대해 논해보려고 한다.
지면에서 각기 다른 높이에 있는 두 점 A, B가 있다. 이 두점이 지면에서 떨어져있는 높이에 따라 받는 힘이 다른가? 아니다. 중력은 높이가 어디에 있든 두 물체에 같게 작용하는 힘이었다.
@vel = @vel + @power;
우리는 속도에 관여하는 힘, @power에 대해 지금까지는 {0,-0.01, 0}과 같이 일정했다.
그런데, 이제 이 @power에 대해 다른 방식으로 규칙을 만들어준다면, 조금 다르게 표현될지도 모른다.
위와 같은 조건의 점 A, B에 대해 두 점이 가지게 될 힘에 대해 다르게 설정해줄 수도 있을 것이다. 거리에 따라 멀면 멀수록 더 큰 힘이 작용한다고 규칙이 만들어진다면, 힘은 아래와 같이 표현될 수 있을 것이다.
이렇게 되면, 힘에 의해서 발생하는 속도의 차이도 달라지게 된다.
만일 반대로 y = 0에 대해 가까우면 가까울 수록 힘이 더 크게 작용하게 된다면, 아래와 같이 표현될 것이다.
우리가 표현할 point gravity는 일종의 '힘'이다.
- 이 힘이 어느 방향으로 얼마나 강하게 작용하게 될지는 우리가 규칙을 정해주기 나름이다.
만약 각 점 0, 1, 2에 대해 빨간 점에 point gravity가 존재하고, 현재 규칙이 거리가 멀면 멀수록 강한 힘을 받는다고 한다면 아래와 같이 표현될 것이다.
그렇다면, 이와 반대되는 규칙에 대해서는 어떻게 될 것인가?
오늘 만들게 될 solver의 세팅에서는 이 두가지 방식은 이용되지 않는다.
어떤 방식으로 규칙을 만들것이냐면, 어느 지점에 포인트가 존재하더라도 'point gravity의 세기는 동일하고, 방향만 바뀐다'는 것이다.
이처럼 방향은 서로 다르지만, 크기가 같은 벡터를 만들어주려면 무엇을 활용하면 좋을까?
- normalize function을 활용하면 된다.
point gravity에서 얻은 위치정보(빨간점의 위치정보)와 prev_frame으로 얻은 각 포인트의 위치의 차이가 발생하게 될 것인데, 이것을 이용해서 방향을 구할 수 있다. 이렇게 구해준 벡터에 대해 normalize를 적용해주면, 그 크기가 1로 같고 방향은 다른 벡터들을 얻을 수 있다.
point gravity의 위치가 vector target에 할당되어있다면,
각 포인트의 위치정보 @P를 빼주게 되면 각 포인에서 point gravity를 향하게 되는 vector들이 만들어진다. 이 값을 normalize 해주면 된다.
point_gravity = normalize(target - @P);
이 값으로 @vel을 갱신할 수 있을 것이다.
@vel = @vel + point_gravity;
만약 point gravity가 너무 강해서 조절이 필요하다면, float 값(여기에서는 power)을 곱해줘서 세기를 조절할 수도 있을 것이다.
point_gravity = normalize(target - @P) * power;
와이어의 순서가 한방향으로 적용되었던 one direction gravity와는 차이가 있을 것이다.
이제 만들어보자.
point gravity를 만들기 위해 점을 하나 더 추가해준다.
그리고 그 점에 움직임을 추가해주고, solver의 input 3에 연결해주었다.
solver 내부를 세팅해주자.
이제 normalize 된 point gravity를 활용한 것, 그리고 하나는 float 값을 곱해준 point gravity를 활용한 것 이 두 경우에 대해 확인을 해보자.
어딘가를 향해 돌고 있다. 좀 더 제대로 보자.
빨간 포인트를 중심으로 돌고 있는 것을 확인할 수 있다.
두 케이스의 결과가 비슷할 것이라 예상했는데, 사뭇 다르다. 왜 그럴까? 곱해준 float 값이 작아서 그런듯 하다(0.01). 키워보자.
우리가 좀 더 다뤄보고 싶은 것은, normalize 한 식에서 힘을 바꾸게 될 경우 어떻게 될 것인가 이다.
normalize 한 결과에 float 값을 곱해보자.(또 다른 힘의 변화를 의미한다.)
끌어당기는 힘에 변화가 생겼기 때문에 이와 같은 움직임이 나타난 것을 확인할 수 있다. 좀 더 힘을 약하게 적용해보자.
solver 내부에 들어와서 숫자를 계속 바꾸는 것은 귀찮은 일이기 때문에, point function을 이용해서 solver 밖에서 숫자를 바꿀 수 있도록 수정해주자.
오늘의 내용은 사실 gravity 쪽만 살짝 바꿔주면 해결이 되는 문제였다.
실제로 그 양도 많은 편은 아니었다.
위치정보를 불러와서 빼주고, normalize 해주는 것, 이정도가 다인 문제였다.
오늘 집중하고 알려주고자 했던 내용은 힘이 일정했던 one direction gravity와는 달리 point gravity는 prev_frame의 위치정보 @P가 반드시 필요하다는 점, 그리고 매순간 다른 힘이 @vel에 영향을 준다는 것이었다.
그리고 solver 상단의 여러개의 input들에 대해 어려워하지 않았으면 좋겠다. '내가 사용할 수 있는, 내가 호출할 수 있는 정보의 창구가 많아서 좋구나' 이렇게 받아들였으면 싶다.
변수와 어트리뷰트의 차이, 애매모호하게 알고 있으면 안된다.
몇가지만 더 실험해보자.
- point gravity power에 애니메이션을 적용해보자.
- target의 지점을 바꿔보자.
- sphere의 사이즈를 바꿔줘보자(source에 변화를 줘보자)
지금부터는 어떻게 하면 더 흥미로워보일까...? 를 고민해보는 것이라고 보면 될 것이다.
일단 transform 노드를 달아서 타겟 포인트가 위로 솟구치게 만들었다.
이번엔 이 상황에서 point gravity power가 잠시 꺼졌다가 켜지도록 해보자.
중간에 파워를 잠깐 0으로 껐다가 올라갔을 때 켜는 애니메이션을 적용한 결과이다.
파워가 0이 되었을 때 라인이 밖으로 퍼져나가는 것이 보인다. (point gravity가 0으로 끌어당기는 힘이 없기 때문이다.)
다시 켜졌을 때 빨간 포인트로 끌려가는 모습이 보인다.
그리고 올라간 뒤의 회전반경이 굉장히 커진 것을 볼 수 있다.
이 반경이 큰 이유는...(어려운 내용이 될 수 있다. 감각적으로 이해를 시도해보자)
처음에 점이 발생하고, point gravity가 존재할 때는 각 점들이 빨간 점을 향해 가고 있는 중이다. 각 점에 대해 빨간 점을 향해 가는데 걸리는 시간이 적기 때문에 누적되는 속도가 작다. 여기에서 누적되는 속도가 작다는 의미는 solver 안의 point gravity 노드에 있는 식 @vel += pointgravity; 에 누적되는 속도의 양이 작다는 것이다.
point gravity가 꺼졌다가 다시 작동하기 시작했을 때, 멀리 있던 각 점들은 다시 빨간점을 향해 끌어당겨지기 시작한다. 그런데, 빨간점과의 거리가 멀어졌기 때문에, 빨간점에 도달하는 시간이 더 오래 걸리게 된다. 이 말은 누적되는 속도의 양이 크다는 의미이다. 그래서, 각 점이 빨간 점에 도달하게 된다면, point gravity가 잡아당기는 힘이 존재하지만, 이곳까지 도달하는데 발생한 힘이 있었기 때문에 더 많은 거리를 튕겨져 나가게 된다. 이 말은 곧, 돌게 되는 반경이 넓어진다는 것을 의미한다. 반경이 바뀌었지만, 어느 일정한 거리 안에서 회전을 계속 이어간다.
이제 다른 부분에 손을 대보자.
라인이 좀 더 얌전하게 움직이도록 solver 안의 vel update 노드에 손을 대보자.
앞서 우리가 만들어줬던 point gravity가 적용되는 @vel이 반으로 감쇄된다는 것을 의미한다.
velocity 자체의 사이즈를 줄이는 행위는 효과가 굉장히 적극적으로 나타난다.(0.9 ~ 1 사이의 값에 대해 눈에 잘 들어오는 결과로 나타난다.)
- 우리가 뭔가 반경을 조절해낼 수 있는 느낌이 온다.
만약 vel update 노드에서 @vel에 대해 제한을 걸어준다면 어떨까?
clamp를 활용해서 @vel이 10은 넘어가지 않도록 하거나, 혹은 1 이하의 속도는 나오지 않도록 한다면... 이런 식으로 최고, 최저 속도에 제한을 걸어줄 수 있을 것이다.
pop drag
어느 한 중심점에 대해 주변 파티클(혹은 포인트)들이 밖으로 발산될 때, 너무 멀리 발산되어 나가지 않도록 중심점의 방향으로 잡아당기는 느낌을 주는 것
(오늘 만들어준 point gravity 처럼 완전히 당기는 것은 아니다. 물론 언리얼 niagara에 drag 처럼 너무 값이 커지면 당기다못해 반대편으로 튀어나가게 하는 것도 있지만 - 이건 내 이야기)
- 아마 위의 vel update에서 이런 효과에 대해 표현해볼 수 있지 않을까?
중간고사
- solver를 얼마나 올바르게 이해했는지 여실히, 낱낱히 드러내게 될 것이다.
- 목표는 간단하다.
초기에 확 뿜어져나오다가 뿜어져나오는 수량은 좀 적어진다.
중간고사이기 때문에, 지금껏 배운 내용에서 답을 찾으려 한다면, 오산이다.
아이디어를 스스로 내보고, 직접 돌파해내야한다.
힌트
어떻게 움직이는 소스를 불러올 것인가
어떻게 점의 경로를 선으로 올바르게 표현할 것인가
어떤 규칙으로 점들이 사라지게 되는 것인가
어떻게 일렁이는듯한 터뷸런스가 존재하는 것인가
이런 질문들을 스스로에게 하고 해결해내야한다.
말로 설명할 수 있다면, 만들 수 있다.
쉬운 길 택하지 말고, 부딪혀서 꼭 이뤄내자.
숙제)
잘 보면 점들이 뿜어져나오는 것이 일자가 아니고 마치 random한 아우라처럼 구불구불 거린다.
- 일단 꾸물텅거리는 오브젝트를 만들어보자.
- attribute noise로 느낌 내주다가, attribute vop 활용해서 turbulence noise로 적용해주었다.
- 오브젝트를 라인으로 연결해주자.
- 뭔가 각 포인트에서 조건을 달아서 가까운 포인트와 본인이 연결이 안되었으면 라인을 추가해주는 것으로 해서 할 수 있을 것 같은데, 현재 머리가 너무 안돌아가는 관계로, 일단 오브젝트에 wire 노드를 달고 color 노드를 달아서 비슷하지만 비슷하지 않게 느낌을 내보았다.
- 포인트가 뿜어져나온다.
- 이거는 일단 solver 안에서 scatter를 달아서 해결했다. solver의 첫번째 input에 초기 sphere에 scatter로 포인트를 뿌려준 것을 연결해주고, 두번째 input에는 sphere에 움직임을 적용한 오브젝트를 연결해주었다. 일단 scatter 자체는 뿌려줄 면이 없으면 점이 생성되지 않는 것 같다는 것이 작업하다가 알게된 것이고, 그렇기 때문에 두번째 input에는 오브젝트를 꼭 연결해준다.
- solver 내에서는 조금 더 랜덤하게 나오는 것이 좋겠다 싶어서 attribute noise를 달고, color 값에 영향을 받아서 scatter의 밀도가 결정되도록 세팅해서 달아주었다. 이렇게 만들어진 포인트와 prev_frame 노드를 merge로 묶어주면 시간이 흘러감에 따라 solver 내부에서 계속 scatter가 돌아가고, 포이트가 생성되었다.
- 뿜어져 나오는 것은 초기 @vel을 적용해주고, 이것저것 만져보다가 solver 내부에서 attribute vop을 활용해서 turbulence noise를 적용해줬다.
- 구현해야 할 것들
- 아직 팍 사라지는 것도 구현못했고, 포인트 수량조절도 구현 못했고, 각 포인트마다 라인으로 연결해주는 것도 구현 못했다.
2차 수정)
- 스위치를 사용해서 각 오브젝트가 특정 구간에서 나타나도록 하였다.
- 스위치 value 적는 곳에 if 조건문 활용해서 특정 프레임 전까지는 sphere가, 중간은 box, 이후에는 toy가 나오도록 조절해주었다.
- 초반 initial vel에 대해 방향을 만들어주는 과정에서 각 오브젝트의 위치가 옮겨지니까 원점에서부터의 방향을 가지게 되어서 스피어, 토이는 옆으로 쏠려서 바람맞는것 마냥 포인트가 뿜어졌었다.
- 그래서 바운드 노드를 활용해서 오브젝트의 중심점을 구하고, 각 포인트에서 중심점 위치정보를 빼줘서 초기 방향을 잡을 수 있었다.
- 포인트에 수명을 부여해줬다.
- 언리얼에서 파티클에 라이프를 부여해서 사라지게 하는것이 있어서 유사하게 따라해보았다.
- solver가 작동을 시작하면 i@age를 생성하고 그 값이 solver가 반복될때마다 1씩 추가되도록 @age++; 해줬다.
- 그리고 if 조건문으로 @age가 10 이상이면, 약간의 랜덤성을 부여하기 위해서 rand function을 활용해서 대략적으로 세가지 분류로 나뉠 수 있도록 조작해준 뒤, 그 중 하나의 분류는 removepoint로 날려버렸다.
- solver가 반복되면서 @age가 10 이상인 포인트들은 다 저 조건으로 판단받고 날아가고, 살아남는 무서운 환경이 만들어졌다.
- 아쉬운 것은 초기에 @age를 할당해줄 때 solver 횟수가 같을 때 생성되는 포인트들은 전부 똑같은 age를 부여받게 되는 것이 아쉽다면 아쉬운 부분이었다. 이것도 약간의 범위를 적용해줘서 시작부터 0 ~ 3 사이의 age를 가지고 값이 증가할 수 있었을텐데, 이 부분은 나중에 적용해봐야겠다.
어제의 과제는 뭔가 아쉽다.
볼륨을 활용해서 포인트를 스피어 내부에 채워주는 것, 한발자국만 더 나가면 나도 할 수 있었는데... 볼륨을 활용해야 할 것 같은데...? 여기에서 멈춰버렸다. 나약한 녀석...
중간고사는 지금 감도 안잡힌다.
solver를 이해하지 못한 것인가...
하루종일 후디니만 붙잡고 씨름하고 싶다...
일단 차근차근 중간고사 과제 만들어보기를 시작해봐야겠다.
공부를 헛한것인가... 후디니 툴에는 익숙해졌다 라는 느낌이 드는데 아이디어랑 머리는 안굴러간다... 머리가 많이 굳었나보다 ㅠ