ПрограммированиеФорумФизика

OBB vs Sphere. Затыки на гранях.

#0
14:31, 2 мар 2016

Очевидный алгоритм, который отдает нормаль от стенки не работает, сфера при маленькой линейной скорости останавливается при переходе на следующий бокс (даже если боксы находятся на одном уровне).

#1
15:32, 2 мар 2016

На всякий случай алг, который использую.

+ Показать
#2
4:43, 3 мая 2016

Попробуй как-то так (вместо 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

ПрограммированиеФорумФизика

Тема в архиве.