( 들어 가면서 )

1. 한글화 목적 : jbox2d 를 위한 기초작업
                     작성자 : 나
                     번역 태클 : 언제든지 해주세요 !!!!!

2. 출처 http://box2d.org/manual.pdf



Box2D의 배포버전에는 Hello World project이 포함 되어 있습니다. 
프로그램은  커다란 ground박스와 하나의 작은 박스를 생성합니다. 
이코드 에는 그래픽적 요소가 없습니다. 
당신이 볼수 있는것은 모든 시간에 대해서 box의 위치를 콘솔로 텍스트로 볼 수 있을 겁니다.

이것은 box2d의 실행과 어떻게 시작해야 할지에 대한 좋은 예를 제공 할수 있습니다.

 
2.1 Creating a world 
모든 box2d 프로그램은  b2World object를 생성하는 것으로 시작한다. 
b2World는 물리공간과 프로그래머의 연결점입니다. b2World는 메모리, 객체, 시뮬레이션
을 관리합니다. 물리공간을 stack과 heap 과 section에 위치 시킬수 잇습니다.

Box2D world 생성하는 것은 매우 쉽습니다. 
첫번째로  중력 벡터를 정의 해야 합니다. (중력의 방향과 중력의 값)
또한 바디들 비활성상태 상태 인지 아닌지를 결정하는 것을 world가 알게 해주어야 한다. 
비활성 상태를 sleep이라고 하는데  sleep 상태이 바디들은 시뮬레이션요청을 받지 않는다.

b2Vec2 gravity(0.0f, -10.0f);
bool doSleep = true;

월드 오브젝트를 생성한다. 아래에 나오는 것은 stack에 world를 생성하는 것이다,
이때 월드는 범위(무슨 범위?) 안에 있어야 한다.
 b2World world(gravity, doSleep);

정리 코드

b2Vec2 gravity(0.0f, -10.0f);
bool doSleep = true;
b2World world(gravity, doSleep); 



이제 물리월드(물리 공간)이 생성되었고 이제 다른요소들을 추가 해보자.

 
2.2 creating a ground Box (바닥 상자 만들기)
바디를 생성하기 위한 단계는 아래와 같다. 

step1. 바디의 위치와 제동(damping)을 정의한다. 
step2. world object를 이용해서 body를 생성하라.
step3. shape와 friction 과 densitiy 와 함께 fixtures 을 정의하라. 
step4. body위에 fixtures을 생성하라




첫번째 단계을 위해서 그라운드 바디를 생성한다. 
이때 생성되는 바디의 정의가 필요하다. 이 정의를 가지고 
그라운드 바다의 초기위치를 정한다.

b2BodyDef groundBodyDef;

groundBodyDef.position.Set(0.0f, -10.0f);



두번째 단계에서는 바디의 정의가 바다의 생성을 위해서 월드 오브젝트로 전달된다. 
월드 오브젝트는 바디정의 에 대한 레퍼런스를 유지하지 않는다 . 바디들은 초기화에 대해
고정적이다. 이 고정적인 바디 (static bodies)들은 다른 static body와 충돌하지 않고
움직이지 안는다. 

b2Body* groundBody = world.CreateBody(&groundBodyDef);



세번재 단계로 그라운드 폴리곤을 생성한다. SetAsBox를 이용해서 그라운드 폴리곤을
box shape 으로 만들어라, 이 박스는 부모의 바디원형에 센터에 자리 잡는다.

b2PolygonShape groundBox;

groundBox.SetAsBox(50.0f, 10.0f);


SetAsBox 함수는 인자값으로 높이와 길이의 1/2값을 받는다  (센터에 맞추니까)
그래서 이 경우에 그라운드 바디는 x축 100단위이고  y축 20 단위이다. 
Box2D의 단위는 KMS 단위로 조정된다.  그래서 위에 넣은 값은 미터단위로  생각해볼수 있다
Box2D 는 오브켁트가 실세계의 사이즈를 기초로 했을때 잘 동작한다.
예를 들어 베럴(오크통)은 높이가 1미터 정도이다. 부동소숫점 연산의 제한때문에 
glaciers(빙하?)나 먼지 입자의 움직임 모델링은 좋은  생각이 아니다. 



