godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.11k stars 69 forks source link

Add methods to rotate Rect2 and AABB (Rect3) #1529

Open Shadowblitz16 opened 3 years ago

Shadowblitz16 commented 3 years ago

Describe the project you are working on: a 3d spaceship builder

Describe the problem or limitation you are having in your project: I am trying to make a spaceship builder but I need to check rotated collisions I was wonding if rect2 and aabb(rect3) could support checking with a x, y and z rotation by 90 degree increments

Describe the feature / enhancement and how it helps to overcome the problem or limitation: giving us this ability allows us check grid coordinates with rotation allowing us to easily build 3d builders

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

aabb1.rotate(Vector3i(0,0,1)) //rotated 90 degrees on z axis

If this enhancement will not be used often, can it be worked around with a few lines of script?: it might be able to be worked around by implementing areas but this requires that node is present and it would be nice to be able to check collision without creating area or physics nodes

Is there a reason why this should be core and not an add-on in the asset library?: it allows us to transform the bounding box without too much overhead

addmix commented 3 years ago

the point of rect2 and AABB is to save processing time checking collisions, this being said, they are not meant to be rotated.

You can check collisions by using the collide_shape() function https://docs.godotengine.org/en/stable/classes/class_physics2ddirectspacestate.html?#class-physics2ddirectspacestate

ShawkMusic commented 2 years ago

The whole point of AABBs is that they are efficient because they are axis-aligned (Axis Aligned Bounding Box). If you want it to be rotated you should use something else. That being said, I do think there should be a function added to rotate them by 90 degree increments

Zireael07 commented 2 years ago

Then some other class we could use for rotating is necessary for 3d. As it stands currently, Rect2 can be rotated and does not need to be axis aligned. AABB can't be doing double duty as Axis Aligned and Rect3 at once.

TurqW commented 8 months ago

The initial proposal doesn't suggest losing the axis-aligned property - it explicitly says to rotate by 90 degree increments. Which should possible by reassigning position and maybe just swapping axes on size? But that leaves the question of how the position reassignment should work, particularly across multiple operations.

If we're ok with always rotating around "position" (and thus not having subsequent rotations return you to the same point) in GodotScript it could be something like:

# Takes rotation in integers indicating increments of 90, in the axis being rotated around . I.e. aabb1.rotate(Vector3i(0,0,1))
func rotate(rotation: Vector3i) -> AABB:
    var axis = rotation.abs().normalized()
    # Optional: confirm rotation length == abs(rotation[axis.max_axis_index()]) i.e. all other values are 0
    var new_size = size * Basis.IDENTITY.rotated(Vector3(axis), deg_to_rad(90*rotation[axis.max_axis_index()]))
    return AABB(position, new_size).abs() # Per the docs, AABB doesn't support having negative size values

You could make it rotate around the center instead, but that involves more matrix math than I want to figure out on 0.5 hours of sleep...

matmas commented 4 months ago

You can rotate AABB by 90 degrees also with a Transform3D and operator *

Example:

Transform3D(Basis.IDENTITY.rotated(Vector3.BACK, deg_to_rad(90))) * aabb

You can also choose to rotate around a different point than Vector3.ZERO which is the default Transform3D.origin