linmath: Support floor division for vector types

Also fix __pow__ so that it returns the derived type, not the base type
This commit is contained in:
rdb 2021-02-22 20:01:30 +01:00
parent 5ae08eadf7
commit 8944737844
12 changed files with 321 additions and 24 deletions

View File

@ -195,11 +195,78 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) {
/** /**
* *
*/ */
INLINE_LINMATH FLOATNAME(LVecBase2) Extension<FLOATNAME(LVecBase2)>:: INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase2)>::
__pow__(FLOATTYPE exponent) const { __floordiv__(PyObject *self, FLOATTYPE scalar) const {
return FLOATNAME(LVecBase2)( if (scalar == (FLOATTYPE)0) {
cpow(_this->_v(0), exponent), return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero");
cpow(_this->_v(1), exponent)); }
#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<FLOATNAME(LVecBase2)>::
__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<FLOATNAME(LVecBase2)>::
__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;
} }
/** /**

View File

@ -23,7 +23,10 @@ public:
INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign); INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign);
INLINE_LINMATH std::string __repr__() const; 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 *__ipow__(PyObject *self, FLOATTYPE exponent);
INLINE_LINMATH PyObject *__round__(PyObject *self) const; INLINE_LINMATH PyObject *__round__(PyObject *self) const;

View File

@ -133,7 +133,10 @@ PUBLISHED:
INLINE_LINMATH void componentwise_mult(const FLOATNAME(LVecBase2) &other); 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 *__ipow__(PyObject *self, FLOATTYPE exponent));
EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self));

View File

@ -196,12 +196,85 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) {
/** /**
* *
*/ */
INLINE_LINMATH FLOATNAME(LVecBase3) Extension<FLOATNAME(LVecBase3)>:: INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase3)>::
__pow__(FLOATTYPE exponent) const { __floordiv__(PyObject *self, FLOATTYPE scalar) const {
return FLOATNAME(LVecBase3)( if (scalar == (FLOATTYPE)0) {
cpow(_this->_v(0), exponent), return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero");
cpow(_this->_v(1), exponent), }
cpow(_this->_v(2), exponent));
#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<FLOATNAME(LVecBase3)>::
__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<FLOATNAME(LVecBase3)>::
__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;
} }
/** /**

View File

@ -23,7 +23,10 @@ public:
INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign); INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign);
INLINE_LINMATH std::string __repr__() const; 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 *__ipow__(PyObject *self, FLOATTYPE exponent);
INLINE_LINMATH PyObject *__round__(PyObject *self) const; INLINE_LINMATH PyObject *__round__(PyObject *self) const;

View File

@ -152,7 +152,10 @@ PUBLISHED:
INLINE_LINMATH void componentwise_mult(const FLOATNAME(LVecBase3) &other); 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 *__ipow__(PyObject *self, FLOATTYPE exponent));
EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self));

View File

@ -202,13 +202,92 @@ __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign) {
/** /**
* *
*/ */
INLINE_LINMATH FLOATNAME(LVecBase4) Extension<FLOATNAME(LVecBase4)>:: INLINE_LINMATH PyObject *Extension<FLOATNAME(LVecBase4)>::
__pow__(FLOATTYPE exponent) const { __floordiv__(PyObject *self, FLOATTYPE scalar) const {
return FLOATNAME(LVecBase4)( if (scalar == (FLOATTYPE)0) {
cpow(_this->_v(0), exponent), return PyErr_Format(PyExc_ZeroDivisionError, "floor division by zero");
cpow(_this->_v(1), exponent), }
cpow(_this->_v(2), exponent),
cpow(_this->_v(3), exponent)); #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<FLOATNAME(LVecBase4)>::
__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<FLOATNAME(LVecBase4)>::
__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;
} }
/** /**

View File

@ -23,7 +23,10 @@ public:
INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign); INLINE_LINMATH int __setattr__(PyObject *self, const std::string &attr_name, PyObject *assign);
INLINE_LINMATH std::string __repr__() const; 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 *__ipow__(PyObject *self, FLOATTYPE exponent);
INLINE_LINMATH PyObject *__round__(PyObject *self) const; INLINE_LINMATH PyObject *__round__(PyObject *self) const;

View File

@ -160,7 +160,10 @@ PUBLISHED:
INLINE_LINMATH void componentwise_mult(const FLOATNAME(LVecBase4) &other); 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 *__ipow__(PyObject *self, FLOATTYPE exponent));
EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self)); EXTENSION(INLINE_LINMATH PyObject *__round__(PyObject *self));

View File

@ -1,6 +1,7 @@
from math import floor, ceil from math import floor, ceil
from panda3d.core import Vec2, Vec3, Vec4, Vec2F, Vec2D from panda3d.core import Vec2, Vec3, Vec4, Vec2F, Vec2D
from panda3d import core
import pytest import pytest
@ -117,3 +118,22 @@ def test_vec2_nan():
assert not Vec2D(inf, 0).is_nan() assert not Vec2D(inf, 0).is_nan()
assert not Vec2D(inf, inf).is_nan() assert not Vec2D(inf, inf).is_nan()
assert not Vec2D(-inf, 0).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

View File

@ -1,6 +1,7 @@
from math import floor, ceil from math import floor, ceil
from panda3d.core import Vec2, Vec3, Vec3F, Vec3D from panda3d.core import Vec2, Vec3, Vec3F, Vec3D
from panda3d import core
import pytest 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(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, 1, 0)) == -1
assert Vec3(0, 0, 1).compare_to(Vec3(0, 0, 1)) == 0 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

View File

@ -1,6 +1,7 @@
from math import floor, ceil from math import floor, ceil
from panda3d.core import Vec2, Vec3, Vec4, Vec4F, Vec4D from panda3d.core import Vec2, Vec3, Vec4, Vec4F, Vec4D
from panda3d import core
import pytest 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, 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, 1, 0)) == -1
assert Vec4(0, 0, 0, 1).compare_to(Vec4(0, 0, 0, 1)) == 0 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