Box2D Forums

It is currently Mon May 20, 2013 3:04 pm

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Tue Aug 07, 2012 2:16 am 
Offline

Joined: Wed Jul 25, 2012 5:08 am
Posts: 53
I tried to port it from the latest Box2D but failed.
The testbed car.h was ported, and I found it a bit difficult to debug..
Could someone give any suggestion on it?


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 2:19 am 
Offline

Joined: Wed Jul 25, 2012 5:08 am
Posts: 53
Here comes the screen snapshot.


Attachments:
car.png
car.png [ 46.74 KiB | Viewed 1290 times ]
Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 2:20 am 
Offline

Joined: Wed Jul 25, 2012 5:08 am
Posts: 53
WheelJointDef.java

Code:
package org.jbox2d.dynamics.joints;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;

public class WheelJointDef extends JointDef {
   /// The local anchor point relative to bodyA's origin.
   public Vec2 localAnchorA;

   /// The local anchor point relative to bodyB's origin.
   public Vec2 localAnchorB;

   /// The local translation axis in bodyA.
   public Vec2 localAxisA;

   /// Enable/disable the joint motor.
   public boolean enableMotor;

   /// The maximum motor torque, usually in N-m.
   public float maxMotorTorque;

   /// The desired motor speed in radians per second.
   public float motorSpeed;

   /// Suspension frequency, zero indicates no suspension
   public float frequencyHz;

   /// Suspension damping ratio, one indicates critical damping
   public float dampingRatio;
   
   public WheelJointDef() {
      type = JointType.WHEEL;
      
      localAnchorA = new Vec2();
      localAnchorB = new Vec2();
      localAxisA = new Vec2(1.0f, 0.0f);
      enableMotor = false;
      maxMotorTorque = 0.0f;
      motorSpeed = 0.0f;
      frequencyHz = 2.0f;
      dampingRatio = 0.7f;
   }

   /// Initialize the bodies, anchors, axis, and reference angle using the world
   /// anchor and world axis.
   public void initialize(Body b1, Body b2, Vec2 anchor, Vec2 axis) {
      bodyA = b1;
      bodyB = b2;
      bodyA.getLocalPointToOut(anchor, localAnchorA);
      bodyB.getLocalPointToOut(anchor, localAnchorB);
      bodyA.getLocalVectorToOut(axis, localAxisA);
   }
}


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 2:20 am 
Offline

Joined: Wed Jul 25, 2012 5:08 am
Posts: 53
WheelJoint.java

Code:
package org.jbox2d.dynamics.joints;

import org.jbox2d.common.Mat22;
import org.jbox2d.common.MathUtils;
import org.jbox2d.common.Settings;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.TimeStep;
import org.jbox2d.pooling.IWorldPool;

public class WheelJoint extends Joint {
   float m_frequencyHz;
   float m_dampingRatio;

   // Solver shared
   Vec2 m_localAnchorA;
   Vec2 m_localAnchorB;
   Vec2 m_localXAxisA;
   Vec2 m_localYAxisA;

   float m_impulse;
   float m_motorImpulse;
   float m_springImpulse;

   float m_maxMotorTorque;
   float m_motorSpeed;
   boolean m_enableMotor;

   // Solver temp
   Vec2 m_ax = new Vec2();
   Vec2 m_ay = new Vec2();
   
   float m_sAx, m_sBx;
   float m_sAy, m_sBy;

   float m_mass;
   float m_motorMass;
   float m_springMass;

   float m_bias;
   float m_gamma;

   protected WheelJoint(IWorldPool argWorldPool, WheelJointDef def) {
      super(argWorldPool, def);
      
      m_localAnchorA = new Vec2(def.localAnchorA);
      m_localAnchorB = new Vec2(def.localAnchorB);
      m_localXAxisA = new Vec2(def.localAxisA);
      m_localYAxisA = Vec2.cross(1.0f, m_localXAxisA);
      
      m_mass = 0.0f;
      m_impulse = 0.0f;
      m_motorMass = 0.0f;
      m_motorImpulse = 0.0f;
      m_springMass = 0.0f;
      m_springImpulse = 0.0f;

      m_maxMotorTorque = def.maxMotorTorque;
      m_motorSpeed = def.motorSpeed;
      m_enableMotor = def.enableMotor;

      m_frequencyHz = def.frequencyHz;
      m_dampingRatio = def.dampingRatio;

      m_bias = 0.0f;
      m_gamma = 0.0f;
   }
   
