So I've been trying to implement a 2d top down door that I want to behave like the doors in the game Darkwood but I'm having trouble getting it to feel even remotely right. So there's a few things to note: the player is an AABB and the door is an OBB, I'm using SAT to detect collisions from them and get the minimum translation vector (mtv) and then I use a simple check to get the collisions points, and after that I translate the player:
CollisionData collided = CheckIfDoorAgentCollided(&door, player);
std::vector<vec2<float>> collisionPoints;
if (collided.collided)
{
collisionPoints = GetPointsInsideDoor(&door, player);
player += V2(collided.mtv.x, collided.mtv.y);
}
So far so good, I should note that the player does not have any acceleration or anything I just instantly move the player by a fixed velocity when a key is pressed (I suspect this might be a problem). Anyway here's the code I'm struggling with:
float dt = 0.0005f;
if (collided.collided)
{
if (collisionPoints.size() > 0)
{
//Apply the force in the opposite way of the minimum translation vector
vec2<float> force = -collided.mtv * 3500.0f;
vec2<float> centerOfMass = door.hingePosition;
vec2<float> momentArm = collisionPoints[0] - centerOfMass;
float inertia = 10.0f;
float torque = Cross(momentArm, force);
door.angularVelocity += door.angularAcceleration * dt;
door.angularAcceleration += (torque / inertia) * dt;
if (door.angularAcceleration > 20.0f)
{
door.angularAcceleration = 20.0f;
}
if (door.angularAcceleration < -20.0f)
{
door.angularAcceleration = -20.0f;
}
door.active = true;
}
}
if (door.active)
{
//If we're close to 0 we stop
if (fabsf(door.angularAcceleration) < 0.0000001f)
{
door.angularAcceleration = 0.0f;
door.angularVelocity = 0.0f;
door.active = false;
}
else
{
//I think this is where something more sophisticated is needed
float fakeFriction = -door.angularAcceleration * 0.08f;
door.angularAcceleration += fakeFriction;
door.angularVelocity += door.angularAcceleration * dt;
}
}
door.rotationRadians += door.angularVelocity * dt;
RotateDoorRadians(&door, door.rotationRadians);
Ignoring all those random float values, its just me trying to find a way to make everything seem more natural. Currently getting the door to stop after no force is applied looks very stiff and I can't find the right values for the player to not start sliding along the door which leads me to believe my approach is wrong, here's how it looks:
As you can see it's very stiff and “slidey”, so I was wondering what else I'd need to make the door more realistic? I'd prefer not having to use something like box2d since I'll only need physics for this one thing.