Box2D - 7.Shapes

번역/Box2D AS3 매뉴얼 2009/11/25 16:58 Posted by 하늘색 공책
일러두기>진행중인 문서입니다. 대부분 완료되었습니다.
원문보기>http://www.box2d.org/wiki/index.php?title=Manual/AS3#Shapes

About 개요

모양은 강체에 붙여지는 충돌 도형이다. 또한 모양은 강체의 질량을 정의하는데 쓰이기도 한다. 이는 당신이 밀도를 명시하게 하고 Box2D가 질량을 계산하는작업을 맡는 것이다.[todo:의역제거]

모양은 마찰과 탄성 속성을 갖는다. 그리고 특정한 게임 객체와의 충돌을 무시하는 필터링 정보를 갖고 있다.

모양은 항상 강체에 의해 소유된다. 당신은 하나의 강체에 며러 개의 모양을 붙일 수 있다. 모양은 추상 클래스이며 다양한 형태의 모양이 Box2D에서 구현될 수 있다. 당신이 용사-_-라면 당신은 고유의 모양을 구현할 수 있다. (또한 충돌 알고리즘도.)

The Shape Definition 모양의 정의

모양의 정의는 모양을 생성하기 위해 사용된다. 모양에서 공통되는 데이터는 b2ShapeDef가 가지고 있고 고유한 데이터는 파생 클래스가 갖고 있다.

Friction and Restitution 마찰과 탄성

마찰은 물체들이 서로 사실적으로 미끄러지도록 만드는 데 쓰인다. Box2D는 정적, 동적마찰을 지원하지만 양자는 같은 인수를 사용한다. 마찰은 Box2D에서 정확하게 시뮬레이트되며 마찰 강도는 법선 힘(이것은 쿨롱 마찰이라고 불린다.)에 비례한다. 마찰 인수는 일반적으로 0과 1사이에서 설저된다. 0의 값은 마찰을 끄고 1의 값은 마찰을 강하게 한다. 두 모양 사이에서 마찰이 계산될 때 Box2D는 두 모양의 마찰 인수를 병합해야 한다. 이것은 다음 수식에 의해 완료된다.

var friction :Number = Math.sqrt(shape1.friction * shape2.friction);
탄성은 물체를 튕겨내는데 사용된다. 탄성 값은 일반적으로 0과 1 사이의 값으로 설정된다. 테이블에 공을 떨어트리는 것을 생각해보자. 0의 값은 공이 튀기지 않음을 의미한다. 이는 비탄성 충돌이라 불린다. 1의 값은 공의 속도가 완전하게 반사됨을 의미한다. 이것은 완전 탄성 충돌이라 불린다. 탄성은 다음 수식을 통해 합성된다.







var restitution: Number = Math.Max(shape1.restitution, shape2.restitution);


모양이 복수의 충돌을 일으켰을 때 탄성은 간략하게 시뮬레이션된다. 이것은 Box2D가 반복적인 처리자를 사용하기 떄문이다. Box2D는 또한 충돌 속도가 작을 때에는 비탄성 충돌을 사용한다.


Density 밀도

Box2D는 강체에 붙여진 모양에 의해 암시된 질량의 분포를 사용해서 질량과 강체의 회전 관성을 선택적으로 계산한다. (todo:오역소지) 직접적으로 질량을 명시하는 것은 때때로 허접한 시뮬레이션을 만든다. 그러므로, 권장하는, 강체의 질량을 명시하는 방법은 모양의 밀도를 지정하고 강체에 붙여진 모든 모양에 대해 b2Body.setMessFromShape를 한번씩 호출하는 것이다.


Filtering

충돌 필터링은 모양들 사이의 충돌을 방지하는 시스템이다. 예를 들어, 당신이 자전거를 타는 캐릭터를 만든다고 해보자. 당신은 자전거가 지형과 충돌하고, 캐릭터도 지형과 충돌하길 원한다. 그러나 캐릭터가 자전거와 충돌하길 원하지는 않을 것이다 (그것들은 겹쳐져 있어야 하니까.) Box2D는 그런 충돌을 카테고리와 그룹을 통해 필터링하는 것을 지원한다.