   float getMotorSpeed() {
      return m_motorSpeed;
   }

   float getMaxMotorTorque() {
      return m_maxMotorTorque;
   }

   void setSpringFrequencyHz(float hz) {
      m_frequencyHz = hz;
   }

   float getSpringFrequencyHz() {
      return m_frequencyHz;
   }

   void setSpringDampingRatio(float ratio) {
      m_dampingRatio = ratio;
   }

   float getSpringDampingRatio() {
      return m_dampingRatio;
   }

   public void initVelocityConstraints(TimeStep step) {
      final Body b1 = m_bodyA;
      final Body b2 = m_bodyB;

      m_invMassA = b1.m_invMass;
      m_invIA = b1.m_invI;
      m_invMassB = b2.m_invMass;
      m_invIB = b2.m_invI;
      m_localCenterA.set(b1.getLocalCenter());
      m_localCenterB.set(b2.getLocalCenter());
      
      Vec2 vA = b1.m_linearVelocity;
      float wA = b1.m_angularVelocity;
      Vec2 vB = b2.m_linearVelocity;
      float wB = b2.m_angularVelocity;

      Vec2 rA = pool.popVec2();
      Vec2 rB = pool.popVec2();
      Vec2 d = pool.popVec2();
      Vec2 tmp = pool.popVec2();
      
      // Compute the effective mass matrix.
      rA.set(m_localAnchorA).subLocal(m_localCenterA);
      rB.set(m_localAnchorB).subLocal(m_localCenterB);
      Mat22.mulToOut(b1.getTransform().R, rA, rA);
      Mat22.mulToOut(b2.getTransform().R, rB, rB);
      
      d.set(b2.m_sweep.c).addLocal(rB).subLocal(b1.m_sweep.c).subLocal(rA);
      tmp.set(d).addLocal(rA);
      
      // Point to lineraint
      {
         Mat22.mulToOut(b1.getTransform().R, m_localYAxisA, m_ay);
         m_sAy = Vec2.cross(tmp, m_ay);
         m_sBy = Vec2.cross(rB, m_ay);

         m_mass = m_invMassA + m_invMassB + m_invIA * m_sAy * m_sAy + m_invIB * m_sBy * m_sBy;

         if (m_mass > 0.0f)
         {
            m_mass = 1.0f / m_mass;
         }
      }

      // Springraint
      m_springMass = 0.0f;
      m_bias = 0.0f;
      m_gamma = 0.0f;
      if (m_frequencyHz > 0.0f) {
         Mat22.mulToOut(b1.getTransform().R, m_localXAxisA, m_ax);
         m_sAx = Vec2.cross(tmp, m_ax);
         m_sBx = Vec2.cross(rB, m_ax);

         float invMass = m_invMassA + m_invMassB + m_invIA * m_sAx * m_sAx + m_invIB * m_sBx * m_sBx;

         if (invMass > 0.0f) {
            m_springMass = 1.0f / invMass;

            float C = Vec2.dot(d, m_ax);

            // Frequency
            float omega = 2.0f * MathUtils.PI * m_frequencyHz;

            // Damping coefficient
            float damping = 2.0f * m_springMass * m_dampingRatio * omega;

            // Spring stiffness
            float k = m_springMass * omega * omega;

            // magic formulas
            float h = step.dt;
            m_gamma = h * (damping + h * k);
            if (m_gamma > 0.0f) {
               m_gamma = 1.0f / m_gamma;
            }

            m_bias = C * h * k * m_gamma;

            m_springMass = invMass + m_gamma;
            if (m_springMass > 0.0f) {
               m_springMass = 1.0f / m_springMass;
            }
         }
      }
      else {
         m_springImpulse = 0.0f;
      }

      // Rotational motor
      if (m_enableMotor) {
         m_motorMass = m_invIA + m_invIB;
         if (m_motorMass > 0.0f) {
            m_motorMass = 1.0f / m_motorMass;
         }
      }
      else {
         m_motorMass = 0.0f;
         m_motorImpulse = 0.0f;
      }

      if (step.warmStarting) {
         // Account for variable time step.
         m_impulse *= step.dtRatio;
         m_springImpulse *= step.dtRatio;
         m_motorImpulse *= step.dtRatio;

         Vec2 P = pool.popVec2();
         Vec2 tmp2 = pool.popVec2();
         getReactionForce(1, P);
         
         float LA = m_impulse * m_sAy + m_springImpulse * m_sAx + m_motorImpulse;
         float LB = m_impulse * m_sBy + m_springImpulse * m_sBx + m_motorImpulse;

         tmp.set(P).mulLocal(m_invMassA);
         vA.subLocal(tmp2);
         b1.m_angularVelocity -= m_invIA * LA;
         
         tmp.set(P).mulLocal(m_invMassB);
         vB.addLocal(tmp2);
         b2.m_angularVelocity += m_invIB * LB;
         
         pool.pushVec2(2);
      }
      else {
         m_impulse = 0.0f;
         m_springImpulse = 0.0f;
         m_motorImpulse = 0.0f;
      }
      
//      b1.synchronizeTransform();
//      b2.synchronizeTransform();

      pool.pushVec2(4);
   }

