728x90

1. Bounding Box

3D World에서 교차 검사는 매우 중요한 이슈이다. 게임을 예로 들자면, 캐릭터끼리 충돌 검출도 해야하고 마우스 Picking도 해야되고 타격 판정도 해야된다. 이외에도 많이 사용되고 있다.

그래서 캐릭터 모델의 특정 범위, 지형 구조물 등에 충돌 판정을 위한 박스나 단순한 모양의 Bounding Volume을 씌운다.

그렇게 복잡한 메쉬끼리 교차 검사를 하는 것이 아니라 단순한 Volume들 끼리 교차 검사를 하는 것이다.

가장 많이 쓰이는 모양이 box이고, 이 box에는 2가지의 종류가 있다.


2. AABB (Axis-Aligned Bounding Box)


기저 축에 정렬된 충돌 박스로 박스를 이루는 면의 노말 벡터들이 곧 X, Y, Z 축과 일치하는 모양이다.

모델을 이루는 다각형의 X, Y, Z 좌표의 최소 최대를 각 박스의 버텍스로 생성한다.

따라서 회전함에 따라 크기가 계속 변하게 된다.

축에 일치된 모양이기 때문에 AABB끼리의 충돌 검출은 매우 간편하다.



void CheckAABB(BoundingBox targetBox)
{
 if (boundingBox.minPos[0] <= targetBox.maxPos[0] && boundingBox.maxPos[0] >= targetBox.minPos[0] &&
 boundingBox.minPos[1] <= targetBox.maxPos[1] && boundingBox.maxPos[1] >= targetBox.minPos[1] &&
 boundingBox.minPos[2] <= targetBox.maxPos[2] && boundingBox.maxPos[2] >= targetBox.minPos[2])
 {
  aabbCollide = true;
  return;
 }
 aabbCollide = false;
}



3. OBB (Oriented Bounding Box)


AABB와 마찬가지로 박스를 이루는 세 면은 서로 수직이지만 해당 면의 노말 벡터가 X, Y, Z와 일치하지 않는 박스이다.

X, Y, Z와 일치하지 않기 때문에 AABB보다 충돌 검출의 시간 복잡도는 높지만 충돌 박스가 XYZ 좌표를 기준으로 최대, 최소로 계속 변하는 AABB보다 항상 좀 더 fit한 바운딩 박스를 만들 수 있다.


