for (WorldCollision &c : col) {
                // diff points from block to state
                glm::vec3 diff = state.RelativePosition(c.ChunkPos()) - c.BlockCoords();
-               float dist = length_squared(diff);
+               float dist = length2(diff);
                if (dist < distance) {
                        nearest = &c;
                        difference = diff;
                return;
        }
        // halt if we're close enough, flee if we're too close
-       float dist_sq = length_squared(e.AbsoluteDifference(ctrl.GetPursuitTarget()));
+       float dist_sq = length2(e.AbsoluteDifference(ctrl.GetPursuitTarget()));
        if (dist_sq < 8.0f) {
                ctrl.SetFleeTarget(ctrl.GetPursuitTarget());
                ctrl.SetState(flee);
 
 #include <algorithm>
 #include <limits>
 #include <glm/glm.hpp>
+#include <glm/gtx/component_wise.hpp>
+#include <glm/gtx/norm.hpp>
 
 
 namespace blank {
 
-inline float length_squared(const glm::vec3 &v) noexcept {
-       return dot(v, v);
-}
-
-inline float distance_squared(const glm::vec3 &a, const glm::vec3 &b) noexcept {
-       return length_squared(a - b);
-}
-
-inline float distance(const glm::vec3 &a, const glm::vec3 &b) noexcept {
-       return length(a - b);
-}
-
 template <class T>
 inline bool iszero(const T &v) noexcept {
-       return length_squared(v) < std::numeric_limits<typename T::value_type>::epsilon();
+       return length2(v) < std::numeric_limits<typename T::value_type>::epsilon();
 }
 
 template<class T>
 T manhattan_distance(const glm::tvec3<T> &a, const glm::tvec3<T> &b) noexcept {
-       glm::tvec3<T> diff(abs(a - b));
-       return diff.x + diff.y + diff.z;
+       return compAdd(abs(a - b));
 }
 
 template<class T>
 T manhattan_radius(const glm::tvec3<T> &v) noexcept {
-       glm::tvec3<T> a(abs(v));
-       return std::max(a.x, std::max(a.y, a.z));
+       return compMax(abs(v));
 }
 
 }
 
                        return glm::mat3(glm::rotate(PI, axis));
                }
        }
-       float mv = length_squared(v);
+       float mv = length2(v);
        float c = dot(a, b);
        float f = (1 - c) / mv;
        glm::mat3 vx(matrixCross3(v));
                glm::vec3(b_m * glm::vec4(b_box.max.x, b_box.max.y, b_box.max.z, 1)),
        };
 
-       glm::vec3 axes[6] = {
-               glm::vec3(a_m * glm::vec4(1, 0, 0, 0)),
-               glm::vec3(a_m * glm::vec4(0, 1, 0, 0)),
-               glm::vec3(a_m * glm::vec4(0, 0, 1, 0)),
-               glm::vec3(b_m * glm::vec4(1, 0, 0, 0)),
-               glm::vec3(b_m * glm::vec4(0, 1, 0, 0)),
-               glm::vec3(b_m * glm::vec4(0, 0, 1, 0)),
+       glm::vec3 axes[15] = {
+               glm::vec3(a_m[0]),
+               glm::vec3(a_m[1]),
+               glm::vec3(a_m[2]),
+               glm::vec3(b_m[0]),
+               glm::vec3(b_m[1]),
+               glm::vec3(b_m[2]),
+               cross(glm::vec3(a_m[0]), glm::vec3(b_m[0])),
+               cross(glm::vec3(a_m[0]), glm::vec3(b_m[1])),
+               cross(glm::vec3(a_m[0]), glm::vec3(b_m[2])),
+               cross(glm::vec3(a_m[1]), glm::vec3(b_m[0])),
+               cross(glm::vec3(a_m[1]), glm::vec3(b_m[1])),
+               cross(glm::vec3(a_m[1]), glm::vec3(b_m[2])),
+               cross(glm::vec3(a_m[2]), glm::vec3(b_m[0])),
+               cross(glm::vec3(a_m[2]), glm::vec3(b_m[1])),
+               cross(glm::vec3(a_m[2]), glm::vec3(b_m[2])),
        };
 
        depth = std::numeric_limits<float>::infinity();
 
        int cur_axis = 0;
        for (const glm::vec3 &axis : axes) {
+               if (iszero(axis)) {
+                       // can result from the cross products if A and B have parallel axes
+                       continue;
+               }
                float a_min = std::numeric_limits<float>::infinity();
                float a_max = -std::numeric_limits<float>::infinity();
                for (const glm::vec3 &corner : a_corners) {