How to rotate 3D object to align with terrain?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jackash

I have a terrain mesh and an object above it and it needs to be rotated according to RaycastHit.normal. Here’s how it was in Unity:

object.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal)

I just can’t “translate this” to Godot, how it’s going to be with Godot’s Quat()?

:bust_in_silhouette: Reply From: omggomb

I don’t know how FromToRotation is implemed (in general) but I think you could do something like this

var n1norm = <yourobject>.transform.basis.y
var n2norm = hit.normal

var cosa =
var alpha = acos(cosa)

var axis = n1norm.cross(n2norm)
axis = axis.normalized()

<yourobject>.transform = <yourobject>.transform.rotated(axis, alpha)

Basically calculate the angle between you object’s up vector and the hit normal and then rotating you object with that angle around the axis that is perpendicular to both vectors.

I get Math::is_nan(v.x) error, do you know what is it?

jackash | 2019-05-01 17:31

No idea, sorry.
What does the callstack say? Also which engine version are you using?

omggomb | 2019-05-01 17:42

I’m using Godot 3.1. The only call is to the object I want to rotate

jackash | 2019-05-01 17:47

It’s working fine when I check if alpha is not NaN but maybe there is a better way to prevent this?

if !is_nan(alpha):
  <yourobject>.transform = <yourobject>.transform.rotated(axis, alpha)

jackash | 2019-05-01 18:03

The only way i can reproduce this is when one of the vectors for the dot product is not normalized. Try normalizing both vectors before calculating the dot product (maybe the hitnormal isn’t normalized?)

n1norm = n1norm.normalized()
n2norm= n2norm.normalized

omggomb | 2019-05-01 18:49

cant thank you enough, this is the first method of aligning objects with surface normals that’s worked for me. i’d only add that to make it work with an object that’s moving along a surface it needs to be rotated incrementally with a slerp.

pioenisgreat | 2021-12-15 23:47