-0 values in 3d transform basis

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

So i’ve started a new game project that has an oldschool 3d dungeoncrawler map.
Made dungeon with gridmap all fine.

Now i want to make playermovement in set steps. Everytime the player hits
a button he moves to the next cell in the grid. The movement is also supposed to be
smooth so i interpolate the movement.

This is the code i have so far for forward movement and left turn:

extends KinematicBody

var t = 0.0
var forwardFlag
var leftTurnFlag

var playerPoint = self.transform
var forwardPoint = self.transform
var leftTurnPoint = self.transform

func _ready():
	#changing target points for later interpolation
	forwardPoint.origin += Vector3(0,0,-2)
	leftTurnPoint = leftTurnPoint.rotated(Vector3(0,1,0), deg2rad(90))
	leftTurnPoint = leftTurnPoint.orthonormalized()
func _physics_process(delta):
	if Input.is_action_just_pressed("forward"):
		forwardFlag = true
	if Input.is_action_just_pressed("left"):
		leftTurnFlag = true
	if forwardFlag:
		t += delta
		self.transform = self.transform.interpolate_with(forwardPoint,t)
		if self.transform == forwardPoint:
			forwardFlag = false
			#update coresponding Point
			forwardPoint.origin += Vector3(0,0,-2)
			#reset t for interpolation speed
			t = 0
	if leftTurnFlag:
		t += delta

		self.transform = self.transform.interpolate_with(leftTurnPoint,t)

		if self.transform == leftTurnPoint:
			leftTurnFlag = false
			#update coresponding Point
			leftTurnPoint = leftTurnPoint.rotated(Vector3(0,1,0), deg2rad(90))
			leftTurnPoint = leftTurnPoint.orthonormalized()
			#reset t for interpolation speed
			t = 0

The forward movement works fine and dandy but for the rotation there comes up this problem:
When i print out each transform.basis values:
player: ((0, 0, 1), (0, 1, 0), (-1, 0, 0))
target: ((-0, 0, 1), (0, 1, 0), (-1, 0, -0))

the check if the interpolation is done isnt possible because the target.basis has -0 values.
The big question now is: Why?
Is there a reason why we have 0 and -0 values in these Datatypes?
And if this is by design and important is there:
a) a better way to accomplish my goal
or b) a more efficient way to test the end of interpolation than to go through the
target.basis and reset each -0 to 0 each time

Thanks a lot for anyone that can help with this.

:bust_in_silhouette: Reply From: wombatstampede

The problem here is that you try to compare floating point values for equality.
As you can read here (for details), this doesn’t work properly by simply using ==:

I looked at Basis and found the function is_equal_approx(otherbasis).

It is undocumented but by its naming that should be the comparison function you search for.

(Just for information:) Looking in the godot code, this function actually tests Math::is_equal_approx for all 9 values in the Basis. This is the function in math_funcs.h:

static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) {
	real_t tolerance = CMP_EPSILON * abs(a);
	if (tolerance < CMP_EPSILON) {
		tolerance = CMP_EPSILON;
	return abs(a - b) < tolerance;

static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b, real_t tolerance) {
	return abs(a - b) < tolerance;

Thanks for the help.

though when i use the basis.is_equal_approx in my code it still
gives only false value back. I rewrote the check in my own code checking
for all 9 values and eventually got it working fine.

Can you send me a link to the sourcecode of this function? Cause i have no
idea how to find a specific function in the sourcecode.

Nazzaroth | 2019-12-10 13:11

line 560:


Takt note that you can switch godot versions with the “Branch” drop down.

wombatstampede | 2019-12-10 14:24

thanks for the help :3

Nazzaroth | 2019-12-10 15:35