2012-10-26 5 views
0

Je suis en train de créer une chose semblable à une voiture en 2D en utilisant box2dweb. J'ai une boîte pour la carrosserie de la voiture et deux cercles, reliés par des joints rotatifs, comme les roues. Tout fonctionne bien pendant un certain temps, mais progressivement les écarts augmentent entre les centres des roues et les points sur la boîte à laquelle ils étaient attachés. Configurer plus d'itérations pour le solveur n'aide pas, et tôt ou tard, les roues s'éloignent complètement de la boîte. Cela ressemble à une erreur accumulée quelconque. En outre, la collision des roues avec quelques bosses sur le terrain semblent être le facteur le plus contribuant à ce problème. Dans un premier temps, il est comme sur la photo à gauche, mais après que je conduis sur la grosse boule sur le sol deux ou trois fois, il obtient comme sur l'image de droite, et reste de cette façon:Box2dWeb joint rotatif "étirement"

Left: initial state, right: after I drive it over the big circle several times.

J'ai utilisé un ancienne bibliothèque box2djs avant et ne semblait pas avoir ce problème là-bas. Le problème est apparu après avoir porté le code sur box2dweb. Il y a quelques différences dans la façon dont les choses sont créées dans ces deux bibliothèques, donc j'ai dû manquer quelque chose, mais je ne sais pas quoi.

Le code de la boîte:

function createBox(world, x, y, width, height) 
{ 
    var fixDef = new b2FixtureDef; 
    fixDef.density = 1.0; 
    fixDef.friction = 1.0; 
    fixDef.restitution = 1.0; 

    var bodyDef = new b2BodyDef; 
    bodyDef.type = b2Body.b2_dynamicBody; 
    bodyDef.position.x = x; 
    bodyDef.position.y = y; 

    fixDef.shape = new b2PolygonShape; 
    fixDef.shape.SetAsBox(width, height); 

    var b = world.CreateBody(bodyDef); 
    b.CreateFixture(fixDef); 
    return b; 
} 

Pour les roues (presque identiques, sauf qu'il crée des cercles):

function createBall(world, x, y, r) 
{ 
    var fixDef = new b2FixtureDef; 
    fixDef.density = 1.0; 
    fixDef.friction = 1.0; 
    fixDef.restitution = 1.0; 

    var bodyDef = new b2BodyDef; 
    bodyDef.type = b2Body.b2_dynamicBody; 
    bodyDef.position.x = x; 
    bodyDef.position.y = y; 

    fixDef.shape = new b2CircleShape(r); 

    var b = world.CreateBody(bodyDef); 
    b.CreateFixture(fixDef); 
    return b; 
} 

Et pour les articulations:

var jointDef_rear = new b2RevoluteJointDef(); 
jointDef_rear.Initialize(rear_wheel, car_body, rear_wheel.GetPosition()); 
jointDef_rear.maxMotorTorque = 10.0; 
jointDef_rear.enableMotor = true; 

rear_joint = world.CreateJoint(jointDef_rear); 

var jointDef_front = new b2RevoluteJointDef(); 
jointDef_front.Initialize(front_wheel, car_body, front_wheel.GetPosition()); 
jointDef_front.maxMotorTorque = 10.0; 
jointDef_front.enableMotor = true; 

front_joint = world.CreateJoint(jointDef_front); 

Alors Autant que je déteste me demander "qu'est-ce qui ne va pas avec mon code" - des questions de kinda, qu'est-ce que je fais de mal ici?

+0

Pouvez-vous télécharger le code afin que je puisse le voir en action? – Shekhar

+0

Bien sûr. http://lazunin.com/ask/rotate.html Le moyen le plus rapide pour voir l'étirement est d'utiliser plusieurs fois les touches "A" et "D" pour frapper la roue avant contre le sol (ASD contrôle la roue arrière, JKL - la roue avant.) http://lazunin.com/poro/J'ai un autre exemple, qui utilise box2djs au lieu de box2dweb et ne montre aucun étirement du tout – Headcrab

Répondre

0

Il semble que le problème a été causé par zéro itérations de position:

world.Step(dt, iterations); 

Il semble que dans les anciennes versions de Box2Djs le prototype de la fonction était exactement comme ça. Dans une version plus récente, cependant, il a été changé pour

function (dt, velocityIterations, positionIterations) 

avec tous les paramètres par défaut à 0. L'appel à l'ancienne, comme world.Step(dt, iterations) serait alors égale à world.Step(dt, iterations, 0), qui encore « sorte de » œuvres, mais le les positions relatives des corps connectés ne sont pas correctement résolues. J'ai essayé de l'appeler comme world.Step(dt, iterations, iterations), et tout à coup tout a été corrigé, même si le nombre d'itérations est faible, comme 3.

0

Très probablement, la raison est dans la masse des corps.

Box2D maunal dit:
chaînes de corps reliés par des joints peuvent s'étirer si un corps de briquet soutient un corps plus lourd. Par exemple, une boule de démolition connectée à une chaîne de corps légers peut ne pas être stable. La stabilité se dégrade à mesure que le rapport massique passe à 10: 1.

Votre roue avant est trop petite et sa densité est égale à celle des autres véhicules. Donc, sa masse est très différente de la masse du corps de la voiture. Essayez, par exemple, de régler la masse volumique de la carrosserie 0,2, la densité de la roue arrière sur 0,5 et la masse volumique avant sur 1,5. Ou mieux définir le manuel de masse à chaque corps par b2Body::SetMassData. Je pense, il vaudrait mieux faire des roues plus lourdes que des box.

+0

J'ai essayé ça, ça n'a pas aidé, ils s'étendent encore, et de façon assez ridicule. – Headcrab