godotjs / javascript

Javascript binding for godotengine
https://godotjs.github.io/
MIT License
976 stars 84 forks source link

godot.lerp errors for Vector3 not using the correct type #71

Open Flux159 opened 4 years ago

Flux159 commented 4 years ago

Hi, getting an error trying to use godot.lerp for Vector3 types (positions).

E 0:00:01.095   call_method: JavaScript Error    at lerp (native)
    at _process (res://src/Camera.jsx:22)
Call builtin function error lerp: Argument of type 'Vector3' is not assignable to parameter #0 of type 'float'
  <C++ Source>  modules/ECMAScript/quickjs/quickjs_binder.cpp:2125 @ call_method()

The documentation in godot.d.ts says that the function should accept Vector2, Vector3, or Color arguments, but it seems like it's only expecting floats at runtime.

/** Linearly interpolates between two values by a normalized value. This is the opposite of `inverse_lerp`.
If the `from` and `to` arguments are of type `int` or `float`, the return value is a `float`.

If both are of the same vector type (`Vector2`, `Vector3` or `Color`), the return value will be of the same type (`lerp` then calls the vector type's `linear_interpolate` method).

gdscript
lerp(0, 4, 0.75) # Returns 3.0
lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Returns Vector2(2, 3.5)
 */
function lerp(p_from: any, to: any, weight: number) : any;

I was able to easily get around this by writing a vector3 lerp function in typescript, but it would be nice to be able to use the builtin function:

function Vector3Lerp(
  a: godot.Vector3,
  b: godot.Vector3,
  t: number
): godot.Vector3 {
  return new godot.Vector3(
    a.x * (1 - t) + b.x * t,
    a.y * (1 - t) + b.y * t,
    a.z * (1 - t) + b.z * t
  );
}
Geequlim commented 4 years ago

How about godot.round and godot.ceil ?

Flux159 commented 4 years ago

godot.round and godot.ceil both are typed properly in godot.d.ts and function as expected on floats / error out on Vector3:

/** Rounds `s` upward, returning the smallest integral value that is not less than `s`.

 i = ceil(1.45)  # i is 2
 i = ceil(1.001) # i is 2
  */
function ceil(s: number) : number;

/** Returns the integral value that is nearest to `s`, with halfway cases rounded away from zero.

 round(2.6) # Returns 3
  */
function round(s: number) : number;

Trying to use a Vector3 ends up failing, but floats work fine:

console.log(godot.ceil(1.6)); // prints 2
// @ts-ignore
console.log(godot.ceil(new godot.Vector3(1.6, 0.6, 0.4)));

console.log(godot.round(1.4)); // prints 1
// @ts-ignore
console.log(godot.round(new godot.Vector3(1.6, 0.6, 0.4)));
E 0:00:01.510   call_method: JavaScript Error    at round (native)
    at _input (res://src/Cursor.jsx:32)
Call builtin function error round: Argument of type 'Vector3' is not assignable to parameter #0 of type 'float'
  <C++ Source>  modules/ECMAScript/quickjs/quickjs_binder.cpp:2125 @ call_method()

E 0:00:01.339   call_method: JavaScript Error    at ceil (native)
    at _input (res://src/Cursor.jsx:38)
Call builtin function error ceil: Argument of type 'Vector3' is not assignable to parameter #0 of type 'float'
  <C++ Source>  modules/ECMAScript/quickjs/quickjs_binder.cpp:2125 @ call_method()