void CheckOBB(BoundingBox targetBox)
{
 double c[3][3];
 double absC[3][3];
 double d[3];
 double r0, r1, r;
 int i;
 const double cutoff = 0.999999;
 bool existsParallelPair = false;
 D3DXVECTOR3 diff = boundingBox.centerPos - targetBox.centerPos;
 
 
 for (i = 0; i < 3; ++i)
 {
  c[0][i] = D3DXVec3Dot(&boundingBox.axis[0], &targetBox.axis[i]);
  absC[0][i] = abs(c[0][i]);
  if (absC[0][i] > cutoff)
   existsParallelPair = true;
 }
 
 
 d[0] = D3DXVec3Dot(&diff, &boundingBox.axis[0]);
 r = abs(d[0]);
 r0 = boundingBox.axisLen[0];
 r1 = targetBox.axisLen[0]* absC[0][0] + targetBox.axisLen[1]* absC[0][1] + targetBox.axisLen[2]* absC[0][2];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 for (i = 0; i < 3; ++i)
 {
  c[1][i] = D3DXVec3Dot(&boundingBox.axis[1], &targetBox.axis[i]);
  absC[1][i] = abs(c[1][i]);
  if (absC[1][i] > cutoff)
   existsParallelPair = true;
 }
 d[1] = D3DXVec3Dot(&diff, &boundingBox.axis[1]);
 r = abs(d[1]);
 r0 = boundingBox.axisLen[1];
 r1 = targetBox.axisLen[0] * absC[1][0] + targetBox.axisLen[1] * absC[1][1] + targetBox.axisLen[2] * absC[1][2];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 for (i = 0; i < 3; ++i)
 {
  c[2][i] = D3DXVec3Dot(&boundingBox.axis[2], &targetBox.axis[i]);
  absC[2][i] = abs(c[2][i]);
  if (absC[2][i] > cutoff)
   existsParallelPair = true;
 }
 d[2] = D3DXVec3Dot(&diff, &boundingBox.axis[2]);
 r = abs(d[2]);
 r0 = boundingBox.axisLen[2];
 r1 = targetBox.axisLen[0] * absC[2][0] + targetBox.axisLen[1] * absC[2][1] + targetBox.axisLen[2] * absC[2][2];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 r = abs(D3DXVec3Dot(&diff, &targetBox.axis[0]));
 r0 = boundingBox.axisLen[0] * absC[0][0] + boundingBox.axisLen[1] * absC[1][0] + boundingBox.axisLen[2] * absC[2][0];
 r1 = targetBox.axisLen[0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(D3DXVec3Dot(&diff, &targetBox.axis[1]));
 r0 = boundingBox.axisLen[0] * absC[0][1] + boundingBox.axisLen[1] * absC[1][1] + boundingBox.axisLen[2] * absC[2][1];
 r1 = targetBox.axisLen[1];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(D3DXVec3Dot(&diff, &targetBox.axis[2]));
 r0 = boundingBox.axisLen[0] * absC[0][2] + boundingBox.axisLen[1] * absC[1][2] + boundingBox.axisLen[2] * absC[2][2];
 r1 = targetBox.axisLen[2];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 if (existsParallelPair == true)
 {
  obbCollide = true;
  return;
 }
 
 
 r = abs(d[2] * c[1][0] - d[1] * c[2][0]);
 r0 = boundingBox.axisLen[1] * absC[2][0] + boundingBox.axisLen[2] * absC[1][0];
 r1 = targetBox.axisLen[1] * absC[0][2] + targetBox.axisLen[2] * absC[0][1];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[2] * c[1][1] - d[1] * c[2][1]);
 r0 = boundingBox.axisLen[1] * absC[2][1] + boundingBox.axisLen[2] * absC[1][1];
 r1 = targetBox.axisLen[0] * absC[0][2] + targetBox.axisLen[2] * absC[0][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[2] * c[1][2] - d[1] * c[2][2]);
 r0 = boundingBox.axisLen[1] * absC[2][2] + boundingBox.axisLen[2] * absC[1][2];
 r1 = targetBox.axisLen[0] * absC[0][1] + targetBox.axisLen[1] * absC[0][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[0] * c[2][0] - d[2] * c[0][0]);
 r0 = boundingBox.axisLen[0] * absC[2][0] + boundingBox.axisLen[2] * absC[0][0];
 r1 = targetBox.axisLen[1] * absC[1][2] + targetBox.axisLen[2] * absC[1][1];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[0] * c[2][1] - d[2] * c[0][1]);
 r0 = boundingBox.axisLen[0] * absC[2][1] + boundingBox.axisLen[2] * absC[0][1];
 r1 = targetBox.axisLen[0] * absC[1][2] + targetBox.axisLen[2] * absC[1][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[0] * c[2][2] - d[2] * c[0][2]);
 r0 = boundingBox.axisLen[0] * absC[2][2] + boundingBox.axisLen[2] * absC[0][2];
 r1 = targetBox.axisLen[0] * absC[1][1] + targetBox.axisLen[1] * absC[1][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[1] * c[0][0] - d[0] * c[1][0]);
 r0 = boundingBox.axisLen[0] * absC[1][0] + boundingBox.axisLen[1] * absC[0][0];
 r1 = targetBox.axisLen[1] * absC[2][2] + targetBox.axisLen[2] * absC[2][1];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[1] * c[0][1] - d[0] * c[1][1]);
 r0 = boundingBox.axisLen[0] * absC[1][1] + boundingBox.axisLen[1] * absC[0][1];
 r1 = targetBox.axisLen[0] * absC[2][2] + targetBox.axisLen[2] * absC[2][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 r = abs(d[1] * c[0][2] - d[0] * c[1][2]);
 r0 = boundingBox.axisLen[0] * absC[1][2] + boundingBox.axisLen[1] * absC[0][2];
 r1 = targetBox.axisLen[0] * absC[2][1] + targetBox.axisLen[1] * absC[2][0];
 if (r > r0 + r1)
 {
  obbCollide = false;
  return;
 }
 
 
 obbCollide = true;
 return;
}


