목차
- 고난주간1일차 숙제 설명
- 오늘의 숙제
- 일기
본인이 직접 시도해보지 않는 것은 강의가 아무런 의미가 없다.
작업에 대한 접근 자체가 막막하다면, 떠오르는대로 해결해야하는 요소를 다 써보자. 그러면 무엇이 더 급한 내용인지, 작업에 대한 순서를 어떻게 나열을 할지, 상대적으로 금방 떠오를 수 있다. (혹은 내가 현재 필요한 기술이 무엇인지, 아니면 필요를 위해 무엇부터 공부를 해야하는지)
Interval - 오늘의 중요 포인트
일단 interval을 고정하고 작업을 진행해보자(선생님은 5로 고정)
solver는 어떤 판단을 스스로 해줘야할까?
이전 프레임과 비교를 해서
- 방향전환을 할 것인가
- 방향을 유지하면서 그대로 진행할 것인가
방향을 유지하다가 인터벌 타이밍이 되면 turn을 하게 된다.
turn에 대해서는 일단 상하좌우, 이렇게 네 가지 선택지가 있다
- 이 선택에는 약간의 랜덤성이 필요하다. 그렇지 않으면 모든 프레임이 같은 타이밍에 같은 방향으로 turn을 하게 되기 때문이다.
오늘의 구현 순서
1) 각각의 포인트가 서로 다른 방향으로 이동하는것을 구현해보자.
- 이 방향은 solver 바깥에서 vector 정보로 정의내릴 것이다.
- solver 밖에서 solver의 두번째 input으로 상하좌우 네가지 vector 정보를 넣어준다.(initial한 정보)
2) interval을 통제해줄 것이다.
- count를 만들어줘서, 인터벌이 발생할 때마다 카운트를 올려주고, 이 카운트의 숫자를 보고 solver가 이번 프레임에 방향을 틀 것인지, 킵을 할건지 판별하도록 해주자.
ex) interval이 5일때,
TKKKK / TKKKK / TKKKK
count1 / count2 / count3
이런식으로 카운트 숫자에 변동이 있을 때 Turn을 해주는 것이다.
선생님은 count만 사용하신 것이 아니고, prev_count라고 이전 프레임에서의 count 숫자와 같이 비교를 한 뒤, count와 prev_count가 같으면 keep, 다를 경우에 turn을 하도록 하였다.
3) 하나의 점에 인터벌에 따라 랜덤하게 움직이도록 적용을 해보자.
4) 여러 점에 동시에 작동하도록 만들어보자.(이때는 seed가 필요하다)
5) 움직임을 디자인하자.(움직임에 제한이 필요하다)
오늘은 조건문이 좀 많아질 뿐이다.
add로 점을 만들고, solver를 달아주자.
일단 벡터로 방향을 만들자.
add로 점을 만들고, attribute wrangle을 달아서 solver의 두번째 input에 넣어준다.
여기에서는 상하좌우에 대한 정보를 만들어줄 것이다.
v@right = chv("right");
v@left = chv("left");
v@upp = chv("upp");
v@down = chv("down");
◎ up 벡터가 존재하기 때문에, 그냥 v@up으로 만드는 것은 의도치 않은 결과를 가져올 수 있으므로 뒤에 p를 하나 더 적은 어트리뷰트 이름을 만들어줬다.
solver에서 이 내용을 point function을 활용해서 불러오자.
v@move라는 어트리뷰트를 만들고, 사용할 수 있도록 해주자.
조건문을 활용해서 @move에 네가지 벡터중 하나가 들어갈 수 있도록 해주자.
조건을 판별하기 위해, i@pick을 만들어주자.
각 점들이 서로 다른 pick을 가지고 있다면, 이동하는 방향이 각각 다를 것이다.
- 랜덤한 값을 만들기 위해 rand()를 사용해주자.
rand()를 자주 사용하다보면 어느정도 정형화된 값이 보인다.
- ex) rand(@ptnum)의 값이 예측이 된다.
그래서 rand()를 사용할 때는 꼭 seed를 만들어주는 것이 좋다. 그렇게 되면 굉장히 유니크한 다른 값을 가질 수 있는 기회가 생긴다.
4를 곱해주게 되면, 0~1사이의 값을 가지고 있던 rand 결과가 4배 증폭되게 된다(마치 fit function에서 증폭 최솟값을 0, 최댓값을 4로 한것 처럼)
그렇게 나온 float 값을 floor 함수를 사용해서 integer로 변경해준다. 소수 부분을 떼어네고 0~3의 정수만 남게 된다.
이렇게 solver에 들어가기 전에 초기 방향이 랜덤하게 결정되었다.
언제 어떤 타이밍에 solver가 방향 전환을 하게 할 것인지를 만들자.
핵심 키워드는 interval, count이다.
이에 따른 keep, turn도 만들어보자.
i@Count = floor((@Frame - @Startframe) / interval);
i@prevCount = floor(((@Frame-1) - @Startframe) / interval);
if(@Count == @prevCount){
s@condition = "keep";
}
else{
s@condition = "turn";
}
이제는 주어진 컨디션에 따라(keep/turn) 우리가 가지고 있는 어트리뷰트 pick이 바뀔 때이다.
solver 내부에서 @pick으로 인해 방향을 설정하게 되는 wrangle 노드 dir 윗선에서 condition에 따라 @pick을 변경할 것인지, 그대로 유지할 것인지를 판단해줘야한다. 판단한 정보를 가지고 아래쪽 노드에서는 움직이기만 하면 된다.
이 때, 기존의 dir의 두번째 인풋에 연결되어있던 라인을 끊으면 안된다. dir 노드의 point function이 작동하지 않는다. 불러온 내용이 어트리뷰트로 남아있는 상황이 아니라면, 이런 부분은 잘 체크해주는 것이 좋다.
조건문에서 스트링 변수 이용에 문제는 없으나, 조건문이 잘 작동하지 않는 느낌이 들 수 있다. 그러므로, condition을 string에서 int형으로 바꿔줘서 불러오자.
condition == 0, 즉 이전 프레임과 현재 프레임의 카운트가 변동이 없을 때는 pick에 별다른 변화없이 계속 작업이 수행된다. 하지만 카운트의 변동이 발생할 경우에는, @pick에 변화를 주는데, 위에서 설명했던 방식과 같이 랜덤함수를 이용해서 값을 만들고, 4를 곱해서 증폭시킨 뒤, floor 함수를 사용해서 정수로 변환해준다.
Trail node
- Trail length - 현재 프레임부터 몇 프레임 뒤까지 볼 것인가.
- ex) Trail length = 2 > 주어진 정보의 현재 프레임과 이전 프레임을 보겠다는 것
이렇게 만들어진 점을 add를 활용해서 선으로 표현한다.
- 하나의 점에 트레일을 달면 잘 출력되지만, 여러개의 점으로 표현할 때는 뭔가 기하학적인 무언가가 출력된다.
- 그 이유는 포인트 넘버 순서대로 다 선으로 이어졌기 때문이다.
- 만일 점이 25개가 있다면, 트레일이 없었을 경우에는 0번부터 마지막 점 24번까지 연결이 되고, 트레일이 생길 경우, 0번부터 24번이 연결된 뒤, 한 프레임 이전의 점이 생성되면서 25번부터 49번이 된다. 이것들이 다 연결되기 때문에 뭔가 기하학적인 무언가가 출력되는 것이다.
이것을 방지하기 위해 포인트에 id를 부여하고, 같은 id를 가진 포인트만 add 노드에서 attribute name으로 by group해주어 선으로 만들어주면 우리가 원하는 결과를 얻을 수 있다.
이제 움직임에 대한 디자인을 해주자.
선생님의 작업예시는 180도를 돌아 뒤로 가는 것은 없다.
현재 우리 작업물은 뒤로 돌아가는 것이 존재한다.
이 부분에 대해 수정을 해주자.
solver 안에서 condition을 가지고 pick을 변경해주는 노드를 수정해주자.
우리가 말로 표현이 가능하다면, 조건들이 머릿속에 떠오르고 있는 것이다. 다만 풀어쓰는 연습을 해본 적이 없어서 막막해 하는 것일 뿐. 같은 뉘앙스인데 반대표 표현을 해보자면, 우리가 어떤 현상을 구현하고 싶다면, 논리적으로 말이나 글로 표현이 가능해야한다. 규칙이 말로 설명이 안되는데 그것은 절대로 만들 수 없을 것이다.
오늘의 숙제
벽에 부딪히면 튕겨져나가는 포인트를 만들어보자.
어떤 벽이 있는 것 처럼 상황을 주고, 포인트는 이 안에서 튕기듯이 움직일 것이다. 기왕이면 움직이는 방향도 바꿀 수 있을 것이다.
회사 끝나고 집에 오면서 열심히 고민하다가 든 아이디어는...
- 좌우 상관없이 x의 한계선에 점이 닿으면 x의 방향이 바뀐다(부호가 바뀐다. 양에서 음으로, 음에서 양으로)
- 상하 상관없이 y의 한계선에 점이 닿으면 y의 방향이 바뀐다(양에서 음으로, 음에서 양으로)
그래서 일단 그 부분에 대해 구상을 해보았다.
점을 만들고, attribute wrangle을 달아서 vector 어트리뷰트 dir을 만들었다. 그리고 v@dir에는 channel vector를 활용해서 점의 이동방향을 사용자가 입력할 수 있도록 하였다. 이렇게 만들어진 정보는 solver의 첫번째 input으로 들어갔고, 두번째 input에는 네가지 값(x 한계값, y 한계값 각각 두개)을 만들어서 solver에 연결해주었다.
solver 안에서는 attribute wrangle을 두개 달아서 prev_frame 바로 아래에서 direction에 대한 판별을 하고, 판별을 한 뒤 다시 정해진 v@dir 값을 가지고 계속 @P의 값을 갱신해주도록 하였다.
코드 내용은 정말 별게 없다. solver 밖에서 사용자가 입력해준 x, y의 한계값을 포인트 함수를 사용해서 가지고 온다. 그리고 점의 포지션에 대해 한계값 안에서 있을 때는 아무런 작업을 수행하지 않고, 한계값을 벗어났을 때 판별을 진행해준다. x의 한계값이 넘어섰을 경우에는 x의 부호를 바꿔주고, y의 한계값을 넘어섰을 때는 y의 부호를 바꿔준다.
근데 영상을 잘 보면 한계값으로 그어준 선을 넘어섰다가 방향을 바꾸게 되는 일들이 자주 발생한다. 초기 방향에 대한 vector값을 크게 잡으면 그것은 더욱 두드러지게 나오는데, 이 부분에 대해서는 고민이 필요하다.
어제 고난주간 숙제를 진행하면서, 조금 지저분하게 코딩이 되긴 했지만, 그래도 결과는 만족스러운것 같다 라는 생각을 잠시 했었다. 하지만 오늘 선생님의 강의를 보면서 더욱 단단하게 표현되는 VEX와 노드들의 구조들을 보면서 아... 만족은 아직 세상 먼나라 이야기이구나 하고 생각했다.
끊임없이 고민하게 되는 후디니가 좋다. 고민이 해결되고 내가 원하는 결과가 출력되었을 때의 기쁨이 매우 커서일 것이다. 마치 어려운 수학문제를 끙끙거리면서 풀어냈을 때의 성취감과도 같은 기분.
한가지 고민 아닌 고민이라면, 이것은 옛날 옛적에 프로그래밍을 할 때도 생각했던 부분인데, 내가 구현하는 VEX가 맞을까...? 하는 고민을 하게 된다. 결과는 나오게 되고 얼추 100까지는 못가더라도 80은 나오는것 같다... 할 수 있지만, 저 80을 출력하는 VEX는 맞게 구현이 된 것일까...? 하는 의문이 들 때가 많은데, 이것은 내가 많이 해봐야 감이 생기는 것이겠지...?
'Houdini > Houdini1_Starter' 카테고리의 다른 글
STARTER09_고난주간 4일차 (0) | 2023.01.25 |
---|---|
STARTER09_고난주간 3일차_Bounce with Solver (0) | 2023.01.21 |
STARTER09_고난주간 1일차 (0) | 2023.01.19 |
STARTER08_Solver (1) | 2023.01.18 |
STARTER07_Block 반복 작업을 위하여 (0) | 2023.01.16 |