I am updating my procedural generation project from Unity. However, some of my logic uses Quaternion.FromToRotation (which Godot doesn't have). I am currently using Godot 4.1.1.

This is the current implementation (with the missing Quaternion.FromToRotation methods)

/// <summary>
/// Attempts to link this gate to another gate.
/// </summary>
/// <param name="other">The gate to link this to.</param>
/// <returns>Whether or not the linking was successful.</returns>
public bool AttemptLink(LG_Gate? other)
{
    if (other == null || !this.IsAvailable || !other.IsAvailable || this.m_area == null)
    {
        return false;
    }

    // store forwards/rights so they don't have to be re-grabbed.

    Vector3 forward = this.Forward;
    Vector3 otherForward = other.Forward;
    Vector3 right = this.Right;
    Vector3 otherRight = other.Right;

    // sometimes rotations make fucky-wuckies when the right directions are equal.
    // so we do a little rotating to fix it.
    if (right == otherRight)
    {
        this.m_area.RootNode.Rotate(forward, 10f);
    }

    Quaternion rotation = Quaternion.FromToRotation(
        forward, -otherForward);
    this.m_area.RootNode.GlobalRotation *= rotation;

    // sometimes rotations make fucky-wuckies when the forward directions are equal.
    // so we do a little rotating to fix it.
    if (forward == otherForward)
    {
        this.m_area.RootNode.Rotate(right, 10f);
    }

    rotation = Quaternion.FromToRotation(
        right, -otherRight);
    this.m_area.RootNode.GlobalRotation *= rotation;


    Vector3 translation = // position translation
        other.Position - this.Position +
        // offset translation
        (other.Rotation * (other.Offset + this.Offset));

    this.m_area.RootNode.GlobalPosition += translation;

    this.m_linkedTo = other;
    other.m_linkedTo = this;

    return true;
}

This implementation was based off of this.

  • xyz replied to this.

    fluffydoggo Use Quaternion constructor that takes axis and angle as arguments. The axis vector is normalized cross product of from and to vectors. The angle is angle between from and to vectors returned by Vector3::AngleTo()

    fluffydoggo

    public Quaternion QuatFromTo(Vector3 vFrom, Vector3 vTo){
    	Vector3 axis = vFrom.Cross(vTo).Normalized();
    	float angle = vFrom.AngleTo(vTo);
    	return new Quaternion(axis, angle);
    }

    Godot 4 effectively does have it. One of the Quaternion constructors takes 2 vector3s and builds the quaternion as a rotation from the first vector to the second vector. (As long as the vectors are normalised)
    Unity:

    Quaternion rotation = Quaternion.FromToRotation(forward, -otherForward);

    Godot:

    var rotation = Quaternion(forward, -otherForward)
    • xyz replied to this.

      Kojack Oops, don't know how I missed this 😊 Yeah, just use this constructor then @fluffydoggo.