출처 : http://hoodymong.tistory.com/8

728x90
728x90

설명 : https://ko.wikipedia.org/wiki/PhysX


설치 : 

1 - https://developer.nvidia.com/physx-sdk 에 가서 Login을 하고, Register 등록하고, Accept EULA에서 인증을 받아야한다.

2 - https://github.com/NVIDIAGameWorks 에서 PhysX 를 다운 받는다.

3 - PhysX_3.4\Source\compiler에 있는 솔루션 중 하나를 열어 PhysX SDK를 빌드한다.

4 - PhysX_3.4\Samples\compiler에 있는 솔루션 중 하나를 열어 빌드한다.

728x90
728x90

DirectX SDK (June 2010) 을 Windows 7 이상의 버전에서 설치하다보면 Error Code S1023이 뜬다.


이것은 결론을 먼저 말하면 무시해도 상관은 없다. 하지만 이게 거슬리고 원인이 궁금해서 찾아보았다.


일단 이것들을 먼저 삭제하고 DirectX SDK 를 다시 설치하면 된다.

MsiExec.exe /passive /X{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}
MsiExec.exe /passive /X{1D8E6291-B0D5-35EC-8441-6616F567A0F7}


참고 자료 : http://stackoverflow.com/questions/4102259/directx-sdk-june-2010-installation-problems-error-code-s1023

728x90
728x90

C#에 보면 #region 이라는 전처리기 지시문이 있다.

이를 사용하면 코드 편집기의 개요 표시 및 숨기기 기능으로 확장하거나 축소할 수 있는 코드 블록을 지정할 수 있다.


이를 Native C++에서도 사용할 수 있다.

이미 자주 사용하고 있는 #pragma 란 전처리기 지시문을 사용하여 할 수 있는데

#pragma region 문자열

#pragma endregion


그런데 이 #pragma 지시어가 이것을 지원하지 않는 다른 컴파일러에서 에러 또는 경고 메시지를 수반하지 않고서 #pragma 지시를 무시하도록 되어 있다고 하는데 어떤 사람은 gcc를 사용하는데 MS VC++로 된 파일을 컴파일 하는데 이 #pragma region 때문에 경고가 발생한다는 이야기를 본 적이 있다.



출처 : http://1and0.tistory.com/47

728x90

'Basic Programming > C, C++' 카테고리의 다른 글

C++ - OutputDebugString()을 편하게 사용  (0) 2019.12.05
C++ - 덤프 파일을 통한 사후 디버깅  (0) 2018.11.21
C++ - Joystick 입력 받기.  (0) 2018.02.01
C++ - inline의 이해  (0) 2017.12.10
C++ - deprecated 키워드  (0) 2017.09.15
728x90

Dithering (디더링)


- 요약

디더링은 해당 픽셀에 요청된 색상이 컴퓨터의 지원 컬러에 없는 색상이면, 다른 색상들을 섞어서 비슷한 색상으로 대체하기 위해 컴퓨터 프로그램에 의해 시도되는 것이다. (오디오 쪽에서는 노이즈를 이용한 방법이 있다....)



- 심화

컴퓨터 그래픽스에 있어서 (흑백 표시 장치나 단색 프린터로) 그레이의 음영변화, 또는 (컬러 표시 장치나 컬러 프린터로) 추가색의 음영 변화의 착각을 생성할 때 사용디는 수법이다. 혼합에서는 어느 이미지의 영역을 여러 가지 패턴으로 착색된 도트의 집합으로서 처리한다. 인쇄 이미지에 가까운 것을 하프톤이라하고, 약간 점묘화법으로 그려진 그림과 비슷하다. 혼합은 각각의 효과를 평균화한다든지 묶어서 하나의 음영 또는 색이라고 인식하도록 인간의 눈이 갖는 성질을 이용하고 있다. 하나의 영역 내의 흰 점과 검은 점과의 비율에 따라서 그 영역은 전체로서 그레이로 보인다. 마찬가지로 붉은 점 중에 흰 점을 섞으면 핑크와 비슷한 색조가 된다. 혼합은 컴퓨터 그래픽스에 현실감을 가한다든지, 해상도가 낮을 때 곡선이나 직선에 나타나는 날카로운 부분을 매끄럽게 하는 데 사용된다. 제한된 수의 색상들을 섞어서 다양한 색을 만들거나 현재 팔래트에 존재하지 않는 컬러를 컬러 패턴으로 대체하여 유사한 컬로로 표현하는 기법으로 포토샵에는 디더링을 조절하는 옵션으로 Diffusion과 Pattern이 있다.


