Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDScript: generalize lerp #16106

Merged
merged 1 commit into from
May 7, 2018
Merged

GDScript: generalize lerp #16106

merged 1 commit into from
May 7, 2018

Conversation

poke1024
Copy link
Contributor

Allow lerp to be used with Vector2, Vector3, Color, e.g. lerp(Color(0.1, 0.2, 0.1), Color(0.5, 0.2, 0.8), t). Yes, you could call linear_interpolate on these types, but I think it would be nice if lerp just works too.

@poke1024
Copy link
Contributor Author

I wonder if Quaternions also be supported, and lerp should just call Quaternion.slerp()...

@ghost ghost added this to the 3.1 milestone Jan 27, 2018
@Causeless
Copy link

Causeless commented Jan 30, 2018

I don't think lerp should call quaternion.slerp().

Firstly, they are different methods of interpolation, and secondly, there are valid reasons to simply linearly interpolate a quaternion (as it is, after all, a vector pointing to the surface of a 3-sphere).

Quaternions aren't limited to only representing rotations. If you want to interpolate through the interior of that 3-sphere instead of along the surface, you'd want to use lerp.

Even regardless of that, many games just use lerp anyways for rotational interpolation as it's significantly faster with only a minor difference in quality.

I'd say for quaternions it should be explicit without any overload for lerp(), to avoid any confusion.

@Zylann
Copy link
Contributor

Zylann commented Jan 30, 2018

I think it's ok to use slerp, since if you use the generic lerp you would expect the most common interpolation method to happen (like when you do tweens or animations, they use slerp too most of the time). The other interpolation methods still exist anyways, and can be called case per case when needed.

@Causeless
Copy link

Causeless commented Jan 30, 2018

Well, that's just incorrect then. It's Linear Interpolation. Tweening is the generic term, but "lerp" specifically refers to a linear interpolation.

@bfloch
Copy link
Contributor

bfloch commented Feb 2, 2018

Related question: Why is it Vector3.linear_interpolate and not Vector3.lerp?

I don't mind having the proposed interface (even with the member function), but I never got why it's inconsistent in naming as is.

@tagcup
Copy link
Contributor

tagcup commented Mar 14, 2018

slerp is a linear interpolation (of the angle between the rotation axes and angles corresponding to from- and to-quaternions).

Generally speaking, that's the only sensible interpolation between two elements of a Lie group. Like they can be written as e^{-i θ1 n1.λ} and e^{-i θ2 n2.λ}, and you tilt the rotation axis n1 to n2 linearly along a geodesic and also θ1 to θ2. Expanding the exponent with respect to some basis and interpolating the elements of that vector (which is what you probably think lerp would mean for a quaternion) makes no sense because it's basis dependent (in Godot, a quaternion is stored as qₙ = tr(e^{-i θ1 n1.λ}.λ'ₙ) with respect to a fixed basis λ'ₙ, and those numbers are basis-dependent and so is interpolating them)

@tagcup
Copy link
Contributor

tagcup commented Mar 14, 2018

I'm not saying that it makes sense that lerp should call slerp for quaternions though; I'm just pointing at a common confusion among programmers about the meaning of interpolation in non-trivial contexts, which is why I think it's probably bad a idea to make lerp call slerp.

@Causeless
Copy link

I think it really depends on that way you look at things - indeed, both are technically linear interpolation, just in difference reference frames.

The way I see it, it comes down to a question of the type moreso than the function. If the type were called Rotation, then I'd be perfectly fine with lerp() actually doing a slerp in the background. When we're instead talking about Quaternion, which doesn't necessarily represent a rotation, I think it's misleading.

@bojidar-bg
Copy link
Contributor

BTW, why not use Variant.interpolate(a,b,t,res) directly?

static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);

@tagcup
Copy link
Contributor

tagcup commented Mar 14, 2018

indeed, both are technically linear interpolation, just in difference reference frames.