마지막 4번째로 shape fixture을 만들어야 한다. 이번 단계에서 간단한 방법이 있다. 
기본 fixture의 요소의 속성을 변화 시킬필요 없다. 픽스쳐의 정의없이 그냥 shape를 바로 body에 전달한다. 이후에 커스터마이징을 위한 fixture을 알아 보겟다. 두번째 파라미터는 shape의 입방미터당 킬로그램 즉 밀도이다.  static body는 디폴트로 0 이다. 그래서 이번 경우에는 사용하지 않는다 

groundBody->CreateFixture(&groundBox, 0.0f);



Box2d 는 shape의 레퍼런스를 유지하지않는다 그 데이터는(레퍼런스) b2Shape 오브젝트에 복사된다. 


주의: 모든 fixture는 부모 body를 가져야한다. (단연한 말이다) 심지어 static(전역?) 이라도 말이다. 그러나  모든 static fixture를 하나의 static body에 붙일수는 있다. 



2.3 Creating a Dynamic Body

지금까지 그라운드 바디를 생성한는 방법을 알았다. 이 방법(테크닉)을 이용해서 다이나믹 바디를 
만들어 보겟다. 그라운드 바디와 다이나믹 바디의 차이점이 있는데 가장 큰 차이점은
다이나믹 바디의 mass 속성을 지정해주어야 한다. 

첫번째로 CreateBody 를 이용해서 body 를 만든다. 디폴트 바디는 static 이기 때문에 
b2BodyType를  다이나믹 바디 오브젝트를 만들때 준비해야 한다. 

b2BodyDef bodyDef;

bodyDef.type = b2_dynamicBody;

bodyDef.position.Set(0.0f, 4.0f);

b2Body* body = world.CreateBody(&bodyDef);

주의 :   body type 을 b2_dynamicBody 으로 설정해한다. 사용자의 입력에 따른 반을을 할려면 말이다. 



다음으로 fixture 정의 를 이용해서 폴리곤 shape를 생성하고 할당한다. 
첫번재로 boxshape를 생성하고 

b2PolygonShape dynamicBox;

dynamicBox.SetAsBox(1.0f, 1.0f);


다은으로 box를 이용해서 fixture정의를 생성한다. 밀도 density는 1로 정해준다.
디폴트 밀도는 0 이다 shape의 마찰(friction)은 0.3으로 하자. 

b2FixtureDef fixtureDef;

fixtureDef.shape = &dynamicBox;

fixtureDef.density = 1.0f;

fixtureDef.friction = 0.3f;



픽스쳐의 정의를 이용하면  fixture를 생성할수 있다. 이것은 body의 mass를 자동으로 업데이트 해준다.  이것으로 많은 fixture를 원하는 body에 추가 할수 있다. 
각각의 요소는 전체 mass를 구성하는 역활은 한다. 



2.4 simulating the world (of Box2D)
지금까지 그라운드 박스를 만들고 다이나믹 박스도 만들어 보았다.
이제 거의 모든 준비는 다되었습니다. 
이제 몇가지만 고려하면 됩니다. 

Box2D 적분기(integrator)라는 컴퓨팅 알고리즘을 이용합니다. 
인터그래이터(알고리즘)는 물리공식을 이산시간에 대해서 시뮬레이션합니다. 
이산시간이란 ( 시간을 연속적으로 보지않고 일정한 간격으로 잘라 사용하는것을
의미합니다.) 전통적인 게임루프(플립북에서 대상이 움직이는 하나의 scene)와 같이 
진행이 된다. 그래서 Box2d를 위한 시간이 필요하다.  일반적으로 게임에서 물리엔진은 
60프레임정도이다. 이 프레임 보다 더 크게 시간을 분할할 필요는 없다. 그러나 생성한
world 오브젝트에 대한 정의를 주의깊게 준비해야 한다. 
다양한 time step은 다양한 결과를 야기 시킨다. 이것은 디버깅 하기도 어렵다 .
그러므로 진행하는 프레임에 time step을 엮지 말라. (진정으로 정말 원한다 하더라도
말이다. )
별다른 고생할 필요없이 여기 간단하게 time step을 설정할수 있다. 

float32 timeStep = 1.0f / 60.0f;


게다가 적분기에 , Box2d는 constraint solver 라고 불리는 코드의 더 많은 비트를
이용할수 있다. constraint solver은 시뮬레이션 제약에 대해서 해결책을 제공해준다. 
하나의 제한은 완전하게 해결할수 있다. 그러나 하나의 제한을 해결할때 또다른 
제한을 약간 방해 한다. 좋은  해결책은 모든 제한에 대해서 여러번 반복할 필요있습니다.

