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

Allow clamping vectors and colors in addition to floats and ints #45624

Merged
merged 2 commits into from
Jun 3, 2021

Conversation

aaronfranke
Copy link
Member

@aaronfranke aaronfranke commented Feb 1, 2021

Implements and closes #13926. Specifically, implements the API described in this comment in both core and C#:

  • Rename Vector2.clamped to Vector2.limit_length. I also gave it a default value of 1.0.

  • Add Vector3.limit_length to be consistent with Vector2. This part closes Add "clamped" method to Vector3 #30058.

  • Add Vector2.clamp(min, max) where min and max are of type Vector2.

  • Add Vector2i.clamp(min, max) where min and max are of type Vector2i.

  • Add Vector3.clamp(min, max) where min and max are of type Vector3.

  • Add Vector3i.clamp(min, max) where min and max are of type Vector3i.

  • Add Color.clamp(min, max) where min and max are of type Color.

    • Color.clamp has default values of min = Color(0, 0, 0, 0) and max = Color(1, 1, 1, 1), since clamping a color to this range seems like it would be a relatively common operation. You can also specify only min as Color.black to clamp to non-transparent colors, since black is Color(0, 0, 0, 1) and so alpha will always be 1.

This PR used to have 3 commits, but the third was un-done. For reference, here was that third commit: aaronfranke@9e04100

@Chaosus
Copy link
Member

Chaosus commented Feb 1, 2021

@aaronfranke: btw, WDYT about setting standard clamp min/max parameters default to 0.0/1.0 respectively?

@aaronfranke
Copy link
Member Author

aaronfranke commented Feb 1, 2021

@Chaosus No objection, and if done for clamp then it should also be done for the vectors. However, I think we should have some use cases in mind rather than just doing it for the sake of doing it. For Color I have a specific use case in mind (clamping to valid SDR colors which have channels on the range of 0 to 1).

@aaronfranke
Copy link
Member Author

aaronfranke commented Feb 3, 2021

@Chaosus I implemented your idea of having the clamp defaults be 0 to 1 everywhere (see the 3rd commit in this PR, I had to add a new macro to variant_utility.cpp). I think this should still be discussed, but worst case scenario it's harmless.

EDIT: This has been reverted, now the PR is only 2 commits. For reference, here was that third commit: aaronfranke@9e04100

@Chaosus
Copy link
Member

Chaosus commented Feb 3, 2021

Yeah, I think it's useful in some cases - this actually what saturate does in HLSL + in Unity there is Mathf.Clamp01 function.

@AndreaCatania
Copy link
Contributor

I think the syntax should be fixed before merge:

  • Clamp should just clamp its own data and don't return anything (or at max return a reference).
  • Clamped should return a copy of data but clamped.

@aaronfranke
Copy link
Member Author

aaronfranke commented Feb 3, 2021

@AndreaCatania Maybe. None of the exposed struct methods mutate the struct. We also have floor which isn't floored, round which isn't rounded, reflect which isn't reflected, bounce which isn't bounced, cross which isn't crossed, etc.

@AndreaCatania
Copy link
Contributor

@aaronfranke While for some of them I would not do that (like cross) for some others I would implement it. Because copy the structure each time you want to perform that operation is not nice.

However, we already have:

So I think that clamp and clamped should both exists.

@aaronfranke
Copy link
Member Author

@AndreaCatania If there was both clamp and clamped then we would only expose the latter, so the former wouldn't be used unless it was needed in the core engine (and I don't know of any parts of the engine that would use it).

@AndreaCatania
Copy link
Contributor

@aaronfranke Though, I think that I would use it extensively:

func _process(delta):
    velocity.clamp(max_velocity, max_velocity)

Which is much better than:

func _process(delta):
    velocity = velocity.clamp(max_velocity, max_velocity)

That also performs more operations for no reason.

@fire
Copy link
Member

fire commented Feb 5, 2021

Do any of these operations run by default and destroy HDR (< 0 and > 1) values?

@aaronfranke
Copy link
Member Author

@fire No, none of these run by default. The clamp methods only run if you explicitly call clamp.

reduz
reduz previously requested changes Jun 3, 2021
core/variant/variant_utility.cpp Outdated Show resolved Hide resolved
@akien-mga akien-mga dismissed reduz’s stale review June 3, 2021 19:20

Changes done.

@akien-mga akien-mga merged commit a9c6d2a into godotengine:master Jun 3, 2021
@akien-mga
Copy link
Member

Thanks!

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.

Add "clamped" method to Vector3 Allow clamping for more than just floats/ints
7 participants