From 89447378440e9b9472a7290facbd8949f41a64ae Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 22 Feb 2021 20:01:30 +0100 Subject: [PATCH] linmath: Support floor division for vector types Also fix __pow__ so that it returns the derived type, not the base type --- panda/src/linmath/lvecBase2_ext_src.I | 77 ++++++++++++++++++++-- panda/src/linmath/lvecBase2_ext_src.h | 5 +- panda/src/linmath/lvecBase2_src.h | 5 +- panda/src/linmath/lvecBase3_ext_src.I | 85 ++++++++++++++++++++++-- panda/src/linmath/lvecBase3_ext_src.h | 5 +- panda/src/linmath/lvecBase3_src.h | 5 +- panda/src/linmath/lvecBase4_ext_src.I | 93 +++++++++++++++++++++++++-- panda/src/linmath/lvecBase4_ext_src.h | 5 +- panda/src/linmath/lvecBase4_src.h | 5 +- tests/linmath/test_lvector2.py | 20 ++++++ tests/linmath/test_lvector3.py | 20 ++++++ tests/linmath/test_lvector4.py | 20 ++++++ 12 files changed, 321 insertions(+), 24 deletions(-) diff --git a/panda/src/linmath/lvecBase2_ext_src.I b/panda/src/linmath/lvecBase2_ext_src.I index e089ec6855..45d64e0de8 100644 --- a/panda/src/linmath/lvecBase2_ext_src.I +++ b/panda/src/linmath/lvecBase2_ext_src.I @@ -195,11 +195,78 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) { /** * */ -INLINE_LINMATH FLOATNAME(LVecBase2) Extension:: -__pow__(FLOATTYPE exponent) const { - return FLOATNAME(LVecBase2)( - cpow(_this->_v(0), exponent), - cpow(_this->_v(1), exponent)); +INLINE_LINMATH PyObject *Extension:: +__floordiv__(PyObject *self, FLOATTYPE scalar) const { + if (scalar == (FLOATTYPE)0) { + return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero"); + } + +#ifndef CPPPARSER + extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2); +#endif + PyObject *py_vec = PyObject_CallNoArgs((PyObject *)DtoolInstance_TYPE(self)); + if (py_vec != nullptr) { + FLOATNAME(LVecBase2) *vec = (FLOATNAME(LVecBase2) *)DtoolInstance_UPCAST(py_vec, FLOATNAME(Dtool_LVecBase2)); + nassertr(vec != nullptr, nullptr); + +#ifdef FLOATTYPE_IS_INT + if (scalar > 0) { + vec->_v(0) = (_this->_v(0) >= 0) ? _this->_v(0) / scalar : -1 - (-1 - _this->_v(0)) / scalar; + vec->_v(1) = (_this->_v(1) >= 0) ? _this->_v(1) / scalar : -1 - (-1 - _this->_v(1)) / scalar; + } else { + vec->_v(0) = (_this->_v(0) <= 0) ? _this->_v(0) / scalar : -1 + (1 - _this->_v(0)) / -scalar; + vec->_v(1) = (_this->_v(1) <= 0) ? _this->_v(1) / scalar : -1 + (1 - _this->_v(1)) / -scalar; + } +#else + vec->_v(0) = std::floor(_this->_v(0) / scalar); + vec->_v(1) = std::floor(_this->_v(1) / scalar); +#endif + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__ifloordiv__(PyObject *self, FLOATTYPE scalar) { + if (scalar == (FLOATTYPE)0) { + return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero"); + } + +#ifdef FLOATTYPE_IS_INT + if (scalar > 0) { + _this->_v(0) = (_this->_v(0) >= 0) ? _this->_v(0) / scalar : -1 - (-1 - _this->_v(0)) / scalar; + _this->_v(1) = (_this->_v(1) >= 0) ? _this->_v(1) / scalar : -1 - (-1 - _this->_v(1)) / scalar; + } else { + _this->_v(0) = (_this->_v(0) <= 0) ? _this->_v(0) / scalar : -1 + (1 - _this->_v(0)) / -scalar; + _this->_v(1) = (_this->_v(1) <= 0) ? _this->_v(1) / scalar : -1 + (1 - _this->_v(1)) / -scalar; + } +#else + _this->_v(0) = std::floor(_this->_v(0) / scalar); + _this->_v(1) = std::floor(_this->_v(1) / scalar); +#endif + Py_INCREF(self); + return self; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__pow__(PyObject *self, FLOATTYPE exponent) const { +#ifndef CPPPARSER + extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase2); +#endif + PyObject *py_vec = PyObject_CallNoArgs((PyObject *)DtoolInstance_TYPE(self)); + if (py_vec != nullptr) { + FLOATNAME(LVecBase2) *vec = (FLOATNAME(LVecBase2) *)DtoolInstance_UPCAST(py_vec, FLOATNAME(Dtool_LVecBase2)); + nassertr(vec != nullptr, nullptr); + + vec->_v(0) = cpow(_this->_v(0), exponent); + vec->_v(1) = cpow(_this->_v(1), exponent); + } + return py_vec; } /** diff --git a/panda/src/linmath/lvecBase2_ext_src.h b/panda/src/linmath/lvecBase2_ext_src.h index 59349980f1..c57dc15504 100644 --- a/panda/src/linmath/lvecBase2_ext_src.h +++ b/panda/src/linmath/lvecBase2_ext_src.h @@ -23,7 +23,10 @@ public: INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign); INLINE_LINMATH std::string __repr__() const; - INLINE_LINMATH FLOATNAME(LVecBase2) __pow__(FLOATTYPE exponent) const; + INLINE_LINMATH PyObject *__floordiv__(PyObject *self, FLOATTYPE scalar) const; + INLINE_LINMATH PyObject *__ifloordiv__(PyObject *self, FLOATTYPE scalar); + + INLINE_LINMATH PyObject *__pow__(PyObject *self, FLOATTYPE exponent) const; INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent); INLINE_LINMATH PyObject *__round__(PyObject *self) const; diff --git a/panda/src/linmath/lvecBase2_src.h b/panda/src/linmath/lvecBase2_src.h index b58a22bd42..6e41088706 100644 --- a/panda/src/linmath/lvecBase2_src.h +++ b/panda/src/linmath/lvecBase2_src.h @@ -133,7 +133,10 @@ PUBLISHED: INLINE_LINMATH void componentwise_mult(const FLOATNAME(LVecBase2) &other); - EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase2) __pow__(FLOATTYPE exponent) const); + EXTENSION(INLINE_LINMATH PyObject *__floordiv__(PyObject *self, FLOATTYPE scalar) const); + EXTENSION(INLINE_LINMATH PyObject *__ifloordiv__(PyObject *self, FLOATTYPE scalar)); + + EXTENSION(INLINE_LINMATH PyObject *__pow__(PyObject *self, FLOATTYPE exponent) const); EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent)); EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); diff --git a/panda/src/linmath/lvecBase3_ext_src.I b/panda/src/linmath/lvecBase3_ext_src.I index a93ae5546d..1197f203d6 100644 --- a/panda/src/linmath/lvecBase3_ext_src.I +++ b/panda/src/linmath/lvecBase3_ext_src.I @@ -196,12 +196,85 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) { /** * */ -INLINE_LINMATH FLOATNAME(LVecBase3) Extension:: -__pow__(FLOATTYPE exponent) const { - return FLOATNAME(LVecBase3)( - cpow(_this->_v(0), exponent), - cpow(_this->_v(1), exponent), - cpow(_this->_v(2), exponent)); +INLINE_LINMATH PyObject *Extension:: +__floordiv__(PyObject *self, FLOATTYPE scalar) const { + if (scalar == (FLOATTYPE)0) { + return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero"); + } + +#ifndef CPPPARSER + extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3); +#endif + PyObject *py_vec = PyObject_CallNoArgs((PyObject *)DtoolInstance_TYPE(self)); + if (py_vec != nullptr) { + FLOATNAME(LVecBase3) *vec = (FLOATNAME(LVecBase3) *)DtoolInstance_UPCAST(py_vec, FLOATNAME(Dtool_LVecBase3)); + nassertr(vec != nullptr, nullptr); + +#ifdef FLOATTYPE_IS_INT + if (scalar > 0) { + vec->_v(0) = (_this->_v(0) >= 0) ? _this->_v(0) / scalar : -1 - (-1 - _this->_v(0)) / scalar; + vec->_v(1) = (_this->_v(1) >= 0) ? _this->_v(1) / scalar : -1 - (-1 - _this->_v(1)) / scalar; + vec->_v(2) = (_this->_v(2) >= 0) ? _this->_v(2) / scalar : -1 - (-1 - _this->_v(2)) / scalar; + } else { + vec->_v(0) = (_this->_v(0) <= 0) ? _this->_v(0) / scalar : -1 + (1 - _this->_v(0)) / -scalar; + vec->_v(1) = (_this->_v(1) <= 0) ? _this->_v(1) / scalar : -1 + (1 - _this->_v(1)) / -scalar; + vec->_v(2) = (_this->_v(2) <= 0) ? _this->_v(2) / scalar : -1 + (1 - _this->_v(2)) / -scalar; + } +#else + vec->_v(0) = std::floor(_this->_v(0) / scalar); + vec->_v(1) = std::floor(_this->_v(1) / scalar); + vec->_v(2) = std::floor(_this->_v(2) / scalar); +#endif + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__ifloordiv__(PyObject *self, FLOATTYPE scalar) { + if (scalar == (FLOATTYPE)0) { + return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero"); + } + +#ifdef FLOATTYPE_IS_INT + if (scalar > 0) { + _this->_v(0) = (_this->_v(0) >= 0) ? _this->_v(0) / scalar : -1 - (-1 - _this->_v(0)) / scalar; + _this->_v(1) = (_this->_v(1) >= 0) ? _this->_v(1) / scalar : -1 - (-1 - _this->_v(1)) / scalar; + _this->_v(2) = (_this->_v(2) >= 0) ? _this->_v(2) / scalar : -1 - (-1 - _this->_v(2)) / scalar; + } else { + _this->_v(0) = (_this->_v(0) <= 0) ? _this->_v(0) / scalar : -1 + (1 - _this->_v(0)) / -scalar; + _this->_v(1) = (_this->_v(1) <= 0) ? _this->_v(1) / scalar : -1 + (1 - _this->_v(1)) / -scalar; + _this->_v(2) = (_this->_v(2) <= 0) ? _this->_v(2) / scalar : -1 + (1 - _this->_v(2)) / -scalar; + } +#else + _this->_v(0) = std::floor(_this->_v(0) / scalar); + _this->_v(1) = std::floor(_this->_v(1) / scalar); + _this->_v(2) = std::floor(_this->_v(2) / scalar); +#endif + Py_INCREF(self); + return self; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__pow__(PyObject *self, FLOATTYPE exponent) const { +#ifndef CPPPARSER + extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase3); +#endif + PyObject *py_vec = PyObject_CallNoArgs((PyObject *)DtoolInstance_TYPE(self)); + if (py_vec != nullptr) { + FLOATNAME(LVecBase3) *vec = (FLOATNAME(LVecBase3) *)DtoolInstance_UPCAST(py_vec, FLOATNAME(Dtool_LVecBase3)); + nassertr(vec != nullptr, nullptr); + + vec->_v(0) = cpow(_this->_v(0), exponent); + vec->_v(1) = cpow(_this->_v(1), exponent); + vec->_v(2) = cpow(_this->_v(2), exponent); + } + return py_vec; } /** diff --git a/panda/src/linmath/lvecBase3_ext_src.h b/panda/src/linmath/lvecBase3_ext_src.h index a80733c6a7..09b6c30234 100644 --- a/panda/src/linmath/lvecBase3_ext_src.h +++ b/panda/src/linmath/lvecBase3_ext_src.h @@ -23,7 +23,10 @@ public: INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign); INLINE_LINMATH std::string __repr__() const; - INLINE_LINMATH FLOATNAME(LVecBase3) __pow__(FLOATTYPE exponent) const; + INLINE_LINMATH PyObject *__floordiv__(PyObject *self, FLOATTYPE scalar) const; + INLINE_LINMATH PyObject *__ifloordiv__(PyObject *self, FLOATTYPE scalar); + + INLINE_LINMATH PyObject *__pow__(PyObject *self, FLOATTYPE exponent) const; INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent); INLINE_LINMATH PyObject *__round__(PyObject *self) const; diff --git a/panda/src/linmath/lvecBase3_src.h b/panda/src/linmath/lvecBase3_src.h index 00575a71a7..72f5ffdf00 100644 --- a/panda/src/linmath/lvecBase3_src.h +++ b/panda/src/linmath/lvecBase3_src.h @@ -152,7 +152,10 @@ PUBLISHED: INLINE_LINMATH void componentwise_mult(const FLOATNAME(LVecBase3) &other); - EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase3) __pow__(FLOATTYPE exponent) const); + EXTENSION(INLINE_LINMATH PyObject *__floordiv__(PyObject *self, FLOATTYPE scalar) const); + EXTENSION(INLINE_LINMATH PyObject *__ifloordiv__(PyObject *self, FLOATTYPE scalar)); + + EXTENSION(INLINE_LINMATH PyObject *__pow__(PyObject *self, FLOATTYPE exponent) const); EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent)); EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); diff --git a/panda/src/linmath/lvecBase4_ext_src.I b/panda/src/linmath/lvecBase4_ext_src.I index b0fa4a76fa..858abf7207 100644 --- a/panda/src/linmath/lvecBase4_ext_src.I +++ b/panda/src/linmath/lvecBase4_ext_src.I @@ -202,13 +202,92 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) { /** * */ -INLINE_LINMATH FLOATNAME(LVecBase4) Extension:: -__pow__(FLOATTYPE exponent) const { - return FLOATNAME(LVecBase4)( - cpow(_this->_v(0), exponent), - cpow(_this->_v(1), exponent), - cpow(_this->_v(2), exponent), - cpow(_this->_v(3), exponent)); +INLINE_LINMATH PyObject *Extension:: +__floordiv__(PyObject *self, FLOATTYPE scalar) const { + if (scalar == (FLOATTYPE)0) { + return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero"); + } + +#ifndef CPPPARSER + extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4); +#endif + PyObject *py_vec = PyObject_CallNoArgs((PyObject *)DtoolInstance_TYPE(self)); + if (py_vec != nullptr) { + FLOATNAME(LVecBase4) *vec = (FLOATNAME(LVecBase4) *)DtoolInstance_UPCAST(py_vec, FLOATNAME(Dtool_LVecBase4)); + nassertr(vec != nullptr, nullptr); + +#ifdef FLOATTYPE_IS_INT + if (scalar > 0) { + vec->_v(0) = (_this->_v(0) >= 0) ? _this->_v(0) / scalar : -1 - (-1 - _this->_v(0)) / scalar; + vec->_v(1) = (_this->_v(1) >= 0) ? _this->_v(1) / scalar : -1 - (-1 - _this->_v(1)) / scalar; + vec->_v(2) = (_this->_v(2) >= 0) ? _this->_v(2) / scalar : -1 - (-1 - _this->_v(2)) / scalar; + vec->_v(3) = (_this->_v(3) >= 0) ? _this->_v(3) / scalar : -1 - (-1 - _this->_v(3)) / scalar; + } else { + vec->_v(0) = (_this->_v(0) <= 0) ? _this->_v(0) / scalar : -1 + (1 - _this->_v(0)) / -scalar; + vec->_v(1) = (_this->_v(1) <= 0) ? _this->_v(1) / scalar : -1 + (1 - _this->_v(1)) / -scalar; + vec->_v(2) = (_this->_v(2) <= 0) ? _this->_v(2) / scalar : -1 + (1 - _this->_v(2)) / -scalar; + vec->_v(3) = (_this->_v(3) <= 0) ? _this->_v(3) / scalar : -1 + (1 - _this->_v(3)) / -scalar; + } +#else + vec->_v(0) = std::floor(_this->_v(0) / scalar); + vec->_v(1) = std::floor(_this->_v(1) / scalar); + vec->_v(2) = std::floor(_this->_v(2) / scalar); + vec->_v(3) = std::floor(_this->_v(3) / scalar); +#endif + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__ifloordiv__(PyObject *self, FLOATTYPE scalar) { + if (scalar == (FLOATTYPE)0) { + return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero"); + } + +#ifdef FLOATTYPE_IS_INT + if (scalar > 0) { + _this->_v(0) = (_this->_v(0) >= 0) ? _this->_v(0) / scalar : -1 - (-1 - _this->_v(0)) / scalar; + _this->_v(1) = (_this->_v(1) >= 0) ? _this->_v(1) / scalar : -1 - (-1 - _this->_v(1)) / scalar; + _this->_v(2) = (_this->_v(2) >= 0) ? _this->_v(2) / scalar : -1 - (-1 - _this->_v(2)) / scalar; + _this->_v(3) = (_this->_v(3) >= 0) ? _this->_v(3) / scalar : -1 - (-1 - _this->_v(3)) / scalar; + } else { + _this->_v(0) = (_this->_v(0) <= 0) ? _this->_v(0) / scalar : -1 + (1 - _this->_v(0)) / -scalar; + _this->_v(1) = (_this->_v(1) <= 0) ? _this->_v(1) / scalar : -1 + (1 - _this->_v(1)) / -scalar; + _this->_v(2) = (_this->_v(2) <= 0) ? _this->_v(2) / scalar : -1 + (1 - _this->_v(2)) / -scalar; + _this->_v(3) = (_this->_v(3) <= 0) ? _this->_v(3) / scalar : -1 + (1 - _this->_v(3)) / -scalar; + } +#else + _this->_v(0) = std::floor(_this->_v(0) / scalar); + _this->_v(1) = std::floor(_this->_v(1) / scalar); + _this->_v(2) = std::floor(_this->_v(2) / scalar); + _this->_v(3) = std::floor(_this->_v(3) / scalar); +#endif + Py_INCREF(self); + return self; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__pow__(PyObject *self, FLOATTYPE exponent) const { +#ifndef CPPPARSER + extern struct Dtool_PyTypedObject FLOATNAME(Dtool_LVecBase4); +#endif + PyObject *py_vec = PyObject_CallNoArgs((PyObject *)DtoolInstance_TYPE(self)); + if (py_vec != nullptr) { + FLOATNAME(LVecBase4) *vec = (FLOATNAME(LVecBase4) *)DtoolInstance_UPCAST(py_vec, FLOATNAME(Dtool_LVecBase4)); + nassertr(vec != nullptr, nullptr); + + vec->_v(0) = cpow(_this->_v(0), exponent); + vec->_v(1) = cpow(_this->_v(1), exponent); + vec->_v(2) = cpow(_this->_v(2), exponent); + vec->_v(3) = cpow(_this->_v(3), exponent); + } + return py_vec; } /** diff --git a/panda/src/linmath/lvecBase4_ext_src.h b/panda/src/linmath/lvecBase4_ext_src.h index e5115fb2df..693c07e111 100644 --- a/panda/src/linmath/lvecBase4_ext_src.h +++ b/panda/src/linmath/lvecBase4_ext_src.h @@ -23,7 +23,10 @@ public: INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign); INLINE_LINMATH std::string __repr__() const; - INLINE_LINMATH FLOATNAME(LVecBase4) __pow__(FLOATTYPE exponent) const; + INLINE_LINMATH PyObject *__floordiv__(PyObject *self, FLOATTYPE scalar) const; + INLINE_LINMATH PyObject *__ifloordiv__(PyObject *self, FLOATTYPE scalar); + + INLINE_LINMATH PyObject *__pow__(PyObject *self, FLOATTYPE exponent) const; INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent); INLINE_LINMATH PyObject *__round__(PyObject *self) const; diff --git a/panda/src/linmath/lvecBase4_src.h b/panda/src/linmath/lvecBase4_src.h index ab98ba88dc..fd73d5dbed 100644 --- a/panda/src/linmath/lvecBase4_src.h +++ b/panda/src/linmath/lvecBase4_src.h @@ -160,7 +160,10 @@ PUBLISHED: INLINE_LINMATH void componentwise_mult(const FLOATNAME(LVecBase4) &other); - EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase4) __pow__(FLOATTYPE exponent) const); + EXTENSION(INLINE_LINMATH PyObject *__floordiv__(PyObject *self, FLOATTYPE scalar) const); + EXTENSION(INLINE_LINMATH PyObject *__ifloordiv__(PyObject *self, FLOATTYPE scalar)); + + EXTENSION(INLINE_LINMATH PyObject *__pow__(PyObject *self, FLOATTYPE exponent) const); EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent)); EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); diff --git a/tests/linmath/test_lvector2.py b/tests/linmath/test_lvector2.py index e44fa17729..42b8c5db48 100644 --- a/tests/linmath/test_lvector2.py +++ b/tests/linmath/test_lvector2.py @@ -1,6 +1,7 @@ from math import floor, ceil from panda3d.core import Vec2, Vec3, Vec4, Vec2F, Vec2D +from panda3d import core import pytest @@ -117,3 +118,22 @@ def test_vec2_nan(): assert not Vec2D(inf, 0).is_nan() assert not Vec2D(inf, inf).is_nan() assert not Vec2D(-inf, 0).is_nan() + + +@pytest.mark.parametrize("type", (core.LVecBase2f, core.LVecBase2d, core.LVecBase2i)) +def test_vec4_floordiv(type): + with pytest.raises(ZeroDivisionError): + type(1, 2) // 0 + + for i in range(-100, 100): + for j in range(1, 100): + assert (type(i) // j).x == i // j + assert (type(i) // -j).x == i // -j + + v = type(i) + v //= j + assert v.x == i // j + + v = type(i) + v //= -j + assert v.x == i // -j diff --git a/tests/linmath/test_lvector3.py b/tests/linmath/test_lvector3.py index d4ae6e0429..1fac580965 100644 --- a/tests/linmath/test_lvector3.py +++ b/tests/linmath/test_lvector3.py @@ -1,6 +1,7 @@ from math import floor, ceil from panda3d.core import Vec2, Vec3, Vec3F, Vec3D +from panda3d import core import pytest @@ -102,3 +103,22 @@ def test_vec3_compare(): assert Vec3(0, 0, 1).compare_to(Vec3(1, 0, 0)) == -1 assert Vec3(0, 0, 1).compare_to(Vec3(0, 1, 0)) == -1 assert Vec3(0, 0, 1).compare_to(Vec3(0, 0, 1)) == 0 + + +@pytest.mark.parametrize("type", (core.LVecBase3f, core.LVecBase3d, core.LVecBase3i)) +def test_vec3_floordiv(type): + with pytest.raises(ZeroDivisionError): + type(1, 2, 3) // 0 + + for i in range(-100, 100): + for j in range(1, 100): + assert (type(i) // j).x == i // j + assert (type(i) // -j).x == i // -j + + v = type(i) + v //= j + assert v.x == i // j + + v = type(i) + v //= -j + assert v.x == i // -j diff --git a/tests/linmath/test_lvector4.py b/tests/linmath/test_lvector4.py index 2b487b9cb4..63c6f58155 100644 --- a/tests/linmath/test_lvector4.py +++ b/tests/linmath/test_lvector4.py @@ -1,6 +1,7 @@ from math import floor, ceil from panda3d.core import Vec2, Vec3, Vec4, Vec4F, Vec4D +from panda3d import core import pytest @@ -118,3 +119,22 @@ def test_vec4_compare(): assert Vec4(0, 0, 0, 1).compare_to(Vec4(0, 1, 0, 0)) == -1 assert Vec4(0, 0, 0, 1).compare_to(Vec4(0, 0, 1, 0)) == -1 assert Vec4(0, 0, 0, 1).compare_to(Vec4(0, 0, 0, 1)) == 0 + + +@pytest.mark.parametrize("type", (core.LVecBase4f, core.LVecBase4d, core.LVecBase4i)) +def test_vec4_floordiv(type): + with pytest.raises(ZeroDivisionError): + type(1, 2, 3, 4) // 0 + + for i in range(-100, 100): + for j in range(1, 100): + assert (type(i) // j).x == i // j + assert (type(i) // -j).x == i // -j + + v = type(i) + v //= j + assert v.x == i // j + + v = type(i) + v //= -j + assert v.x == i // -j