How to make a 3D object's rotation equal to another object plane's Normal at Realtime

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Corruptinator
:warning: Old Version Published before Godot 3 was released.

Here is an interesting question that interrupted my mind minutes ago,

Is there a way to make a kinematic3D object rotate equal to whatever normal is collided against?

For example, I have a kinematic3D test cube with a raycast aiming downward underneath it and it is colliding against an another cube that is rotated. The normals on the cube is rotated and when I am using GDScript for the Raycast to get the normal Vector3 from the rotated cube it should provide enough data for me to tell the raycasted cube to rotate based on what normals is colliding…

However, it’s rotating the wrong way, so is there a way to make an object rotate based on what normals it is colliding at? Using get_collision_normal()?

The reason why I like to try this out because it would be useful for gravity defying gameplay, (A.K.A. F-ZERO X/GX) for example.

UPDATE: I need to clarify more to explain things a bit better, What I am looking for is a way to make the object rotate from an offset position, rather than the object’s origin if the raycast is colliding and gives the collision point. in other cases, making an object rotate from an origin offset of “get_collision_point()”.

Here are some rotation basics that may be helpful:
http://codetuto.com/2016/01/godot-engine-movement-and-rotation-basics/

eons | 2016-12-17 21:03

:bust_in_silhouette: Reply From: Warlaan

Objects aren’t actually rotated, they are transformed by a matrix by multiplying with it. Multiplying with a matrix means basically setting custom vectors for x, y and z. So the x-Direction is replaced with the first column, y with the second and so on.
So you just need to create a matrix from the normal and two vectors inside the collision plane.
To simplify that you can use Spatial.look_at(), which auromatically deduces the third column from the normal and one vector inside the collision plane.

Sounds interesting, I’ll have to observe the look_at() and see if it works in any way. I’ll let you know if anything happens.

Corruptinator | 2016-12-18 01:04

I’ve tried out look_at() in several ways but isn’t giving me the result I’m looking for.

Corruptinator | 2016-12-18 01:49

It’s a little tricky, since the first parameter of the look_at-function expects a position and the second one a direction.

I also ran into a problem when the collision occurs between a face of the kinematic body and an edge or single vertex of the static body. In that case the returned normal wasn’t perpendicular to any specific face.

For me it works when I make sure that the static body is large so the collision hits a face and when I use get_translation() + normal as the first parameter of the look_at-function. The second parameter isn’t as important, it just mustn’t be parallel to the normal.

In order to work around the issue with normals not working as needed when colliding with a vertex you could use a raycast instead of calling get_collision_normal() on the kinematic body itself.

Warlaan | 2016-12-19 14:02