   public void solveVelocityConstraints(final TimeStep step) {
      final Body b1 = m_bodyA;
      final Body b2 = m_bodyB;

      Vec2 vA = b1.m_linearVelocity;
      float wA = b1.m_angularVelocity;
      Vec2 vB = b2.m_linearVelocity;
      float wB = b2.m_angularVelocity;

      Vec2 P = pool.popVec2();
      Vec2 tmp = pool.popVec2();
      
      // Solve springraint
      {
         tmp.set(vB).subLocal(vA);
         float Cdot = Vec2.dot(m_ax, tmp) + m_sBx * wB - m_sAx * wA;
         float impulse = -m_springMass * (Cdot + m_bias + m_gamma * m_springImpulse);
         m_springImpulse += impulse;

         P.set(m_ax).mulLocal(impulse);
         
         float LA = impulse * m_sAx;
         float LB = impulse * m_sBx;

         tmp.set(P).mulLocal(m_invMassA);
         vA.subLocal(tmp);
         b1.m_angularVelocity -= m_invIA * LA;

         tmp.set(P).mulLocal(m_invMassB);
         vB.addLocal(tmp);
         b2.m_angularVelocity += m_invIB * LB;
      }

      // Solve rotational motorraint
      {
         float Cdot = wB - wA - m_motorSpeed;
         float impulse = -m_motorMass * Cdot;

         float oldImpulse = m_motorImpulse;
         float maxImpulse = step.dt * m_maxMotorTorque;
         m_motorImpulse = MathUtils.clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse);
         impulse = m_motorImpulse - oldImpulse;

         b1.m_angularVelocity -= m_invIA * impulse;
         b2.m_angularVelocity += m_invIB * impulse;
      }

      // Solve point to lineraint
      {
         tmp.set(vB).subLocal(vA);
         float Cdot = Vec2.dot(m_ay, tmp) + m_sBy * wB - m_sAy * wA;
         float impulse = -m_mass * Cdot;
         m_impulse += impulse;

         P.set(m_ay).mulLocal(impulse);
         float LA = impulse * m_sAy;
         float LB = impulse * m_sBy;

         tmp.set(P).mulLocal(m_invMassA);
         vA.subLocal(tmp);
         b1.m_angularVelocity -= m_invIA * LA;

         tmp.set(P).mulLocal(m_invMassB);
         vB.addLocal(tmp);
         b2.m_angularVelocity += m_invIB * LB;
      }
      