- Diffusion : 색상간의 경계를 자연스럽게 흩어 주는 방법

- Pattern : 이미지를 삼베 같은 패턴으로 거칠게 만드는 방식


        

                                                  (24bit Color)                           (8bit Color)



(Diffusion Dither)

(Pattern Dither)


출처 : http://kbp.kongju.ac.kr/cg_edu/cg1_data/5week_4.htm


728x90
728x90

나의 경우 회사에서 개발할 때에는 항상 워터폴(Waterfall) 방법론이었다.


워터폴 방법론은 다음과 같다.



사실 고객은 자기가 원하는 것을 스스로도 정확하게 알지 못한다. 그냥 이런 기능이 있으면 좋겠는데, 저런 기능이 있으면 좋겠는데 할 뿐이다....


그렇기 때문에 처음부터 고객의 요구조건에 맞춰서 개발하다보면 계속해서 추가 요구 사항이 들어오게되고, 그러다보니 점점 구조가 꼬이는 형태가 될 수 밖에 없었다. (내가 근무한 방위산업체쪽에서는 항상 이랬다 ㅎㅎㅎㅎ)


즉, 이 워터폴 방식은 정말 제대로된 관리자가 고객의 요구를 정확하게 알고, 완벽한 설계를 하고, 완벽한 구현을 한 후 개발 완료를 할 때에는 좋은 개발 방법이지만, 그게 아니라면 좋지 못한 방법론이다. (보통 개발을 모르는 사람이 관리자였다...)




위의 문제 때문에 새롭게 나온 개발 방법론이 바로 애자일 모델(Agile Model) 이다.


사전에서 먼저 찾아보면 "Agile = 기민한, 날렵한" 이란 뜻이다.

즉 좋은 것을 빠르게 취하고, 낭비 없게 만드는 다양한 방법론을 통칭해 일컫는 말이다.


애자일 모델이 다른 방법론과 구별되는 가장 큰 차이점은 Less Document-Oriented, 즉 문서를 통한 개발이 아니라 Code-Oriented 실질적인 코딩을 통한 방법론이라는 것이다.



애자일 모델은 일정한 주기를 가지고 계속해서 프로토 타입(Proto Type)을 만들어서 고객에게 보여주며 고객과의 소통을 통한 요구사항을 추가하거나, 필요없는 부분은 제거하면서 점점 프로그램을 개발해 나가는 방법이다.


이렇게 실질적인 프로토 타입을 계속해서 만들어내는 과정에서 고객이 자연스럽게 참여할 수 있게 되고, 수정 요청을 하거나 다음 단계로 넘어가는 과정을 고객과 긴밀한 관계를 형성할 수 있다.




애자일 방식은 일반적으로 스크럼 프로세스를 따르게 되는데, 스크럼은 보통 30일 단위로 주기를 나누고, 짧게는 1~2주 길게는 3~4주 단위의 스프린트(개발 주기)로 쪼개서 개발하게 된다.


특정 기간 동안 해야 할 목표와 필요 작업을 명시하고, 실제로 어떻게 진행 되었는지 백로그(Backlog)를 남겨 각 스프린트가 끝나는 시점에 함께 모여 리뷰하고 피드백을 주고 받는 형태의 업무를 진행한다.


출처 : http://blog.rightbrain.co.kr/?p=5810

728x90
728x90

애트리뷰트는 클래스에 메타데이터를 추가할수 있도록 제공한다.

주석과는 달리 클래스부터 시작해서 메소드구조체생성자프로퍼티필드이벤트인터페이스 등 여러가지 요소에 애트리뷰트를 사용할 수 있다.

 

우리가 필요에 의해서 이 애트리뷰트를 사용해 코드 앞에다 설명을 덧붙일 수도 있다.

애트리뷰트의 기본 형식은 다음과 같다:

