glm::vec3 Entity::ControlForce(const EntityState &s) const noexcept {
if (HasController()) {
- return GetController().ControlForce(s);
+ return GetController().ControlForce(*this, s);
} else {
return -s.velocity;
}
}
+bool EntityController::MaxOutForce(
+ glm::vec3 &out,
+ const glm::vec3 &add,
+ float max
+) noexcept {
+ if (iszero(add) || any(isnan(add))) {
+ return false;
+ }
+ float current = iszero(out) ? 0.0f : length(out);
+ float remain = max - current;
+ if (remain <= 0.0f) {
+ return true;
+ }
+ float additional = length(add);
+ if (additional > remain) {
+ out += normalize(add) * remain;
+ return true;
+ } else {
+ out += add;
+ return false;
+ }
+}
+
EntityState::EntityState()
: chunk_pos(0)
next.velocity += delta.velocity * dt;
next.AdjustPosition();
+ if (dot(next.velocity, next.velocity) > entity.MaxVelocity() * entity.MaxVelocity()) {
+ next.velocity = normalize(next.velocity) * entity.MaxVelocity();
+ }
+
EntityDerivative out;
out.position = next.velocity;
out.velocity = CalculateForce(entity, next); // by mass = 1kg
const Entity &entity,
const EntityState &state
) {
- return ControlForce(entity, state) + CollisionForce(entity, state) + Gravity(entity, state);
+ glm::vec3 force(ControlForce(entity, state) + CollisionForce(entity, state) + Gravity(entity, state));
+ if (dot(force, force) > entity.MaxControlForce() * entity.MaxControlForce()) {
+ return normalize(force) * entity.MaxControlForce();
+ } else {
+ return force;
+ }
}
glm::vec3 World::ControlForce(