노력과 삽질 퇴적물

Box2d: 요약 및 정리 본문

프로그래밍note/엔진 관련

Box2d: 요약 및 정리

MTG 2017. 8. 30. 22:55


* 용어는 가급적 원어를 한글로 옮긴방식을 쓰고 있지만, 발음표기상 생소한건(주관적 기준) 참조자료등의 번역을 사용했습니다.






0. 준비


* 공식페이지: Box2D | A 2D Physics Engine for Games


1) 필요한 파일

파일명

예시 경로

 Box2d 프로젝트파일

Box2D_v2.3.0.7z

Box2D-master.zip

 (해당사항 없음)

 Visual Studio Community [#]

 (설치시 기본경로)



2) 목차

상위

하위

 1. 용어

 1) 주요용어
 2) 모듈
 3) 유닛
 4) 팩토리&정의

 2. 기본용법

 1) 월드
 2) 그라운드 박스

 3) 다이나믹 body

 4) 시뮬레이팅

 5) 클린업

 3. Common 1) 설정
 2) 메모리 관리
 3) 수학
 4. 충돌 모듈(Collision Module)

 1) Shape

 2) 레이캐스트(RayCast)

 3) 쌍방함수    

 4) 다이나믹 트리(Dynamic Tree)     

 5) Broad-phase

 5. 다이나믹 모듈

 1) Body
 2) Fixture

 6. 조인트(Joint) 1) 정의
 2) 사용 절차
 7. Contacts 1) 클래스
 8. 월드 클래스 1) Creating and Destroying
 2) Using
 3) Simulation
 4) Exploring the World
 5) Ray Cast
 6) 회전 및 이동
 7) AABB Queries






1. 용어


* 참조

> Box2D_v2.3.0\Box2D\Documentation\manual.docx

: 1.5 Core Concepts


1) 주요용어

용어

-

 쉐이프(shape)

 2D상의 기하학적인 오브젝트
> 예. 원[O]   구[X, 3D]

 rigid body

 번역시 '강체'로 표기.

 물리적으로 단단한 오브젝트.

 fixture

 밀도, 마찰력, 콜라이더등의 속성을 가지게 함.
> body가 부모라는 전제가 필요.

> 어찌보면 body의 하위에 있는 물리적 요소 집합체격?

 constraint

 a physical connection that removes degrees of freedom from bodies.

 2D body has 3 degrees of freedom (two translation coordinates and one rotation coordinate, 이동축 2개+회전축 1개).

 contact constraint designed to prevent penetration of rigid bodies and to simulate friction and restitution.
> RigidBody끼리 뚫고 지나가지 않게 하고, 마찰등의 물리법칙을 작용케함.
 조인트(joint) 다수의 몸체(body)를 연결
 박스2d에서 지원하는 조인트
> revolute, prismatic, distance
 조인트 리밋(joint limit)

 인간의 관절처럼 회전각도등에 제한값을 두는것.

 조인트의 자유도를 제한하는격.

 조인트 모터(joint motor)

 (허용된 제한값내에서) 조인트를 움직인다.

 world

 오브젝트가 위치해있고, 물리가 작용하는 세계.

 solver The physics world has a solver that is used to advance time and to resolve contact and joint constraints. The Box2D solver is a high performance iterative solver that operates in order N time, where N is the number of constraints.
 continuous collision

 The solver advances bodies in time using discrete time steps. Without intervention this can lead to tunneling.
> 선형보간법이 엮인 충돌처리?



2) 모듈

Box2d 모듈들 = Common + Collision + Dynamics


 Common
 (= Common module)

 수학 및 설정관련 모듈
 Collision shape, 충돌함수관련 정의
 Dynamics world, body, fixture, joint 관련



3) 유닛

> 물체의 이동단위 0.1~10m로 유지하라고 명시됨.

> 라디안[ (π/180)*x ]을 각도로 사용. [호도법]

> 각도조절시, b2Body::SetAngle 사용.



4) 팩토리&정의

1
2
3
4
5
6
7
8
9
b2Body* b2World::CreateBody(const b2BodyDef* def)
b2Joint* b2World::CreateJoint(const b2JointDef* def)
 
void b2World::DestroyBody(b2Body* body)
void b2World::DestroyJoint(b2Joint* joint)
 
b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def)
void b2Body::DestroyFixture(b2Fixture* fixture)
b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float32 density)
cs

