: Controller(ctrl)
, world(world)
, tgt(tgt)
-, chase_speed(0.002f)
-, flee_speed(-0.005f)
+, chase_speed(2.0f)
+, flee_speed(-5.0f)
, stop_dist(10)
, flee_dist(5) {
tgt.Ref();
start_vel = target_vel;
start_rot = target_rot;
- constexpr float base = 0.000001f;
+ constexpr float base = 0.001f;
target_vel.x = base * (random.Next<short>() % 1024);
target_vel.y = base * (random.Next<short>() % 1024);
struct PlayerHistory {
EntityState state;
glm::vec3 tgt_vel;
- int delta_t;
+ float delta_t;
std::uint16_t packet;
- PlayerHistory(EntityState s, const glm::vec3 &tv, int dt, std::uint16_t p)
+ PlayerHistory(EntityState s, const glm::vec3 &tv, float dt, std::uint16_t p)
: state(s), tgt_vel(tv), delta_t(dt), packet(p) { }
};
std::list<PlayerHistory> player_hist;
InventorySlot()
);
if (player_hist.size() < 16) {
- player_hist.emplace_back(state, GetPlayer().GetEntity().TargetVelocity(), dt, packet);
+ player_hist.emplace_back(state, GetPlayer().GetEntity().TargetVelocity(), dt * 0.001f, packet);
} else {
auto entry = player_hist.begin();
entry->state = state;
entry->tgt_vel = GetPlayer().GetEntity().TargetVelocity();
- entry->delta_t = dt;
+ entry->delta_t = dt * 0.001f;
entry->packet = packet;
player_hist.splice(player_hist.end(), player_hist, entry);
}
}
void PlayerController::UpdatePlayer() noexcept {
- constexpr float max_vel = 0.005f;
+ constexpr float max_vel = 5.0f; // in m/s
if (dirty) {
player.GetEntity().Orientation(glm::quat(glm::vec3(pitch, yaw, 0.0f)));
player.GetEntity().TargetVelocity(glm::rotateY(move_dir * max_vel, yaw));
return state.Diff(other.state);
}
- /// direction is rotation axis, magnitude is speed in rad/ms
+ /// direction is rotation axis, magnitude is speed in rad/s
const glm::vec3 &AngularVelocity() const noexcept { return state.ang_vel; }
void AngularVelocity(const glm::vec3 &v) noexcept { state.ang_vel = v; }
std::list<Entity> &Entities() noexcept { return entities; }
const std::list<Entity> &Entities() const noexcept { return entities; }
+ // dt in ms
void Update(int dt);
+ // dt in s
void Update(Entity &, float dt);
void Render(Viewport &);
void World::Update(int dt) {
- float fdt(dt);
+ float fdt(dt * 0.001f);
for (Entity &entity : entities) {
Update(entity, fdt);
}
EntityDerivative out;
out.position = next.velocity;
- out.velocity = CalculateForce(entity, next); // by mass = 1
+ out.velocity = CalculateForce(entity, next); // by mass = 1kg
return out;
}
const Entity &entity,
const EntityState &state
) {
- constexpr float k = 1.0f; // spring constant
- constexpr float b = 1.0f; // damper constant
- constexpr float t = 0.01f; // 1/time constant
- const glm::vec3 x(-entity.TargetVelocity()); // endpoint displacement from equilibrium
- const glm::vec3 v(state.velocity); // relative velocity between endpoints
- return (((-k) * x) - (b * v)) * t; // times mass = 1
+ constexpr float k = 10.0f; // spring constant
+ constexpr float b = 10.0f; // damper constant
+ const glm::vec3 x(-entity.TargetVelocity()); // endpoint displacement from equilibrium, by 1s, in m
+ const glm::vec3 v(state.velocity); // relative velocity between endpoints in m/s
+ return ((-k) * x) - (b * v); // times 1kg/s, in kg*m/s²
}
namespace {
glm::vec3 normal_velocity(normal * dot(state.velocity, normal));
// apply force proportional to penetration
// use velocity projected onto normal as damper
- constexpr float k = 1.0f; // spring constant
- constexpr float b = 1.0f; // damper constant
- constexpr float t = 0.001f; // 1/time constant
- const glm::vec3 x(penetration); // endpoint displacement from equilibrium
- const glm::vec3 v(normal_velocity); // relative velocity between endpoints
- return (((-k) * x) - (b * v)) * t; // times mass = 1
+ constexpr float k = 1000.0f; // spring constant
+ constexpr float b = 100.0f; // damper constant
+ const glm::vec3 x(penetration); // endpoint displacement from equilibrium in m
+ const glm::vec3 v(normal_velocity); // relative velocity between endpoints in m/s
+ return (((-k) * x) - (b * v)); // times 1kg/s, in kg*m/s²
} else {
return glm::vec3(0.0f);
}