Wiązania (joints) Malwina Łagód
Informacje ogólne Wiązania służą do ograniczania ciała. Występują między dwoma ciałami (min. jedno dynamiczne) Każdy joint to potomek klasy b2JointDef Parametry: 2 ciała, które wiąże, punkty zaczepu, kolizja. Są konstruowane do ograniczania ruchu ciała względem świata lub innego ciała. Niektóre rodzaje wiązań pozwalają na ustalanie granic, dzięki temu można kontrolowac zakres ruchu ciała. Połączenia mięczy statycznymi/kinematycznymi sa możliwe, ale nie mają żadnych efektów i tylko zwiekszają czas przetwarzania.
Tworzenie XXX – rodzaj wiązania. b2XXXJointDef jointDef; // np b2PrismaticJointDef jointDef.Initialize( /* parametry */ ); jointDef.collideConnected = true; // kolizje b2XXXJoint * joint =( b2XXXJoint * ) world.Crea teJoint( & jointDef ); // tworzymy joint // coś tam się dzieje world.DestroyJoint( joint ); // usuwanie XXX – rodzaj wiązania.
Dziedziczone metody joint->GetBodyA(); // wskaźnik na pierwsze ciało joint->GetBodyB(); // wskaźnik na drugie ciało joint->GetAnchorA(); // punkt zaczepu w ciele pierwszym joint->GetAnchorB(); // punkt zaczepu w ciele drugim joint->GetCollideConnected(); // czy połączone ciała mają ze sobą kolidować?
Napęd Niektóre wiązania udostępniają napęd (revolute, gear i wheel) jointDef.motorEnabled = true; // włączamy motor jointDef.maxMotorTorque = 20; // maksymalna siła, jakiej może użyć motor jointDef.motorSpeed = 36; // docelowa prędkość obrotu (radiany/sekundę) Jeśli wiązanie ma coś wspólnego z obracaniem się, będzie się obracało ze stałą prędkością.
Rodzaje jointów
Distance joint Pomaga w utrzymaniu stałego dystansu. Może być „twardy” lub „miękki” Parametry: częstotliwość drgań - im więcej, tym joint będzie twardszy współczynnik tłumienia - tłumienie wychyleń, między 0 a 1. 1 całkowicie wyłącza miękkość "twardy" - wtedy nie będzie pozwalał na zmianę dystansu niezlażnie od sił działających na ciała "miękki" - będzie działał jak sprężyna dążąca do utrzymania stałego dystansu
Distance joint
Distance joint b2DistanceJointDef jointDef; jointDef.Initialize( myBodyA, myBodyB, myBodyA- >GetWorldCenter(), myBodyB- >GetWorldCenter() ); // w tym przypadku łączymy ze sobą środki ciężkości tych dwóch ciał jointDef.collideConnected = true;// miękkość jointDef.frequencyHz = 4.0f; // częstotliwość drgania jointDef.dampingRatio = 0.45f; // tłumienie
Revolute joint Pozwala utrzymać punkt jednego ciała w jakimś punkcie innego ciała. Mamy do dyspozycji: motor - regulowanie wzajemnego obrotu ciał limit - do jakiego kąta względem początkowego mogą obrócić się ciała Działa jak szpilka
Revolute joint
Revolute joint b2RevoluteJointDef jointDef; // pierwsza metoda jointDef.Initialize( bodyA, bodyB, bodyB- >GetWorldCenter() ); // inicjalizacja. // alternatywny sposób jointDef.bodyA = bodyA; jointDef.bodyB = bodyB; jointDef.localAnchorA = bodyA- >GetLocalCenter(); // ustawiamy punkt zaczepu w pierwszym ciele. jointDef.localAnchorB = bodyB- >GetLocalCenter(); // i w drugim Trzeci argument to punkt zaczepu w koordynatach globalnych. W tym punkcie muszą znajdować się fragmenty obydwu tych ciał! ciała będą się poruszać jak dwie kulki na końcu sznurka, który w pewnym miejscu jest trzymany w powietrzu. W takim wypadku można włączyć parametr collideConnected Punkt zaczepu Jest we współrzędnych LOKALNYCH ciała // obie te metody będą miały taki sam skutek, ponieważ punkt zaczepu drugiego ciała zostanie natychmiast "przyciągnięty" do punkt zaczepu w pierwszym ciele
Revolute joint jointDef.collideConnected = false; // limit jointDef.enableLimit = true; // musimy włączyć limit jointDef.referenceAngle = 75.5f; // kąt uznawany za "początkowy" jointDef.lowerAngle = 32.f; // minimalny obrót jointDef.upperAngle = 89.5f; // maksymalny obrót. // motor jointDef.enableMotor = true; // musimy włączyć motor jointDef.motorSpeed = 46.f; // docelowa prędkość jointDef.maxMotorTorque = 100.0f; // maksymalna siła, jakiej może użyć motor, kiedy próbuje uzyskać prędkość docelową ciała połączone revolute jointem NIE MOGĄ ze sobą kolidować Kąt poczatkowy od niego liczą sie limity (domyślnie 0) Radiany
Prismatic joint Pozwala na ruch jednego ciała po osi drugiego Udostępnia: punkt wspólny kąt – stały oś – względem niej możliwy jest ruch motor – prędkość poruszania się limit – jak bardzo mogą się „rozjechać” przypomina przypiętą do pierszwego ciała szynę, po której może poruszać sie drugie.
Prismatic joint
Prismatic joint b2PrismaticJointDef jointDef; b2Vec2 moveAxis( 1.0f, 0.0f ); //poruszaja się poziomo jointDef.Initialize( bodyA, bodyB, b2Vec2( 35.f, 52.0 f ), moveAxis ); // inicjalizacja jointDef.collideConnected = true; jointDef.enableLimit = true; jointDef.lowerTranslation = 0.0f; // min przesunięcie jointDef.upperTranslation = 50.0f; // max przesunięcie jointDef.enableMotor = true; jointDef.motorSpeed = 30.0f; // prędkość przesuwania się jointDef.maxMotorForce = 300.0f; // maksymalna siła
Pulley joint Pozwala stworzyć układ ciężarków Posiada 4 punkty zaczepu 2 na ciałach 2 w miejscach zawieszenia Przełożenie (ratio) – jak bardzo działanie na pierwszy ciężarek działa na drugi
Pulley joint
Pulley joint b2PulleyJointDef jointDef; b2Vec2 anchor1 = bodyA- >GetWorldPoint( 0.0f, - 1.0f ); // punkt zaczepu w pierwszym ciele b2Vec2 anchor2 = bodyB->GetWorldCenter(); b2Vec2 block1( 3.4f, 2.5f ); // punkt "zwieszania" się pierwszego ciężarka b2Vec2 block2( 5.4f, 2.5f ); // i drugiego float ratio = 1.0f; // przełożenie jointDef.Initialize(bodyA, bodyB, block1, block2, anchor1, anchor2, ratio ); // inicjalizacja
Mouse joint Przyciąga jedno ciało do dowolnego punktu w świecie Drugie ciało powinno być statyczne. Działa podobnie do distance joint działa tylko na jedno ciało, jako drugie powinno być podane dowolne istniejące statyczne ciało.
Mouse joint b2MouseJointDef jointDef; jointDef.bodyA = myStaticBody; // jakieś statyczne ciało jointDef.bodyB = body; // ciało, na które chcemy działać jointDef.target.Set( 0.5f, 24.f ); // punkt, do którego chcemy przyciągać ciało, jednocześnie będący punktem zaczepienia jointDef.maxForce = 300.0f; // max siła przyciągania jointDef.frequencyHz = 4.0f; // jak w distance joincie jointDef.dampingRatio = 0.5f; // później na utworzonym już joincie: joint->SetTarget( 0.45f, 34.f ); // zmiana punktu docelowego (ale punktu zaczepu już nie!)
Wheel joint Wiązanie to jest kombinacją distance, revolute i prismatic jointa. Pozwala poruszać się po jednej osi, przyciągać do jednego punktu oraz swobodnie obracać się. Koła samochodu, motocyklu, roweru, itd. Pozwala on poruszać się po jednej osi, jednocześnie przyciągając go do pewnego punktu na tej osi. Ponadto pozwala mu sie swobodnie obracać.
Wheel joint
Wheel joint // amortyzatory b2WheelJointDef spr; spr.collideConnected = false; spr.enableMotor = true; spr.motorSpeed = 0.0f; spr.dampingRatio = 4.0f; spr.frequencyHz = 0.4f; spr.maxMotorTorque = 1000.0f; b2Vec2 axis( 0.0f, 1.0f ); // pionowo w dół spr.Initialize( carBody, leftWheelBody, carOriginPos + b2Vec2( 20.0f, 60.0f ), axis); world.CreateJoint( & spr ); spr.Initialize( carBody, rightWheelBody, carOriginPos + b2Vec2 ( 90.0f, 60.0f ), axis); world.CreateJoint( & spr );
Rope joint Pozwala ustalić maksymalny dystans między dwoma ciałami.
Rope joint b2RopeJointDef jointDef; jointDef.bodyA = bodyA; jointDef.bodyB = bodyB; jointDef.localAnchorA = bodyA- >GetLocalCenter(); jointDef.localAnchorB = bodyB- >GetLocalCenter(); jointDef.maxLength = 30.0f; // max dystans
Koniec