> b2Body 또는 b2Joint 생성시, 팩토리 함수를 사용. 메모리 관리상 다른 방법은 금지하는쪽으로 다뤄짐.







2. 기본용법


* 순서상, 세상-땅-땅위에 있는 무언가(body 오브젝트)로 연상가능.


1) 월드

> Box2D 프로그램은 b2World 오브젝트 생성으로 시작됨.

> 스탭/힙 혹은 데이터 섹션에 물리 월드를 할당 가능.

> 중력가속도는 9.8㎨이지만, 계산상 편의를 위해 10이 표준격.

1
2
3
4
5
6
7
//setp 1.
//중력벡터 선언, sleep여부 지정가능
2Vec2 gravity(0.0f, -10.0f);
 
//setp 2.
//월드객체 생성
b2World world(gravity);
cs



2) 그라운드 박스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//setp 1.
//body정의: with position, damping, etc.
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0.0f, -10.0f);
 
//setp 2.
//월드객체를 이용한 body생성
b2Body* groundBody = world.CreateBody(&groundBodyDef);
 
//setp 3.
//fixtures정의: with a shape, friction, density, etc.
b2PolygonShape groundBox;
groundBox.SetAsBox(50.0f, 10.0f);
 
//setp 4.
//body에 fixtures생성.//body의 하위가 fixtures
groundBody->CreateFixture(&groundBox, 0.0f);
cs



3) 다이나믹 body

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//setp 1.
//body생성.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;//외력(?)등에 반응하게 할 경우.
bodyDef.position.Set(0.0f, 4.0f);
b2Body* body = world.CreateBody(&bodyDef);
 
//setp 2.
//shape
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(1.0f, 1.0f);
 
//setp 3.
//주의. 밀도 기본값이 0이라, 1로 설정필요.
body->CreateFixture(&fixtureDef);
cs



4) 시뮬레이팅

> integrator: Box2D에서 사용하는 계산 알고리즘으로, time step를 별도로 설정할 필요가 없게한다.

1
2
3
4
//sample.
//속도와 정확도는 개발목적에 맞게 조절
int32 velocityIterations = 6;
int32 positionIterations = 2;
cs



5) 클린업

> 메모리 관리관련.

> delete시킨 body/fixture등등도 null 초기화 필요(?)






3. Common


* Common (= Common module)은 설정/메모리관리/벡터관련 처리.


1) 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//(Box2D_v2.3.0)\Box2D\Box2D\Common\b2Settings.h
Type
> (기성_자료형)+(숫자)로 조합된 변수명으로 조합됨.
 
Constants
> b2_xxx식으로 명명법 사용.
> 쓸일이 별로 없다고 한다.(원문. Normally you do not need to adjust these constants.)
 
Allocation wrappers
> 메모리 관리 관련
> b2Alloc, b2Free를 활용.
void* b2Alloc(int32 size);
void b2Free(void* mem);
 
Version
> b2Version구조체 참조.
cs



2) 메모리 관리

> Box2D는 다량의 작은객체를 할당하는 경향O

> SOA(Small Object Allocator)

: b2BlockAllocator를 통해 사용가능

: 다량의 가변크기를 가진 pool보유. 요청받은 크기에 맞는 메모리 블럭을 할당해주고, 해당 블럭을 해제하면 pool에 반환되는데, 이 연산들은 빠르고 힙 트래픽이 최소화 가능.

: 이 방식때문에 body/fixture/joint에 메모리 할당&삭제 사용금지.  (body에 직접연결된 오브젝트들?)

: b2World를 통해서 할당해야.

> stack allocator

: b2StackAllocator를 통해 사용가능.

: time step이 실행되는 과정에서 매 단계마다 힙에 할당되는걸 막기 위해 약간의 임시 메모리 공간을 제어.



3) 수학

> 간단한 벡터/배열 모듈이 포함됨.






4. Collision Module


1) Shape

> 충돌이 가능한 영역. 

> Box2D에서는 쉐이프 충돌시 1개 이상의 볼륨(volume)이 있어야 처리가 가능.

  (원형, 폴리곤에도 볼륨 존재)

> 엣지 쉐이프: 엣지에는 볼륨이 없음. 즉 볼륨이 없는 엣지끼리는 충돌불가.

> 체인 쉐이프

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
① 원형 쉐이프
b2CircleShape circle;
circle.m_p.Set(2.0f, 3.0f);
circle.m_radius = 0.5f;
 
