From 967fbbc49efa5607ff171ee5ec7daef5a990fc4f Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 1 Jun 2021 09:56:04 +0200 Subject: [PATCH 1/6] glgsg: Fix regression uploading buffer texture with null image Regression in c1babd1ad157b16f0a8d63b21d303e82c48489f4 - it caused an assertion to be thrown when uploading a buffer texture without a RAM image. --- .../glstuff/glGraphicsStateGuardian_src.cxx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 674962ff4f..04ffe9b94c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -12846,22 +12846,23 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { image = tex->get_uncompressed_ram_image(); } + bool is_buffer_texture = tex->get_texture_type() == Texture::TT_buffer_texture; + Texture::CompressionMode image_compression; if (image.is_null()) { image_compression = Texture::CM_off; } else { image_compression = tex->get_ram_image_compression(); - } - bool is_buffer_texture = tex->get_texture_type() == Texture::TT_buffer_texture; - if (is_buffer_texture || - !get_supports_compressed_texture_format(image_compression)) { - image = tex->get_uncompressed_ram_image(); - image_compression = Texture::CM_off; + if (is_buffer_texture || + !get_supports_compressed_texture_format(image_compression)) { + image = tex->get_uncompressed_ram_image(); + image_compression = Texture::CM_off; - // If this triggers, Panda cannot decompress the texture. Compile with - // libsquish support or precompress the texture. - nassertr(!image.is_null(), false); + // If this triggers, Panda cannot decompress the texture. Compile with + // libsquish support or precompress the texture. + nassertr(!image.is_null(), false); + } } int mipmap_bias = 0; From 42d292ee1711f21f04efd42adfaa3356b0acafa0 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 1 Jun 2021 10:00:43 +0200 Subject: [PATCH 2/6] glgsg: Slight optimization, don't get texture type more than once --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 04ffe9b94c..95521ece40 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -12846,15 +12846,14 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { image = tex->get_uncompressed_ram_image(); } - bool is_buffer_texture = tex->get_texture_type() == Texture::TT_buffer_texture; - + Texture::TextureType texture_type = tex->get_texture_type(); Texture::CompressionMode image_compression; if (image.is_null()) { image_compression = Texture::CM_off; } else { image_compression = tex->get_ram_image_compression(); - if (is_buffer_texture || + if (texture_type == Texture::TT_buffer_texture || !get_supports_compressed_texture_format(image_compression)) { image = tex->get_uncompressed_ram_image(); image_compression = Texture::CM_off; @@ -12874,7 +12873,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { // If we'll use immutable texture storage, we have to pick a sized image // format. bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage) || - (is_buffer_texture); + (texture_type == Texture::TT_buffer_texture); GLint internal_format = get_internal_image_format(tex, force_sized); GLint external_format = get_external_image_format(tex); @@ -12903,7 +12902,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { int max_dimension_y; int max_dimension_z; - switch (tex->get_texture_type()) { + switch (texture_type) { case Texture::TT_3d_texture: max_dimension_x = _max_3d_texture_dimension; max_dimension_y = _max_3d_texture_dimension; @@ -13008,7 +13007,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLenum target = get_texture_target(tex->get_texture_type()); + GLenum target = get_texture_target(texture_type); uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps; #ifndef OPENGLES if (target == GL_TEXTURE_BUFFER) { @@ -13184,7 +13183,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { << ", uses_mipmaps = " << uses_mipmaps << "\n"; } - switch (tex->get_texture_type()) { + switch (texture_type) { case Texture::TT_buffer_texture: // Won't get here, but squelch compiler warning case Texture::TT_1d_texture: @@ -13232,7 +13231,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { } bool success = true; - if (tex->get_texture_type() == Texture::TT_cube_map) { + if (texture_type == Texture::TT_cube_map) { // A cube map must load six different 2-d images (which are stored as the // six pages of the system ram image). if (!_supports_cube_map) { From 4e0e94527976a429400263b1b0edeac350d9d5d8 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 1 Jun 2021 10:07:43 +0200 Subject: [PATCH 3/6] linmath: Backport round(), floor(), ceil() support for vectors See #821 --- panda/src/linmath/lvecBase2_ext_src.I | 58 ++++++++++++++++++++++++ panda/src/linmath/lvecBase2_ext_src.h | 4 ++ panda/src/linmath/lvecBase2_src.h | 4 ++ panda/src/linmath/lvecBase3_ext_src.I | 60 +++++++++++++++++++++++++ panda/src/linmath/lvecBase3_ext_src.h | 4 ++ panda/src/linmath/lvecBase3_src.h | 4 ++ panda/src/linmath/lvecBase4_ext_src.I | 63 +++++++++++++++++++++++++++ panda/src/linmath/lvecBase4_ext_src.h | 4 ++ panda/src/linmath/lvecBase4_src.h | 4 ++ tests/linmath/test_lvector2.py | 31 +++++++++++++ tests/linmath/test_lvector3.py | 34 +++++++++++++++ tests/linmath/test_lvector4.py | 37 ++++++++++++++++ 12 files changed, 307 insertions(+) diff --git a/panda/src/linmath/lvecBase2_ext_src.I b/panda/src/linmath/lvecBase2_ext_src.I index c76cb6649f..7f1980d52f 100644 --- a/panda/src/linmath/lvecBase2_ext_src.I +++ b/panda/src/linmath/lvecBase2_ext_src.I @@ -218,5 +218,63 @@ __ipow__(PyObject *self, FLOATTYPE exponent) { return self; } +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__round__(PyObject *self) 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) = std::round(_this->_v(0)); + vec->_v(1) = std::round(_this->_v(1)); + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__floor__(PyObject *self) 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) = std::floor(_this->_v(0)); + vec->_v(1) = std::floor(_this->_v(1)); + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__ceil__(PyObject *self) 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) = std::ceil(_this->_v(0)); + vec->_v(1) = std::ceil(_this->_v(1)); + } + return py_vec; +} + #undef PYNUMBER_FLOATTYPE #undef PY_AS_FLOATTYPE diff --git a/panda/src/linmath/lvecBase2_ext_src.h b/panda/src/linmath/lvecBase2_ext_src.h index 9abffe5859..59349980f1 100644 --- a/panda/src/linmath/lvecBase2_ext_src.h +++ b/panda/src/linmath/lvecBase2_ext_src.h @@ -25,6 +25,10 @@ public: INLINE_LINMATH FLOATNAME(LVecBase2) __pow__(FLOATTYPE exponent) const; INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent); + + INLINE_LINMATH PyObject *__round__(PyObject *self) const; + INLINE_LINMATH PyObject *__floor__(PyObject *self) const; + INLINE_LINMATH PyObject *__ceil__(PyObject *self) const; }; #include "lvecBase2_ext_src.I" diff --git a/panda/src/linmath/lvecBase2_src.h b/panda/src/linmath/lvecBase2_src.h index c868f90d60..b58a22bd42 100644 --- a/panda/src/linmath/lvecBase2_src.h +++ b/panda/src/linmath/lvecBase2_src.h @@ -136,6 +136,10 @@ PUBLISHED: EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase2) __pow__(FLOATTYPE exponent) const); EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent)); + EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); + EXTENSION(INLINE_LINMATH PyObject *__floor__(PyObject *self)); + EXTENSION(INLINE_LINMATH PyObject *__ceil__(PyObject *self)); + INLINE_LINMATH FLOATNAME(LVecBase2) fmax(const FLOATNAME(LVecBase2) &other) const; INLINE_LINMATH FLOATNAME(LVecBase2) fmin(const FLOATNAME(LVecBase2) &other) const; diff --git a/panda/src/linmath/lvecBase3_ext_src.I b/panda/src/linmath/lvecBase3_ext_src.I index ba163ec637..1eda4d2534 100644 --- a/panda/src/linmath/lvecBase3_ext_src.I +++ b/panda/src/linmath/lvecBase3_ext_src.I @@ -221,5 +221,65 @@ __ipow__(PyObject *self, FLOATTYPE exponent) { return self; } +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__round__(PyObject *self) 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) = std::round(_this->_v(0)); + vec->_v(1) = std::round(_this->_v(1)); + vec->_v(2) = std::round(_this->_v(2)); + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__floor__(PyObject *self) 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) = std::floor(_this->_v(0)); + vec->_v(1) = std::floor(_this->_v(1)); + vec->_v(2) = std::floor(_this->_v(2)); + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__ceil__(PyObject *self) 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) = std::ceil(_this->_v(0)); + vec->_v(1) = std::ceil(_this->_v(1)); + vec->_v(2) = std::ceil(_this->_v(2)); + } + return py_vec; +} + #undef PYNUMBER_FLOATTYPE #undef PY_AS_FLOATTYPE diff --git a/panda/src/linmath/lvecBase3_ext_src.h b/panda/src/linmath/lvecBase3_ext_src.h index 4f91322f23..a80733c6a7 100644 --- a/panda/src/linmath/lvecBase3_ext_src.h +++ b/panda/src/linmath/lvecBase3_ext_src.h @@ -25,6 +25,10 @@ public: INLINE_LINMATH FLOATNAME(LVecBase3) __pow__(FLOATTYPE exponent) const; INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent); + + INLINE_LINMATH PyObject *__round__(PyObject *self) const; + INLINE_LINMATH PyObject *__floor__(PyObject *self) const; + INLINE_LINMATH PyObject *__ceil__(PyObject *self) const; }; #include "lvecBase3_ext_src.I" diff --git a/panda/src/linmath/lvecBase3_src.h b/panda/src/linmath/lvecBase3_src.h index 3536615aeb..00575a71a7 100644 --- a/panda/src/linmath/lvecBase3_src.h +++ b/panda/src/linmath/lvecBase3_src.h @@ -155,6 +155,10 @@ PUBLISHED: EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase3) __pow__(FLOATTYPE exponent) const); EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent)); + EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); + EXTENSION(INLINE_LINMATH PyObject *__floor__(PyObject *self)); + EXTENSION(INLINE_LINMATH PyObject *__ceil__(PyObject *self)); + INLINE_LINMATH FLOATNAME(LVecBase3) fmax(const FLOATNAME(LVecBase3) &other) const; INLINE_LINMATH FLOATNAME(LVecBase3) fmin(const FLOATNAME(LVecBase3) &other) const; diff --git a/panda/src/linmath/lvecBase4_ext_src.I b/panda/src/linmath/lvecBase4_ext_src.I index 78d359c315..5436f28f6d 100644 --- a/panda/src/linmath/lvecBase4_ext_src.I +++ b/panda/src/linmath/lvecBase4_ext_src.I @@ -229,5 +229,68 @@ __ipow__(PyObject *self, FLOATTYPE exponent) { return self; } +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__round__(PyObject *self) 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) = std::round(_this->_v(0)); + vec->_v(1) = std::round(_this->_v(1)); + vec->_v(2) = std::round(_this->_v(2)); + vec->_v(3) = std::round(_this->_v(3)); + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__floor__(PyObject *self) 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) = std::floor(_this->_v(0)); + vec->_v(1) = std::floor(_this->_v(1)); + vec->_v(2) = std::floor(_this->_v(2)); + vec->_v(3) = std::floor(_this->_v(3)); + } + return py_vec; +} + +/** + * + */ +INLINE_LINMATH PyObject *Extension:: +__ceil__(PyObject *self) 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) = std::ceil(_this->_v(0)); + vec->_v(1) = std::ceil(_this->_v(1)); + vec->_v(2) = std::ceil(_this->_v(2)); + vec->_v(3) = std::ceil(_this->_v(3)); + } + return py_vec; +} + #undef PYNUMBER_FLOATTYPE #undef PY_AS_FLOATTYPE diff --git a/panda/src/linmath/lvecBase4_ext_src.h b/panda/src/linmath/lvecBase4_ext_src.h index 9d7d837c89..e5115fb2df 100644 --- a/panda/src/linmath/lvecBase4_ext_src.h +++ b/panda/src/linmath/lvecBase4_ext_src.h @@ -25,6 +25,10 @@ public: INLINE_LINMATH FLOATNAME(LVecBase4) __pow__(FLOATTYPE exponent) const; INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent); + + INLINE_LINMATH PyObject *__round__(PyObject *self) const; + INLINE_LINMATH PyObject *__floor__(PyObject *self) const; + INLINE_LINMATH PyObject *__ceil__(PyObject *self) const; }; #include "lvecBase4_ext_src.I" diff --git a/panda/src/linmath/lvecBase4_src.h b/panda/src/linmath/lvecBase4_src.h index b634791d91..ab98ba88dc 100644 --- a/panda/src/linmath/lvecBase4_src.h +++ b/panda/src/linmath/lvecBase4_src.h @@ -163,6 +163,10 @@ PUBLISHED: EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase4) __pow__(FLOATTYPE exponent) const); EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent)); + EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); + EXTENSION(INLINE_LINMATH PyObject *__floor__(PyObject *self)); + EXTENSION(INLINE_LINMATH PyObject *__ceil__(PyObject *self)); + INLINE_LINMATH FLOATNAME(LVecBase4) fmax(const FLOATNAME(LVecBase4) &other) const; INLINE_LINMATH FLOATNAME(LVecBase4) fmin(const FLOATNAME(LVecBase4) &other) const; diff --git a/tests/linmath/test_lvector2.py b/tests/linmath/test_lvector2.py index 4dd4571d11..e97529d116 100644 --- a/tests/linmath/test_lvector2.py +++ b/tests/linmath/test_lvector2.py @@ -1,4 +1,8 @@ +from math import floor, ceil +import sys + from panda3d.core import Vec2, Vec3, Vec4, Vec2F, Vec2D +import pytest def test_vec2_creation(): @@ -90,3 +94,30 @@ 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.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec2_round(): + original_vector = Vec2(2.3, -2.6) + + rounded_vector = round(original_vector) + assert rounded_vector.x == 2 + assert rounded_vector.y == -3 + + +@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec2_floor(): + original_vector = Vec2(2.3, -2.6) + + rounded_vector = floor(original_vector) + assert rounded_vector.x == 2 + assert rounded_vector.y == -3 + + +@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec2_ceil(): + original_vector = Vec2(2.3, -2.6) + + rounded_vector = ceil(original_vector) + assert rounded_vector.x == 3 + assert rounded_vector.y == -2 diff --git a/tests/linmath/test_lvector3.py b/tests/linmath/test_lvector3.py index 016c2e8420..ee4b6069de 100644 --- a/tests/linmath/test_lvector3.py +++ b/tests/linmath/test_lvector3.py @@ -1,4 +1,8 @@ +from math import floor, ceil +import sys + from panda3d.core import Vec2, Vec3, Vec3F, Vec3D +import pytest def test_vec3_creation(): @@ -72,3 +76,33 @@ 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.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec3_round(): + original_vector = Vec3(2.3, -2.6, 3.5) + + rounded_vector = round(original_vector) + assert rounded_vector.x == 2 + assert rounded_vector.y == -3 + assert rounded_vector.z == 4 + + +@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec3_floor(): + original_vector = Vec3(2.3, -2.6, 3.5) + + rounded_vector = floor(original_vector) + assert rounded_vector.x == 2 + assert rounded_vector.y == -3 + assert rounded_vector.z == 3 + + +@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec3_ceil(): + original_vector = Vec3(2.3, -2.6, 3.5) + + rounded_vector = ceil(original_vector) + assert rounded_vector.x == 3 + assert rounded_vector.y == -2 + assert rounded_vector.z == 4 diff --git a/tests/linmath/test_lvector4.py b/tests/linmath/test_lvector4.py index 5a65c7842c..edecfdf689 100644 --- a/tests/linmath/test_lvector4.py +++ b/tests/linmath/test_lvector4.py @@ -1,4 +1,8 @@ +from math import floor, ceil +import sys + from panda3d.core import Vec2, Vec3, Vec4, Vec4F, Vec4D +import pytest def test_vec4_creation(): @@ -85,3 +89,36 @@ 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.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec4_round(): + original_vector = Vec4(2.3, -2.6, 3.5, 1) + + rounded_vector = round(original_vector) + assert rounded_vector.x == 2 + assert rounded_vector.y == -3 + assert rounded_vector.z == 4 + assert rounded_vector.w == 1 + + +@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec4_floor(): + original_vector = Vec4(2.3, -2.6, 3.5, 1) + + rounded_vector = floor(original_vector) + assert rounded_vector.x == 2 + assert rounded_vector.y == -3 + assert rounded_vector.z == 3 + assert rounded_vector.w == 1 + + +@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python 3") +def test_vec4_ceil(): + original_vector = Vec4(2.3, -2.6, 3.5, 1) + + rounded_vector = ceil(original_vector) + assert rounded_vector.x == 3 + assert rounded_vector.y == -2 + assert rounded_vector.z == 4 + assert rounded_vector.w == 1 From 2386e80448a78dca898cdcb2007a02bbebb6a310 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 1 Jun 2021 10:44:39 +0200 Subject: [PATCH 4/6] linmath: Backport support for floor division to 1.10 Backport of 89447378440e9b9472a7290facbd8949f41a64ae (Also fixes return type of `__pow__` to always be derived class) --- 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 7f1980d52f..da9f52388d 100644 --- a/panda/src/linmath/lvecBase2_ext_src.I +++ b/panda/src/linmath/lvecBase2_ext_src.I @@ -200,11 +200,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 1eda4d2534..e59a032b89 100644 --- a/panda/src/linmath/lvecBase3_ext_src.I +++ b/panda/src/linmath/lvecBase3_ext_src.I @@ -201,12 +201,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 5436f28f6d..9db21d73ee 100644 --- a/panda/src/linmath/lvecBase4_ext_src.I +++ b/panda/src/linmath/lvecBase4_ext_src.I @@ -207,13 +207,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 e97529d116..d955fe8d8e 100644 --- a/tests/linmath/test_lvector2.py +++ b/tests/linmath/test_lvector2.py @@ -2,6 +2,7 @@ from math import floor, ceil import sys from panda3d.core import Vec2, Vec3, Vec4, Vec2F, Vec2D +from panda3d import core import pytest @@ -121,3 +122,22 @@ def test_vec2_ceil(): rounded_vector = ceil(original_vector) assert rounded_vector.x == 3 assert rounded_vector.y == -2 + + +@pytest.mark.parametrize("type", (core.LVecBase2f, core.LVecBase2d, core.LVecBase2i)) +def test_vec2_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 ee4b6069de..31f1ff5fe8 100644 --- a/tests/linmath/test_lvector3.py +++ b/tests/linmath/test_lvector3.py @@ -2,6 +2,7 @@ from math import floor, ceil import sys from panda3d.core import Vec2, Vec3, Vec3F, Vec3D +from panda3d import core import pytest @@ -106,3 +107,22 @@ def test_vec3_ceil(): assert rounded_vector.x == 3 assert rounded_vector.y == -2 assert rounded_vector.z == 4 + + +@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 edecfdf689..7cf375589e 100644 --- a/tests/linmath/test_lvector4.py +++ b/tests/linmath/test_lvector4.py @@ -2,6 +2,7 @@ from math import floor, ceil import sys from panda3d.core import Vec2, Vec3, Vec4, Vec4F, Vec4D +from panda3d import core import pytest @@ -122,3 +123,22 @@ def test_vec4_ceil(): assert rounded_vector.y == -2 assert rounded_vector.z == 4 assert rounded_vector.w == 1 + + +@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 From 0415a084161f7ed778d9ce69ffbe693fca98d25b Mon Sep 17 00:00:00 2001 From: Ben Humphries Date: Tue, 1 Jun 2021 10:56:55 +0200 Subject: [PATCH 5/6] cocoadisplay: Round refresh rates when choosing display mode on macOS Closes #1144 Co-authored-by: rdb --- panda/src/cocoadisplay/cocoaGraphicsWindow.mm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index 11266cc173..df80308b62 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -1233,7 +1233,7 @@ find_display_modes(int width, int height) { // Get the current refresh rate and pixel encoding. CFStringRef current_pixel_encoding; - int refresh_rate; + double refresh_rate; mode = CGDisplayCopyDisplayMode(_display); // First check if the current mode is adequate. @@ -1267,7 +1267,7 @@ find_display_modes(int width, int height) { // the mode width and height but also actual pixel widh and height. if (CGDisplayModeGetWidth(mode) == width && CGDisplayModeGetHeight(mode) == height && - CGDisplayModeGetRefreshRate(mode) == refresh_rate && + (int)(CGDisplayModeGetRefreshRate(mode) + 0.5) == (int)(refresh_rate + 0.5) && #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_14 || (CGDisplayModeGetPixelWidth(mode) == expected_pixel_width && @@ -1275,7 +1275,12 @@ find_display_modes(int width, int height) { #endif CFStringCompare(pixel_encoding, current_pixel_encoding, 0) == kCFCompareEqualTo) { - CFArrayAppendValue(valid_modes, mode); + if (CGDisplayModeGetRefreshRate(mode) == refresh_rate) { + // Exact match for refresh rate, prioritize this. + CFArrayInsertValueAtIndex(valid_modes, 0, mode); + } else { + CFArrayAppendValue(valid_modes, mode); + } } CFRelease(pixel_encoding); } From 5804c663a93e9435e94918c5c85091430960b9da Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 1 Jun 2021 11:47:19 +0200 Subject: [PATCH 6/6] tests: Backport unit test fix from c0d34912230495bb20c581de9d111a87a0336893 --- tests/linmath/test_lvector2.py | 4 ++-- tests/linmath/test_lvector3.py | 4 ++-- tests/linmath/test_lvector4.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/linmath/test_lvector2.py b/tests/linmath/test_lvector2.py index d955fe8d8e..1bb17aee7e 100644 --- a/tests/linmath/test_lvector2.py +++ b/tests/linmath/test_lvector2.py @@ -129,8 +129,8 @@ def test_vec2_floordiv(type): with pytest.raises(ZeroDivisionError): type(1, 2) // 0 - for i in range(-100, 100): - for j in range(1, 100): + for i in range(-11, 11): + for j in range(1, 11): assert (type(i) // j).x == i // j assert (type(i) // -j).x == i // -j diff --git a/tests/linmath/test_lvector3.py b/tests/linmath/test_lvector3.py index 31f1ff5fe8..44fc17e015 100644 --- a/tests/linmath/test_lvector3.py +++ b/tests/linmath/test_lvector3.py @@ -114,8 +114,8 @@ 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): + for i in range(-11, 11): + for j in range(1, 11): assert (type(i) // j).x == i // j assert (type(i) // -j).x == i // -j diff --git a/tests/linmath/test_lvector4.py b/tests/linmath/test_lvector4.py index 7cf375589e..3fd283e2d3 100644 --- a/tests/linmath/test_lvector4.py +++ b/tests/linmath/test_lvector4.py @@ -130,8 +130,8 @@ 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): + for i in range(-11, 11): + for j in range(1, 11): assert (type(i) // j).x == i // j assert (type(i) // -j).x == i // -j