정보공간_1

[PhysX] 2부 PhysX 소스 분석! 본문

IT 놀이터/IT Storehouse

[PhysX] 2부 PhysX 소스 분석!

알 수 없는 사용자 2011. 11. 29. 01:51

안녕하세요. 대구 멤버십 20-1기 박수완입니다.

앞서 포스팅한 PhysX에대해 좀더 알아보도록 하겠습니다. ㅎ

오늘 포스팅은 Sample을 하나 분석하고 

다음 포스팅에서는 MFC위에 PhysX를 적용 해보도록 하겠습니다.

우선 PhysX SDK 가 설치된 경로로 가서 Sample 프로젝트를 열어보도록 하겠습니다.

저 같은경우는 아래와 같은 폴더에 프로젝트 파일이 들어있군요 ^^
C:\Program Files\NVIDIA Corporation\NVIDIA PhysX SDK\v2.8.4_win\Samples\compiler\vc9win32


프로젝트를 열게되면 많은 Sample 프로젝트가 존재합니다. 



이중에 SampleBoxes프로젝트를 시작 프로젝트로 설정후 실행 해보겠습니다.



키보드 w, t, s, b 그리고 space를 누를경우 Box가 추가되고 마우스를 통해 시야를 조절할 수 있는 간단한 예제 입니다.

구성된것을 보면 일단 Ground가 존재하고 그위에 Box들이 추가되서 물리엔진이 적용된것을 볼수 있습니다.

이제 소스를 보도록 하겠습니다.

여러가지 파일이 있는데 NxBoxes.cpp가 주 소스 입니다. 나머지 파일들은 PhysX SDK에 필요한 파일이라고 보시면 됩니다.

NxBoxes의 main문을 보게되면

OpenGL에서 창을 띄울때 썼던 glut함수들을 볼수 있습니다.   OpenGL은 다 아실꺼라 생각하여 밑에

InitNX 함수부분 부터 보겠습니다.

InitNX()함수를 보게 되면
 
크게 4가지로 이루어져 있습니다. (※ 제가 관리자 권한이 없어서 tistory소스 코드 스킨을 못올리네요..ㅠ)

1. physicsSDK 생성
2. Scene 생성
3. Default Material 설정
4. ground plane 생성 (땅바닥 생성ㅎㅎ)


1. physicsSDK생성이란 PhysX를 구동하기 위한 최상위 클래스 생성이라고 생각하면 쉬울 수 있습니다.

2. 그 후에 Scene(장면)생성을 하게 되고, 그 장면에 대한 설정을 하게 됩니다.(예 : 중력, 스레드 카운트, Plane, 사용자 데이터 등) 

3. Scene에 대한 Material 의 포인터를 얻어와서 기본 물리 속성에대한 정보를 입력합니다.
  여기서 보게되면 static Friction, Dynamic Friction이라는 것이 있는데 Friction은 마찰에 관한 상수를 입력 하는겁니다. static과 dynamic의 차이점은 정적이냐 동적이냐 차이인데 움직이는 개체(힘을 적용받는)와 힘을 적용받지 않고 항상 그자리에 존재하게되는 개체라고 보시면 됩니다.  이 프로젝트에서 설명드리자면 Ground는 Static 추가되는 Box는 Dynamic에 속하겠군요!  둘다 0.0f 값을 주게되면 박스가 한없이 미끄러지는 것을 확인 할 수 있습니다. ^^
그리고 Restitution은 배상 계수라고 보면 되는데 이 값은 객체의 Bounce되는 효과와 관련 있습니다.  마치 젤리처럼 말이죠 ㅎㅎ (1.0으로 하고 컴파일 해보면 박스가 통통 튑니다 ㅎ)

4. Ground plane생성 이라고 합니다.  기본 땅바닥을 생성하는거죠 물론 다른 효과를 주기위해서는 생략될 수 있는 코드 입니다. ㅎ  Plane 에 대해 Descriptor를 Actor Descriptor에 추가한 후 actor를 생성하고 있습니다.
Descriptor란 그 객체에 대한 정보를 담고 있는 클래스라고 보시면 됩니다.  그리고 PhysX에서 객체의 기본이 되는것이 Actor입니다.  어느 물리엔진에서도 같은 원리죠!  Actor에 대한 Descriptor를 정의 해주고 Actor를 생성해주는 것입니다. ㅎ