--------------------------------------------------
② 폴리곤 쉐이프(Polygon Shapes, 다각형 쉐이프)
// This defines a triangle in CCW order.
b2Vec2 vertices[3];
vertices[0].Set(0.0f, 0.0f);
vertices[1].Set(1.0f, 0.0f);
vertices[2].Set(0.0f, 1.0f);
int32 count = 3;
 
b2PolygonShape polygon;
polygon.Set(vertices, count);
 
void SetAsBox(float32 hx, float32 hy);
void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);
 
--------------------------------------------------
③ 엣지 쉐이프(Edge Shapes)
b2Vec2 v1(0.0f, 0.0f);
b2Vec2 v2(1.0f, 0.0f);
 
b2EdgeShape edge;
edge.Set(v1, v2);
 
// This is an edge shape with ghost vertices.
b2Vec2 v0(1.7f, 0.0f);
b2Vec2 v1(1.0f, 0.25f);
b2Vec2 v2(0.0f, 0.0f);
b2Vec2 v3(-1.7f, 0.4f);
 
b2EdgeShape edge;
edge.Set(v1, v2);
edge.m_hasVertex0 = true;
edge.m_hasVertex3 = true;
edge.m_vertex0 = v0;
edge.m_vertex3 = v3;
 
--------------------------------------------------
④ 체인 쉐이프(Chain Shapes)
// This a chain shape with isolated vertices
b2Vec2 vs[4];
vs[0].Set(1.7f, 0.0f);
vs[1].Set(1.0f, 0.25f);
vs[2].Set(0.0f, 0.0f);
vs[3].Set(-1.7f, 0.4f);
 
b2ChainShape chain;
chain.CreateChain(vs, 4);
 
// Install ghost vertices
chain.SetPrevVertex(b2Vec2(3.0f, 1.0f));
chain.SetNextVertex(b2Vec2(-2.0f, 0.0f));
 
// Create a loop. The first and last vertices are connected.
b2ChainShape chain;
chain.CreateLoop(vs, 4);
 
// Visit each child edge.
for (int32 i = 0; i < chain.GetChildCount(); ++i)
{
b2EdgeShape edge;
chain.GetChildEdge(&edge, i);
}
cs



2) 레이캐스트(RayCast)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
b2Transfrom transform;
transform.SetIdentity();
b2RayCastInput input;
input.p1.Set(0.0f, 0.0f, 0.0f);
input.p2.Set(1.0f, 0.0f, 0.0f);
input.maxFraction = 1.0f;
int32 childIndex = 0;
b2RayCastOutput output;
bool hit = shape->RayCast(&output, input, transform, childIndex);
if (hit)
{
  b2Vec2 hitPoint = input.p1 + output.fraction * (input.p2 – input.p1);
  …
}
cs



3) 쌍방함수

① 오버랩(Overlap)

> 2개의 쉐이프 영역이 겹치는지 체크


② 광범위 접촉(Contact manifolds)

> 보통은 직접처리할 필요가 없다.(원문.you don’t need to compute contact manifolds directly)

1
2
3
4
5
6
7
8
b2WorldManifold worldManifold;
worldManifold.Initialize(&manifold, transformA, shapeA.m_radius,
                         transformB, shapeB.m_radius);
for (int32 i = 0; i < manifold.pointCount; ++i)
{
  b2Vec2 point = worldManifold.points[i];
  …
}
cs


③ 거리(Distance)




④ 타임 오브 임팩트(Time of Impact)

> b2TimeOfImpact클래스 참조.

: Box2D_v2.3.0\Box2D\Box2D\Collision\b2TimeOfImpact.cpp

> 시간 및 경로상, 2개 이상의 shape가 충돌하는걸 계산해내서 오브젝트가 통과되지 않게 하는 목적.

> shape의 회전각이 너무 크면 오차가 발생할수 있다고 함.



4) 다이나믹 트리(Dynamic Tree)

          

> 계층적 AABB트리(Axis-Aligned Bounding Box)

> 직접사용할수는 없고, b2World로 사용이 가능.



5) Broad-phase

> b2BroadPhase클래스로 

> 프로그래머가 직접 관여친 못한다.





5. 다이나믹 모듈


> Box2D에서 가장 복잡한 파트

> 다이나믹 모듈에 포함된 클래스들

: 해당 클래스들간에는 많은 의존성이 있어서 다른 클래스 참조없이 명시가 어려움.

 fixture class [1.1) 주요용어 참조]
 rigid body class [1.1) 주요용어 참조]
 contact class 
 joint classes [1.1) 주요용어 참조]
 world class [1.1) 주요용어 참조]
 listener classes 



