본문 바로가기
회사 TIL

[TIL] 22.12.09 / 레버 돌리기, 종합 수학 개념들

by imagineer_jinny 2022. 12. 10.

TIL (Today I Learned)

 

오늘 해야할 것

  • RollerBase 코드 보고 어떤 메쉬를 회전 시키는지 확실히 그림 봐가면서 비교하기
  • Finger point 방식이랑 Grab 방식이랑 잡는 방법이 다르다는게 문제인데, 이 부분 코드를 자세히 보기
  • Lever Mesh(Grab)에  Rotate 코드 적용시키기
  • 레버에 잘 안돌아가면/잘 돌아가면 RollerBase랑 비슷한 메쉬(혹은 같은거)로 시도해보기

 

오늘 한 것

  • 회전 구현...

 

오늘 배운 것

  • 레버를 Y축을 중심으로 돌리고 싶었던 상황이 있다. 어떻게 돌려야할까?

이 때 외적과 내적을 쓴다.  

구현 방법을 생각해보면, 

얼마정도 돌리고싶다 -> 이 필요함 -> 내적으로 구한다

어느 방향으로 돌리고 싶다 -> 방향이 필요함 -> 외적으로 구한다

 

레버 끝을 잡고 핸들 돌리듯 돌리는거면 변하지 않는 중심 축이 있어야 한다는 생각은 할 수 있을 것이다.

만약 레버에 중심축을 둔다고 생각하면 레버는 회전하면서 계속 축들이 바뀌기 때문에 기준 점이 되기 힘들다.

그래서 Base Mesh를 활용하는거다. 

Base Mesh가 시계 중심 같은 역할을 하도록.

 

 Base Mesh에도 x,y,z축이 있다. 여기서 우리는 파란색 z축을 사용할건데 이걸 코드에서 baseMesh -> GetUpVector()로 표현한다. 위를 향하고 있으니 이 벡터의 UpVector라고 생각하면 될것이고 밑에 나오겠지만 빨간 x축은 GetForwardVector()를 이용해서 구한다(전체 코드 사진에서 87번 주석처리된부분)

 

FVector meshToHandDir = _handSocketRef->GetComponentLocation() - _baseMesh->GetComponentLocation(); //1
FVector meshForwardDir = _baseMesh->GetUpVector(); //2
meshToHandDir.Y = 0;
meshForwardDir.Y = 0;

 

 Y축은 왜 0으로 해주지?

순수하게 Y축 기준으로 돌리려면 Y축을 0으로 만들어놓고 2차원에서 돌려주는 것이 계산이 편하기 때문.

 

 

Cross_VectorVector에서 왼쪽에 있는 meshToHandDir, 오른쪽에 있는 meshForwardDir를 생각해보면 v의 방향은 어디인가? 

벡터의 외적은 교환법칙이 성립하지 않는다는 중요한 특징이 있다. 

이 말은 무슨 말이냐면 Cross_VectorVector(meshToHandDir, meshForwardDir);이랑 

Cross_VectorVector(meshForwardDir, meshToHandDir);이랑 결과 값이 다르다는 것이다.

//외적으로 방향 구하기
FVector v = UKismetMathLibrary::Cross_VectorVector(meshToHandDir, meshForwardDir);

 여기까진 이해했는데 결과 값이 뭐 어떻게 다른데? 라고 생각할 수 있다.

 

1과 2를 외적하면 1이 먼저 2가 나중이니까 방향이 반시계 방향이다. -> 외적한 v 값은 -값(질문하기)

 

1과 2를 외적하는데 이번엔 1이 2보다 왼쪽에 있고 1에서 2로 가는게 시계 방향이다 -> 외적한 v값은 +값 

 

이번엔 식을 바꿔보자

//외적으로 방향 구하기
FVector v = UKismetMathLibrary::Cross_VectorVector(meshForwardDir, meshToHandDir);

 

1과 2를 외적하는데 1에서 2로 가니까  시계 방향이니까 -> 외적한 v값은 +

 1과 2를 외적하는데 1에서 2로 가니까 반시계 방향이니까 -> 외적한 v값은 -

 

그래서 이 식이 탄생하는것이다. 

// 내적으로 각도 구하기
double angle = UKismetMathLibrary::Abs(R1Math::GetAngleBetweenTwoVectors(meshToHandDir, meshForwardDir));

if (v.Y < 0)
	_mesh->SetRelativeRotation(FRotator(-angle, 0, 0));
else
	_mesh->SetRelativeRotation(FRotator(angle, 0, 0)); //AddRelativeRotation

angle은 절댓값 씌워서 무조건 양수이고,

외적 값이 -이면 각도 -, 외적 값이 +이면 각도 +

 

FRotator안에 angle은 왜 x축에 있는지 생각해보고, GetAngleBetweenTwoVectors도 보고 이해해보자.

SetRelativeRotationAddRelativeRotation도 찾아보자.

 

double R1Math::GetAngleBetweenTwoVectors(FVector a, FVector b)
{
	a.Normalize();
	b.Normalize();
	double rad = UKismetMathLibrary::Acos(a.Dot(b));
	return UKismetMathLibrary::RadiansToDegrees(rad);
}

 

  • Forward Vector로 바꾸면 angle에 -90을 해줘야했다. 왜 그랬을까?

 

  • 기능 구현하려 할 때 코드만 보지 말고 BP 창 켜서 그림 그려가면서 이해하기.
  • (언리얼에)축은 어디를 가리키고 있는지, 절대좌표, 상대좌표 신경쓰면서!
  • 월드좌표, 로컬 좌표 개념

 

오늘 느낀 것

  • 못하는 건 어쩔 수 없고 다음에 똑같은 거 할 때 잘하면 되지 않을까.
  • 조급하면 할 줄 아는것도 못하거나 느리게 하는 것 같다. 하지만 마인드 컨트롤이 쉽지 않다.
  • 수학 개념들 외우려하지 말고 정말 이해를 하고 적용을 많이 해보자. 못하겠으면 문제라도 풀자.
  • 강의 듣는 코드들도 생각없이 따라치지 말고 생각을 하고 따라 치자.
  • 지금보다는 대표님/기획자님한테 약간 더 물어보는게 좋을 것 같다. 가만히 질문 안하고 있으면 그만큼 기대감만 쌓인다. 질문을 빨리 할 수록 실망이 없다. 중요한건 결과..!!
  • 조금은 더 먹으려고 하자. 체력에 먹는것도 중요하다.

 

다음주에  진행할 것

  • 수학 잘 복습해서 가기
  • 롤러베이스에 배운것 적용해서 검사 받기
  • 롤러베이스 vs 레버 차이점 생각해보기
  • 오늘 정리한 것 설명해보기
  • 과제 : UpVector를 Forward 벡터로 바꿔서 돌아가게 만들기.

 

앞으로 진행할 것

  • 오큘러스 내 빌드 해결
  • SCP 914 찾아보기

https://www.youtube.com/watch?v=-9rbYP0cDjU 

https://www.youtube.com/watch?v=V2Ps5bM4TwE 

  • 회전 공부하기
  • 체력을 위한 운동...
 

댓글