Box2D는 16개의 충돌 카테고리를 지원한다. 각 모양을 위해 당신은 어느 카테고리에 그것이 속할 것인지 지정할 수 있다. 또한 어떤 카테고리가 이 모양과 충돌할 수 있을지도 지정할 수 있다. 예를 들면, 당신은 모든 플레이어가 서로 충돌하지 않고 몬스터들도 서로 충돌하지 않지만 플레이어와 몬스터는 충돌해야 하는 다중사용자 게임을 정의할 수 있다. 이것은 비트 마스크를 통해 이루어진다. 다음 예제를 보자.


playerShapeDef.filter.categoryBits = 0x0002;

monsterShapeDef.filter.categoryBits  = 0x0004;

playerShapeDef.filter.maskBits       = 0x0004;

monsterShapeDef.filter.maskBits      = 0x0002;

충돌 그룹은 필수적인 그룹 인덱스를 명시해야 한다. 당신은 같은 인덱스를 가진 모든 모양들이 항상 충돌(양수 인덱스)하거나, 또는 절대 충돌하지 않(음수 인덱스)도록 할 수 있다. 그룹 인덱스들은 일반적으로, 자전거의 각 부품들처럼 어떻게든 관계가 있는 것들을 위해 사용된다. 다음 예제에서는, shape1과 shape2가 항상 충돌한다. 그러나 shape3과 shape4는 절대 충돌하지 않는다.


shape1Def.filter.groupIndex = 2;
shape2Def.filter.groupIndex = 2;
shape3Def.filter.groupIndex = -8;
shape4Def.filter.groupIndex = -8;

다른 그룹 인덱스를 가진 모양들 사이의 충돌은 카테고리와 마스크 비트에 의해 걸러진다. 달리 말하면, 그룹 필터링은 그룹 필터링은 카테고리 필터링보다 선행한다는 것이다.

다음은 Box2D에서 일어나는 추가적인 필터링의 목록이다.

  • 정적 강체에 있는 모양은 다른 정적 강체의 모양과 절대 충돌하지 않는다.
  • 한 강체 안의 모양들은 절대 서로 충돌하지 않는다.
  • 당신은 조인트로 연결된 강체들의 모양이 서로 충돌할지 선택할 수 있다.

Sometimes you might need to change collision filtering after a shape has already been created. You can get and set the b2FilterData structure on an existing shape using b2Shape.GetFilterData and b2Shape.SetFilterData. Box2D caches filtering results, so you must manually re-filter a shape using b2World.Refilter.

때떄로 당신은 모양이 기존에 생성된 후에 충돌 필터링을 변경할 필요가 있을 것이다. 당신은 b2FilterData 구조체를 기존 모양의 b2Shape.GetFilterData와 b2Shape.SetFilterData를 통해 얻거나 지정할 수 있다. Box2D는 필터링 결과를 캐시해 두므로, 당신은 b2World.Refilter를 통해 수동으로 모양들을 다시 필터링할 필요가 있다.


Sensors

때떄로 게임 로직은 아직 충돌 반응이 없을 때라도 언제 두 모양이 겹쳐졌는지를 알 필요가 있다. 이것은 센서를 통해 이루어진다. 센서는 충돌을 감지하지만 반응을 일으키지는 않는 모양의 하나이다.


You can flag any shape as being a sensor. Sensors may be static or dynamic. Remember that you may have multiple shapes per body and you can have any mix of sensors and solid shapes.

당신은 어떤 모양이든 센서로서 기능하는 플래그를 지정할 수 있다. 센서는 정적이거나 동적일 수 있다. 강체 하나가 복수의 모양을 가질 수 있으며, 센서와 일반적인 모양을 아무렇게든 섞을 수 있음을 기억하라.


myShapeDef.isSensor = true;

Circle Definitions 원의 정의

b2CicleDef는 b2ShapeDef를 확장하며 지역적 위치와 반지름을 추가한다.


var def:b2CircleDef;
def.radius = 1.5;
def.localPosition.Set(1.0, 0.0);

Polygon Definitions 폴리곤의 정의

b2PolyDef is used to implement convex polygons. They are a bit tricky to use correctly, so please read closely. The maximum vertex count is defined by b2_maxPolyVertices which is currently 8. If you need to use more vertices, you must modify b2_maxPolyVertices in file b2Settings.
b2PolyDef는 볼록한 폴리곤을 구현한다. (todo:의불) 정점 수의 최대값은 b2_maxPolyVertices에 의해 정의되며 이 값은 현재 8이다. 만약 더 많은 정점을 필요로 한다면 b2Settings파일에 있는 b2_maxPolyVertices를 수정해야 한다.