이 4단계가 끝나게 되면 기본적으로 PhysX 초기화는 끝나게 됩니다. 물론 사용자의 필요에 따라 다른 초기화 과정을 넣을 수 도 있습니다.  기본적인 배경 랜더링이나 객체 삽입등 초기에 들어가줘야 할 구문을 추가 할 수 있겠죠 ^^


랜더링 부분을 설명 하겠습니다. 일단 PhysX Sample 코드에서는 PhysicsSDK나 Scene은 전역변수로 관리되는것을 볼수 있습니다.  실제로 사용하려면 클래스를 생성하여 멤버변수로 빼는것도 큰 무리가 없습니다. ㅎ

이제 동일한 NxBoxes.cpp에 RenderCallback() 함수 쪽을 살펴보겠습니다.
일반적으로 glClear로 버퍼를 Clear해주고 시점 설정등 보통 OpenGL에서 하던 것과 크게 다르지 않습니다.
허나 다른점은 장면에 대해 Simulate를 해주는것을 볼 수 있습니다. 


이것의 정체는 현재 PhysX Scene에 등록된 객체들을 Simulation한다는 뜻입니다.(물리 연산을 진행 하겠다!)
이 구문을 빼게되면 상자를 추가해도 물리 연산이 되지 않는것을 확인 할 수 있습니다. 

랜더링 부분을 잠깐 살펴보겠습니다. PhysX는 물리엔진이지 랜더링 엔진이 아닙니다. ㅎ 그래서 추가된 Actor에 대해 값을 받아와서 직접 그려줘야 합니다.


OpenGL을 아시는분이라면 금방 이해가 되는 아주 간단한 코드입니다.
현재 장면인 gScene에서 Actor 및 그 수를 받아와서 while문을 돌게 됩니다.
Actor의 더블 포인터를 받아와서 하나의 Actor 포인터로 받습니다.  그후 그 Actor의 Global 좌표를 4x4행렬로 받아와서 glMultMatrixf함수를 통해 이동 및 회전 시켜 줍니다.  그후 glut 함수를 이용하여 solidCube를 그려줍니다.

밑에 Shadow는 그림자를 그려주는 것으로.. Shadow메트릭스를 한번더 행렬에 곱해주어서 사각형을 찌그러트려 그림자를 표현하게 되는것입니다.



그리고 키보드 값에 대해 어떻게 박스들이 추가되는것인지는 KeyboardCallback()함수 에서 확인 할 수 있습니다.

키보드 입력에 따라 CreateCube, CreateStack, CreateTower, CreateCubeFromEye라는 함수가 호출 되고 있습니다.  
CreateStack, CreateTower, CreateCubeFromEye 3가지 함수는 결국 CreateCube라는 함수를 호출하여 Box를 생성하고 있습니다.  그럼 CreateCube 함수에 대해서 보도록 하겠습니다.


위에 설명드렸던 Ground Actor추가와 크게 다른게 없습니다. 일단 넘어오는 파라미터로는
NxVec3& pos, int size, NxVec3* initialVelocity 3가지 입니다.

1. NxVec3& pos : 객체가 추가될 Position 백터입니다.
2. int size : 객체의 Size입니다.
3. NxVec3* initialVelocity : Velocity로서 여기서는 Linear Velocity로 보면 될것 같습니다.  물체에 현재 작용하는 힘으로 보시면 됩니다.

우선 Body Desc에 대해 정의를 하는데 Damping이라는 것이 나옵니다.  이것은 평시에 감소되는 값에 대해 정의 하는것입니다.  크게 Linear Damping과 Angular Damping이 있는데 작용하는 힘, 각도에 대한 Damping이라고 보면 됩니다. 예를 들어 Angular Damping이 크게되면 객체의 회전이 금방 멈출 수 있다는 것입니다.

그리고 BoxSahpeDesc에 대해서 정의를 합니다.  여기서는 dimension정의만 하게 되는데 상자의 높이, 너비 깊이에 대해 정의를 합니다.  그 후 Actor Desc에 위에서 만든 Body Desc와 Shape Desc를 적용시킨후 User Data에 size를 넣어준후 Actor를 생성합니다! 헥헥~~ 기네요 ㅎㅎ
이렇게되면 Scene에 Actor가 등록되어 상자가 나타나게 되는겁니다!

(UserData에 Size를 넣는 이유는 Render함수쪽을 자세히 보시면 이해가 가실 껍니다. )

하하 밤이 깊었네요~ 일단 오늘은 여기까지 하고 다음 포스팅때에는 MFC에 올려서 이것저것 이벤트에 대해 컨트롤 해보도록 하겠습니다. ㅎ