1 [attribute(positional_parameter, name_parameter = value, ...)]

여기서 positional_parameter는 위치지정 파라미터라고 해서 반드시 적어야하는 부분으로, " "를 사용하여 작성한다그리고 name_parameter는 명명 파라미터로선택적인 정보이며 = 를 사용해서 값을 기입한다.

이 애트리뷰트는 크게 두가지로 나뉘는데사용자가 정의하는 커스텀 애트리뷰트와 내장되어 있는 공통 애트리뷰트로 나뉜다공통 애트리뷰트의 경우는 추가된 정보가 컴파일 방식에 영향을 줄 수 있는데반대로 커스텀 애트리뷰트는 영향을 주지 못한다.

 

대표적인 공통 애트리뷰트로는

Obsolete, Conditional, DllImport이 있다.


1. Obsolete

함수위에 [Obsolete(“출력하고싶은내용”] 을 걸면,

해당 함수 실행시 경고창이 콘솔에 출력된다.


2. Conditional

함수위에 [Conditional(“조건”] 을 걸고,

코드상에 #define 조건을 선언하면해당 함수가 실행되고해당 정의를 빼버리면 실행되지 않는다.


3.  DllImport

함수위에 [DllImport(“Example.dll”)] 을 걸고 extern 키워드를 이용하여 외부 dll에 정의 되어있는 함수를 사용할수 있다.

Public static extern int MessageBox()

 

이 외에도 많은 종류의 애트리뷰트를 제공한다.

 

유니티에서의 제공하는 커스텀 애트리뷰트로는 다음과 같은 것이 있다:


1) AddComponentMenu

기본적으로 스크립트는 유니티의 Component->Scripts 메뉴에 자동추가된다자동추가말고 아무데나 맘대로 넣고 싶으면 AddComponentMenu를 사용한다


2)  ContextMenu

스크립트를 우클릭시 뜨는 context menu에 커맨드를 추가할 수 있다


3) ExecuteInEditMode 기본적으로 play mode일 때만 스크립트가 실행되나 attribute를 사용하면edit mode일 때도 스크립트가 실행되게 한다.

 

4) HideInInspector

inspector에서 안보이게 한다.

 

5) NonSerialized

앞서 HideInInspector는 값을 유지하지만이건 그냥 리셋하여 디폴트값 으로 바꾼다


6) RPC

원격 컴퓨터의 해당 함수를 호출하는 것을 가능케 하는 애트리뷰트다. Remote Procedure Calls라고도 부르며,  유니티 5.1부터는 사용하지 않는 애트리뷰트이다.

 

7) RequireComponent 

함께 필요한 다른 컴포넌트가 자동으로 추가된다.

 

8) Serializable

직렬화 하여 유니티에서 해당 클래스의 내용물이 Inspector에서 보일 수 있도록 한다.


9) SerializeField

private필드를 강제로 serialize한다그러므로 inspector에서도 편집이 가능해진다.




출처 : https://blog.naver.com/captainj/221102947400


728x90

'Basic Programming > C#' 카테고리의 다른 글

C# - 작업 스케줄러에 등록하기  (0) 2021.12.10
C# - Steam Game 실행하기  (0) 2020.07.21
C# - Dispose  (0) 2018.10.12
C# - WeakReference  (0) 2018.10.11
C# - 공부하기 좋은 사이트  (0) 2018.09.05
728x90
  • Make a new C++ project
  • Default options for everything
  • Once created, right-click the project and go to "Properties"
  • C/C++ Build -> Settings -> Tool Settings -> GCC C++ Compiler -> Miscellaneous -> Other Flags. Put -std=c++0x (or for newer compiler version -std=c++11 at the end . ... instead of GCC C++ Compiler I have also Cygwin compiler
  • C/C++ General -> Paths and Symbols -> Symbols -> GNU C++. Click "Add..." and paste __GXX_EXPERIMENTAL_CXX0X__ (ensure to append and prepend two underscores) into "Name" and leave "Value" blank.
  • Hit Apply, do whatever it asks you to do, then hit OK.


출처 : https://stackoverflow.com/questions/9131763/eclipse-cdt-c11-c0x-support


728x90

+ Recent posts