When you build a polygon definition you must specify the number of vertices you will use. The vertices must be specified in counter-clockwise (CCW) order about the z-axis of a right-handed coordinate system. This might turn out to be clockwise on your screen, depending on your coordinate system conventions.

당신이 폴리곤의 정의를 구성할 때 사용할 정점의 갯수를 명시해야 한다. 정점들은 오른손 법칙 체계의 z축에 대해 시계반대방향 순서로 명시되어야 한다. 이것은 좌표체계의 방식에 의존하는 화면상에서는 결국 시계 반대 방향이 될 것이다. (todo:오역)


폴리곤은 반드시 볼록해야 한다. 달리 말하면, 각 정점은 일정 각도만큼 밖으로 향해야 한다. 마지막으로, 당신은 어떤 정점도 겹치지 않도록 해야 한다. Box2D는 자동적으로 루프를 끝낼 것이다.

convex_concave.gif

여기 삼각형을 이루는 폴리곤의 정의에 대한 예제가 있다.


var triangleDef:b2PolygonDef = b2PolygonDef()
triangleDef.vertexCount = 3
triangleDef.vertices[0].Set(-1.0, 0.0)
triangleDef.vertices[1].Set(1.0, 0.0)
triangleDef.vertices[2].Set(0.0, 2.0)

정점들은 부모 강체의 좌표체계 안에서 정의된다. 만약 당신이 상위 강체 안에서 폴리곤을 이동시키려면 단지 모든 정점을 이동시키면 된다.

편의를 위해서 폴리곤을 상자로서 초기화하는 함수가 있다. 당신은 강체 원점에 중심을 두는 축 정렬 상자나 강체 원점에서 이동된 상자를 얻을 수 있다.


// aligned

var alignedBoxDef:b2PolygonDef = new b2PolygonDef();
var hx:Number = 1.0; // half-width
var hy:Number = 2.0; // half-height
alignedBoxDef.SetAsBox(hx, hy);
// oriented var orientedBoxDef:b2PolygonDef = new b2PolygonDef(); var center:b2Vec2 = new b2Vec2(-1.5, 0.0); var angle:Number = 0.5 * b2Settings.b2_pi; orientedBoxDef.SetAsOrientedBox(hx, hy, center, angle);

Shape Factory

모양들은 강체 정의의 초기화에 의해 생성되며 상위 강체의 정의에 전달된다.


var circleDef:b2CircleDef = new b2CircleDef();
circleDef.radius = 3.0;
circleDef.density = 2.5;
var myShape:b2Shape = myBody.CreateShape(circleDef);
//[선택적으로 어딘가에 모양 객체를 저장한다]

이것은 모양을 생성하고 강체에 붙인다. 당신은 모양의 포인터를 저장할 필요가 없다. 모양은 상위 강체가 파괴될 때 자동적으로 파괴되므로. (묵시적 파괴를 보라)


당신이 모양을 강체에 붙이는 작업을 마친 후, 당신은 강체의 질량을 자식 모양에 기반해 재계산하기를 원할 것이다.


myBody.SetMassFromShapes()

이 함수는 실행 비용이 크다. 그러므로 당신은 이것을 필요할 때에만 호출해야 한다.

You can destroy a shape on the parent body easily. You may do this to model a breakable object. Otherwise you can just leave the shape alone and let the body destruction take care of destroying the attached shapes.

당신은 상위 강체 위에서 모양을 쉽게 파괴할 수 있다. 당신은 파괴 가능한 물체를 만들 때 이를 행할 것이다. (todo:의불)

myBody.DestroyShape(myShape)

강체로부터 모양이 삭제된 후, 당신은 SetMassFromShapes를 다시 호출하고 싶을 것이다.


Using a Shape 모양의 사용

여기서 할 말은 많지 않다. 당신은 모양의 종류와 그 상위의 강체를 얻을 수 있다. 또한 한 점이 모양 위에 포함되는지를 보기 위해 테스트를 할 수도 있다. 자세한 것은 b2Shape.h를 보라.

저작자 표시 비영리 동일 조건 변경 허락