@Causeless No, slerp is independent of the reference frame, as opposed to being tied to one. That's the point, it makes no sense otherwise.

Quaternion, which doesn't necessarily represent a rotation, I think it's misleading.

A unit quaternion is a representation of rotation (same holds for any representation of any Lie group), and a general quaternion is the representation of the Lie algebra (which generates the corresponding Lie group) spin(3) which is isomorphic to su(2) and so(3). More precisely, it's the representation of Spin(3), which is a double cover of SO(3), the group of 3D rotations. The "usual" rotation matrix is the fundamental representation SO(3).

The only reason I think it's "misleading" is because programmers think they understand rotations, quaternions and slerp but what they think they know is either totally wrong or incomplete, rather than being aware of what they actually don't know (and I'm not saying this in an offensive manner, so please don't take this negatively [nothing personal, it's a very common thing among programmers], but you just reinforced my point).

(I started a write up about Lie groups with focus on U(1), SO(2), SO(3), Spin(3), SU(2) and also talks about different parameterizations of SO(3) as well as slerp; it will hopefully be accessible and clear things up for programmers. I'll submit it to the docs repository once I find some time and finish it up.)

@Causeless
Copy link

Causeless commented Mar 14, 2018

@tagcup I may have made myself misunderstood. I'm not saying that lerp/sleep are fundamentally tied to a reference frame, I'm merely stating that a lerp in one reference frame (for example, a spherical reference frame) can have the equivalent result to a slerp in another (e.g Cartesian).

A quaternion is a representation of a rotation. However, a quaternion is not a rotation.

The point I am making there is that although a lerp of a rotation and a slerp could be seen as equivalent, a lerp and slerp of a quaternion aren't. Quaternions can represent more than just rotations.

@poke1024
Copy link
Contributor Author

@bojidar-bg That would be a very pragmatic approach and I like that. We could prohibit quaternions and strings, but pass all other types to Variant.interpolate(), which also gives us some pool vector interpolation support (and we can add more there in one logical place).

@tagcup
Copy link
Contributor

tagcup commented Mar 14, 2018

It's not the you made yourself misunderstood; you basically misunderstand what a Lie algebra and Lie group is, and by extension, what a quaternion is.

You're conflating reference frame (how your origin and axes are laid out) with coordinate system (how you parameterize your coordinates, cartesian, spherical, etc).

Independent of reference frame means the results shouldn't depend on where you put your origin or however you orient the axes of your coordinate system. It has nothing to do with being cartesian or whatever.

A quaternion is a representation of a rotation. However, a quaternion is not a rotation.

Both of these sentences are simply wrong.
I'm going to reiterate what I said above: a quaternion is generator of rotations, and it automatically leads to result that a unit quaternion is represents a rotation.

In Godot (which is the context we have here) and all game engines, quaternions are assumed to have unit norms and their only purpose is to represent rotations.

Quaternion is a representation, that's all it is. So saying "it represents X but it's not X" is nonsense. And what it represents is spin(3) which is isomorphic to so(3).

Quaternions can represent more than just rotations.

FYI, representation and generate are technical words in group theory. Quaternion represents one and only one thing: the Lie algebra spin(3).

The points you're making are plain wrong, which is sort of the point that I'm trying to make at large.

@Causeless
Copy link

No, an observational frame of reference refers to the position of the axes. A frame of reference, in the generic term, can refers to both the coordinate system as well as the position of the axes. This is basic, easily verifiable stuff.

Furthermore it seems as if you are avoiding the point for the sake of intellectual masturbation, to bring up group theory and argue semantics. It is ignoring the fundamental point:

A: Quaternions can represent more than just rotations.
B: Quaternions have valid reasons to be both lerp()ed and slerp()ed.

@tagcup
Copy link
Contributor

tagcup commented Mar 15, 2018

Yeah whatever. I got better things to do to educate random illiterate people on the net. Go "masturbate" or whatever and have a happy day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants