Skip to content

Commit

Permalink
Added vector operations (#199)
Browse files Browse the repository at this point in the history
+ Added int vector operation '//' (floordiv)
+ Added bool vector operations '&', '|' and '^'.
+ Should fix #198
  • Loading branch information
Zuzu-Typ authored Jan 11, 2023
1 parent 3fcb38e commit 1d3e142
Show file tree
Hide file tree
Showing 47 changed files with 273 additions and 92 deletions.
60 changes: 60 additions & 0 deletions PyGLM/type_methods/mvec.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "../types/mvec/all.h"

#include "vec.h"

static void
mvec_dealloc(PyObject* self)
{
Expand Down Expand Up @@ -222,6 +224,49 @@ mvec_div(PyObject *obj1, PyObject *obj2)
return pack_vec<L, T>(o / o2);
}

template<int L, typename T>
static PyObject *
imvec_floordiv(PyObject *obj1, PyObject *obj2)
{
if (PyGLM_Number_Check(obj1)) { // obj1 is a scalar, obj2 is self
PyObject* temp = pack_vec(glm::vec<L, T>(PyGLM_Number_FromPyObject<T>(obj1)));
PyObject* result = imvec_floordiv<L, T>(temp, obj2);
Py_DECREF(temp);
return result;
}

if (PyGLM_Number_Check(obj2)) { // obj2 is a scalar, obj1 is self
PyObject* temp = pack_vec(glm::vec<L, T>(PyGLM_Number_FromPyObject<T>(obj2)));
PyObject* result = imvec_floordiv<L, T>(obj1, temp);
Py_DECREF(temp);
return result;
}

PyGLM_PTI_Init0(obj1, (get_vec_PTI_info<L, T>()));

if (PyGLM_PTI_IsNone(0)) { // obj1 is not supported.
PyGLM_TYPEERROR_O("unsupported operand type(s) for /: 'glm.vec' and ", obj1);
return NULL;
}

glm::vec<L, T> o = PyGLM_Vec_PTI_Get0(L, T, obj1);

PyGLM_PTI_Init1(obj2, (get_vec_PTI_info<L, T>()));

if (PyGLM_PTI_IsNone(1)) { // obj1 is self, obj2 is something else
Py_RETURN_NOTIMPLEMENTED;
}

glm::vec<L, T> o2 = PyGLM_Vec_PTI_Get1(L, T, obj2);

if (!glm::all((glm::vec<L, bool>)o2)) {
PyGLM_ZERO_DIVISION_ERROR_T(T);
}

// obj1 and obj2 can be interpreted as a mvec
return pack_vec<L, T>(ivec_floordivmod(o, o2));
}

template<int L, typename T>
static PyObject *
mvec_mod(PyObject *obj1, PyObject *obj2)
Expand Down Expand Up @@ -683,6 +728,21 @@ mvec_ifloordiv(mvec<L, T> *self, PyObject *obj)
return (PyObject*)self;
}

template<int L, typename T>
static PyObject *
imvec_ifloordiv(mvec<L, T> *self, PyObject *obj)
{
vec<L, T> * temp = (vec<L, T>*)imvec_floordiv<L, T>((PyObject*)self, obj);

if (Py_IS_NOTIMPLEMENTED(temp)) return (PyObject*)temp;

*self->super_type = temp->super_type;

Py_DECREF(temp);
Py_INCREF(self);
return (PyObject*)self;
}

template<int L, typename T>
static PyObject*
mvec_imatmul(mvec<L, T>* self, PyObject* obj)
Expand Down
79 changes: 79 additions & 0 deletions PyGLM/type_methods/vec.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,70 @@ vec_div(PyObject *obj1, PyObject *obj2)
return pack_vec<L, T>(o / o2);
}

template<int L, typename T>
static glm::vec<L, T>
ivec_floordivmod(glm::vec<L, T> a, glm::vec<L, T> b) {
const glm::vec<L, T> u = glm::abs(a);
const glm::vec<L, T> v = glm::abs(b);

glm::vec<L, T> result;

for (int i = 0; i < L; i++) {
T q = u[i] / v[i];
T r = u[i] % v[i];
if ((a[i] < 0) != (b[i] < 0)) {
result[i] = -(q + (r > 0));
} else {
result[i] = q;
}
}

return result;
}

