이것은
바퀴, 롤러, 사슬, 선개교, 봉제 인형, 회전문, 투석기, 레버
등에 이용된다.
localAnchorA - 강체 A가 그 주변에서 회전할 정점
localAnchorB - 강체 B가 그 주변에서 회전할 정점
referenceAngle - 처음의 강체간 각도를 0으로(변경 가능) 하는 접합점의 회전각
enableLimit - 접합점의 회전제한 여부
lowerAngle - 하한각
upperAngle - 상한각
enableMotor - 접합점의 모터의 활성화 여부
motorSpeed - 모터의 목적 속도
maxMotorTorque - 모터가 사용가능한 최대 토크의 크기
을 속성으로 가진다.
- 지역 거점
  revoluteJointDef.localAnchorA.Set(1,1);
  revoluteJointDef.localAnchorB.Set(0,0);
  사각형이 A, 원이 B
이 값은 GetAnchorA() 와 GetAnchorB() 메서드를 통해 얻을 수 있다.
 주의할 것은 고정체를 연결하는 것이 아닌 강체를 연결한다는 것이다.
 항상 Box2D에서 위 두 강체를 접합시킬 수 있는 것은 아니며, 지속적으로 우측의 그림과 같이 형상을 유지하도록 힘을 가한다.
 - 참조 각
  revoluteJointDef.referenceAngle = 0;  //기본값이기도 하다.
 이 각은 GetJointAngle() 메서드를 통해 가능한데 얻는 값은 referenceAngle의 초기 설정값에 따라 그림의 우측과 같이 다르게 출력된다.
 이 각은 강체간 사이의 각도에 관계되어 있으므로 위와 같이 저 전체가 회전하였다고 하여도 GetJointAngle() 메서드의 출력값은 변하지 않는다.
 - 회전각 제한
  revoluteJointDef.enableLimit = true;
  revoluteJointDef.lowerAngle = -45 * DEGTORAD;
  revoluteJointDef.upperAngle =  45 * DEGTORAD;
 제한을 걸게 되면, 상한, 하한 모두 같이 제한이 설정된다. 즉, 하나만 제한을 걸 수 없다. 따라서 상한만 제한을 걸고자 한다면, 하한의 제한값을 크게 낮게 잡아야 한다.
  void EnableLimit(bool enabled);
  void SetLimits( float lower, float upper );
  bool IsLimitEnabled();
  float GetLowerLimit();
  float GetUpperLimit();
 이 메서드로 실행 중 값을 얻어올 수 있다.
 물론 이 또한 큰 속도로 강체가 회전하고 있었을 경우, 제한을 넘겼을 때, 잠깐 초과된 모습이 화면에 그려질 수 있으나 곧 Box2D가 제한점으로 위치시킨다.
 현재 접합점이 제한점 상에 있는지를 확인하는 방법은 간단하며 다음과 같다.
bool atLowerLimit = joint->GetJointAngle() <= joint->GetLowerLimit();
bool atUpperLimit = joint->GetJointAngle() >= joint->GetUpperLimit();
 - 모터
 기본 접합점의 행동방식은 저항 없이 회전하는 것이다. 허나 모터를 적용하여 이를 회전시킬 수 있다. 회전은 각속도를 명시함으로 이루어진다. 단 이는 최대 도달가능한 각속도를 명시하는 것이며 즉시 속도를 설정하는 것이 아니다.
 회전을 시키는 것은 토크의 크기를 지정함으로써 이루어진다. 이 말은 반드시 최대 각속도에 도달할 수 있다는 보장이 없다는 것이다.
  revoluteJointDef.enableMotor = true;
  revoluteJointDef.maxMotorTorque = 20;
  revoluteJointDef.motorSpeed = 360 * DEGTORAD;
 //alter joint motor
  void EnableMotor(bool enabled);
  void SetMotorSpeed(float speed);
  void SetMaxMotorTorque(float torque);
  //query joint motor
  bool IsMotorEnabled();
  float GetMotorSpeed();
  float GetMotorTorque();
