diff --git a/docs/modules/linalg.md b/docs/modules/linalg.md index f270fb40..3e19798a 100644 --- a/docs/modules/linalg.md +++ b/docs/modules/linalg.md @@ -15,6 +15,8 @@ class vec2(_StructLike['vec2']): x: float y: float + def assign(self, other: vec2) -> None: ... + def __init__(self, x: float, y: float) -> None: ... def __add__(self, other: vec2) -> vec2: ... def __sub__(self, other: vec2) -> vec2: ... @@ -47,6 +49,8 @@ class vec3(_StructLike['vec3']): y: float z: float + def assign(self, other: vec3) -> None: ... + def __init__(self, x: float, y: float, z: float) -> None: ... def __add__(self, other: vec3) -> vec3: ... def __sub__(self, other: vec3) -> vec3: ... @@ -65,6 +69,8 @@ class vec4(_StructLike['vec4']): z: float w: float + def assign(self, other: vec4) -> None: ... + def __init__(self, x: float, y: float, z: float, w: float) -> None: ... def __add__(self, other: vec4) -> vec4: ... def __sub__(self, other: vec4) -> vec4: ... @@ -87,6 +93,8 @@ class mat3x3(_StructLike['mat3x3']): _32: float _33: float + def assign(self, other: mat3x3) -> None: ... + @overload def __init__(self) -> None: ... @overload @@ -128,7 +136,7 @@ class mat3x3(_StructLike['mat3x3']): # affine transformations @staticmethod def trs(t: vec2, r: float, s: vec2) -> mat3x3: ... - + def set_trs(self, t: vec2, r: float, s: vec2) -> None: ... def is_affine(self) -> bool: ... diff --git a/include/pocketpy/linalg.h b/include/pocketpy/linalg.h index 577280b7..aaaab2c9 100644 --- a/include/pocketpy/linalg.h +++ b/include/pocketpy/linalg.h @@ -28,6 +28,7 @@ struct Vec2{ float length() const { return sqrtf(x * x + y * y); } float length_squared() const { return x * x + y * y; } Vec2 normalize() const { float l = length(); return Vec2(x / l, y / l); } + NoReturn assign(const Vec2& v) { x = v.x; y = v.y; return {}; } }; struct Vec3{ @@ -52,6 +53,7 @@ struct Vec3{ float length() const { return sqrtf(x * x + y * y + z * z); } float length_squared() const { return x * x + y * y + z * z; } Vec3 normalize() const { float l = length(); return Vec3(x / l, y / l, z / l); } + NoReturn assign(const Vec3& v) { x = v.x; y = v.y; z = v.z; return {}; } }; struct Vec4{ @@ -75,6 +77,7 @@ struct Vec4{ float length() const { return sqrtf(x * x + y * y + z * z + w * w); } float length_squared() const { return x * x + y * y + z * z + w * w; } Vec4 normalize() const { float l = length(); return Vec4(x / l, y / l, z / l, w / l); } + NoReturn assign(const Vec4& v) { x = v.x; y = v.y; z = v.z; w = v.w; return {}; } }; struct Mat3x3{ diff --git a/include/typings/linalg.pyi b/include/typings/linalg.pyi index 83d4618a..d72853e0 100644 --- a/include/typings/linalg.pyi +++ b/include/typings/linalg.pyi @@ -5,6 +5,8 @@ class vec2(_StructLike['vec2']): x: float y: float + def assign(self, other: vec2) -> None: ... + def __init__(self, x: float, y: float) -> None: ... def __add__(self, other: vec2) -> vec2: ... def __sub__(self, other: vec2) -> vec2: ... @@ -37,6 +39,8 @@ class vec3(_StructLike['vec3']): y: float z: float + def assign(self, other: vec3) -> None: ... + def __init__(self, x: float, y: float, z: float) -> None: ... def __add__(self, other: vec3) -> vec3: ... def __sub__(self, other: vec3) -> vec3: ... @@ -55,6 +59,8 @@ class vec4(_StructLike['vec4']): z: float w: float + def assign(self, other: vec4) -> None: ... + def __init__(self, x: float, y: float, z: float, w: float) -> None: ... def __add__(self, other: vec4) -> vec4: ... def __sub__(self, other: vec4) -> vec4: ... @@ -77,6 +83,8 @@ class mat3x3(_StructLike['mat3x3']): _32: float _33: float + def assign(self, other: mat3x3) -> None: ... + @overload def __init__(self) -> None: ... @overload diff --git a/src/linalg.cpp b/src/linalg.cpp index 7e262624..41c7732b 100644 --- a/src/linalg.cpp +++ b/src/linalg.cpp @@ -162,6 +162,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float BIND_VEC_FIELD(2, y) BIND_VEC_FUNCTION_1(2, dot) BIND_VEC_FUNCTION_1(2, cross) + BIND_VEC_FUNCTION_1(2, assign) BIND_VEC_FUNCTION_0(2, length) BIND_VEC_FUNCTION_0(2, length_squared) BIND_VEC_FUNCTION_0(2, normalize) @@ -200,6 +201,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float BIND_VEC_FIELD(3, z) BIND_VEC_FUNCTION_1(3, dot) BIND_VEC_FUNCTION_1(3, cross) + BIND_VEC_FUNCTION_1(3, assign) BIND_VEC_FUNCTION_0(3, length) BIND_VEC_FUNCTION_0(3, length_squared) BIND_VEC_FUNCTION_0(3, normalize) @@ -239,6 +241,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float BIND_VEC_FIELD(4, z) BIND_VEC_FIELD(4, w) BIND_VEC_FUNCTION_1(4, dot) + BIND_VEC_FUNCTION_1(4, assign) BIND_VEC_FUNCTION_0(4, length) BIND_VEC_FUNCTION_0(4, length_squared) BIND_VEC_FUNCTION_0(4, normalize) @@ -279,6 +282,13 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float return VAR(std::move(t)); }); + vm->bind_method<1>(type, "assign", [](VM* vm, ArgsView args){ + PyMat3x3& self = _CAST(PyMat3x3&, args[0]); + const PyMat3x3& other = CAST(PyMat3x3&, args[1]); + self = other; + return vm->None; + }); + vm->bind_method<0>(type, "set_zeros", PK_ACTION(PK_OBJ_GET(PyMat3x3, args[0]).set_zeros())); vm->bind_method<0>(type, "set_ones", PK_ACTION(PK_OBJ_GET(PyMat3x3, args[0]).set_ones())); vm->bind_method<0>(type, "set_identity", PK_ACTION(PK_OBJ_GET(PyMat3x3, args[0]).set_identity())); diff --git a/tests/80_linalg.py b/tests/80_linalg.py index e3c5aec9..cf3caaf0 100644 --- a/tests/80_linalg.py +++ b/tests/80_linalg.py @@ -487,3 +487,22 @@ class mymat3x3(mat3x3): return _0 == _1 == _2 assert mymat3x3().f() + + +# test assign +a = vec2(1, 2) +assert a.assign(vec2(3, 4)) is None +assert a == vec2(3, 4) + +b = vec3(1, 2, 3) +assert b.assign(vec3(4, 5, 6)) is None +assert b == vec3(4, 5, 6) + +c = vec4(1, 2, 3, 4) +assert c.assign(vec4(5, 6, 7, 8)) is None +assert c == vec4(5, 6, 7, 8) + +d = mat3x3.identity() +assert d.assign(mat3x3.zeros()) is None +assert d == mat3x3.zeros() +