1
\$\begingroup\$

First of all, I'm a beginner in game physics, and I think this is a relatively easy problem that I'm not grasping.

Short Version:

I have a box(representing a ship on water) going forward with a constant thrust and I need to be able to steer it with the arrow keys so that it rotates and moves along a curved path. My code is not working and I'm obviously not understanding how to achieve this using Bullet-Physics.

Long version:

I'm creating a top-down-view naval game and I'm having a hard time trying to figure out how to use Bullet-physics to steer entities. I'm trying to make it feel somehow realistic by using a physics library.

I'm using SFML to prototype and test Bullet-physics. I have a 2D box representing a ship and during the main loop I'm updating its position and heading this way:

    box_bt->getMotionState()->getWorldTransform(trans);
    box_sprite.setPosition(trans.getOrigin().getX(), trans.getOrigin().getY());
    box_sprite.setRotation(RadToDeg(trans.getRotation().getAngle()));

relevant code:

  (...)

btTransform trans;

while (window.isOpen())
{
        dynamicsWorld->stepSimulation(1 / 60.f, 10);


        // Apply drag force                                     
        box_bt->applyCentralForce(getDrag(box->getLinearVelocity().y()));


        box_bt->getMotionState()->getWorldTransform(trans);
        box_sprite.setPosition(trans.getOrigin().getX(), trans.getOrigin().getY());
        box_sprite.setRotation(RadToDeg(trans.getRotation().getAngle()));


        if (Force < 0)
          Force = 0;

      // Method to apply thrust force along the Y axis relative to the rigidbody 
      // from: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=2366
        btVector3    relativeForce = btVector3(0, -Force, 0);
        btMatrix3x3& boxRot = box_bt->getWorldTransform().getBasis();
        btVector3    correctedForce = boxRot * relativeForce;
        box_bt->applyCentralForce(correctedForce);


        (...)

        if (event.key.code == sf::Keyboard::Up)
        {
            Force += 1000;
        }
        if (event.key.code == sf::Keyboard::Down)
        {
            Force -= 1000;
        }                       
        if (event.key.code == sf::Keyboard::Right)
        {
           box_bt->applyTorque(btVector3(0, 0, 1000));
        }
        if (event.key.code == sf::Keyboard::Right)
        {
           box_bt->applyTorque(btVector3(0, 0, -1000));
        }

    //draw box
}

I'm using applyTorque but I'm not sure if that is the best method to steer a ship in this case.

For the water drag/resistance force I'm using the simplified formula:

Force = vel*(k1*vel + k2*vel^2) where k1 and k2 being tweakable "drag coefficients."

btScalar getDrag(btScalar velocity)
{
    btScalar k1 = 0.06f;
    btScalar k2 = 0.03f;
    return velocity * ((k1 * velocity) + (k2 * (velocity*velocity))) * 100;
}

I tried to get the drag force on all three axes but when I use the following code the ship doesn't behave right:

 btVector3 getDragVec(const btVector3& velocity)
{
    btVector3 Rt(0, 0, 0);

    btScalar k1 = 0.06f;
    btScalar k2 = 0.03f;

    Rt.setX(velocity.getX() * ((k1 * velocity.getX()) + (k2 * (velocity.getX()*velocity.getX()))) * 100); // 100 for scaling
    Rt.setY(velocity.getY() * ((k1 * velocity.getY()) + (k2 * (velocity.getY()*velocity.getY()))) * 100);
    Rt.setZ(velocity.getZ() * ((k1 * velocity.getZ()) + (k2 * (velocity.getZ()*velocity.getZ()))) * 100);

    return Rt;  
}

Both thrust and drag work well when moving forward, but once I try to introduce the steering part it rotates the box but it doesn't follow a curved path, the angles keep "flipping" once it gets to a certain limit, and the x-axis speed increases too much compared to the rotation.

Thank you for any insight!

\$\endgroup\$
  • 1
    \$\begingroup\$ You should not rotate the ship. Because that is not how a ship normally works. Apply torque to the stern(Back of the ship) and it should rotate naturally. \$\endgroup\$ – KaareZ Nov 18 '16 at 12:50
  • \$\begingroup\$ Agree with above commentor, ships don't rotate. They have to take a long angled breadth to achieve a turn. \$\endgroup\$ – Krythic Dec 19 '16 at 19:12
-1
\$\begingroup\$

Introducing a rate of change to the current heading

Heading= 050 Change= 0.2/second

(Current Heading + Rate of Change*Time)=New Heading

(050+0.2*1)=50.2

(050+0.2*2)=50.4

(050+0.2*3)=50.6

(050+0.2*4)=50.8

(050+0.2*5)=51.0

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.