최대 각속도를 0으로 지정할 경우 모터는 브레이크와 같은 역할을 하게 된다.
Testbed에는 0, 0에 정적 강체가 멤버로 존재한다. 그 이름은 m_goundBody  이다.
다음은 맨 상위 주소에서 제공한 튜토리얼의 결과이다.
접합점을 연결한 강체 두개와, 체인을 하나 생성해 본다.
#ifndef __MYREVOLUTEJOINTTEST_H__
#define __MYREVOLUTEJOINTTEST_H__
class MyRevoluteJointTest : public Test {
public:
 //각각 강체와 접합점의 포인터.
 b2Body* m_bodyA, *m_bodyB;
 b2RevoluteJoint* m_joint;
 MyRevoluteJointTest(){
  //이하는 맵을 정의
  //body definition
  b2BodyDef myBodyDef;
  myBodyDef.type = b2_dynamicBody;
  //shape definition
  b2PolygonShape polygonShape;
  polygonShape.SetAsBox(1, 1); //a 2x2 rectangle
  //fixture definition
  b2FixtureDef myFixtureDef;
  myFixtureDef.shape = &polygonShape;
  myFixtureDef.density = 1;
  //create dynamic body
  myBodyDef.position.Set(0, 10);
  //pBody1 = m_world->CreateBody(&myBodyDef);
  //pBody1->CreateFixture(&myFixtureDef);
  //a static body
  myBodyDef.type = b2_staticBody;
  myBodyDef.position.Set(0, 0);
  b2Body* staticBody = m_world->CreateBody(&myBodyDef);
  //add four walls to the static body
  polygonShape.SetAsBox( 20, 1, b2Vec2(0, 0), 0);//ground
  staticBody->CreateFixture(&myFixtureDef);
  polygonShape.SetAsBox( 20, 1, b2Vec2(0, 40), 0);//ceiling
  staticBody->CreateFixture(&myFixtureDef);
  polygonShape.SetAsBox( 1, 20, b2Vec2(-20, 20), 0);//left wall
  staticBody->CreateFixture(&myFixtureDef);
  polygonShape.SetAsBox( 1, 20, b2Vec2(20, 20), 0);//right wall
  staticBody->CreateFixture(&myFixtureDef);
  //이하는 두 강체를 연결하는 단계,
  //body and fixture defs - the common parts
  b2BodyDef bodyDef;
  bodyDef.type = b2_dynamicBody;
  b2FixtureDef fixtureDef;
  fixtureDef.density = 1;
  //two shapes
  b2PolygonShape boxShape;
  boxShape.SetAsBox(2,2);
  b2CircleShape circleShape;
  circleShape.m_radius = 2;     
  //make box a little to the left
  bodyDef.position.Set(-3, 10);
  fixtureDef.shape = &boxShape;
  m_bodyA = m_world->CreateBody( &bodyDef );
  m_bodyA->CreateFixture( &fixtureDef );
  //and circle a little to the right
  bodyDef.position.Set( 3, 10);
  fixtureDef.shape = &circleShape;
  fixtureDef.friction = 0.5;
  m_bodyB = m_world->CreateBody( &bodyDef );
  m_bodyB->CreateFixture( &fixtureDef );
  b2RevoluteJointDef revoluteJointDef;
  revoluteJointDef.bodyA = m_bodyA;
  revoluteJointDef.bodyB = m_bodyB;
  revoluteJointDef.collideConnected = false;
  revoluteJointDef.localAnchorA.Set(2,2);//the top right corner of the box
  revoluteJointDef.localAnchorB.Set(0,0);//center of the circle
  //revoluteJointDef.localAnchorA.Set(4,4);//the top right corner of the box
  //revoluteJointDef.localAnchorB.Set(-2,0);//center of the circle
  //revoluteJointDef.enableLimit = true;
  //revoluteJointDef.lowerAngle = -45 * DEGTORAD;
  //revoluteJointDef.upperAngle =  45 * DEGTORAD;
  revoluteJointDef.enableMotor = true;
  revoluteJointDef.maxMotorTorque = 225;
  revoluteJointDef.motorSpeed = 1390 * DEGTORAD;//90 degrees per second
  m_joint = (b2RevoluteJoint*)m_world->CreateJoint( &revoluteJointDef );
  {//이하는 체인 생성을 위한 단계
   b2BodyDef bodyDef;
   bodyDef.type = b2_dynamicBody;
   bodyDef.position.Set(5,10);
   b2FixtureDef fixtureDef;
   fixtureDef.density = 1;
   b2PolygonShape polygonShape;
   polygonShape.SetAsBox(1,0.25);
   fixtureDef.shape = &polygonShape;
   //create first link
   b2Body* link = m_world->CreateBody( &bodyDef );
   link->CreateFixture( &fixtureDef );
   //set up the common properties of the joint before entering the loop
   b2RevoluteJointDef revoluteJointDef;
   revoluteJointDef.localAnchorA.Set( 0.75,0);
   revoluteJointDef.localAnchorB.Set(-0.75,0);
   //use same definitions to create multiple bodies
   for (int i = 0; i < 10; i++) {
    b2Body* newLink = m_world->CreateBody( &bodyDef );
    newLink->CreateFixture( &fixtureDef );
    //...joint creation will go here...
    //inside the loop, only need to change the bodies to be joined
    revoluteJointDef.bodyA = link;
    revoluteJointDef.bodyB = newLink;
    m_world->CreateJoint( &revoluteJointDef );
    link = newLink;//prepare for next iteration
   }
   //body with circle fixture
   b2CircleShape circleShape;
   circleShape.m_radius = 2;
   fixtureDef.shape = &circleShape;
   b2Body* chainBase = m_world->CreateBody( &bodyDef );
   chainBase->CreateFixture( &fixtureDef );
   //a revolute joint to connect the circle to the ground
   revoluteJointDef.bodyA = m_groundBody;//provided by testbed
   revoluteJointDef.bodyB = chainBase;
   revoluteJointDef.localAnchorA.Set(4,20);//world coords, because m_groundBody is at (0,0)
   revoluteJointDef.localAnchorB.Set(0,0);//center of circle
   m_world->CreateJoint( &revoluteJointDef );
   //another revolute joint to connect the chain to the circle
   revoluteJointDef.bodyA = link;//the last added link of the chain
   revoluteJointDef.bodyB = chainBase;
   revoluteJointDef.localAnchorA.Set(0.75,0);//the regular position for chain link joints, as above
   revoluteJointDef.localAnchorB.Set(1.75,0);//a little in from the edge of the circle
   m_world->CreateJoint( &revoluteJointDef );
  }
 }
 void Step(Settings* settings){
  Test::Step(settings);
 }
 void MouseDown(const b2Vec2& p){
  b2Vec2 pp = p;
  pp.y = pp.y -1;
  Test::MouseDown(pp);
 }
 static Test* Create(){
  return new MyRevoluteJointTest();
 }
};
#endif
이상. 기록 끝.



 
댓글 없음:
댓글 쓰기