template<int L, typename T>
static PyObject *
ivec_floordiv(PyObject *obj1, PyObject *obj2)
{
if (PyGLM_Number_Check(obj1)) { // obj1 is a scalar, obj2 is self
PyObject* temp = pack_vec(glm::vec<L, T>(PyGLM_Number_FromPyObject<T>(obj1)));
PyObject* result = ivec_floordiv<L, T>(temp, obj2);
Py_DECREF(temp);
return result;
}

if (PyGLM_Number_Check(obj2)) { // obj1 is self, obj2 is a scalar
PyObject* temp = pack_vec(glm::vec<L, T>(PyGLM_Number_FromPyObject<T>(obj2)));
PyObject* result = ivec_floordiv<L, T>(obj1, temp);
Py_DECREF(temp);
return result;
}

PyGLM_PTI_Init0(obj1, (get_vec_PTI_info<L, T>()));

if (PyGLM_PTI_IsNone(0)) { // obj1 is not supported.
PyGLM_TYPEERROR_O("unsupported operand type(s) for /: 'glm.vec' and ", obj1);
return NULL;
}

glm::vec<L, T> o = PyGLM_Vec_PTI_Get0(L, T, obj1);

PyGLM_PTI_Init1(obj2, (get_vec_PTI_info<L, T>()));

if (PyGLM_PTI_IsNone(1)) { // obj1 is self, obj2 is something else
Py_RETURN_NOTIMPLEMENTED;
}

glm::vec<L, T> o2 = PyGLM_Vec_PTI_Get1(L, T, obj2);

if (!glm::all((glm::vec<L, bool>)o2)) {
PyGLM_ZERO_DIVISION_ERROR_T(T);
}

// obj1 and obj2 can be interpreted as a vec
return pack_vec<L, T>(ivec_floordivmod<L, T>(o, o2));
}

template<int L>
static inline glm::vec<L, float>
vec_mod_f(glm::vec<L, float> a, glm::vec<L, float> b) {
Expand Down Expand Up @@ -1234,6 +1298,21 @@ vec_ifloordiv(vec<L, T> *self, PyObject *obj)
return (PyObject*)self;
}

template<int L, typename T>
static PyObject *
ivec_ifloordiv(vec<L, T> *self, PyObject *obj)
{
vec<L, T> * temp = (vec<L, T>*)ivec_floordiv<L, T>((PyObject*)self, obj);

if (Py_IS_NOTIMPLEMENTED(temp)) return (PyObject*)temp;

self->super_type = temp->super_type;

Py_DECREF(temp);
Py_INCREF(self);
return (PyObject*)self;
}

template<int L, typename T>
static PyObject*
vec_imatmul(vec<L, T>* self, PyObject* obj)
Expand Down
6 changes: 6 additions & 0 deletions PyGLM/types/mvec/forward_declarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,15 @@ static PyObject * mvec_floordiv(PyObject *obj1, PyObject *obj2);
template<int L, typename T>
static PyObject * mvec_div(PyObject *obj1, PyObject *obj2);

template<int L, typename T>
static PyObject* imvec_floordiv(PyObject* obj1, PyObject* obj2);

template<int L, typename T>
static PyObject * mvec_ifloordiv(mvec<L, T>* self, PyObject *obj);

template<int L, typename T>
static PyObject* imvec_ifloordiv(mvec<L, T>* self, PyObject* obj);

