godotgdscriptgodot4

How to calculate Transform3D given position, rotation and scale?


I'm trying to mimic a 3D transformation in a 2D environment and hence am trying to do the 3D part of the calculations myself

For reference sake I've used a Node3D to check if my calculation method is correct

func calc_transform_3d(position_3d:Vector3, rotation_3d:Vector3, scale_3d:Vector3 ) -> Transform3D:
    
    var transform_3d := Transform3D(
        Basis.from_euler(rotation_3d).scaled(scale_3d),
        position_3d
    )
    
    return transform_3d

func _ready():
    var node_3d:Node3D = $Node3D
    var custom_transform := calc_transform_3d(node_3d.position, node_3d.rotation, node_3d.scale)
    
    print(custom_transform == node_3d.transform) # returns false

But the calc_transform_3d() method gives the wrong output (fyi it's not floating point error I checked)

So how to calculate a Transform3D (similar to how a Node3D calculates it) given only position, rotation and scale ?


Solution

  • Your rotation and scale are done in this order: S * R * INPUT. If you transformed a cube this way, you can easily get a skewed diamond shape out.

    Flip the order and use local rather than global scaling: R * S * INPUT, (this will mean your cube will only become a rectangular prism with scaling). So write your function something like this instead :

    func calc_transform_3d(position_3d:Vector3, rotation_3d:Vector3, scale_3d:Vector3 ) -> Transform3D:
    
        var transform_3d := Transform3D(
            Basis.from_euler(rotation_3d),
            position_3d
        ).scaled_local(scale_3d)
        
        return transform_3d