2D OBB collision detection, resolving collisions?
- by Milo
I currently use OBBs and I have a vehicle that is a rigid body and some buildings.
Here is my update()
private void update()
{
camera.setPosition((vehicle.getPosition().x * camera.getScale()) - ((getWidth() ) / 2.0f),
(vehicle.getPosition().y * camera.getScale()) - ((getHeight() ) / 2.0f));
//camera.move(input.getAnalogStick().getStickValueX() * 15.0f, input.getAnalogStick().getStickValueY() * 15.0f);
if(input.isPressed(ControlButton.BUTTON_GAS))
{
vehicle.setThrottle(1.0f, false);
}
if(input.isPressed(ControlButton.BUTTON_BRAKE))
{
vehicle.setBrakes(1.0f);
}
vehicle.setSteering(input.getAnalogStick().getStickValueX());
vehicle.update(16.6666f / 1000.0f);
ArrayList<Building> buildings = city.getBuildings();
for(Building b : buildings)
{
if(vehicle.getRect().overlaps(b.getRect()))
{
vehicle.update(-17.0f / 1000.0f);
break;
}
}
}
The collision detection works well. What doesn't is how they are dealt with.
My goal is simple. If the vehicle hits a building, it should stop, and never go into the building. When I apply negative torque to reverse the car should not feel buggy and move away from the building. I don't want this to look buggy.
This is my rigid body class:
class RigidBody extends Entity
{
//linear
private Vector2D velocity = new Vector2D();
private Vector2D forces = new Vector2D();
private float mass;
//angular
private float angularVelocity;
private float torque;
private float inertia;
//graphical
private Vector2D halfSize = new Vector2D();
private Bitmap image;
public RigidBody()
{
//set these defaults so we don't get divide by zeros
mass = 1.0f;
inertia = 1.0f;
}
//intialize out parameters
public void initialize(Vector2D halfSize, float mass, Bitmap bitmap)
{
//store physical parameters
this.halfSize = halfSize;
this.mass = mass;
image = bitmap;
inertia = (1.0f / 20.0f) * (halfSize.x * halfSize.x) * (halfSize.y * halfSize.y) * mass;
RectF rect = new RectF();
float scalar = 10.0f;
rect.left = (int)-halfSize.x * scalar;
rect.top = (int)-halfSize.y * scalar;
rect.right = rect.left + (int)(halfSize.x * 2.0f * scalar);
rect.bottom = rect.top + (int)(halfSize.y * 2.0f * scalar);
setRect(rect);
}
public void setLocation(Vector2D position, float angle)
{
getRect().set(position, getWidth(), getHeight(), angle);
}
public Vector2D getPosition()
{
return getRect().getCenter();
}
@Override
public void update(float timeStep)
{
//integrate physics
//linear
Vector2D acceleration = Vector2D.scalarDivide(forces, mass);
velocity = Vector2D.add(velocity, Vector2D.scalarMultiply(acceleration, timeStep));
Vector2D c = getRect().getCenter();
c = Vector2D.add(getRect().getCenter(), Vector2D.scalarMultiply(velocity , timeStep));
setCenter(c.x, c.y);
forces = new Vector2D(0,0); //clear forces
//angular
float angAcc = torque / inertia;
angularVelocity += angAcc * timeStep;
setAngle(getAngle() + angularVelocity * timeStep);
torque = 0; //clear torque
}
//take a relative Vector2D and make it a world Vector2D
public Vector2D relativeToWorld(Vector2D relative)
{
Matrix mat = new Matrix();
float[] Vector2Ds = new float[2];
Vector2Ds[0] = relative.x;
Vector2Ds[1] = relative.y;
mat.postRotate(JMath.radToDeg(getAngle()));
mat.mapVectors(Vector2Ds);
return new Vector2D(Vector2Ds[0], Vector2Ds[1]);
}
//take a world Vector2D and make it a relative Vector2D
public Vector2D worldToRelative(Vector2D world)
{
Matrix mat = new Matrix();
float[] Vectors = new float[2];
Vectors[0] = world.x;
Vectors[1] = world.y;
mat.postRotate(JMath.radToDeg(-getAngle()));
mat.mapVectors(Vectors);
return new Vector2D(Vectors[0], Vectors[1]);
}
//velocity of a point on body
public Vector2D pointVelocity(Vector2D worldOffset)
{
Vector2D tangent = new Vector2D(-worldOffset.y, worldOffset.x);
return Vector2D.add( Vector2D.scalarMultiply(tangent, angularVelocity) , velocity);
}
public void applyForce(Vector2D worldForce, Vector2D worldOffset)
{
//add linear force
forces = Vector2D.add(forces ,worldForce);
//add associated torque
torque += Vector2D.cross(worldOffset, worldForce);
}
@Override
public void draw( GraphicsContext c)
{
c.drawRotatedScaledBitmap(image, getPosition().x, getPosition().y,
getWidth(), getHeight(), getAngle());
}
}
Essentially, when any rigid body hits a building it should exhibit the same behavior.
How is collision solving usually done?
Thanks