Очевидный алгоритм, который отдает нормаль от стенки не работает, сфера при маленькой линейной скорости останавливается при переходе на следующий бокс (даже если боксы находятся на одном уровне).
На всякий случай алг, который использую.
Попробуй как-то так (вместо quat2 сгодится и матрица)
vec3 vec3::min(const vec3 &v) const { return vec3( _min( x, v.x), _min( y, v.y), _min( z, v.z)); } vec3 vec3::max( const vec3 &v) const { return vec3( _max( x, v.x), _max( y, v.y), _max( z, v.z)); } ... bool Box::intersect( const vec3 &point) const { return point.x >= min.x && point.x <= max.x && point.y >= min.y && point.y <= max.y && point.z >= min.z && point.z <= max.z; } bool Box::intersect( const Sphere &sphere, vec3 &outNormal, float &outDist) const { if ( intersect( sphere.center)) return true; // outNormal? vec3 p = max.min( min.max( sphere.center)); outNormal = sphere.center - p; outDist = outNormal.length2( ); if ( outDist >= ( sphere.radius * sphere.radius) || outDist == 0.0f) return false; outDist = sqrtf( outDist); outNormal *= 1.0f / outDist; return true; } bool Box::intersect( const quat2 &basis, const Sphere &sphere, vec3 &outNormal, float &outDist) const { vec3 center = basis.inverse( ) * sphere.center; if ( intersect( Sphere( center, sphere.radius), outNormal, outDist)) { outNormal = basis.getRot( ) * outNormal; return true; } return false; }
Тут я сферу поворачиваю обратной трансформацией бокса, тем самым сведя задачу к AABB vs Sphere, затем полученную нормаль поворачиваю матрицей поворота бокса. В итоге, в случае столкновения, сферу нужно будет вытолкнуть на outNormal * outDist
Тема в архиве.