1) Body

① 종류

> 위치와 속도값을 가진다.

 b2_staticBody

 속도를 내지 않는다.(원문. has zero velocity.)
 시뮬레이션에서는 움직이지 않고, 사용자에 의해서 이동가능.

 다른 static or kinematic와는 충돌하지 않음.

 b2_kinematicBody

 시뮬레이션에서 자체속도에 맞춰 이동.

 다른 static or kinematic와는 충돌하지 않음.

 b2_dynamicBody

 모든 타입의 body와 충돌이 가능.
 부피가 0이 아닌 유한값을 가짐.
 강체 하나에 2개의 fixture가 붙어있으면, 움직이지도 충돌처리도 안 된다.


② 정의

> Damping

: 공기저항처럼 body의 속도에 영향을 주는 요소.

: Damping parameters should be between 0 and infinity, with 0 meaning no damping, and infinity meaning full damping. Normally you will use a damping value between 0 and 0.1

> Bullets

: Box2D에서는 dynamic 바디와 static바디하고의 터널링을 방지하기 위해 CCD를 기본으로 사용하나, dynamic 바디사이의 충돌에는 사용되지 않습니다.

(Box2D uses continuous collision detection (CCD) to prevent dynamic bodies from tunneling through static bodies. Normally CCD is not used between dynamic bodies.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bodyDef.type = b2_dynamicBody;
 
bodyDef.position.Set(0.0f, 2.0f);   // the body's origin position.
bodyDef.angle = 0.25f * b2_pi;      // the body's angle in radians.
 
bodyDef.linearDamping = 0.0f;      //no damping
bodyDef.angularDamping = 0.01f;    //damping value between 0 and 0.1
 
// Set the gravity scale to zero so this body will float
bodyDef.gravityScale = 0.0f;
 
bodyDef.allowSleep = true;
bodyDef.awake = true;
 
bodyDef.fixedRotation = true;
 
bodyDef.bullet = true;    //dynamic바디와 static바디간 터널링 방지
 
bodyDef.active = true;    //충돌체크 및 레이캐스트등이 적용되는 옵션
 
b2BodyDef bodyDef;
bodyDef.userData = &myActor;    //User data is a void pointer
cs



2) Fixture

> body하나에 0개 혹은 1개 이상의 fixture보유.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//생성
b2FixtureDef fixtureDef;
fixtureDef.shape = &myShape;
fixtureDef.density = 1.0f;
b2Fixture* myFixture = myBody->CreateFixture(&fixtureDef);
 
//소멸
myBody->DestroyFixture(myFixture);
 
//밀도(Density)
fixture->SetDensity(5.0f);//0 ~ +N
body->ResetMassData();
 
//마찰(Friction)
float32 friction;
friction = sqrtf(fixtureA->friction * fixtureB->friction);
 
//탄성(튕김 혹은 반발력, Restitution)
//restitution value is usually set to be between 0 and 1
//b2Contact::SetRestitution를 재정의 가능(원문. You can override the default mixed restitution using b2Contact::SetRestitution)
float32 restitution;
restitution = b2Max(fixtureA->restitution, fixtureB->restitution);
 
//필터링
playerFixtureDef.filter.categoryBits = 0x0002;
monsterFixtureDef.filter.categoryBits = 0x0004;
playerFixtureDef.filter.maskBits = 0x0004;
monsterFixtureDef.filter.maskBits = 0x0002;
 
//센서(Sensor)
/*
    Sensors do not generate contact points. There are two ways to get the state of a sensor
    > b2Contact::IsTouching
    > b2ContactListener::BeginContact and EndContact 
*/
cs






6. 조인트(Joint)


1) 정의

Many joint definitions require that you provide some geometric data. Often a joint will be defined by anchor points. These are points fixed in the attached bodies. Box2D requires these points to be specified in local coordinates.



2) 사용 절차

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
    Joint Factory
    Don't try to create a joint on the stack or on the heap using new or malloc.
    Joints are destroyed when an attached body is destroyed.
*/
b2RevoluteJointDef jointDef;
jointDef.bodyA = myBodyA;
jointDef.bodyB = myBodyB;
jointDef.anchorPoint = myBodyA->GetCenterPosition();
b2RevoluteJoint* joint = (b2RevoluteJoint*)myWorld->CreateJoint(&jointDef);
... do stuff ...
myWorld->DestroyJoint(joint);
joint = NULL;
 
 
/*
    Using 
*/
b2Body* GetBodyA();
b2Body* GetBodyB();
b2Vec2 GetAnchorA();
b2Vec2 GetAnchorB();
void* GetUserData();
 
b2Vec2 GetReactionForce();
float32 GetReactionTorque();
 
 
/*
    Distance Joint
    > 충돌이 일어나지 않을정도로 떨어진 body들이 body내 anchor로 연결됨.
*/
b2DistanceJointDef jointDef;
jointDef.Initialize(myBodyA, myBodyB, worldAnchorOnBodyA, worldAnchorOnBodyB);
jointDef.collideConnected = true;
jointDef.frequencyHz = 4.0f;
jointDef.dampingRatio = 0.5f;
 
 
/*
    Revolute Joint
    > 겹쳐있는 body들이 body내 anchor로 연결됨.
*/
b2RevoluteJointDef jointDef;
jointDef.Initialize(myBodyA, myBodyB, myBodyA->GetWorldCenter());
... ... ...
b2RevoluteJointDef jointDef;
jointDef.Initialize(bodyA, bodyB, myBodyA->GetWorldCenter());
jointDef.lowerAngle = -0.5f * b2_pi; // -90 degrees
jointDef.upperAngle = 0.25f * b2_pi; // 45 degrees
jointDef.enableLimit = true;
jointDef.maxMotorTorque = 10.0f;
jointDef.motorSpeed = 0.0f;
jointDef.enableMotor = true;
float32 GetJointAngle() const;
float32 GetJointSpeed() const;
float32 GetMotorTorque() const;
... ... ...
void SetMotorSpeed(float32 speed);
void SetMaxMotorTorque(float32 torque);
... Game Loop Begin ...
float32 angleError = myJoint->GetJointAngle() - angleTarget;
float32 gain = 0.1f;
myJoint->SetMotorSpeed(-gain * angleError);
... Game Loop End ...
 
 
/*
    Prismatic Joint
*/
b2PrismaticJointDef jointDef;
b2Vec2 worldAxis(1.0f, 0.0f);
jointDef.Initialize(myBodyA, myBodyB, myBodyA->GetWorldCenter(), worldAxis);
jointDef.lowerTranslation = -5.0f;
jointDef.upperTranslation = 2.5f;
jointDef.enableLimit = true;
jointDef.maxMotorForce = 1.0f;
jointDef.motorSpeed = 0.0f;
jointDef.enableMotor = true;
 
float32 GetJointTranslation() const;
float32 GetJointSpeed() const;
float32 GetMotorForce() const;
void SetMotorSpeed(float32 speed);
void SetMotorForce(float32 force);
 
 
/*
    기타 조인트들
    Pulley Joint
    Gear Joint
    Mouse Joint
    Wheel Joint
    Weld Joint
    Rope Joint
    Friction Joint
    Motor Joint
*/
cs






7. Contacts


Contacts are objects created by Box2D to manage collision between two fixtures.


1) 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
b2Manifold* GetManifold();
const b2Manifold* GetManifold() const;
 
void GetWorldManifold(b2WorldManifold* worldManifold) const;
 
bool touching = sensorContact->IsTouching();
 
b2Fixture* fixtureA = myContact->GetFixtureA();
b2Body* bodyA = fixtureA->GetBody();
MyActor* actorA = (MyActor*)bodyA->GetUserData();
 
 
/*
    Accessing Contacts
    Accessing contacts off b2World and b2Body may miss some transient contacts that occur in the middle of the time step.
    Use b2ContactListener to get the most accurate results.
*/
for (b2Contact* c = myWorld->GetContactList(); c; c = c->GetNext())
{
  // process c
}
 
for (b2ContactEdge* ce = myBody->GetContactList(); ce; ce = ce->next)
{
  b2Contact* c = ce->contact;
  // process c
  // stored in a graph using a contact edge structure.
}
 
 
/*
    Contact Listener
*/
class MyContactListener : public b2ContactListener
{
    public:
    void BeginContact(b2Contact* contact)
      { /* handle begin event */ }
 
      void EndContact(b2Contact* contact)
      { /* handle end event */ }
 
      void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
      { /* handle pre-solve event */ }
 
      void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
      { /* handle post-solve event */ }
};
cs






8. 월드 클래스


1) Creating and Destroying

1
2
3
b2World* myWorld = new b2World(gravity, doSleep);
... do stuff ...
delete myWorld;
cs



