flip-flop, Cache Memory
capacitor + transistor, Main Memory, refresh
fixed size blocks
오늘 : TIL 정리하기
이슈 : AI 스터디 이번주에 하면 듣고싶다
장르 : 2D 전략
출시 : 2001.10.16
시점 : 탑뷰
목표 : 물풍선을 터트려서 상대방을 없애기
상하좌우로 움직이면서 물풍선을 놓기
→ 부실 수 있는 블록을 부수기
→ 랜덤한 확률로 부서진 블록에서 돈 / 아이템을 얻기
→ 상대가 터진 물풍선에 갇히도록 물풍선을 놓기
드랍되는 아이템, 맵의 구성, 플레이어의 속도 등으로 난이도를 조절한다.
플레이어가 물풍선으로 다른 유저를 다 죽임 → WIN
플레이어가 다른 적보다 먼저 죽음 → LOSE
Stage를 진행하며 적의 숫자, 적의 생명으로 난이도를 조절한다.
여러 명의 유저가 한 게임에 매칭해 난이도를 조절한다.
장르 : 2D 전략
시점 : 탑뷰
유사한 게임 : 봄버맨 https://namu.wiki/w/봄버맨(패미컴)
Map Tool
AABB
OBB
A* algorithm
follow player
PerspectiveFov UI
Ortho UI
Mouse Icon
Map
NevMesh
Object
Component
Sprite
Transform
Collider
Save
Load
언리얼 표준 따라가기
이서영 - 프로그래머
김형환 - 프로그래머
김정우 - 프로그래머
int& : Lvalue reference
const int& : const Lvalue reference
int&& : Rvalue reference
Lvalue / Rvalue 둘 다 담기
Rvalue 일 때 임시 객체의 lifetime이 reference 에 맞게 늘어난다
Rvalue 함수의 인자로 보내기 O
call by ref → 값 복사 X
move semantics
rvalue : const / non const
int& : reference를 리턴 / Lvalue
int : 값을 리턴 / Rvalue
존재하지 않는 것을 가리키는 것
범위 넘어가거나 delete처리 되었을 때
Alias
리소스의 lifetime을 object의 lifetime에 묶는다
std나 smartpointer로 직접 new delete 하지 않게 한다
오브젝트를 표현하는 크기
ray-intersection 테스트에 bounding volume 쓴다
각 축에 평행한 상자를 만들어서 충돌 체크하기
모든 축에 대해 A.max ≥ B.min 인지 체크하기
→ 한 축이라도 A.max < B.min || B.max < A.min 이면 충돌 안함
회전된 상자가 충돌했는지 체크한다
박스A X/Y/Z + 박스B X/Y/Z + CrossProduct XX/XY/XZ/YX/YY/YZ/ZX/ZY/ZZ
convex shape에서 겹친 부분 찾기
두 개의 도형을 투영한 축에서 하나로도 겹치지 않으면 겹치지 않은 도형이다
그림자로 두 상자를 비춰서 2차원에 투영하기 → dot product로 각 축에 대한 scalar 값으로 바꾼다
1차원으로 줄여서 scalar 값 이용하기
A의 평면 3개 → 1차원 해당 평면의 Normal에 대한 값
B의 평면 3개 → 1차원 해당 평면의 Normal에 대해 값이 0
A Edge 경우의 수 3개 X B Edge 경우의 수 3개 → 두 Egde에 대해 외적해서 Normal을 만든다 : 두 Edge로 하나의 평면을 만들어서 체크한다 = 3차원을 1차원으로 만든다 → OBB랑 동일하게 모든 A B의 Vertex에 대한 min max 구하기
두 개의 오브젝트가 투영한 값이 겹치지 않는 축 → 볼록한 도형이면 충돌하지 않았다
각 Edge의 노말 벡터가 체크해야하는 방향 벡터이다
A 평면의 Normal 3개 + B 평면의 Normal 3개 : 평면에 닿을 때 체크
모든 축에 대한 Cross Products : Edge - Edge일 때 체크
Convex 두 개가 교차하지 않으면 두 개를 나누는 hyperplane이 존재한다
8각형 / 8면체로 된 Bounding Volume
같은 방식으로 Normal을 축으로 해서 그 축에 대해 DotProduct해서 min max 겹쳐있는지 체크한다
가장 바깥의 Vertex들을 감싸는 Convex를 만든다
같은 방식으로 각 노말을 축으로 해서 모든 축에 대해서 겹친지 체크한다
입력을 객체로 캡슐화 할 때 / 실행취소, 재실행
간단한 작업 만들 때 / 자원관리, 충돌감지
이벤트 시스템, 상태변화 감지할 때 / 객체간의 상호작용 관리, 업데이트
동적으로 생성되는 캐릭터, 아이템 / 기존 객체 복제해서 만들 때
리소스 관리자, 로그 기록 / 단일 인스턴스 유지하는 객체
캐릭터의 상태변화 / 상태 전환 → 상태마다 특정 동작 수행할 때
게임 특정동작, 이벤트 처리 순서대로 할 때
요청 보내는 오브젝트 - 받는 오브젝트 디커플링 : 여러 오브젝트가 요청 처리하도록 허용
버퍼써서 깜박이지 않게 할 때 / 화면 렌더링
게임 로직 실행 / 입력처리 → 물리 시뮬레이션 → 그래픽 업데이트
input processing → game logic → physics simulation → graphics update
LateUpdate : 오브젝트들이 Update에서 Transform 처리한 후 해야하는 Physics LateUpdate에서 처리한다
BeginPlay() → Tick() → EndPlay()
객체의 상태, 동작을 주기적으로 업데이트 / 이동, 애니메이션
AI 동작, 플레이어 상호작용 / 복잡한 동작, 상호작용
게임엔진, 스크립트 엔진 / 실행가능한 상태로 변환해서 실행
외부에서 악의적인 코드 실행 방지할 때 / 하위 클래스 권한 제한
동적 타입 시스템, 객체 동작 / 객체의 타입에 따라 동적으로 행동, 속성 변경
Runtime에 객체의 타입을 체크한다
오브젝트의 포인터 / 타입 인자로 받아서 해당하는 오브젝트 포인터나 nullptr로 돌려준다
컴포넌트의 의존성 낮추기, 유연성과 재사용성 높일 때
이벤트 처리, 메시지 전달 / 비동기적인 상호작용 구현할 때
서비스 간의 통신, 상호작용 관리할 때
model : 데이터, 비즈니스 로직
view : 유저에게 데이터 보여준다
controller : 유저의 input 처리해서 모델과 뷰를 업데이트한다
알고리즘, 자원관리, 그래픽 처리 최적화할 때
Single Responsibility : 하나의 클래스는 하나의 기능을 맡기
Open-Closed : 기존 코드를 변경하지 않고 기능 추가하기
Liskov Substitution : derived가 base를 포함하게 만들기
Interface Segregation : 필요한 Interface만 넣기
Dependency Inversion : 아래 레이어 - 위 레이어를 직접 연결하면 아래 변경하면 위에도 변경한다 → abstract 한 중간 레이어 만들기
cache hit 늘리기 위해 데이터 모을 때
필요한 부분만 업데이트 할 때
자주 생성, 삭제되는 객체 재사용 할 때 / 생성, 삭제 비용 줄이기
오브젝트가 크다
생성/ 소멸자에서 하는 일이 많다
힙에 메모리 올리고 내리고 하면 Fragmentation 발생한다
constructor / initalizer 분리하기
충돌감지, 시야 계산 / 공간을 분할하기
격자 만들어서 체크하기
공간을 N개씩 나누어서 트리 구조로 저장해서 충돌 가능성 있는 것들을 나누어서 체크하기
그리드 방식인 이차원 배열 → 해시테이블을 이용해 유연한 사이즈 사용해서 체크하기
D2D 솔루션 -D2DApp -D2DEngineStaticLibrary 프로젝트 생성하기
빈 실행 EXE 넣기
전에 만든 프로젝트 삭제
현재 솔루션 필요없는 리소스 삭제
D2DEngine 필터 만들어서 저장하기
🔨 Static Library로 Engine 빼기
230613_D2D_lib_primitive
🚧 프로젝트 복사해서 3에 올리기 / 충돌하기 위해서 수학 관련 파일들 생성하기
🚧 D2DEngineStaticLibrary/MathUtility.h
🚧 수학 연산들 추가하기
()이 함수 declaration으로 파싱된다
{}은 더 큰 타입에 자동으로 형변환이 안된다
Actor를 움직인다
FTransform / TransformCalculus.h
Matrix.h / FMatrix
Scale → Rotate → Translate
transform 3 / rotation quaternion 4 / scale 3
쿼터니언
point - point : vector
vector + point : vector
point + point : ERROR
같은 공간의 다른 점들로 매핑한다
local → world → camera → projection
(x/w, y/w, z/w)
A 에서 B로 가는 벡터 : -A +B
O(N^3)
Transform.h : FTransform
Quat.h : FQuat
Matrix.h : FMatrix
TransformVectorized.h : FTransform
RotationTranslationMatrix.h : FRotationTranslationMatrix
RotationAboutPointMatrix.h : FRotationAboutPointMatrix
ScaleRotationTranslationMatrix.h : FScaleRotationTranslationMatrix
*는 해당 Class 주소를 담는 포인터를 선언한다
variable : 각 instance에서 자신의 copy value를 갖고있다
function : text segment에 저장된 내용을 pointer에 저장된 주소로 따라가서 호출한다
stack frame : 하나의 함수 호출에 대한 정보를 가진다
call stack : 하나의 프로그램에서 실행중인 함수들을 스택을 이용해서 저장한다
컴파일러가 obj의 주소를 함수에 argument로 넘긴다
매개변수, 멤버변수 변수명 같을 경우
컴파일러가 address를 argument로 넘기는 코드를 만든다
data segment에 저장된다
멤버 변수의 사이즈
가상테이블 포인터 사이즈
base class에서 virtual 키워드로 써있어서 derived에서 override 할 수 있다
오브젝트가 dynamic type에 맞게 동작하게 한다
여러 타입을 generic 하게 쓰기
virtual function + dynamic dispatch
컴파일타임에 정확한 타입 몰라도 된다
함수 포인터를 배열로 저장했다
read-only memory에 저장되어 있다
virtual function을 가진 하나의 클래스의 하나의 vtable을 갖고 있다
virtual function : runtime polymorphism을 하기 위한 interface
dynamic dispatch : 적절한 함수를 런타임에 고르는 방식에 대한 구현
함수를 호출할 때 어떤 함수인지 메모리를 할당하는 것
compile time에 필요한 함수 바인딩 / virtual function이 아닌 member function
runtime에 함수 바인딩 / virtual function
base pointer / ref일 때
base pointer가 derived 오브젝트를 가리킬 때
base class의 member + virtual function만 접근할 수 있다
derived에 destrctor 있어도 base의 destructor만 부른다 → new 한 메모리 delete 안함 → memory leak
이서영/DynamicArray2.cpp
✨ D2DEngineStaticLibrary/Vector2D.cpp
이서영/DoublyLinkedList.cpp
✨ D2D/D2DEngineStaticLibrary/Object.cpp SetPosition
TODO: GameProcess.cpp 에서 전체 프로세스 돌리기
🐛 include 문제 -> pch.h 만들기
벡터의 크기가 1인 벡터 == Normalize() 한 벡터
방향에 대한 값만 이용하기 때문이다\
B에서 A로 가는 벡터
벡터의 방향성이 사라지고 크기값만 남는다
연산 비용 싸다 : 곱셈 3번 + 덧셈 2번 → |a| |b| cos(seta)
단위벡터면 |a| == |b| == 1 이여서 cos(seta) 얻는 연산 → 두 벡터 사이의 관계
값 1 → 동일한 단위벡터 / 값 0 → 직교
Diffuse = N * L
N * C > 0 → 메시의 뒷면 : 뒷면 안 그릴 수 있다
N * C = 0 → 메시의 윤곽선
시선 벡터에 따라서 외곽선을 그릴 수 있다
근사값 사용한다
N * C < 0 → 메시의 앞면 : 앞면 보여서 그려야 한다
카메라가 빛을 준다
캐릭터의 방향을 클릭한 그 위치 방향으로 회전시킨다
Direction * Target = cos(seta)
왼쪽 오른쪽 외적으로 판단
내적해서 cos(seta) 값을 구했는데 여기서 seta를 구해야 한다
arcos(cos(seta)) → seta
두 벡터 모두에 수직인 벡터 구하기
연산 순서에 따라 방향이 바뀐다 → 교환법칙 X
부호가 나온다
Normal Vector = U X V
Light Vector 값이 너무 커지면 하얗게 된다 → 0 ~1
✨ CollisionCheck_CC D2D/D2DEngineStaticLibrary/Object.cpp
✨ CC D2D/D2DEngineStaticLibrary/Object.cpp
🚧 AABB
✨ AABB D2D/D2DEngineStaticLibrary/Object.cpp
함수가 object의 member var을 바꾸지 않는다
함수 호출할 때 this pointer 쓴다 거기에 const qualifer 붙혀서 포인터를 const object로 바꾼다
→ this pointer로 member 변수 못 부르고 const 아닌 member 함수 못 부른다
read-only
const member function 만 쓸 수 있다
block scope
원래 object 사라지면 dangling reference
여러 ref가 동시에 접근해서 쓸 때 aliasing 조심하기
Overriding X / Dynamic binding X
객체의 멤버 X / class 기반 O
전역변수와 동일 / 클래스명으로 접근해야한다
this X / instance variable X / overriding X
🐛 SetOBB에서 DegreeToRadian 안해서 추가하기
🐛 CollisionCheck_OBB를 나눠서 Update에서 해서 CollisionCheck_OBB 첫 번째가 무시됨 -> CollisionCheck_OBB를 하나의 함수에서 다 처리
🎉 transform 프로젝트 시작하기
230623_CC.exe 추가하기
✨ LineToCircle D2D/D2DEngineStaticLibrary/Object.cpp
이서영/D2D/D2DEngineStaticLibrary/Matrix.h
3 원 - 선 업데이트 해서 4에도 업데이트 했다
할당이 해제된 메모리를 가리키는 포인터
delete X / 주소 잃어버림 / 중복 할당
virtualized geometry
polycount, draw call, mesh memory 사용이 frame budget에 제한되지 않는다
노말맵 텍스쳐로 baking X → 높은 폴리곤의 디테일 O
Level of Detail
vertices animation X
bone 갖고 있어서 vertices animation O
풀 나무 본 없이 쓴다
그림자를 opacity mask로 그린다
Preserve area 전체적 모양 유지
표면의 모양을 실제 점의 위치에 맞게 displacement map에 계산한다
xyz → rgb 노말 값을 텍스쳐로 쓴다
보이는 모습만 바뀌고 실제 모양은 안 바뀐다
grayscale image
죽었을 때 중력의 영향을 받아 몸이 떨어진다
애니메이션 → ragdoll physics
각 부위의 rigidbody connection을 조정한다
soft body
유체 관련 기능
파티클이 벽을 타고 흐르는 시뮬레이션
animation + physics + skeletal structure
이서영/isSameString.cpp
unique_ptr from const pointer
리소스의 lifetime을 object의 lifetime에 묶는다
std나 smartpointer로 직접 new delete 하지 않게 한다
raw pointer 에 추가 기능하도록 해서 객체 생성한다
unique : 하나만 한번에 갖기
shared : 여러개 갖기 가능
weak : 소유 안함
unique : 범위 넘어가면 지우기
shared : 마지막 남아있는 포인터가 범위 넘어가면 지우기
weak : X
unique : RAII
shared : 여러 오브젝트가 하나의 리소스 가질 때
weak : shared에서 원형참조 없앨 때
대각선 성분만 1이고 나머지는 0인 행렬
행렬에서 항등원
연산을 했을 때 항등원이 나오는 것
M * M^-1 = I
행과 열을 바꾸었다
j행 k열의 원소 → k행 j열의 원소
A^T
벡터 내적해서 0 → 모든 행, 열벡터가 직교
벡터의 내적을 모으기
D = detA = a11a22 - a12a21
D == 0 → 역행렬이 존재하지 않는다 → linear transform 에서 그 행렬변환이 축 하나를 사라지게 한다
벡터 공간이 얼마나 변하는지 / 방향이 바뀌는지
2D : 변환된 평행 사변형의 크기 3D : 변환된 평형 육면체의 부
basis 찾기
rendering pipeline만 해도 계산량이 엄청 많다
간단한 계산 연산은 cpu에서 하고 렌더링은 gpu에서 데이터 그린다
gpu올리고 난 다음에 메인 메모리 데이터 버릴까 상황따라 다르다
gpu 데이터 접근 X → 메인 메모리에 메모리 매핑 → gpu 멈춤
콘솔 PCLe(Peripheral Component Interconnect Express) expressX 보드에 GPU 있어서 설계가 다르다
함수 포인터로 함수 전달하는 것 대신 Functor를 이용해 함수를 전달한다
변수 + 함수를 전달한다
operator()를 오버로딩한 객체
함수를 호출하듯이 객체를 호출 Callable
객체가 다른 객체의 값으로 초기화 될 때 자동으로 만든다
const TVector&
default copy constructor
멤버 변수로 pointer가 있을 때 필요하다 (동적 메모리, 문자열)
객체의 형 변환
p2 = p1에서 멤버 변수에 포인터 있을 때 같은 값 가리키기 때문에 만들어서 지원해줘야 한다
메모리 누수 가능성 체크하기 : 기존 내용 delete하기 → new로 메모리 잡기
© == this → return : 자기 자신이면 통과하기
rvalue로 새로운 객체 생성할 때 호출되는 생성자
복사생성 빠르게 하기
shallow copy
소유권 이동
원본 객체 nullptr 초기화 → 접근 못한다
copy X 주소만 바꿔서 이동된 효과 만들어서 성능 향상
rvalue를 참조하기 위해 rvalue ref 변수를 선언한다
주소값을 가질 수 없는 값
copy : 전체 값 복사하기
move : 소유권 이동해서 새로운 객체 생성하기
임시객체 전달
std::move()
Lvalue 객체 넣으면 Rvalue ref로 변환해서 전달해준다
heap에 할당 있는 클래스 가능성 높다
destructor + copy assignment / destructor + copy + move assignment
안 붙히면 move 에서 그 함수 안 부른다
RValue : eXpiringValue + PureValue
Xvlaue : Rvale 이동 연산 가능
gvlaue : 메모리 상의 고정된 위치를 가지는 표현식
lvalue + xvalue