      b1.synchronizeTransform();
      b2.synchronizeTransform();

      pool.pushVec2(2);
   }

   public boolean solvePositionConstraints(float baumgarte) {
      final Body b1 = m_bodyA;
      final Body b2 = m_bodyB;
      Vec2 cA = b1.m_sweep.c, cB = b2.m_sweep.c;

      final Vec2 rA = pool.popVec2();
      final Vec2 rB = pool.popVec2();
      final Vec2 d = pool.popVec2();
      Vec2 ay = pool.popVec2();
      Vec2 P = pool.popVec2();
      Vec2 tmp = pool.popVec2();
      
      rA.set(m_localAnchorA).subLocal(m_localCenterA);
      rB.set(m_localAnchorB).subLocal(m_localCenterB);
      Mat22.mulToOut(b1.getTransform().R, rA, rA);
      Mat22.mulToOut(b2.getTransform().R, rB, rB);

      d.set(cB).subLocal(cA).addLocal(rB).subLocal(rA);
      
      Mat22.mulToOut(b1.getTransform().R, m_localYAxisA, ay);
      
      tmp.set(d).addLocal(rA);
      float sAy = Vec2.cross(tmp, ay);
      float sBy = Vec2.cross(rB, ay);

      float C = Vec2.dot(d, ay);

      float k = m_invMassA + m_invMassB + m_invIA * m_sAy * m_sAy + m_invIB * m_sBy * m_sBy;

      float impulse = k == 0.0f ? 0.0f : -C / k;

      P.set(ay).mulLocal(impulse);
      float LA = impulse * sAy;
      float LB = impulse * sBy;

      tmp.set(P).mulLocal(m_invMassA);
      cA.subLocal(tmp);
      b1.m_sweep.a -= m_invIA * LA;
      
      tmp.set(P).mulLocal(m_invMassB);
      cB.addLocal(tmp);
      b2.m_sweep.a += m_invIB * LB;
      
      b1.synchronizeTransform();
      b2.synchronizeTransform();
      pool.pushVec2(6);

      return MathUtils.abs(C) < Settings.linearSlop;
   }

   Vec2 getAnchorA() {
      return m_bodyA.getWorldPoint(m_localAnchorA);
   }

   Vec2 getAnchorB() {
      return m_bodyB.getWorldPoint(m_localAnchorB);
   }

   Vec2 getReactionForce(float inv_dt) {
      Vec2 result = new Vec2();
      getReactionForce(inv_dt, result);
      
      return result;
   }

   public float getReactionTorque(float inv_dt) {
      return inv_dt * m_motorImpulse;
   }

   float getJointTranslation() {
      Body bA = m_bodyA;
      Body bB = m_bodyB;

      Vec2 pA = bA.getWorldPoint(m_localAnchorA);
      Vec2 pB = bB.getWorldPoint(m_localAnchorB);
      Vec2 d = pB.sub(pA);
      Vec2 axis = bA.getWorldVector(m_localXAxisA);

      float translation = Vec2.dot(d, axis);
      return translation;
   }

   float getJointSpeed() {
      float wA = m_bodyA.m_angularVelocity;
      float wB = m_bodyB.m_angularVelocity;
      return wB - wA;
   }

   boolean isMotorEnabled() {
      return m_enableMotor;
   }

   void enableMotor(boolean flag) {
      m_bodyA.setAwake(true);
      m_bodyB.setAwake(true);
      m_enableMotor = flag;
   }

   void setMotorSpeed(float speed) {
      m_bodyA.setAwake(true);
      m_bodyB.setAwake(true);
      m_motorSpeed = speed;
   }

   void setMaxMotorTorque(float torque) {
      m_bodyA.setAwake(true);
      m_bodyB.setAwake(true);
      m_maxMotorTorque = torque;
   }

   float getMotorTorque(float inv_dt) {
      return inv_dt * m_motorImpulse;
   }

   void dump() {
//      int indexA = m_bodyA.m_islandIndex;
//      int indexB = m_bodyB.m_islandIndex;
//
//      b2Log("  b2WheelJointDef jd;\n");
//      b2Log("  jd.bodyA = bodies[%d];\n", indexA);
//      b2Log("  jd.bodyB = bodies[%d];\n", indexB);
//      b2Log("  jd.collideConnected = bool(%d);\n", m_collideConnected);
//      b2Log("  jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y);
//      b2Log("  jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y);
//      b2Log("  jd.localAxisA.Set(%.15lef, %.15lef);\n", m_localXAxisA.x, m_localXAxisA.y);
//      b2Log("  jd.enableMotor = bool(%d);\n", m_enableMotor);
//      b2Log("  jd.motorSpeed = %.15lef;\n", m_motorSpeed);
//      b2Log("  jd.maxMotorTorque = %.15lef;\n", m_maxMotorTorque);
//      b2Log("  jd.frequencyHz = %.15lef;\n", m_frequencyHz);
//      b2Log("  jd.dampingRatio = %.15lef;\n", m_dampingRatio);
//      b2Log("  joints[%d] = m_world.CreateJoint(&jd);\n", m_index);
   }

   @Override
   public void getAnchorA(Vec2 argOut) {
      m_bodyA.getWorldPointToOut(m_localAnchorA, argOut);
   }

   @Override
   public void getAnchorB(Vec2 argOut) {
      m_bodyB.getWorldPointToOut(m_localAnchorB, argOut);
   }

   @Override
   public void getReactionForce(float inv_dt, Vec2 argOut) {
      argOut.set(m_ax.x * m_springImpulse + m_ay.x * m_impulse, m_ax.y * m_springImpulse + m_ay.y * m_impulse);
      argOut.mulLocal(inv_dt);
   }
}


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 2:26 am 
Offline