constraint solver 에 2개의 단계가 있다. : 속도 단계 위치 단계
속도 단계에서 solver 바디를 정확하게 움직이기 위해서는 필수적으로 impulses를 연산
할 필요가 있다. 위치 단계에서는 solver는 overlap 과 조인트 분리를 오차를 줄이기 위해서 
바디의 포지션을 조정한다. 각각의 단계는 자기자신의 iteration count 를 가지고 있다 
만약 에러가 작다면 위치 단계는 반복을 일찍 벗어난다.

box2d에서 추천하는 iteration은 속도 8이고 위치3 이다. 이 숫자는 임의로 조정할수 있다.
명심할것은 속도와 정확도는 trade-off 이다. 적은 숫자의 iteration은 속도를 증가 시키지만.
정호가도는 개판이다. 반대로  많은 iteration은 속도를 줄이지만 시뮬레이션의 정확도는 좋다
간단한 예제에서 많은 iteration은 필요없다. 
여기에 우리가 선택한 iteration counts가 있다. 

int32 velocityIterations = 6;

int32 positionIterations = 2;


time step 과 iteration counts은 아무 상관이 없다. iteration은 sub-step 이 아니다. 
하나의 solver iteration 은 time step내의 모든 constraints(제약조건)을 한번씩은 통과해야 한다
(확인해야 한다.)최소한 한번이다. 이말은 여러번 반복할수 있다라는 말이다. 

우리는 시뮬레이션 루프시작을 준비한다. 당신의 게임에서 시뮬레이션루프는 게임루프에 
통합된다.당신의 게임루프전체의 각각의 단계에서 당신은 b2World::step를 호출할수 있다.
일반적으로 당신의 프레임과 물리 time step 에 따라  다릅니다.

Hello World 프로그램은 심플하게 디자인(구성)되어 있다. 그래서 
그래픽적 아웃풋은 없다. 코드는 다이나믹바디의 위치와 회전값을 출력한다. 
여기에 시뮬레이션 루프가 있다. 이는 시뮬레이션 타임의 1초에서 60번의 time step을 
시뮬레이션한다.

for (int32 i = 0; i < 60; ++i)

{

    world.Step(timeStep, velocityIterations, positionIterations);

    b2Vec2 position = body->GetPosition();

    float32 angle = body->GetAngle();

    printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);

}


출력되는 데이터는 박스의 떨어짐과 그라운드 박스에 안착하는 것을 보여준다.
아마도 당신이 볼수 있는 데이터는 

0.00 4.00 0.00

0.00 3.99 0.00

0.00 3.98 0.00

...

0.00 1.25 0.00

0.00 1.13 0.00

0.00 1.01 0.00


이럴것이다.


2.5 Cleanup
world 가 범위를 벗어나거나 pointer에 삭제가 호출될때 bodies,fixtures,joints에 남겨놓은
모든 메모리는 해제된다. 이것은 퍼포먼스를 향상시키고 당신의 삶을 좀더 쉽게 해주기위해서
이다.

그러나 당신이 가지고 있는 bodies,fixtures,joints의 포인터를 해제할 필요가 있을것이다.
그것들은 필요가 없어 질것이기 때문이다. 


2.6 The Testbed 
HelloWorld 예제를 정복하기 위해서는 Box2d의 testbed를 보아야 할것이다. 
testbed는 프레임워크와 메모환경을 unit 단위로 테스트 할수 있다. 
여기에 몇가지 특징이 있다. 

• Camera with pan and zoom.

• Mouse picking of shapes attached to dynamic bodies.

• Extensible set of tests.

• GUI for selecting tests, parameter tuning, and debug drawing options.

• Pause and single step simulation.

• Text rendering.



testbed 는 box2d 사용에 대한 많은 예제를 가지고 있다. 많이 고치고 찾아보아라.

testbed는 freeglut와 GLUI를 사용해서 작성되었다. testbed는 box2d 라이브러리의 일부분이
아니다. box2d 라이브러리는 렌더링에 대해서 문외한이다.? 예제에 보여지는 것은 box2d를
사용하여 렌더링할수 없다 ?

 



























Posted by 수다쟁이증후군 :