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

#changing target points for later interpolation
forwardPoint.origin += Vector3(0,0,-2)
leftTurnPoint = leftTurnPoint.orthonormalized()

print(self.transform)
print(leftTurnPoint)

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)
print(self.transform.basis)
print(forwardPoint.basis)

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)

print(self.transform.basis)
print(leftTurnPoint.basis)

if self.transform == leftTurnPoint:
leftTurnFlag = false
#update coresponding Point
leftTurnPoint = leftTurnPoint.orthonormalized()
print(self.transform)
print(leftTurnPoint)
#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.

in Engine

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 ==:
https://floating-point-gui.de/errors/comparison/

I looked at Basis and found the function `is_equal_approx(otherbasis)`.
https://docs.godotengine.org/en/3.1/classes/class_basis.html#class-basis-method-is-equal-approx

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::isequalapprox 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;
}
``````
by (3,240 points)

Thanks for the help.

though when i use the basis.isequalapprox 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.

https://github.com/godotengine/godot/blob/3.1/core/math/math_funcs.h

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

thanks for the help :3