s.vel += ds.acc * dt;
glm::dvec3 force(steering.Force(s));
// gravity = antinormal * mass * Gm / r²
- double elevation = situation.GetPlanet().DistanceAt(s.pos);
glm::dvec3 normal(situation.GetPlanet().NormalAt(s.pos));
force += glm::dvec3(
-normal
* Mass() * situation.GetPlanet().GravitationalParameter()
- / (elevation * elevation));
+ / glm::length2(s.pos));
// if net force is applied and in contact with surface
- if (!allzero(force) && std::abs(std::abs(elevation) - situation.GetPlanet().Radius()) < 0.001) {
+ if (!allzero(force) && glm::length2(s.pos) < (situation.GetPlanet().Radius() + 0.01) * (situation.GetPlanet().Radius() + 0.01)) {
// apply friction = -|normal force| * tangential force * coefficient
glm::dvec3 fn(normal * glm::dot(force, normal));
glm::dvec3 ft(force - fn);
}
}
-math::AABB Creature::CollisionBox() const noexcept {
+math::AABB Creature::CollisionBounds() const noexcept {
return { glm::dvec3(size * -0.5), glm::dvec3(size * 0.5) };
}
return type == PLANET_SURFACE;
}
+bool Situation::OnGround() const noexcept {
+ return OnSurface() && glm::length2(state.pos) < (planet->Radius() + 0.05) * (planet->Radius() + 0.05);
+}
+
glm::dvec3 Situation::SurfaceNormal() const noexcept {
return planet->NormalAt(state.pos);
}
result += TargetVelocity(s, diff * std::min(dist * force, speed) / dist, force);
}
}
+ // remove vertical component, if any
+ const glm::dvec3 normal(c.GetSituation().GetPlanet().NormalAt(s.pos));
+ result += normal * glm::dot(normal, result);
+ // clamp to max
if (glm::length2(result) > max_force * max_force) {
result = glm::normalize(result) * max_force;
}