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()); }
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); }
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); }
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); }
template<UnsignedInt dimensions> void Line<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) { _transformedA = matrix.transformPoint(_a); _transformedB = matrix.transformPoint(_b); }
template<UnsignedInt dimensions> void AxisAlignedBox<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) { _transformedMin = matrix.transformPoint(_min); _transformedMax = matrix.transformPoint(_max); }
template<UnsignedInt dimensions> void Capsule<dimensions>::applyTransformationMatrix(const typename DimensionTraits<dimensions>::MatrixType& matrix) { _transformedA = matrix.transformPoint(_a); _transformedB = matrix.transformPoint(_b); Float scaling = (matrix.rotationScaling()*typename DimensionTraits<dimensions>::VectorType(1/Constants::sqrt3())).length(); _transformedRadius = scaling*_radius; }
template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ColorFormat format, ColorType type, const void* data, BufferUsage usage) { _format = format; _type = type; _size = size; _buffer.setData({data, pixelSize()*size.product()}, usage); }
template<UnsignedInt dimensions> void ForceRenderer<dimensions>::draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>& camera) { shader->setTransformationProjectionMatrix(camera.projectionMatrix()*Implementation::forceRendererTransformation<dimensions>(transformationMatrix.transformPoint(forcePosition), force)*DimensionTraits<dimensions, Float>::MatrixType::scaling(typename DimensionTraits<dimensions, Float>::VectorType(options->scale()))) .setColor(options->color()) .use(); mesh->draw(); }
template<UnsignedInt dimensions> Cylinder<dimensions> Cylinder<dimensions>::transformed(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) const { return Cylinder<dimensions>(matrix.transformPoint(_a), matrix.transformPoint(_b), matrix.uniformScaling()*_radius); }
template<UnsignedInt dimensions> AxisAlignedBox<dimensions> AxisAlignedBox<dimensions>::transformed(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) const { return AxisAlignedBox<dimensions>(matrix.transformPoint(_min), matrix.transformPoint(_max)); }
template<UnsignedInt dimensions> Sphere<dimensions> Sphere<dimensions>::transformed(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) const { return Sphere<dimensions>(matrix.transformPoint(_position), matrix.uniformScaling()*_radius); }