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\$
2
  • 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
    Commented Nov 18, 2016 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
    Commented Dec 19, 2016 at 19:12

1 Answer 1

-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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .