Skip to content

Commit

Permalink
cmd: Fix physics obstacles
Browse files Browse the repository at this point in the history
Physics contacts can be checked iterating through the contact list of a
body, but some controls are needed in order to exclude invalid values.
  • Loading branch information
Fahien committed Mar 27, 2021
1 parent da6e834 commit 0982d2f
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 31 deletions.
2 changes: 1 addition & 1 deletion data
Submodule data updated 3 files
+1 −1 imgui.ini
+1 −1 tilemap.json
+1 −1 tileset.json
5 changes: 2 additions & 3 deletions include/component/physics.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ class PhysicsComponent

void set_enabled(bool e);

/// @brief Called by a physics listener, it is used to update
/// the current obstacle flags and list of obstacle bodies
void update(b2Contact& contact);
/// @brief Updates current obstacle flags and list of obstacle bodies
void update(b2ContactEdge& contact);

void update();

Expand Down
33 changes: 21 additions & 12 deletions src/component/physics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,49 +156,58 @@ inline b2WorldManifold get_world_manifold(const b2Contact& contact)
return wm;
}

void PhysicsComponent::update(b2Contact& contact)
void PhysicsComponent::update(b2ContactEdge& contact)
{
b2Body* other = contact.GetFixtureA()->GetBody();
if (other == body) {
other = contact.GetFixtureB()->GetBody();
b2Body* other = contact.other;
ASSERT(other);

auto normal = get_normal(*contact.contact);

// Skip abnormal values
if (normal.x > 1.0 || normal.y > 1.0 || normal.x < -1.0 || normal.y < -1.0) {
return;
}

auto normal = get_normal(contact);
const f32 threshold = 0.80f;

if (normal.x < -0.99f) {
if (normal.x < -threshold) {
obstacle |= DirectionFlags::RIGHT;
obstacles_dir[Direction::RIGHT].emplace_back(other);
}

if (normal.x > 0.99f) {
if (normal.x > threshold) {
obstacle |= DirectionFlags::LEFT;
obstacles_dir[Direction::LEFT].emplace_back(other);
}

if (normal.y > 0.99f) {
if (normal.y > threshold) {
obstacle |= DirectionFlags::DOWN;
obstacles_dir[Direction::DOWN].emplace_back(other);
}

if (normal.y < -0.99f) {
if (normal.y < -threshold) {
obstacle |= DirectionFlags::UP;
obstacles_dir[Direction::UP].emplace_back(other);
}
}

void PhysicsComponent::reset()
{
// Update some variables
// Clear list of obstacles from previous frame
for (auto& obstacles : obstacles_dir) {
obstacles.clear();
}

obstacle = DirectionFlags::NONE;
}

void PhysicsComponent::update()
{
// Clear list of obstacles from previous frame
reset();

for (auto contact = body->GetContactList(); contact; contact = contact->next) {
update(*contact);
}

// Apply air resistance
auto vel = -body->GetLinearVelocity();
auto vel_len = vel.LengthSquared();
Expand Down
8 changes: 4 additions & 4 deletions src/entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ void Entity::update(const f32 dt)
{
assert(enabled);

if (physics) {
physics->update();
}

for (auto& command : commands) {
command->execute(*this);
}
Expand All @@ -124,10 +128,6 @@ void Entity::update(const f32 dt)
if (state) {
state->update(*this);
}

if (physics) {
physics->update();
}
}

} // namespace jmp
3 changes: 0 additions & 3 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ void Game::update(const f32 dt)
// @todo Move this somewhere else? Possibly PhysicsSystem?
// Update entity from body
entity.transform.node->setPosition(entity.get_physics()->get_position());

entity.get_physics()->reset();
}

// Update tilemap entities from their bodies
Expand All @@ -119,7 +117,6 @@ void Game::update(const f32 dt)

if (auto& physics = entity->get_physics()) {
entity->transform.node->setPosition(physics->get_position());
physics->reset();
}
}

Expand Down
8 changes: 0 additions & 8 deletions src/system/physics/destruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,6 @@ b2Fixture* get_enemy_or_null(b2Contact& contact)

void DestructionListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{
// TODO move this into a generic contact listener
{
auto& a = Entity::from(*contact->GetFixtureA());
auto& b = Entity::from(*contact->GetFixtureB());
a.get_physics()->update(*contact);
b.get_physics()->update(*contact);
}

float impulse_factor = 1.0f;

if (auto player_fixture = get_player_or_null(*contact)) {
Expand Down

0 comments on commit 0982d2f

Please sign in to comment.