diff --git a/include/typings/linalg.pyi b/include/typings/linalg.pyi index bc74c92f..5c2aac97 100644 --- a/include/typings/linalg.pyi +++ b/include/typings/linalg.pyi @@ -48,7 +48,10 @@ class vec2(_vecF['vec2']): def with_y(self, y: float) -> vec2: ... def with_z(self, z: float) -> vec3: ... + @overload def __init__(self, x: float, y: float) -> None: ... + @overload + def __init__(self, xy: vec2i) -> None: ... def rotate(self, radians: float) -> vec2: ... @@ -159,7 +162,10 @@ class vec3(_vecF['vec3']): def with_z(self, z: float) -> vec3: ... def with_xy(self, xy: vec2) -> vec3: ... + @overload def __init__(self, x: float, y: float, z: float) -> None: ... + @overload + def __init__(self, xyz: vec3i) -> None: ... diff --git a/src/modules/linalg.c b/src/modules/linalg.c index 34d79f12..851f0cf0 100644 --- a/src/modules/linalg.c +++ b/src/modules/linalg.c @@ -110,10 +110,17 @@ static py_Ref _const(py_Type type, const char* name) { #define DEF_VECTOR_OPS(D) \ static bool vec##D##__new__(int argc, py_Ref argv) { \ - PY_CHECK_ARGC(D + 1); \ c11_vec##D res; \ - for(int i = 0; i < D; i++) { \ - if(!py_castfloat32(&argv[i + 1], &res.data[i])) return false; \ + if(argc == 2) { \ + PY_CHECK_ARG_TYPE(1, tp_vec##D##i); \ + c11_vec##D##i v = py_tovec##D##i(&argv[1]); \ + for(int i = 0; i < D; i++) \ + res.data[i] = v.data[i]; \ + } else { \ + PY_CHECK_ARGC(D + 1); \ + for(int i = 0; i < D; i++) { \ + if(!py_castfloat32(&argv[i + 1], &res.data[i])) return false; \ + } \ } \ py_newvec##D(py_retval(), res); \ return true; \ diff --git a/tests/80_linalg.py b/tests/80_linalg.py index 4bc46cb7..1dc8cd3b 100644 --- a/tests/80_linalg.py +++ b/tests/80_linalg.py @@ -400,3 +400,8 @@ a[vec2i(1, 2)] = 1 assert a[vec2i(1, 2)] == 1 a[vec3i(1, 2, 3)] = 2 assert a[vec3i(1, 2, 3)] == 2 + +assert vec2(vec2i.LEFT) == vec2(-1, 0) +assert vec2(vec2i.RIGHT) == vec2(1, 0) +assert vec3(vec3i.ONE) == vec3(1, 1, 1) +assert vec3(vec3i.ZERO) == vec3(0, 0, 0)