blob: 3ea5e6643d1c1c8f2b852f459572e2e0b93bb525 [file] [log] [blame]
#include "rive/constraints/distance_constraint.hpp"
#include "rive/bones/bone.hpp"
#include "rive/artboard.hpp"
#include <algorithm>
using namespace rive;
enum class Mode
{
Closer = 0,
Further = 1,
Exact = 2
};
void DistanceConstraint::constrain(TransformComponent* component)
{
if (m_Target == nullptr || m_Target->isCollapsed())
{
return;
}
const Vec2D targetTranslation = m_Target->worldTranslation();
const Vec2D ourTranslation = component->worldTranslation();
Vec2D toTarget = ourTranslation - targetTranslation;
float currentDistance = toTarget.length();
switch (static_cast<Mode>(modeValue()))
{
case Mode::Closer:
if (currentDistance < distance())
{
return;
}
break;
case Mode::Further:
if (currentDistance > distance())
{
return;
}
break;
case Mode::Exact:
break;
}
if (currentDistance < 0.001f)
{
return;
}
toTarget *= (distance() / currentDistance);
Mat2D& world = component->mutableWorldTransform();
Vec2D position = targetTranslation + toTarget;
position = Vec2D::lerp(ourTranslation, position, strength());
world[4] = position.x;
world[5] = position.y;
}
void DistanceConstraint::distanceChanged() { markConstraintDirty(); }
void DistanceConstraint::modeValueChanged() { markConstraintDirty(); }