template<int L, typename T>
static PyObject * mvec_idiv(mvec<L, T>* self, PyObject *obj);

Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/mvec/int/mvec2.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ static PyNumberMethods himvec2NumMethods = {
(binaryfunc)mvec_iand<2, glm::i32>, //nb_inplace_and
(binaryfunc)mvec_ixor<2, glm::i32>, //nb_inplace_xor
(binaryfunc)mvec_ior<2, glm::i32>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)imvec_floordiv<2, glm::i32>, //nb_floor_divide
(binaryfunc)mvec_div<2, glm::i32>,
0, //nb_inplace_floor_divide
(binaryfunc)imvec_ifloordiv<2, glm::i32>, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<2, glm::i32>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)mvec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/mvec/int/mvec3.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ static PyNumberMethods himvec3NumMethods = {
(binaryfunc)mvec_iand<3, glm::i32>, //nb_inplace_and
(binaryfunc)mvec_ixor<3, glm::i32>, //nb_inplace_xor
(binaryfunc)mvec_ior<3, glm::i32>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)imvec_floordiv<3, glm::i32>, //nb_floor_divide
(binaryfunc)mvec_div<3, glm::i32>,
0, //nb_inplace_floor_divide
(binaryfunc)imvec_ifloordiv<3, glm::i32>, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<3, glm::i32>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)mvec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/mvec/int/mvec4.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ static PyNumberMethods himvec4NumMethods = {
(binaryfunc)mvec_iand<4, glm::i32>, //nb_inplace_and
(binaryfunc)mvec_ixor<4, glm::i32>, //nb_inplace_xor
(binaryfunc)mvec_ior<4, glm::i32>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)imvec_floordiv<4, glm::i32>, //nb_floor_divide
(binaryfunc)mvec_div<4, glm::i32>,
0, //nb_inplace_floor_divide
(binaryfunc)imvec_ifloordiv<4, glm::i32>, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<4, glm::i32>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)mvec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/mvec/uint/mvec2.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ static PyNumberMethods humvec2NumMethods = {
(binaryfunc)mvec_iand<2, glm::u32>, //nb_inplace_and
(binaryfunc)mvec_ixor<2, glm::u32>, //nb_inplace_xor
(binaryfunc)mvec_ior<2, glm::u32>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)mvec_div<2, glm::u32>, //nb_floor_divide
(binaryfunc)mvec_div<2, glm::u32>,
0, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<2, glm::u32>, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<2, glm::u32>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)mvec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/mvec/uint/mvec3.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ static PyNumberMethods humvec3NumMethods = {
(binaryfunc)mvec_iand<3, glm::u32>, //nb_inplace_and
(binaryfunc)mvec_ixor<3, glm::u32>, //nb_inplace_xor
(binaryfunc)mvec_ior<3, glm::u32>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)mvec_div<3, glm::u32>, //nb_floor_divide
(binaryfunc)mvec_div<3, glm::u32>,
0, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<3, glm::u32>, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<3, glm::u32>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)mvec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/mvec/uint/mvec4.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ static PyNumberMethods humvec4NumMethods = {
(binaryfunc)mvec_iand<4, glm::u32>, //nb_inplace_and
(binaryfunc)mvec_ixor<4, glm::u32>, //nb_inplace_xor
(binaryfunc)mvec_ior<4, glm::u32>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)mvec_div<4, glm::u32>, //nb_floor_divide
(binaryfunc)mvec_div<4, glm::u32>,
0, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<4, glm::u32>, //nb_inplace_floor_divide
(binaryfunc)mvec_idiv<4, glm::u32>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)mvec_matmul, //nb_matrix_multiply
Expand Down
6 changes: 3 additions & 3 deletions PyGLM/types/vec/bool/vec1.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ static PyNumberMethods hbvec1NumMethods = {
0, //nb_invert
0, //nb_lshift
0, //nb_rshift
0, //nb_and
0, //nb_xor
0, //nb_or
vec_and<1, bool>, //nb_and
vec_xor<1, bool>, //nb_xor
vec_or<1, bool>, //nb_or
0, //nb_int
0, //nb_reserved
0, //nb_int
Expand Down
6 changes: 3 additions & 3 deletions PyGLM/types/vec/bool/vec2.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ static PyNumberMethods hbvec2NumMethods = {
0, //nb_invert
0, //nb_lshift
0, //nb_rshift
0, //nb_and
0, //nb_xor
0, //nb_or
vec_and<2, bool>, //nb_and
vec_xor<2, bool>, //nb_xor
vec_or<2, bool>, //nb_or
0, //nb_int
0, //nb_reserved
0, //nb_int
Expand Down
6 changes: 3 additions & 3 deletions PyGLM/types/vec/bool/vec3.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ static PyNumberMethods hbvec3NumMethods = {
0, //nb_invert
0, //nb_lshift
0, //nb_rshift
0, //nb_and
0, //nb_xor
0, //nb_or
vec_and<3, bool>, //nb_and
vec_xor<3, bool>, //nb_xor
vec_or<3, bool>, //nb_or
0, //nb_int
0, //nb_reserved
0, //nb_int
Expand Down
6 changes: 3 additions & 3 deletions PyGLM/types/vec/bool/vec4.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ static PyNumberMethods hbvec4NumMethods = {
0, //nb_invert
0, //nb_lshift
0, //nb_rshift
0, //nb_and
0, //nb_xor
0, //nb_or
vec_and<4, bool>, //nb_and
vec_xor<4, bool>, //nb_xor
vec_or<4, bool>, //nb_or
0, //nb_int
0, //nb_reserved
0, //nb_int
Expand Down
6 changes: 6 additions & 0 deletions PyGLM/types/vec/forward_declarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,18 @@ static PyObject * vec_ipow(vec<L, T>* self, PyObject * obj2, PyObject * obj3);
template<int L, typename T>
static PyObject * vec_floordiv(PyObject *obj1, PyObject *obj2);

template<int L, typename T>
static PyObject * ivec_floordiv(PyObject *obj1, PyObject *obj2);

template<int L, typename T>
static PyObject * vec_div(PyObject *obj1, PyObject *obj2);

template<int L, typename T>
static PyObject * vec_ifloordiv(vec<L, T>* self, PyObject *obj);

template<int L, typename T>
static PyObject * ivec_ifloordiv(vec<L, T> *self, PyObject *obj);

template<int L, typename T>
static PyObject * vec_idiv(vec<L, T>* self, PyObject *obj);

Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/vec/int16/vec1.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ static PyNumberMethods hi16vec1NumMethods = {
(binaryfunc)vec_iand<1, glm::i16>, //nb_inplace_and
(binaryfunc)vec_ixor<1, glm::i16>, //nb_inplace_xor
(binaryfunc)vec_ior<1, glm::i16>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)ivec_floordiv<1, glm::i16>, //nb_floor_divide
(binaryfunc)vec_div<1, glm::i16>,
0, //nb_inplace_floor_divide
(binaryfunc)ivec_ifloordiv<1, glm::i16>, //nb_inplace_floor_divide
(binaryfunc)vec_idiv<1, glm::i16>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)vec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/vec/int16/vec2.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ static PyNumberMethods hi16vec2NumMethods = {
(binaryfunc)vec_iand<2, glm::i16>, //nb_inplace_and
(binaryfunc)vec_ixor<2, glm::i16>, //nb_inplace_xor
(binaryfunc)vec_ior<2, glm::i16>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)ivec_floordiv<2, glm::i16>, //nb_floor_divide
(binaryfunc)vec_div<2, glm::i16>,
0, //nb_inplace_floor_divide
(binaryfunc)ivec_ifloordiv<2, glm::i16>, //nb_inplace_floor_divide
(binaryfunc)vec_idiv<2, glm::i16>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)vec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/vec/int16/vec3.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ static PyNumberMethods hi16vec3NumMethods = {
(binaryfunc)vec_iand<3, glm::i16>, //nb_inplace_and
(binaryfunc)vec_ixor<3, glm::i16>, //nb_inplace_xor
(binaryfunc)vec_ior<3, glm::i16>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)ivec_floordiv<3, glm::i16>, //nb_floor_divide
(binaryfunc)vec_div<3, glm::i16>,
0, //nb_inplace_floor_divide
(binaryfunc)ivec_ifloordiv<3, glm::i16>, //nb_inplace_floor_divide
(binaryfunc)vec_idiv<3, glm::i16>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)vec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/vec/int16/vec4.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ static PyNumberMethods hi16vec4NumMethods = {
(binaryfunc)vec_iand<4, glm::i16>, //nb_inplace_and
(binaryfunc)vec_ixor<4, glm::i16>, //nb_inplace_xor
(binaryfunc)vec_ior<4, glm::i16>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)ivec_floordiv<4, glm::i16>, //nb_floor_divide
(binaryfunc)vec_div<4, glm::i16>,
0, //nb_inplace_floor_divide
(binaryfunc)ivec_ifloordiv<4, glm::i16>, //nb_inplace_floor_divide
(binaryfunc)vec_idiv<4, glm::i16>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)vec_matmul, //nb_matrix_multiply
Expand Down
4 changes: 2 additions & 2 deletions PyGLM/types/vec/int32/vec1.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ static PyNumberMethods hivec1NumMethods = {
(binaryfunc)vec_iand<1, glm::i32>, //nb_inplace_and
(binaryfunc)vec_ixor<1, glm::i32>, //nb_inplace_xor
(binaryfunc)vec_ior<1, glm::i32>, //nb_inplace_or
0, //nb_floor_divide
(binaryfunc)ivec_floordiv<1, glm::i32>, //nb_floor_divide
(binaryfunc)vec_div<1, glm::i32>,
0, //nb_inplace_floor_divide
(binaryfunc)ivec_ifloordiv<1, glm::i32>, //nb_inplace_floor_divide
(binaryfunc)vec_idiv<1, glm::i32>, //nb_inplace_true_divide
0, //nb_index
(binaryfunc)vec_matmul, //nb_matrix_multiply
Expand Down
Loading

0 comments on commit 1d3e142

Please sign in to comment.