Joined: Wed Jul 25, 2012 5:08 am
Posts: 53
To run the CarTest.java in testbed, following things to do:
1. Add WHEEL in JointType
Code:
public enum JointType {
   UNKNOWN, REVOLUTE, PRISMATIC, DISTANCE, PULLEY,
   MOUSE, GEAR, LINE, WELD, WHEEL, FRICTION, CONSTANT_VOLUME
}


2. Create a WheelJoint in Joint.java:
Code:
public static Joint create(World argWorld, JointDef def) {
...
         case WHEEL:
            return new WheelJoint(argWorld.getPool(), (WheelJointDef) def);


3. Here's CarTest.java:
Code:
package org.jbox2d.testbed.tests;

import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.MathUtils;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.joints.RevoluteJointDef;
import org.jbox2d.dynamics.joints.WheelJoint;
import org.jbox2d.dynamics.joints.WheelJointDef;
import org.jbox2d.testbed.framework.TestbedSettings;
import org.jbox2d.testbed.framework.TestbedTest;

public class CarTest extends TestbedTest {

   int m_motoKeepTime;

   Body m_car;
   Body m_wheel1;
   Body m_wheel2;

   float m_hz;
   float m_zeta;
   float m_speed;
   WheelJoint m_spring1;
   WheelJoint m_spring2;

   @Override
   public void initTest(boolean argDeserialized) {
      // TODO Auto-generated method stub
      
      m_hz = 4.0f;
      m_zeta = 0.7f;
      m_speed = 50.0f;
      
      World world = getWorld();

      Body ground = null;
      {
         BodyDef bd = new BodyDef();
         ground = world.createBody(bd);

         PolygonShape shape = new PolygonShape();

         shape.setAsEdge(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f));
         ground.createFixture(shape, 0.0f);

         // TODO: EdgeShape not implemented yet.
         float hs[] = {0.25f, 1.0f, 4.0f, 0.0f, 0.0f, -1.0f, -2.0f, -2.0f, -1.25f, 0.0f};

         float x = 20.0f, y1 = 0.0f, dx = 5.0f;

         for (int i = 0; i < 10; ++i)
         {
            float y2 = hs[i];
            shape.setAsEdge(new Vec2(x, y1), new Vec2(x + dx, y2));
            ground.createFixture(shape, 0.0f);
            y1 = y2;
            x += dx;
         }

         shape.setAsEdge(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f));
         ground.createFixture(shape, 0.0f);

         x += 80.0f;
         shape.setAsEdge(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f));
         ground.createFixture(shape, 0.0f);

         x += 40.0f;
         shape.setAsEdge(new Vec2(x, 0.0f), new Vec2(x + 10.0f, 5.0f));
         ground.createFixture(shape, 0.0f);

         x += 20.0f;
         shape.setAsEdge(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f));
         ground.createFixture(shape, 0.0f);

         x += 40.0f;
         shape.setAsEdge(new Vec2(x, 0.0f), new Vec2(x, 20.0f));
         ground.createFixture(shape, 0.0f);
      }

      // Teeter
      {
         BodyDef bd = new BodyDef();
         bd.position.set(140.0f, 1.0f);
         bd.type = BodyType.DYNAMIC;
         Body body = world.createBody(bd);

         PolygonShape box = new PolygonShape();
         box.setAsBox(10.0f, 0.25f);
         body.createFixture(box, 1.0f);

         RevoluteJointDef jd = new RevoluteJointDef();
         jd.initialize(ground, body, body.getPosition());
         jd.lowerAngle = -8.0f * MathUtils.PI / 180.0f;
         jd.upperAngle = 8.0f * MathUtils.PI / 180.0f;
         jd.enableLimit = true;
         world.createJoint(jd);

         body.applyAngularImpulse(100.0f);
      }

      // Bridge
      {
         int N = 20;
         PolygonShape shape = new PolygonShape();
         shape.setAsBox(1.0f, 0.125f);

         FixtureDef fd = new FixtureDef();
         fd.shape = shape;
         fd.density = 1.0f;
         fd.friction = 0.6f;

         RevoluteJointDef jd = new RevoluteJointDef();

         Body prevBody = ground;
         for (int i = 0; i < N; ++i)
         {
            BodyDef bd = new BodyDef();
            bd.type = BodyType.DYNAMIC;
            bd.position.set(161.0f + 2.0f * i, -0.125f);
            Body body = world.createBody(bd);
            body.createFixture(fd);

            Vec2 anchor = new Vec2(160.0f + 2.0f * i, -0.125f);
            jd.initialize(prevBody, body, anchor);
            world.createJoint(jd);

            prevBody = body;
         }

         Vec2 anchor = new Vec2(160.0f + 2.0f * N, -0.125f);
         jd.initialize(prevBody, ground, anchor);
         world.createJoint(jd);
      }

      // Boxes
      {
         PolygonShape box = new PolygonShape();
         box.setAsBox(0.5f, 0.5f);

         BodyDef bd = new BodyDef();
         bd.type = BodyType.DYNAMIC;

         bd.position.set(230.0f, 0.5f);
         Body body = world.createBody(bd);
         body.createFixture(box, 0.5f);

         bd.position.set(230.0f, 1.5f);
         body = m_world.createBody(bd);
         body.createFixture(box, 0.5f);

         bd.position.set(230.0f, 2.5f);
         body = world.createBody(bd);
         body.createFixture(box, 0.5f);

         bd.position.set(230.0f, 3.5f);
         body = world.createBody(bd);
         body.createFixture(box, 0.5f);

         bd.position.set(230.0f, 4.5f);
         body = world.createBody(bd);
         body.createFixture(box, 0.5f);
      }

      // Car
      {
         PolygonShape chassis = new PolygonShape();
         Vec2[] vertices = new Vec2[8];
         for (int i = 0; i < vertices.length; i++)
            vertices[i] = new Vec2();
         
         vertices[0].set(-1.5f, -0.5f);
         vertices[1].set(1.5f, -0.5f);
         vertices[2].set(1.5f, 0.0f);
         vertices[3].set(0.0f, 0.9f);
         vertices[4].set(-1.15f, 0.9f);
         vertices[5].set(-1.5f, 0.2f);
         chassis.set(vertices, 6);

         CircleShape circle = new CircleShape();
         circle.m_radius = 0.4f;

         BodyDef bd = new BodyDef();
         bd.type = BodyType.DYNAMIC;
         bd.position.set(0.0f, 1.0f);
         m_car = world.createBody(bd);
         m_car.createFixture(chassis, 1.0f);

         FixtureDef fd = new FixtureDef();
         fd.shape = circle;
         fd.density = 1.0f;
         fd.friction = 0.9f;

         bd.position.set(-1.0f, 0.35f);
         m_wheel1 = world.createBody(bd);
         m_wheel1.createFixture(fd);

         bd.position.set(1.0f, 0.4f);
         m_wheel2 = world.createBody(bd);
         m_wheel2.createFixture(fd);

         WheelJointDef jd = new WheelJointDef();
         Vec2 axis = new Vec2(0.0f, 1.0f);

         jd.initialize(m_car, m_wheel1, m_wheel1.getPosition(), axis);
         jd.motorSpeed = 0.0f;
         jd.maxMotorTorque = 20.0f;
         jd.enableMotor = true;
         jd.frequencyHz = m_hz;
         jd.dampingRatio = m_zeta;
         m_spring1 = (WheelJoint) world.createJoint(jd);

         jd.initialize(m_car, m_wheel2, m_wheel2.getPosition(), axis);
         jd.motorSpeed = 0.0f;
         jd.maxMotorTorque = 10.0f;
         jd.enableMotor = false;
         jd.frequencyHz = m_hz;
         jd.dampingRatio = m_zeta;
         m_spring2 = (WheelJoint) world.createJoint(jd);
      }

      m_motoKeepTime = 0;
   }

   @Override
   public String getTestName() {
      // TODO Auto-generated method stub
      return "CarTest";
   }

   /**
    * @see org.jbox2d.testbed.framework.TestbedTest#keyPressed(char, int)
    */
   @Override
   public void keyPressed(char argKeyChar, int argKeyCode) {
      
//      switch (argKeyChar) {
//         case 'l' :
//            m_joint.enableLimit(!m_joint.isLimitEnabled());
//            getModel().getKeys()['l'] = false;
//            break;
//         case 'm' :
//            m_joint.enableMotor(!m_joint.isMotorEnabled());
//            getModel().getKeys()['m'] = false;
//            break;
//         case 'a' :
//            m_joint.setMotorSpeed(1.0f * MathUtils.PI);
//            getModel().getKeys()['a'] = false;
//            isLeft = true;
//            break;
//         case 'd' :
//            m_joint.setMotorSpeed(-1.0f * MathUtils.PI);
//            getModel().getKeys()['d'] = false;
//            isLeft = false;
//            break;
//      }
   }
   
   /**
    * @see org.jbox2d.testbed.framework.TestbedTest#step(org.jbox2d.testbed.framework.TestbedSettings)
    */
   @Override
   public void step(TestbedSettings settings) {
      super.step(settings);
//      addTextLine("Limits " + (m_joint.isLimitEnabled() ? "on" : "off") + ", Motor "
//            + (m_joint.isMotorEnabled() ? "on " : "off ") + (isLeft ? "left" : "right"));
//      addTextLine("Keys: (l) limits, (m) motor, (a) left, (d) right");
   }
}


Top
 Profile  
 
PostPosted: Wed Aug 08, 2012 10:37 pm 
Offline

Joined: Wed Jul 25, 2012 5:08 am
Posts: 53
Comparing to Box2D, I made a lot of data dumping, it's aweful job really!
Finally I found a bug in solvePositionConstraints(). And now, WheelJoint works! :D


Top
 Profile  
 
PostPosted: Wed Aug 08, 2012 11:22 pm 
Offline

Joined: Wed Jul 25, 2012 5:08 am
Posts: 53
No, it's not working very well, some times the two wheels just won't stick to the body..


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group