Beispiel #1
0
template<UnsignedInt dimensions> Collision<dimensions> InvertedSphere<dimensions>::operator/(const Point<dimensions>& other) const {
    const typename DimensionTraits<dimensions, Float>::VectorType separating = other.position() - position();
    const Float dot = separating.dot();

    /* No collision occured */
    if(dot < Math::pow<2>(radius())) return {};

    /* Actual distance from the center */
    const Float distance = Math::sqrt(dot);

    /* Separating normal */
    const typename DimensionTraits<dimensions, Float>::VectorType separatingNormal = separating/distance;

    /* Collision position is on the point */
    return Collision<dimensions>(other.position(), separatingNormal, distance - radius());
}
Beispiel #2
0
template<UnsignedInt dimensions> Collision<dimensions> InvertedSphere<dimensions>::operator/(const Sphere<dimensions>& other) const {
    const Float maxDistance = radius() - other.radius();
    /** @todo How to handle inseparable shapes or shapes which can't be separated by movement only (i.e. two half-spaces)? */
    CORRADE_INTERNAL_ASSERT(maxDistance > 0.0f);
    const typename DimensionTraits<dimensions, Float>::VectorType separating = other.position() - position();
    const Float dot = separating.dot();

    /* No collision occured */
    if(dot < Math::pow<2>(maxDistance)) return {};

    /* Actual distance */
    const Float distance = Math::sqrt(dot);

    /* Separating normal */
    const typename DimensionTraits<dimensions, Float>::VectorType separatingNormal = separating/distance;

    /* Contact position is on the surface of `other`, distance > maxDistance */
    return Collision<dimensions>(other.position() + separatingNormal*other.radius(), separatingNormal, distance - maxDistance);
}
Beispiel #3
0
template<UnsignedInt dimensions> Collision<dimensions> Sphere<dimensions>::operator/(const Point<dimensions>& other) const {
    const typename DimensionTraits<dimensions, Float>::VectorType separating = _position - other.position();
    const Float dot = separating.dot();

    /* No collision occured */
    if(dot > Math::pow<2>(_radius)) return {};

    /* Actual distance from the center */
    const Float distance = Math::sqrt(dot);

    /* Separating normal. If can't decide on direction, just move up. */
    /** @todo How to handle this in a configurable way? */
    const typename DimensionTraits<dimensions, Float>::VectorType separatingNormal =
        Math::TypeTraits<Float>::equals(dot, 0.0f) ?
        DimensionTraits<dimensions, Float>::VectorType::yAxis() :
        separating/distance;

    /* Collision position is on the point */
    return Collision<dimensions>(other.position(), separatingNormal, _radius - distance);
}
Beispiel #4
0
template<UnsignedInt dimensions> Collision<dimensions> Sphere<dimensions>::operator/(const Sphere<dimensions>& other) const {
    const Float minDistance = _radius + other._radius;
    const typename DimensionTraits<dimensions, Float>::VectorType separating = _position - other._position;
    const Float dot = separating.dot();

    /* No collision occured */
    if(dot > Math::pow<2>(minDistance)) return {};

    /* Actual distance */
    const Float distance = Math::sqrt(dot);

    /* Separating normal. If can't decide on direction, just move up. */
    /** @todo How to handle this in a configurable way? */
    const typename DimensionTraits<dimensions, Float>::VectorType separatingNormal =
        Math::TypeTraits<Float>::equals(dot, 0.0f) ?
        DimensionTraits<dimensions, Float>::VectorType::yAxis() :
        separating/distance;

    /* Contact position is on the surface of `other`, minDistace > distance */
    return Collision<dimensions>(other._position + separatingNormal*other._radius, separatingNormal, minDistance - distance);
}