2) Using

> b2World에는 body와 joint가 포함되어 있고, 이걸 생성 및 파괴할 factory도 포함되어 있다.



3) Simulation

1
2
3
4
5
6
7
float32 timeStep = 1.0f / 60.f;
int32 velocityIterations = 10;
int32 positionIterations = 8;
myWorld->Step(timeStep, velocityIterations, positionIterations);
 
//After stepping, you should clear any forces you have applied to your bodies.
myWorld->ClearForces();
cs



4) Exploring the World

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//too simple code(with awake)
for (b2Body* b = myWorld->GetBodyList(); b; b = b->GetNext())
{
    b->SetAwake(true);
}
 
 
//    sample 1.
for (b2Body* b = myWorld->GetBodyList(); b; b = b->GetNext())
{
    GameActor* myActor = (GameActor*)b->GetUserData();
    if (myActor->IsDead())
    {
        myWorld->DestroyBody(b); // ERROR: now GetNext returns garbage.
    }
}
 
//    sample 2.
b2Body* node = myWorld->GetBodyList();
while (node)
{
    b2Body* b = node;
    node = node->GetNext();
    
    GameActor* myActor = (GameActor*)b->GetUserData();
    if (myActor->IsDead())
    {
        bool otherBodiesDestroyed = GameCrazyBodyDestroyer(b);
        if (otherBodiesDestroyed)
        {
            node = myWorld->GetBodyList();
        }
    }
}
cs



5) Ray Cast

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// This class captures the closest hit shape.
class MyRayCastCallback : public b2RayCastCallback
{
public:
    MyRayCastCallback()
    {
        m_fixture = NULL;
    }
    
    float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point,
                        const b2Vec2& normal, float32 fraction)
    {
        m_fixture = fixture;
        m_point = point;
        m_normal = normal;
        m_fraction = fraction;
        return fraction;
    }
    
    b2Fixture* m_fixture;
    b2Vec2 m_point;
    b2Vec2 m_normal;
    float32 m_fraction;
};
 
MyRayCastCallback callback;
b2Vec2 point1(-1.0f, 0.0f);
b2Vec2 point2(3.0f, 1.0f);
myWorld->RayCast(&callback, point1, point2);
 
 
/*
    Caution
    Due to round-off errors,
    ray casts can sneak through small cracks between polygons in your static environment.
    If this is not acceptable in your application, please enlarge your polygons slightly.
*/
void SetLinearVelocity(const b2Vec2& v);
b2Vec2 GetLinearVelocity() const;
void SetAngularVelocity(float32 omega);
float32 GetAngularVelocity() const;
cs



6) 회전 및 이동

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
    Forces and Impulses
*/
void ApplyForce(const b2Vec2& force, const b2Vec2& point);
void ApplyTorque(float32 torque);
void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point);
void ApplyAngularImpulse(float32 impulse);
 
if (myBody->IsAwake() == true)
{
    myBody->ApplyForce(myForce, myPoint);
}
 
 
/*
    Transformations
*/
b2Vec2 GetWorldPoint(const b2Vec2& localPoint);
b2Vec2 GetWorldVector(const b2Vec2& localVector);
b2Vec2 GetLocalPoint(const b2Vec2& worldPoint);
b2Vec2 GetLocalVector(const b2Vec2& worldVector);
 
for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext())
{
    MyFixtureData* data = (MyFixtureData*)f->GetUserData();
    ... do something with data ...
}
cs



7) AABB Queries

> b2World class has a fast log(N) method for this using the broad-phase data structure. You provide an AABB in world coordinates and an implementation of b2QueryCallback.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyQueryCallback : public b2QueryCallback
{
public:
    bool ReportFixture(b2Fixture* fixture)
    {
        b2Body* body = fixture->GetBody();
        body->SetAwake(true);
        
        // Return true to continue the query.
        return true;
    }
};
 
...
 
MyQueryCallback callback;
b2AABB aabb;
aabb.lowerBound.Set(-1.0f, -1.0f);
aabb.upperBound.Set(1.0f, 1.0f);
myWorld->Query(&callback, aabb);
cs






기타. 참조자료


소난의 실험실 :: '컴퓨터/Box2D' 카테고리의 글 목록

하얀기적이 있는 곳.. :: IOS Cocos2d 물리엔진 Box2d 번역






기타. 변경이력


일자

변경이력

2017-08-30

 초안 작성 시작

2018-04-03

 초안 공개