Rotate orientation towards shortest arc

This commit is contained in:
2024-01-07 08:46:55 +01:00
parent adf8545b6e
commit 8ff0078b70
2 changed files with 29 additions and 12 deletions

View File

@@ -67,6 +67,6 @@ void setupSystems() {
renderArmPositionSystem = renderArmPosition; renderArmPositionSystem = renderArmPosition;
renderCollidersSystem = renderColliders; renderCollidersSystem = renderColliders;
ecs_enable(ECS, renderOrientDirSystem, false); //ecs_enable(ECS, renderOrientDirSystem, false);
ecs_enable(ECS, renderArmPositionSystem, false); //ecs_enable(ECS, renderArmPositionSystem, false);
} }

View File

@@ -5,6 +5,14 @@
#include <raymath.h> #include <raymath.h>
float shortestArc(float a, float b) {
if (fabs(b - a) < M_PI)
return b - a;
if (b > a)
return b - a - M_PI * 2.0f;
return b - a + M_PI * 2.0f;
}
void actionMoveTo(ecs_entity_t entity, Action *action, Game *game) { void actionMoveTo(ecs_entity_t entity, Action *action, Game *game) {
if (action->finished) return; if (action->finished) return;
const Vector2 target = action->as.moveTo.target; const Vector2 target = action->as.moveTo.target;
@@ -16,9 +24,12 @@ void actionMoveTo(ecs_entity_t entity, Action *action, Game *game) {
const Vector2 pos = *ecs_get(ECS, entity, Position); const Vector2 pos = *ecs_get(ECS, entity, Position);
if (ecs_has(ECS, entity, Orientation)) { if (ecs_has(ECS, entity, Orientation)) {
Orientation *orientation = ecs_get_mut(ECS, entity, Orientation); Orientation *orientation = ecs_get_mut(ECS, entity, Orientation);
f32 dif = Vector2Angle(pos, target) - *orientation; f32 currentAngle = *orientation;
dif = Clamp(dif, -10, 10) * dt * 10; f32 targetAngle = Vector2Angle(pos, target);
f32 dif = shortestArc(currentAngle, targetAngle);
dif = Clamp(dif, -1, 1) * dt * 10;
*orientation += dif; *orientation += dif;
*orientation = fmodf(*orientation + 180.0f, 360.0f) - 180.0f;
} }
f32 dst = Vector2Distance(pos, target); f32 dst = Vector2Distance(pos, target);
if (dst < action->as.moveTo.proximityThreshold) { if (dst < action->as.moveTo.proximityThreshold) {
@@ -26,6 +37,7 @@ void actionMoveTo(ecs_entity_t entity, Action *action, Game *game) {
ecs_remove(ECS, entity, Path); ecs_remove(ECS, entity, Path);
} }
} }
void actionCollectResource(ecs_entity_t entity, Action *action, Game *game) { void actionCollectResource(ecs_entity_t entity, Action *action, Game *game) {
if (action->finished) return; if (action->finished) return;
BZ_ASSERT(ecs_has(ECS, entity, Worker)); BZ_ASSERT(ecs_has(ECS, entity, Worker));
@@ -42,13 +54,14 @@ void actionCollectResource(ecs_entity_t entity, Action *action, Game *game) {
if (!action->finished && action->elapsed > worker->collectSpeed) { if (!action->finished && action->elapsed > worker->collectSpeed) {
i32 spareCapacity = worker->carryCapacity - worker->carry; i32 spareCapacity = worker->carryCapacity - worker->carry;
i32 collected = harvestEvent(target, (HarvestEvent) { i32 collected = harvestEvent(target, (HarvestEvent) {
.amount = BZ_MIN(1, spareCapacity), .amount = BZ_MIN(1, spareCapacity),
}); });
worker->carry += collected; worker->carry += collected;
action->elapsed = 0; action->elapsed = 0;
} }
} }
void actionDepositResource(ecs_entity_t entity, Action *action, Game *game) { void actionDepositResource(ecs_entity_t entity, Action *action, Game *game) {
if (action->finished) return; if (action->finished) return;
@@ -64,7 +77,7 @@ void actionDepositResource(ecs_entity_t entity, Action *action, Game *game) {
if (!action->finished && action->elapsed > worker->depositSpeed) { if (!action->finished && action->elapsed > worker->depositSpeed) {
depositEvent(target, (DepositEvent) { depositEvent(target, (DepositEvent) {
.amount = worker->carry .amount = worker->carry
}); });
worker->carry = 0; worker->carry = 0;
action->finished = true; action->finished = true;
@@ -93,6 +106,7 @@ void handleAction(ecs_entity_t entity, UnitAction *unitAction, Game *game) {
} }
} }
void updateAction(UnitAction *unitAction, Game *game) { void updateAction(UnitAction *unitAction, Game *game) {
Action *action = unitAction->first; Action *action = unitAction->first;
if (action == NULL) return; if (action == NULL) return;
@@ -108,6 +122,7 @@ void updateAction(UnitAction *unitAction, Game *game) {
bzObjectPoolRelease(pool, action); bzObjectPoolRelease(pool, action);
} }
} }
void clearActions(ecs_entity_t entity, Game *game) { void clearActions(ecs_entity_t entity, Game *game) {
if (!ecs_has(ECS, entity, UnitAction)) return; if (!ecs_has(ECS, entity, UnitAction)) return;
UnitAction *unitAction = ecs_get_mut(ECS, entity, UnitAction); UnitAction *unitAction = ecs_get_mut(ECS, entity, UnitAction);
@@ -121,14 +136,15 @@ void clearActions(ecs_entity_t entity, Game *game) {
} }
unitAction->first = NULL; unitAction->first = NULL;
unitAction->last = NULL; unitAction->last = NULL;
} }
void addAction(ecs_entity_t entity, Game *game, const Action *action) { void addAction(ecs_entity_t entity, Game *game, const Action *action) {
BZ_ASSERT(action); BZ_ASSERT(action);
BZ_ASSERT(ecs_has(ECS, entity, UnitAction)); BZ_ASSERT(ecs_has(ECS, entity, UnitAction));
UnitAction *unitAction = ecs_get_mut(ECS, entity, UnitAction); UnitAction *unitAction = ecs_get_mut(ECS, entity, UnitAction);
BzObjectPool *pool = game->pools.actions; BzObjectPool *pool = game->pools.actions;
Action *newAction = bzObjectPool(pool); Action *newAction = bzObjectPool(pool);
BZ_ASSERT(newAction); BZ_ASSERT(newAction);
@@ -136,20 +152,21 @@ void addAction(ecs_entity_t entity, Game *game, const Action *action) {
newAction->next = NULL; newAction->next = NULL;
if (unitAction->last) { if (unitAction->last) {
Action *last = unitAction->last; Action *last = unitAction->last;
last->next = newAction; last->next = newAction;
unitAction->last = newAction; unitAction->last = newAction;
} else { } else {
unitAction->first = newAction; unitAction->first = newAction;
unitAction->last = newAction; unitAction->last = newAction;
} }
} }
void prependAction(ecs_entity_t entity, Game *game, const Action *action) { void prependAction(ecs_entity_t entity, Game *game, const Action *action) {
BZ_ASSERT(action); BZ_ASSERT(action);
BZ_ASSERT(ecs_has(ECS, entity, UnitAction)); BZ_ASSERT(ecs_has(ECS, entity, UnitAction));
UnitAction *unitAction = ecs_get_mut(ECS, entity, UnitAction); UnitAction *unitAction = ecs_get_mut(ECS, entity, UnitAction);
BzObjectPool *pool = game->pools.actions; BzObjectPool *pool = game->pools.actions;
Action *newAction = bzObjectPool(pool); Action *newAction = bzObjectPool(pool);
BZ_ASSERT(newAction); BZ_ASSERT(newAction);