Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-06-25 14:11:37 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-06-25 14:11:37 +0400
commitd428ba1de8074e8b0ca2b7c0b060c18ebf7d6b0c (patch)
tree0200656374d9d08125eba99ecc009ca3e70cc7fb
parent7a357cba3994bee7d05c7a8bf5736eb94067d564 (diff)
PyAPI RNA/BGE
* all mathutils types now have optional callbacks * PyRNA returns mathutils quat and euler types automatically when they have the rotation subtype. * PyRNA, reuse the BPy_StructRNA PyObject rather name making a new one for each function returned. * use more arithb.c functions for Mathutils quaternion type (less inline cruft). * BGE Mathutils integration mostly finished- KX_PyMath now converts to Mathutils types rather then lists. * make all mathutils types share the same header so they can share a number of functions - dealloc, getWrapped, getOwner.
-rw-r--r--source/blender/python/generic/Geometry.c12
-rw-r--r--source/blender/python/generic/Mathutils.c127
-rw-r--r--source/blender/python/generic/Mathutils.h41
-rw-r--r--source/blender/python/generic/euler.c182
-rw-r--r--source/blender/python/generic/euler.h14
-rw-r--r--source/blender/python/generic/matrix.c114
-rw-r--r--source/blender/python/generic/matrix.h21
-rw-r--r--source/blender/python/generic/quat.c328
-rw-r--r--source/blender/python/generic/quat.h16
-rw-r--r--source/blender/python/generic/vector.c136
-rw-r--r--source/blender/python/generic/vector.h9
-rw-r--r--source/blender/python/intern/bpy_rna.c54
-rw-r--r--source/gameengine/Expressions/KX_Python.h2
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp7
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h8
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp130
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h11
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.cpp66
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.h35
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.cpp3
21 files changed, 715 insertions, 612 deletions
diff --git a/source/blender/python/generic/Geometry.c b/source/blender/python/generic/Geometry.c
index ec76675f652..8a748241570 100644
--- a/source/blender/python/generic/Geometry.c
+++ b/source/blender/python/generic/Geometry.c
@@ -165,7 +165,7 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq )
polyVec= PySequence_GetItem( polyLine, index );
if(VectorObject_Check(polyVec)) {
- if(!Vector_ReadCallback((VectorObject *)polyVec))
+ if(!BaseMath_ReadCallback((VectorObject *)polyVec))
ls_error= 1;
fp[0] = ((VectorObject *)polyVec)->vec[0];
@@ -238,7 +238,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(line_a1) || !Vector_ReadCallback(line_a2) || !Vector_ReadCallback(line_b1) || !Vector_ReadCallback(line_b2))
+ if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2))
return NULL;
a1x= line_a1->vec[0];
@@ -338,7 +338,7 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args
return NULL;
}
- if(!Vector_ReadCallback(pt) || !Vector_ReadCallback(line_1) || !Vector_ReadCallback(line_2))
+ if(!BaseMath_ReadCallback(pt) || !BaseMath_ReadCallback(line_1) || !BaseMath_ReadCallback(line_2))
return NULL;
/* accept 2d verts */
@@ -374,7 +374,7 @@ static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args
return NULL;
}
- if(!Vector_ReadCallback(pt_vec) || !Vector_ReadCallback(tri_p1) || !Vector_ReadCallback(tri_p2) || !Vector_ReadCallback(tri_p3))
+ if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(tri_p1) || !BaseMath_ReadCallback(tri_p2) || !BaseMath_ReadCallback(tri_p3))
return NULL;
return PyLong_FromLong(IsectPT2Df(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec));
@@ -395,7 +395,7 @@ static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(pt_vec) || !Vector_ReadCallback(quad_p1) || !Vector_ReadCallback(quad_p2) || !Vector_ReadCallback(quad_p3) || !Vector_ReadCallback(quad_p4))
+ if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(quad_p1) || !BaseMath_ReadCallback(quad_p2) || !BaseMath_ReadCallback(quad_p3) || !BaseMath_ReadCallback(quad_p4))
return NULL;
return PyLong_FromLong(IsectPQ2Df(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec));
@@ -517,7 +517,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(vec_k1) || !Vector_ReadCallback(vec_h1) || !Vector_ReadCallback(vec_k2) || !Vector_ReadCallback(vec_h2))
+ if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2))
return NULL;
dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
diff --git a/source/blender/python/generic/Mathutils.c b/source/blender/python/generic/Mathutils.c
index cd9705236d7..d7330ac46c0 100644
--- a/source/blender/python/generic/Mathutils.c
+++ b/source/blender/python/generic/Mathutils.c
@@ -155,10 +155,13 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
if(QuaternionObject_Check(arg1)){
quat = (QuaternionObject*)arg1;
+ if(!BaseMath_ReadCallback(quat))
+ return NULL;
+
if(VectorObject_Check(arg2)){
vec = (VectorObject*)arg2;
- if(!Vector_ReadCallback(vec))
+ if(!BaseMath_ReadCallback(vec))
return NULL;
rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] -
@@ -178,11 +181,14 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
}else if(VectorObject_Check(arg1)){
vec = (VectorObject*)arg1;
- if(!Vector_ReadCallback(vec))
+ if(!BaseMath_ReadCallback(vec))
return NULL;
if(QuaternionObject_Check(arg2)){
quat = (QuaternionObject*)arg2;
+ if(!BaseMath_ReadCallback(quat))
+ return NULL;
+
rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] -
2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] +
2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] -
@@ -247,7 +253,7 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
if(vec1->size != vec2->size)
goto AttributeError1; //bad sizes
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
//since size is the same....
@@ -296,7 +302,7 @@ static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
return NULL;
}
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
for(x = 0; x < vec1->size; x++) {
@@ -322,7 +328,7 @@ static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
return NULL;
}
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
@@ -389,7 +395,7 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
return NULL;
}
- if(!Vector_ReadCallback(vec))
+ if(!BaseMath_ReadCallback(vec))
return NULL;
}
@@ -492,7 +498,7 @@ static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * v
return NULL;
}
- if(!Vector_ReadCallback(vec))
+ if(!BaseMath_ReadCallback(vec))
return NULL;
//create a identity matrix and add translation
@@ -528,7 +534,7 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
return NULL;
}
- if(!Vector_ReadCallback(vec))
+ if(!BaseMath_ReadCallback(vec))
return NULL;
}
@@ -607,7 +613,7 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
return NULL;
}
- if(!Vector_ReadCallback(vec))
+ if(!BaseMath_ReadCallback(vec))
return NULL;
}
@@ -766,6 +772,10 @@ static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
PyErr_SetString(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types");
return NULL;
}
+
+ if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
+ return NULL;
+
tempQuat[0] = quatU->quat[0];
tempQuat[1] = -quatU->quat[1];
tempQuat[2] = -quatU->quat[2];
@@ -793,6 +803,10 @@ static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float");
return NULL;
}
+
+ if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
+ return NULL;
+
if(param > 1.0f || param < 0.0f) {
PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0");
return NULL;
@@ -856,7 +870,7 @@ static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(ray) || !Vector_ReadCallback(ray_off))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off))
return NULL;
VECCOPY(v1, vec1->vec);
@@ -928,7 +942,7 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(vec4))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
return NULL;
if( vec1->size == 3 || vec1->size == 2) {
@@ -1002,7 +1016,7 @@ static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(vec4))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
return NULL;
VECCOPY(v1, vec1->vec);
@@ -1050,7 +1064,7 @@ static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
return NULL;
VECCOPY(v1, vec1->vec);
@@ -1085,7 +1099,7 @@ static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
return NULL;
if (vec1->size == 3) {
@@ -1167,75 +1181,66 @@ int Mathutils_RegisterCallback(Mathutils_Callback *cb)
}
/* use macros to check for NULL */
-int _Vector_ReadCallback(VectorObject *self)
+int _BaseMathObject_ReadCallback(BaseMathObject *self)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
- if(cb->get(self->cb_user, self->cb_subtype, self->vec)) {
+ if(cb->get(self->cb_user, self->cb_subtype, self->data))
return 1;
- }
- else {
- PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
- return 0;
- }
+
+ PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
+ return 0;
}
-int _Vector_WriteCallback(VectorObject *self)
+int _BaseMathObject_WriteCallback(BaseMathObject *self)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
- if(cb->set(self->cb_user, self->cb_subtype, self->vec)) {
+ if(cb->set(self->cb_user, self->cb_subtype, self->data))
return 1;
- }
- else {
- PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
- return 0;
- }
+
+ PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
+ return 0;
}
-int _Vector_ReadIndexCallback(VectorObject *self, int index)
+int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
- if(cb->get_index(self->cb_user, self->cb_subtype, self->vec, index)) {
+ if(cb->get_index(self->cb_user, self->cb_subtype, self->data, index))
return 1;
- }
- else {
- PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
- return 0;
- }
+
+ PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
+ return 0;
}
-int _Vector_WriteIndexCallback(VectorObject *self, int index)
+int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
{
Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
- if(cb->set_index(self->cb_user, self->cb_subtype, self->vec, index)) {
+ if(cb->set_index(self->cb_user, self->cb_subtype, self->data, index))
return 1;
- }
- else {
- PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
- return 0;
- }
+
+ PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
+ return 0;
}
-/* matrix callbacks */
-int _Matrix_ReadCallback(MatrixObject *self)
+/* BaseMathObject generic functions for all mathutils types */
+PyObject *BaseMathObject_getOwner( BaseMathObject * self, void *type )
{
- Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
- if(cb->get(self->cb_user, self->cb_subtype, self->contigPtr)) {
- return 1;
- }
- else {
- PyErr_SetString(PyExc_SystemError, "Matrix user has become invalid");
- return 0;
- }
+ PyObject *ret= self->cb_user ? self->cb_user : Py_None;
+ Py_INCREF(ret);
+ return ret;
}
-int _Matrix_WriteCallback(MatrixObject *self)
+PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void *type )
{
- Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
- if(cb->set(self->cb_user, self->cb_subtype, self->contigPtr)) {
- return 1;
- }
- else {
- PyErr_SetString(PyExc_SystemError, "Matrix user has become invalid");
- return 0;
- }
+ PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0);
}
+
+void BaseMathObject_dealloc(BaseMathObject * self)
+{
+ /* only free non wrapped */
+ if(self->wrapped != Py_WRAP)
+ PyMem_Free(self->data);
+
+ Py_XDECREF(self->cb_user);
+ PyObject_DEL(self);
+}
+
diff --git a/source/blender/python/generic/Mathutils.h b/source/blender/python/generic/Mathutils.h
index a89b779ecbb..d234ebf1452 100644
--- a/source/blender/python/generic/Mathutils.h
+++ b/source/blender/python/generic/Mathutils.h
@@ -38,6 +38,24 @@
#include "quat.h"
#include "euler.h"
+/* Can cast different mathutils types to this, use for generic funcs */
+
+typedef struct {
+ PyObject_VAR_HEAD
+ float *data; /*array of data (alias), wrapped status depends on wrapped status */
+ PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
+ unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
+ unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+ unsigned char wrapped; /* wrapped data type? */
+} BaseMathObject;
+
+PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * );
+PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * );
+void BaseMathObject_dealloc(BaseMathObject * self);
+
+
+
+
PyObject *Mathutils_Init( const char * from );
PyObject *quat_rotation(PyObject *arg1, PyObject *arg2);
@@ -75,22 +93,15 @@ struct Mathutils_Callback {
int Mathutils_RegisterCallback(Mathutils_Callback *cb);
-int _Vector_ReadCallback(VectorObject *self);
-int _Vector_WriteCallback(VectorObject *self);
-int _Vector_ReadIndexCallback(VectorObject *self, int index);
-int _Vector_WriteIndexCallback(VectorObject *self, int index);
+int _BaseMathObject_ReadCallback(BaseMathObject *self);
+int _BaseMathObject_WriteCallback(BaseMathObject *self);
+int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index);
+int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
/* since this is called so often avoid where possible */
-#define Vector_ReadCallback(_self) (((_self)->cb_user ? _Vector_ReadCallback(_self):1))
-#define Vector_WriteCallback(_self) (((_self)->cb_user ?_Vector_WriteCallback(_self):1))
-#define Vector_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _Vector_ReadIndexCallback(_self, _index):1))
-#define Vector_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _Vector_WriteIndexCallback(_self, _index):1))
-
-
-int _Matrix_ReadCallback(MatrixObject *self);
-int _Matrix_WriteCallback(MatrixObject *self);
-
-#define Matrix_ReadCallback(_self) (((_self)->cb_user ?_Matrix_ReadCallback(_self):1))
-#define Matrix_WriteCallback(_self) (((_self)->cb_user ?_Matrix_WriteCallback(_self):1))
+#define BaseMath_ReadCallback(_self) (((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):1))
+#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):1))
+#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1))
+#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1))
#endif /* EXPP_Mathutils_H */
diff --git a/source/blender/python/generic/euler.c b/source/blender/python/generic/euler.c
index e78a5739347..eb9358774e1 100644
--- a/source/blender/python/generic/euler.c
+++ b/source/blender/python/generic/euler.c
@@ -123,6 +123,9 @@ static PyObject *Euler_ToQuat(EulerObject * self)
float eul[3], quat[4];
int x;
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
for(x = 0; x < 3; x++) {
eul[x] = self->eul[x] * ((float)Py_PI / 180);
}
@@ -137,6 +140,9 @@ static PyObject *Euler_ToMatrix(EulerObject * self)
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
int x;
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
for(x = 0; x < 3; x++) {
eul[x] = self->eul[x] * ((float)Py_PI / 180);
}
@@ -152,6 +158,9 @@ static PyObject *Euler_Unique(EulerObject * self)
double piO2 = Py_PI / 2.0f;
double Opi2 = 1.0f / pi2;
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
//radians
heading = self->eul[0] * (float)Py_PI / 180;
pitch = self->eul[1] * (float)Py_PI / 180;
@@ -191,6 +200,7 @@ static PyObject *Euler_Unique(EulerObject * self)
self->eul[1] = (float)(pitch * 180 / (float)Py_PI);
self->eul[2] = (float)(bank * 180 / (float)Py_PI);
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -202,6 +212,7 @@ static PyObject *Euler_Zero(EulerObject * self)
self->eul[1] = 0.0;
self->eul[2] = 0.0;
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -223,6 +234,9 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
return NULL;
}
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
//covert to radians
angle *= ((float)Py_PI / 180);
for(x = 0; x < 3; x++) {
@@ -234,6 +248,7 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
self->eul[x] *= (180 / (float)Py_PI);
}
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -248,6 +263,9 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
return NULL;
}
+ if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+ return NULL;
+
//covert to radians
for(x = 0; x < 3; x++) {
self->eul[x] = self->eul[x] * ((float)Py_PI / 180);
@@ -259,6 +277,7 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
self->eul[x] *= (180 / (float)Py_PI);
}
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -267,19 +286,10 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
// return a copy of the euler
static PyObject *Euler_copy(EulerObject * self, PyObject *args)
{
- return newEulerObject(self->eul, Py_NEW);
-}
-
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
-//----------------------------dealloc()(internal) ------------------
-//free the py_object
-static void Euler_dealloc(EulerObject * self)
-{
- //only free py_data
- if(self->data.py_data){
- PyMem_Free(self->data.py_data);
- }
- PyObject_DEL(self);
+ return newEulerObject(self->eul, Py_NEW);
}
//----------------------------print object (internal)--------------
@@ -287,6 +297,10 @@ static void Euler_dealloc(EulerObject * self)
static PyObject *Euler_repr(EulerObject * self)
{
char str[64];
+
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
sprintf(str, "[%.6f, %.6f, %.6f](euler)", self->eul[0], self->eul[1], self->eul[2]);
return PyUnicode_FromString(str);
}
@@ -297,7 +311,18 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar
EulerObject *eulA = NULL, *eulB = NULL;
int result = 0;
- if (!EulerObject_Check(objectA) || !EulerObject_Check(objectB)){
+ if(EulerObject_Check(objectA)) {
+ eulA = (EulerObject*)objectA;
+ if(!BaseMath_ReadCallback(eulA))
+ return NULL;
+ }
+ if(EulerObject_Check(objectB)) {
+ eulB = (EulerObject*)objectB;
+ if(!BaseMath_ReadCallback(eulB))
+ return NULL;
+ }
+
+ if (!eulA || !eulB){
if (comparison_type == Py_NE){
Py_RETURN_TRUE;
}else{
@@ -342,13 +367,16 @@ static int Euler_len(EulerObject * self)
//sequence accessor (get)
static PyObject *Euler_item(EulerObject * self, int i)
{
- if(i<0)
- i= 3-i;
+ if(i<0) i= 3-i;
if(i < 0 || i >= 3) {
PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range");
return NULL;
}
+
+ if(!BaseMath_ReadIndexCallback(self, i))
+ return NULL;
+
return PyFloat_FromDouble(self->eul[i]);
}
@@ -363,8 +391,7 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value)
return -1;
}
- if(i<0)
- i= 3-i;
+ if(i<0) i= 3-i;
if(i < 0 || i >= 3){
PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range\n");
@@ -372,6 +399,10 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value)
}
self->eul[i] = f;
+
+ if(!BaseMath_WriteIndexCallback(self, i))
+ return -1;
+
return 0;
}
//----------------------------object[z:y]------------------------
@@ -381,6 +412,9 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end)
PyObject *list = NULL;
int count;
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
CLAMP(begin, 0, 3);
if (end<0) end= 4+end;
CLAMP(end, 0, 3);
@@ -401,7 +435,10 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end,
{
int i, y, size = 0;
float eul[3];
- PyObject *e, *f;
+ PyObject *e;
+
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
CLAMP(begin, 0, 3);
if (end<0) end= 4+end;
@@ -421,21 +458,20 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end,
return -1;
}
- f = PyNumber_Float(e);
- if(f == NULL) { // parsed item not a number
- Py_DECREF(e);
+ eul[i] = (float)PyFloat_AsDouble(e);
+ Py_DECREF(e);
+
+ if(eul[i]==-1 && PyErr_Occurred()) { // parsed item not a number
PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: sequence argument not a number");
return -1;
}
-
- eul[i] = (float)PyFloat_AS_DOUBLE(f);
- Py_DECREF(f);
- Py_DECREF(e);
}
//parsed well - now set in vector
for(y = 0; y < 3; y++){
self->eul[begin + y] = eul[y];
}
+
+ BaseMath_WriteCallback(self);
return 0;
}
//-----------------PROTCOL DECLARATIONS--------------------------
@@ -450,79 +486,30 @@ static PySequenceMethods Euler_SeqMethods = {
};
-
/*
* vector axis, vector.x/y/z/w
*/
static PyObject *Euler_getAxis( EulerObject * self, void *type )
{
- switch( (long)type ) {
- case 'X': /* these are backwards, but that how it works */
- return PyFloat_FromDouble(self->eul[0]);
- case 'Y':
- return PyFloat_FromDouble(self->eul[1]);
- case 'Z':
- return PyFloat_FromDouble(self->eul[2]);
- }
-
- PyErr_SetString(PyExc_SystemError, "corrupt euler, cannot get axis");
- return NULL;
+ return Euler_item(self, GET_INT_FROM_POINTER(type));
}
static int Euler_setAxis( EulerObject * self, PyObject * value, void * type )
{
- float param= (float)PyFloat_AsDouble( value );
-
- if (param==-1 && PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError, "expected a number for the vector axis");
- return -1;
- }
-
- switch( (long)type ) {
- case 'X': /* these are backwards, but that how it works */
- self->eul[0]= param;
- break;
- case 'Y':
- self->eul[1]= param;
- break;
- case 'Z':
- self->eul[2]= param;
- break;
- }
-
- return 0;
-}
-
-static PyObject *Euler_getWrapped( VectorObject * self, void *type )
-{
- if (self->wrapped == Py_WRAP)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value);
}
-
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Euler_getseters[] = {
- {"x",
- (getter)Euler_getAxis, (setter)Euler_setAxis,
- "Euler X axis",
- (void *)'X'},
- {"y",
- (getter)Euler_getAxis, (setter)Euler_setAxis,
- "Euler Y axis",
- (void *)'Y'},
- {"z",
- (getter)Euler_getAxis, (setter)Euler_setAxis,
- "Euler Z axis",
- (void *)'Z'},
- {"wrapped",
- (getter)Euler_getWrapped, (setter)NULL,
- "True when this wraps blenders internal data",
- NULL},
+ {"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis", (void *)0},
+ {"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis", (void *)1},
+ {"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis", (void *)2},
+
+ {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL},
+ {"__owner__", (getter)BaseMathObject_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -538,7 +525,7 @@ PyTypeObject euler_Type = {
"euler", //tp_name
sizeof(EulerObject), //tp_basicsize
0, //tp_itemsize
- (destructor)Euler_dealloc, //tp_dealloc
+ (destructor)BaseMathObject_dealloc, //tp_dealloc
0, //tp_print
0, //tp_getattr
0, //tp_setattr
@@ -593,24 +580,22 @@ PyObject *newEulerObject(float *eul, int type)
int x;
self = PyObject_NEW(EulerObject, &euler_Type);
- self->data.blend_data = NULL;
- self->data.py_data = NULL;
+
+ /* init callbacks as NULL */
+ self->cb_user= NULL;
+ self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP){
- self->data.blend_data = eul;
- self->eul = self->data.blend_data;
+ self->eul = eul;
self->wrapped = Py_WRAP;
}else if (type == Py_NEW){
- self->data.py_data = PyMem_Malloc(3 * sizeof(float));
- self->eul = self->data.py_data;
+ self->eul = PyMem_Malloc(3 * sizeof(float));
if(!eul) { //new empty
for(x = 0; x < 3; x++) {
self->eul[x] = 0.0f;
}
}else{
- for(x = 0; x < 3; x++){
- self->eul[x] = eul[x];
- }
+ VECCOPY(self->eul, eul);
}
self->wrapped = Py_NEW;
}else{ //bad type
@@ -618,3 +603,16 @@ PyObject *newEulerObject(float *eul, int type)
}
return (PyObject *)self;
}
+
+PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
+{
+ EulerObject *self= (EulerObject *)newEulerObject(NULL, Py_NEW);
+ if(self) {
+ Py_INCREF(cb_user);
+ self->cb_user= cb_user;
+ self->cb_type= (unsigned char)cb_type;
+ self->cb_subtype= (unsigned char)cb_subtype;
+ }
+
+ return self;
+}
diff --git a/source/blender/python/generic/euler.h b/source/blender/python/generic/euler.h
index 3be629351cb..0bff6de6964 100644
--- a/source/blender/python/generic/euler.h
+++ b/source/blender/python/generic/euler.h
@@ -40,12 +40,13 @@ extern PyTypeObject euler_Type;
typedef struct {
PyObject_VAR_HEAD
- struct{
- float *py_data; //python managed
- float *blend_data; //blender managed
- }data;
- float *eul; //1D array of data (alias)
- int wrapped; //is wrapped data?
+ float *eul; /*1D array of data */
+ PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
+ unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
+ unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+ unsigned char wrapped; /* wrapped data type? */
+ /* end BaseMathObject */
+
} EulerObject;
/*struct data contains a pointer to the actual data that the
@@ -55,5 +56,6 @@ blender (stored in blend_data). This is an either/or struct not both*/
//prototypes
PyObject *newEulerObject( float *eul, int type );
+PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype);
#endif /* EXPP_euler_h */
diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c
index db5b4ab08bf..ef4f7280cdc 100644
--- a/source/blender/python/generic/matrix.c
+++ b/source/blender/python/generic/matrix.c
@@ -39,13 +39,13 @@ int mathutils_matrix_vector_cb_index= -1;
static int mathutils_matrix_vector_check(MatrixObject *self)
{
- return Matrix_ReadCallback(self);
+ return BaseMath_ReadCallback(self);
}
static int mathutils_matrix_vector_get(MatrixObject *self, int subtype, float *vec_from)
{
int i;
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return 0;
for(i=0; i<self->colSize; i++)
@@ -57,19 +57,19 @@ static int mathutils_matrix_vector_get(MatrixObject *self, int subtype, float *v
static int mathutils_matrix_vector_set(MatrixObject *self, int subtype, float *vec_to)
{
int i;
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return 0;
for(i=0; i<self->colSize; i++)
self->matrix[subtype][i]= vec_to[i];
- Matrix_WriteCallback(self);
+ BaseMath_WriteCallback(self);
return 1;
}
static int mathutils_matrix_vector_get_index(MatrixObject *self, int subtype, float *vec_from, int index)
{
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return 0;
vec_from[index]= self->matrix[subtype][index];
@@ -78,12 +78,12 @@ static int mathutils_matrix_vector_get_index(MatrixObject *self, int subtype, fl
static int mathutils_matrix_vector_set_index(MatrixObject *self, int subtype, float *vec_to, int index)
{
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return 0;
self->matrix[subtype][index]= vec_to[index];
- Matrix_WriteCallback(self);
+ BaseMath_WriteCallback(self);
return 1;
}
@@ -164,7 +164,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
argObject = PyTuple_GET_ITEM(args, 0);
if(MatrixObject_Check(argObject)){
mat = (MatrixObject*)argObject;
- if(!Matrix_ReadCallback(mat))
+ if(!BaseMath_ReadCallback(mat))
return NULL;
argSize = mat->rowSize; //rows
@@ -225,7 +225,7 @@ static PyObject *Matrix_toQuat(MatrixObject * self)
{
float quat[4];
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -248,13 +248,16 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
EulerObject *eul_compat = NULL;
int x;
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat))
return NULL;
if(eul_compat) {
+ if(!BaseMath_ReadCallback(eul_compat))
+ return NULL;
+
for(x = 0; x < 3; x++) {
eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180);
}
@@ -343,7 +346,7 @@ PyObject *Matrix_TranslationPart(MatrixObject * self)
{
float vec[4];
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if(self->colSize < 3 || self->rowSize < 4){
@@ -363,7 +366,7 @@ PyObject *Matrix_RotationPart(MatrixObject * self)
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if(self->colSize < 3 || self->rowSize < 3){
@@ -389,7 +392,7 @@ PyObject *Matrix_scalePart(MatrixObject * self)
float scale[3], rot[3];
float mat[3][3], imat[3][3], tmat[3][3];
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -422,7 +425,7 @@ PyObject *Matrix_Invert(MatrixObject * self)
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if(self->rowSize != self->colSize){
@@ -465,7 +468,7 @@ PyObject *Matrix_Invert(MatrixObject * self)
return NULL;
}
- Matrix_WriteCallback(self);
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -476,7 +479,7 @@ PyObject *Matrix_Determinant(MatrixObject * self)
{
float det = 0.0f;
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if(self->rowSize != self->colSize){
@@ -504,7 +507,7 @@ PyObject *Matrix_Transpose(MatrixObject * self)
{
float t = 0.0f;
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if(self->rowSize != self->colSize){
@@ -522,7 +525,7 @@ PyObject *Matrix_Transpose(MatrixObject * self)
Mat4Transp((float (*)[4])*self->matrix);
}
- Matrix_WriteCallback(self);
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject *)self;
}
@@ -539,7 +542,7 @@ PyObject *Matrix_Zero(MatrixObject * self)
}
}
- if(!Matrix_WriteCallback(self))
+ if(!BaseMath_WriteCallback(self))
return NULL;
Py_INCREF(self);
@@ -548,7 +551,7 @@ PyObject *Matrix_Zero(MatrixObject * self)
/*---------------------------Matrix.identity(() ------------------*/
PyObject *Matrix_Identity(MatrixObject * self)
{
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if(self->rowSize != self->colSize){
@@ -567,7 +570,7 @@ PyObject *Matrix_Identity(MatrixObject * self)
Mat4One((float (*)[4]) *self->matrix);
}
- if(!Matrix_WriteCallback(self))
+ if(!BaseMath_WriteCallback(self))
return NULL;
Py_INCREF(self);
@@ -577,25 +580,12 @@ PyObject *Matrix_Identity(MatrixObject * self)
/*---------------------------Matrix.inverted() ------------------*/
PyObject *Matrix_copy(MatrixObject * self)
{
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
return (PyObject*)(MatrixObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW);
}
-/*----------------------------dealloc()(internal) ----------------*/
-/*free the py_object*/
-static void Matrix_dealloc(MatrixObject * self)
-{
- PyMem_Free(self->matrix);
- /*only free py_data*/
- if(self->wrapped==Py_WRAP)
- PyMem_Free(self->contigPtr);
-
- Py_XDECREF(self->cb_user);
- PyObject_DEL(self);
-}
-
/*----------------------------print object (internal)-------------*/
/*print the object to screen*/
static PyObject *Matrix_repr(MatrixObject * self)
@@ -603,7 +593,7 @@ static PyObject *Matrix_repr(MatrixObject * self)
int x, y;
char buffer[48], str[1024];
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
BLI_strncpy(str,"",1024);
@@ -642,7 +632,7 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa
matA = (MatrixObject*)objectA;
matB = (MatrixObject*)objectB;
- if(!Matrix_ReadCallback(matA) || !Matrix_ReadCallback(matB))
+ if(!BaseMath_ReadCallback(matA) || !BaseMath_ReadCallback(matB))
return NULL;
if (matA->colSize != matB->colSize || matA->rowSize != matB->rowSize){
@@ -692,7 +682,7 @@ static int Matrix_len(MatrixObject * self)
the wrapped vector gives direct access to the matrix data*/
static PyObject *Matrix_item(MatrixObject * self, int i)
{
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if(i < 0 || i >= self->rowSize) {
@@ -709,7 +699,7 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
float vec[4];
PyObject *m, *f;
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return -1;
if(i >= self->rowSize || i < 0){
@@ -746,7 +736,7 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
self->matrix[i][y] = vec[y];
}
- Matrix_WriteCallback(self);
+ BaseMath_WriteCallback(self);
return 0;
}else{
PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: expects a sequence of column size\n");
@@ -761,7 +751,7 @@ static PyObject *Matrix_slice(MatrixObject * self, int begin, int end)
PyObject *list = NULL;
int count;
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
CLAMP(begin, 0, self->rowSize);
@@ -787,7 +777,7 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end,
PyObject *subseq;
PyObject *m;
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return -1;
CLAMP(begin, 0, self->rowSize);
@@ -848,7 +838,7 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end,
self->matrix[begin + (int)floor(x / self->colSize)][x % self->colSize] = mat[x];
}
- Matrix_WriteCallback(self);
+ BaseMath_WriteCallback(self);
return 0;
}else{
PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation\n");
@@ -872,7 +862,7 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
return NULL;
}
- if(!Matrix_ReadCallback(mat1) || !Matrix_ReadCallback(mat2))
+ if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2))
return NULL;
if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){
@@ -905,7 +895,7 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
return NULL;
}
- if(!Matrix_ReadCallback(mat1) || !Matrix_ReadCallback(mat2))
+ if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2))
return NULL;
if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){
@@ -934,12 +924,12 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
if(MatrixObject_Check(m1)) {
mat1 = (MatrixObject*)m1;
- if(!Matrix_ReadCallback(mat1))
+ if(!BaseMath_ReadCallback(mat1))
return NULL;
}
if(MatrixObject_Check(m2)) {
mat2 = (MatrixObject*)m2;
- if(!Matrix_ReadCallback(mat2))
+ if(!BaseMath_ReadCallback(mat2))
return NULL;
}
@@ -1000,7 +990,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
}
static PyObject* Matrix_inv(MatrixObject *self)
{
- if(!Matrix_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
return Matrix_Invert(self);
@@ -1052,33 +1042,15 @@ static PyObject *Matrix_getColSize( MatrixObject * self, void *type )
return PyLong_FromLong((long) self->colSize);
}
-static PyObject *Matrix_getOwner( MatrixObject * self, void *type )
-{
- if(self->cb_user==NULL) {
- Py_RETURN_NONE;
- }
- else {
- Py_INCREF(self->cb_user);
- return self->cb_user;
- }
-}
-
-static PyObject *Matrix_getWrapped( MatrixObject * self, void *type )
-{
- if (self->wrapped == Py_WRAP)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
-}
-
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
static PyGetSetDef Matrix_getseters[] = {
{"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL},
{"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL},
- {"wrapped", (getter)Matrix_getWrapped, (setter)NULL, "", NULL},
- {"__owner__",(getter)Matrix_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
+ {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "", NULL},
+ {"__owner__",(getter)BaseMathObject_getOwner, (setter)NULL, "",
+ NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -1094,7 +1066,7 @@ PyTypeObject matrix_Type = {
"matrix", /*tp_name*/
sizeof(MatrixObject), /*tp_basicsize*/
0, /*tp_itemsize*/
- (destructor)Matrix_dealloc, /*tp_dealloc*/
+ (destructor)BaseMathObject_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
@@ -1245,7 +1217,7 @@ static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject*
double dot = 0.0f;
int x, y, z = 0;
- if(!Matrix_ReadCallback(mat) || !Vector_ReadCallback(vec))
+ if(!BaseMath_ReadCallback(mat) || !BaseMath_ReadCallback(vec))
return NULL;
if(mat->rowSize != vec->size){
diff --git a/source/blender/python/generic/matrix.h b/source/blender/python/generic/matrix.h
index cc3928f1632..4b073668969 100644
--- a/source/blender/python/generic/matrix.h
+++ b/source/blender/python/generic/matrix.h
@@ -37,16 +37,19 @@ extern PyTypeObject matrix_Type;
#define MatrixObject_Check(v) ((v)->ob_type == &matrix_Type)
typedef float **ptRow;
-typedef struct _Matrix {
- PyObject_VAR_HEAD
- ptRow matrix; /*ptr to the contigPtr (accessor)*/
- float* contigPtr; /*1D array of data (alias)*/
- PyObject* cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
- unsigned char rowSize;
- unsigned char colSize;
- unsigned char wrapped; /*is wrapped data?*/
+typedef struct _Matrix { /* keep aligned with BaseMathObject in Mathutils.h */
+ PyObject_VAR_HEAD
+ float *contigPtr; /*1D array of data (alias)*/
+ PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
- unsigned int cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+ unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+ unsigned char wrapped; /*is wrapped data?*/
+ /* end BaseMathObject */
+
+ unsigned char rowSize;
+ unsigned int colSize;
+ ptRow matrix; /*ptr to the contigPtr (accessor)*/
+
} MatrixObject;
/*struct data contains a pointer to the actual data that the
diff --git a/source/blender/python/generic/quat.c b/source/blender/python/generic/quat.c
index 8a3ded80455..b1e9f4a1d31 100644
--- a/source/blender/python/generic/quat.c
+++ b/source/blender/python/generic/quat.c
@@ -78,7 +78,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
PyObject *listObject = NULL, *n, *q;
int size, i;
float quat[4], scalar;
- double norm = 0.0f, angle = 0.0f;
+ double angle = 0.0f;
size = PyTuple_GET_SIZE(args);
if (size == 1 || size == 2) { //seq?
@@ -152,28 +152,19 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
}
scalar = PyFloat_AsDouble(q);
+ Py_DECREF(q);
+
if (scalar==-1 && PyErr_Occurred()) {
- Py_DECREF(q);
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
return NULL;
}
-
quat[i] = scalar;
- Py_DECREF(q);
- }
- if(size == 3){ //calculate the quat based on axis/angle
- norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
- quat[0] /= (float)norm;
- quat[1] /= (float)norm;
- quat[2] /= (float)norm;
-
- angle = angle * (Py_PI / 180);
- quat[3] =(float) (sin(angle/ 2.0f)) * quat[2];
- quat[2] =(float) (sin(angle/ 2.0f)) * quat[1];
- quat[1] =(float) (sin(angle/ 2.0f)) * quat[0];
- quat[0] =(float) (cos(angle/ 2.0f));
}
+ if(size == 3) //calculate the quat based on axis/angle
+ AxisAngleToQuat(quat, quat, angle * (Py_PI / 180)); // TODO - 2.5 use radians, note using quat for src and target is ok here
+
+
return newQuaternionObject(quat, Py_NEW);
}
@@ -189,9 +180,15 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat))
return NULL;
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
if(eul_compat) {
float mat[3][3], eul_compatf[3];
+ if(!BaseMath_ReadCallback(eul_compat))
+ return NULL;
+
for(x = 0; x < 3; x++) {
eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180);
}
@@ -214,8 +211,11 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
{
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
- QuatToMat3(self->quat, (float (*)[3]) mat);
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ QuatToMat3(self->quat, (float (*)[3]) mat);
return newMatrixObject(mat, 3, 3, Py_NEW);
}
@@ -230,6 +230,9 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va
return NULL;
}
+ if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+ return NULL;
+
QuatMul(quat, self->quat, value->quat);
return newQuaternionObject(quat, Py_NEW);
}
@@ -238,25 +241,27 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va
//return the dot quat
static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
{
- int x;
- double dot = 0.0;
-
if (!QuaternionObject_Check(value)) {
PyErr_SetString( PyExc_TypeError, "quat.dot(value): expected a quaternion argument" );
return NULL;
}
-
- for(x = 0; x < 4; x++) {
- dot += self->quat[x] * value->quat[x];
- }
- return PyFloat_FromDouble(dot);
+
+ if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+ return NULL;
+
+ return PyFloat_FromDouble(QuatDot(self->quat, value->quat));
}
//----------------------------Quaternion.normalize()----------------
//normalize the axis of rotation of [theta,vector]
static PyObject *Quaternion_Normalize(QuaternionObject * self)
{
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
NormalQuat(self->quat);
+
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -264,20 +269,12 @@ static PyObject *Quaternion_Normalize(QuaternionObject * self)
//invert the quat
static PyObject *Quaternion_Inverse(QuaternionObject * self)
{
- double mag = 0.0f;
- int x;
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
- for(x = 1; x < 4; x++) {
- self->quat[x] = -self->quat[x];
- }
- for(x = 0; x < 4; x++) {
- mag += (self->quat[x] * self->quat[x]);
- }
- mag = sqrt(mag);
- for(x = 0; x < 4; x++) {
- self->quat[x] /= (float)(mag * mag);
- }
+ QuatInv(self->quat);
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -285,11 +282,12 @@ static PyObject *Quaternion_Inverse(QuaternionObject * self)
//generate the identity quaternion
static PyObject *Quaternion_Identity(QuaternionObject * self)
{
- self->quat[0] = 1.0;
- self->quat[1] = 0.0;
- self->quat[2] = 0.0;
- self->quat[3] = 0.0;
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ QuatOne(self->quat);
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -297,10 +295,12 @@ static PyObject *Quaternion_Identity(QuaternionObject * self)
//negate the quat
static PyObject *Quaternion_Negate(QuaternionObject * self)
{
- int x;
- for(x = 0; x < 4; x++) {
- self->quat[x] = -self->quat[x];
- }
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ QuatMulf(self->quat, -1.0f);
+
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -308,10 +308,12 @@ static PyObject *Quaternion_Negate(QuaternionObject * self)
//negate the vector part
static PyObject *Quaternion_Conjugate(QuaternionObject * self)
{
- int x;
- for(x = 1; x < 4; x++) {
- self->quat[x] = -self->quat[x];
- }
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ QuatConj(self->quat);
+
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -319,18 +321,10 @@ static PyObject *Quaternion_Conjugate(QuaternionObject * self)
//return a copy of the quat
static PyObject *Quaternion_copy(QuaternionObject * self)
{
- return newQuaternionObject(self->quat, Py_NEW);
-}
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
-//----------------------------dealloc()(internal) ------------------
-//free the py_object
-static void Quaternion_dealloc(QuaternionObject * self)
-{
- //only free py_data
- if(self->data.py_data){
- PyMem_Free(self->data.py_data);
- }
- PyObject_DEL(self);
+ return newQuaternionObject(self->quat, Py_NEW);
}
//----------------------------print object (internal)--------------
@@ -338,6 +332,10 @@ static void Quaternion_dealloc(QuaternionObject * self)
static PyObject *Quaternion_repr(QuaternionObject * self)
{
char str[64];
+
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
sprintf(str, "[%.6f, %.6f, %.6f, %.6f](quaternion)", self->quat[0], self->quat[1], self->quat[2], self->quat[3]);
return PyUnicode_FromString(str);
}
@@ -348,15 +346,24 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c
QuaternionObject *quatA = NULL, *quatB = NULL;
int result = 0;
- if (!QuaternionObject_Check(objectA) || !QuaternionObject_Check(objectB)){
+ if(QuaternionObject_Check(objectA)) {
+ quatA = (QuaternionObject*)objectA;
+ if(!BaseMath_ReadCallback(quatA))
+ return NULL;
+ }
+ if(QuaternionObject_Check(objectB)) {
+ quatB = (QuaternionObject*)objectB;
+ if(!BaseMath_ReadCallback(quatB))
+ return NULL;
+ }
+
+ if (!quatA || !quatB){
if (comparison_type == Py_NE){
Py_RETURN_TRUE;
}else{
Py_RETURN_FALSE;
}
}
- quatA = (QuaternionObject*)objectA;
- quatB = (QuaternionObject*)objectB;
switch (comparison_type){
case Py_EQ:
@@ -393,10 +400,16 @@ static int Quaternion_len(QuaternionObject * self)
//sequence accessor (get)
static PyObject *Quaternion_item(QuaternionObject * self, int i)
{
+ if(i<0) i= 4-i;
+
if(i < 0 || i >= 4) {
PyErr_SetString(PyExc_IndexError, "quaternion[attribute]: array index out of range\n");
return NULL;
}
+
+ if(!BaseMath_ReadIndexCallback(self, i))
+ return NULL;
+
return PyFloat_FromDouble(self->quat[i]);
}
@@ -404,21 +417,23 @@ static PyObject *Quaternion_item(QuaternionObject * self, int i)
//sequence accessor (set)
static int Quaternion_ass_item(QuaternionObject * self, int i, PyObject * ob)
{
- PyObject *f = NULL;
-
- f = PyNumber_Float(ob);
- if(f == NULL) { // parsed item not a number
- PyErr_SetString(PyExc_TypeError, "quaternion[attribute] = x: argument not a number\n");
+ float scalar= (float)PyFloat_AsDouble(ob);
+ if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
+ PyErr_SetString(PyExc_TypeError, "quaternion[index] = x: index argument not a number\n");
return -1;
}
+ if(i<0) i= 4-i;
+
if(i < 0 || i >= 4){
- Py_DECREF(f);
PyErr_SetString(PyExc_IndexError, "quaternion[attribute] = x: array assignment index out of range\n");
return -1;
}
- self->quat[i] = (float)PyFloat_AS_DOUBLE(f);
- Py_DECREF(f);
+ self->quat[i] = scalar;
+
+ if(!BaseMath_WriteIndexCallback(self, i))
+ return -1;
+
return 0;
}
//----------------------------object[z:y]------------------------
@@ -428,6 +443,9 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end)
PyObject *list = NULL;
int count;
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
CLAMP(begin, 0, 4);
if (end<0) end= 5+end;
CLAMP(end, 0, 4);
@@ -443,12 +461,14 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end)
}
//----------------------------object[z:y]------------------------
//sequence slice (set)
-static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
- PyObject * seq)
+static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, PyObject * seq)
{
int i, y, size = 0;
float quat[4];
- PyObject *q, *f;
+ PyObject *q;
+
+ if(!BaseMath_ReadCallback(self))
+ return -1;
CLAMP(begin, 0, 4);
if (end<0) end= 5+end;
@@ -468,21 +488,19 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
return -1;
}
- f = PyNumber_Float(q);
- if(f == NULL) { // parsed item not a number
- Py_DECREF(q);
+ quat[i]= (float)PyFloat_AsDouble(q);
+ Py_DECREF(q);
+
+ if(quat[i]==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: sequence argument not a number\n");
return -1;
}
-
- quat[i] = (float)PyFloat_AS_DOUBLE(f);
- Py_DECREF(f);
- Py_DECREF(q);
}
//parsed well - now set in vector
- for(y = 0; y < size; y++){
+ for(y = 0; y < size; y++)
self->quat[begin + y] = quat[y];
- }
+
+ BaseMath_WriteCallback(self);
return 0;
}
//------------------------NUMERIC PROTOCOLS----------------------
@@ -490,7 +508,6 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
//addition
static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
{
- int x;
float quat[4];
QuaternionObject *quat1 = NULL, *quat2 = NULL;
@@ -498,14 +515,13 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n");
return NULL;
}
-
quat1 = (QuaternionObject*)q1;
quat2 = (QuaternionObject*)q2;
- for(x = 0; x < 4; x++) {
- quat[x] = quat1->quat[x] + quat2->quat[x];
- }
+ if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
+ return NULL;
+ QuatAdd(quat, quat1->quat, quat2->quat, 1.0f);
return newQuaternionObject(quat, Py_NEW);
}
//------------------------obj - obj------------------------------
@@ -524,6 +540,9 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
quat1 = (QuaternionObject*)q1;
quat2 = (QuaternionObject*)q2;
+ if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
+ return NULL;
+
for(x = 0; x < 4; x++) {
quat[x] = quat1->quat[x] - quat2->quat[x];
}
@@ -534,29 +553,31 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
//mulplication
static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
{
- int x;
float quat[4], scalar;
- double dot = 0.0f;
QuaternionObject *quat1 = NULL, *quat2 = NULL;
VectorObject *vec = NULL;
- quat1 = (QuaternionObject*)q1;
- quat2 = (QuaternionObject*)q2;
+ if(QuaternionObject_Check(q1)) {
+ quat1 = (QuaternionObject*)q1;
+ if(!BaseMath_ReadCallback(quat1))
+ return NULL;
+ }
+ if(QuaternionObject_Check(q2)) {
+ quat2 = (QuaternionObject*)q2;
+ if(!BaseMath_ReadCallback(quat2))
+ return NULL;
+ }
- if(QuaternionObject_Check(q1) && QuaternionObject_Check(q2)) { /* QUAT*QUAT (dot product) */
- for(x = 0; x < 4; x++) {
- dot += quat1->quat[x] * quat1->quat[x];
- }
- return PyFloat_FromDouble(dot);
+ if(quat1 && quat2) { /* QUAT*QUAT (dot product) */
+ return PyFloat_FromDouble(QuatDot(quat1->quat, quat2->quat));
}
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
if(!QuaternionObject_Check(q1)) {
scalar= PyFloat_AsDouble(q1);
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */
- for(x = 0; x < 4; x++) {
- quat[x] = quat2->quat[x] * scalar;
- }
+ QUATCOPY(quat, quat2->quat);
+ QuatMulf(quat, scalar);
return newQuaternionObject(quat, Py_NEW);
}
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type");
@@ -574,9 +595,8 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
scalar= PyFloat_AsDouble(q2);
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */
- for(x = 0; x < 4; x++) {
- quat[x] = quat1->quat[x] * scalar;
- }
+ QUATCOPY(quat, quat1->quat);
+ QuatMulf(quat, scalar);
return newQuaternionObject(quat, Py_NEW);
}
}
@@ -625,63 +645,17 @@ static PyNumberMethods Quaternion_NumMethods = {
static PyObject *Quaternion_getAxis( QuaternionObject * self, void *type )
{
- switch( (long)type ) {
- case 'W':
- return PyFloat_FromDouble(self->quat[0]);
- case 'X':
- return PyFloat_FromDouble(self->quat[1]);
- case 'Y':
- return PyFloat_FromDouble(self->quat[2]);
- case 'Z':
- return PyFloat_FromDouble(self->quat[3]);
- }
-
- PyErr_SetString(PyExc_SystemError, "corrupt quaternion, cannot get axis");
- return NULL;
+ return Quaternion_item(self, GET_INT_FROM_POINTER(type));
}
static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * type )
{
- float param= (float)PyFloat_AsDouble( value );
-
- if (param==-1 && PyErr_Occurred()) {
- PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" );
- return -1;
- }
- switch( (long)type ) {
- case 'W':
- self->quat[0]= param;
- break;
- case 'X':
- self->quat[1]= param;
- break;
- case 'Y':
- self->quat[2]= param;
- break;
- case 'Z':
- self->quat[3]= param;
- break;
- }
-
- return 0;
-}
-
-static PyObject *Quaternion_getWrapped( QuaternionObject * self, void *type )
-{
- if (self->wrapped == Py_WRAP)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value);
}
static PyObject *Quaternion_getMagnitude( QuaternionObject * self, void *type )
{
- double mag = 0.0;
- int i;
- for(i = 0; i < 4; i++) {
- mag += self->quat[i] * self->quat[i];
- }
- return PyFloat_FromDouble(sqrt(mag));
+ return PyFloat_FromDouble(sqrt(QuatDot(self->quat, self->quat)));
}
static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type )
@@ -720,19 +694,19 @@ static PyGetSetDef Quaternion_getseters[] = {
{"w",
(getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
"Quaternion W value",
- (void *)'W'},
+ (void *)0},
{"x",
(getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
"Quaternion X axis",
- (void *)'X'},
+ (void *)1},
{"y",
(getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
"Quaternion Y axis",
- (void *)'Y'},
+ (void *)2},
{"z",
(getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
"Quaternion Z axis",
- (void *)'Z'},
+ (void *)3},
{"magnitude",
(getter)Quaternion_getMagnitude, (setter)NULL,
"Size of the quaternion",
@@ -746,9 +720,14 @@ static PyGetSetDef Quaternion_getseters[] = {
"quaternion axis as a vector",
NULL},
{"wrapped",
- (getter)Quaternion_getWrapped, (setter)NULL,
+ (getter)BaseMathObject_getWrapped, (setter)NULL,
"True when this wraps blenders internal data",
NULL},
+ {"__owner__",
+ (getter)BaseMathObject_getOwner, (setter)NULL,
+ "Read only owner for vectors that depend on another object",
+ NULL},
+
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -765,7 +744,7 @@ PyTypeObject quaternion_Type = {
"quaternion", //tp_name
sizeof(QuaternionObject), //tp_basicsize
0, //tp_itemsize
- (destructor)Quaternion_dealloc, //tp_dealloc
+ (destructor)BaseMathObject_dealloc, //tp_dealloc
0, //tp_print
0, //tp_getattr
0, //tp_setattr
@@ -817,26 +796,22 @@ PyTypeObject quaternion_Type = {
PyObject *newQuaternionObject(float *quat, int type)
{
QuaternionObject *self;
- int x;
self = PyObject_NEW(QuaternionObject, &quaternion_Type);
- self->data.blend_data = NULL;
- self->data.py_data = NULL;
+
+ /* init callbacks as NULL */
+ self->cb_user= NULL;
+ self->cb_type= self->cb_subtype= 0;
if(type == Py_WRAP){
- self->data.blend_data = quat;
- self->quat = self->data.blend_data;
+ self->quat = quat;
self->wrapped = Py_WRAP;
}else if (type == Py_NEW){
- self->data.py_data = PyMem_Malloc(4 * sizeof(float));
- self->quat = self->data.py_data;
+ self->quat = PyMem_Malloc(4 * sizeof(float));
if(!quat) { //new empty
- Quaternion_Identity(self);
- Py_DECREF(self);
+ QuatOne(self->quat);
}else{
- for(x = 0; x < 4; x++){
- self->quat[x] = quat[x];
- }
+ QUATCOPY(self->quat, quat);
}
self->wrapped = Py_NEW;
}else{ //bad type
@@ -844,3 +819,16 @@ PyObject *newQuaternionObject(float *quat, int type)
}
return (PyObject *) self;
}
+
+PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
+{
+ QuaternionObject *self= (QuaternionObject *)newQuaternionObject(NULL, Py_NEW);
+ if(self) {
+ Py_INCREF(cb_user);
+ self->cb_user= cb_user;
+ self->cb_type= (unsigned char)cb_type;
+ self->cb_subtype= (unsigned char)cb_subtype;
+ }
+
+ return (PyObject *)self;
+}
diff --git a/source/blender/python/generic/quat.h b/source/blender/python/generic/quat.h
index ebbac26e39c..2e74b5fa7f9 100644
--- a/source/blender/python/generic/quat.h
+++ b/source/blender/python/generic/quat.h
@@ -38,14 +38,15 @@ extern PyTypeObject quaternion_Type;
#define QuaternionObject_Check(v) (Py_TYPE(v) == &quaternion_Type)
-typedef struct {
+typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */
PyObject_VAR_HEAD
- struct{
- float *py_data; //python managed
- float *blend_data; //blender managed
- }data;
- float *quat; //1D array of data (alias)
- int wrapped; //is wrapped data?
+ float *quat; /* 1D array of data (alias) */
+ PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
+ unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
+ unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+ unsigned char wrapped; /* wrapped data type? */
+ /* end BaseMathObject */
+
} QuaternionObject;
/*struct data contains a pointer to the actual data that the
@@ -55,5 +56,6 @@ blender (stored in blend_data). This is an either/or struct not both*/
//prototypes
PyObject *newQuaternionObject( float *quat, int type );
+PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype);
#endif /* EXPP_quat_h */
diff --git a/source/blender/python/generic/vector.c b/source/blender/python/generic/vector.c
index dea5bc93898..d68d3f41370 100644
--- a/source/blender/python/generic/vector.c
+++ b/source/blender/python/generic/vector.c
@@ -144,7 +144,7 @@ static PyObject *Vector_Zero(VectorObject * self)
self->vec[i] = 0.0f;
}
- Vector_WriteCallback(self);
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -155,7 +155,7 @@ static PyObject *Vector_Normalize(VectorObject * self)
int i;
float norm = 0.0f;
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
for(i = 0; i < self->size; i++) {
@@ -166,7 +166,7 @@ static PyObject *Vector_Normalize(VectorObject * self)
self->vec[i] /= norm;
}
- Vector_WriteCallback(self);
+ BaseMath_WriteCallback(self);
Py_INCREF(self);
return (PyObject*)self;
}
@@ -266,7 +266,7 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
return NULL;
}
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
if (strack) {
@@ -385,7 +385,7 @@ static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value )
return NULL;
}
- if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
+ if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
mirror[0] = value->vec[0];
@@ -431,7 +431,7 @@ static PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
return NULL;
}
- if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
+ if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW);
@@ -454,7 +454,7 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
return NULL;
}
- if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
+ if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
return NULL;
for(x = 0; x < self->size; x++) {
@@ -467,24 +467,12 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
return a copy of the vector */
static PyObject *Vector_copy(VectorObject * self)
{
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
return newVectorObject(self->vec, self->size, Py_NEW);
}
-/*----------------------------dealloc()(internal) ----------------
- free the py_object */
-static void Vector_dealloc(VectorObject * self)
-{
- /* only free non wrapped */
- if(self->wrapped != Py_WRAP)
- PyMem_Free(self->vec);
-
- Py_XDECREF(self->cb_user);
- PyObject_DEL(self);
-}
-
/*----------------------------print object (internal)-------------
print the object to screen */
static PyObject *Vector_repr(VectorObject * self)
@@ -492,7 +480,7 @@ static PyObject *Vector_repr(VectorObject * self)
int i;
char buffer[48], str[1024];
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
BLI_strncpy(str,"[",1024);
@@ -520,12 +508,14 @@ static int Vector_len(VectorObject * self)
sequence accessor (get)*/
static PyObject *Vector_item(VectorObject * self, int i)
{
+ if(i<0) i= self->size-i;
+
if(i < 0 || i >= self->size) {
PyErr_SetString(PyExc_IndexError,"vector[index]: out of range\n");
return NULL;
}
- if(!Vector_ReadIndexCallback(self, i))
+ if(!BaseMath_ReadIndexCallback(self, i))
return NULL;
return PyFloat_FromDouble(self->vec[i]);
@@ -541,13 +531,15 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob)
return -1;
}
+ if(i<0) i= self->size-i;
+
if(i < 0 || i >= self->size){
PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range\n");
return -1;
}
self->vec[i] = scalar;
- if(!Vector_WriteIndexCallback(self, i))
+ if(!BaseMath_WriteIndexCallback(self, i))
return -1;
return 0;
}
@@ -559,7 +551,7 @@ static PyObject *Vector_slice(VectorObject * self, int begin, int end)
PyObject *list = NULL;
int count;
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
CLAMP(begin, 0, self->size);
@@ -584,7 +576,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
float vec[4], scalar;
PyObject *v;
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return -1;
CLAMP(begin, 0, self->size);
@@ -620,7 +612,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
self->vec[begin + y] = vec[y];
}
- if(!Vector_WriteCallback(self))
+ if(!BaseMath_WriteCallback(self))
return -1;
return 0;
@@ -644,7 +636,7 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2)
/* make sure v1 is always the vector */
if (vec1 && vec2 ) {
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
/*VECTOR + VECTOR*/
@@ -679,7 +671,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
/* make sure v1 is always the vector */
if (vec1 && vec2 ) {
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
/*VECTOR + VECTOR*/
@@ -694,7 +686,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
return v1;
}
- Vector_WriteCallback(vec1);
+ BaseMath_WriteCallback(vec1);
PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n");
return NULL;
}
@@ -714,7 +706,7 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2)
vec1 = (VectorObject*)v1;
vec2 = (VectorObject*)v2;
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
if(vec1->size != vec2->size) {
@@ -747,14 +739,14 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2)
return NULL;
}
- if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+ if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
return NULL;
for(i = 0; i < vec1->size; i++) {
vec1->vec[i] = vec1->vec[i] - vec2->vec[i];
}
- Vector_WriteCallback(vec1);
+ BaseMath_WriteCallback(vec1);
Py_INCREF( v1 );
return v1;
}
@@ -768,12 +760,12 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
if VectorObject_Check(v1) {
vec1= (VectorObject *)v1;
- if(!Vector_ReadCallback(vec1))
+ if(!BaseMath_ReadCallback(vec1))
return NULL;
}
if VectorObject_Check(v2) {
vec2= (VectorObject *)v2;
- if(!Vector_ReadCallback(vec2))
+ if(!BaseMath_ReadCallback(vec2))
return NULL;
}
@@ -805,7 +797,8 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
/* VEC * MATRIX */
return row_vector_multiplication(vec1, (MatrixObject*)v2);
} else if (QuaternionObject_Check(v2)) {
- QuaternionObject *quat = (QuaternionObject*)v2;
+ QuaternionObject *quat = (QuaternionObject*)v2; /* quat_rotation validates */
+
if(vec1->size != 3) {
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
return NULL;
@@ -835,7 +828,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
int i;
float scalar;
- if(!Vector_ReadCallback(vec))
+ if(!BaseMath_ReadCallback(vec))
return NULL;
/* only support vec*=float and vec*=mat
@@ -845,7 +838,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
int x,y, size = vec->size;
MatrixObject *mat= (MatrixObject*)v2;
- if(!Vector_ReadCallback(mat))
+ if(!BaseMath_ReadCallback(mat))
return NULL;
if(mat->colSize != size){
@@ -883,7 +876,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
return NULL;
}
- Vector_WriteCallback(vec);
+ BaseMath_WriteCallback(vec);
Py_INCREF( v1 );
return v1;
}
@@ -902,7 +895,7 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2)
}
vec1 = (VectorObject*)v1; /* vector */
- if(!Vector_ReadCallback(vec1))
+ if(!BaseMath_ReadCallback(vec1))
return NULL;
scalar = (float)PyFloat_AsDouble(v2);
@@ -930,7 +923,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
float scalar;
VectorObject *vec1 = (VectorObject*)v1;
- if(!Vector_ReadCallback(vec1))
+ if(!BaseMath_ReadCallback(vec1))
return NULL;
scalar = (float)PyFloat_AsDouble(v2);
@@ -947,7 +940,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
vec1->vec[i] /= scalar;
}
- Vector_WriteCallback(vec1);
+ BaseMath_WriteCallback(vec1);
Py_INCREF( v1 );
return v1;
@@ -960,7 +953,7 @@ static PyObject *Vector_neg(VectorObject *self)
int i;
float vec[4];
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
for(i = 0; i < self->size; i++){
@@ -1008,7 +1001,7 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
vecA = (VectorObject*)objectA;
vecB = (VectorObject*)objectB;
- if(!Vector_ReadCallback(vecA) || !Vector_ReadCallback(vecB))
+ if(!BaseMath_ReadCallback(vecA) || !BaseMath_ReadCallback(vecB))
return NULL;
if (vecA->size != vecB->size){
@@ -1137,12 +1130,12 @@ static PyNumberMethods Vector_NumMethods = {
static PyObject *Vector_getAxis( VectorObject * self, void *type )
{
- return Vector_item(self, (int)type);
+ return Vector_item(self, GET_INT_FROM_POINTER(type));
}
static int Vector_setAxis( VectorObject * self, PyObject * value, void * type )
{
- return Vector_ass_item(self, (int)type, value);
+ return Vector_ass_item(self, GET_INT_FROM_POINTER(type), value);
}
/* vector.length */
@@ -1151,7 +1144,7 @@ static PyObject *Vector_getLength( VectorObject * self, void *type )
double dot = 0.0f;
int i;
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
for(i = 0; i < self->size; i++){
@@ -1165,7 +1158,7 @@ static int Vector_setLength( VectorObject * self, PyObject * value )
double dot = 0.0f, param;
int i;
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return -1;
param= PyFloat_AsDouble( value );
@@ -1203,30 +1196,11 @@ static int Vector_setLength( VectorObject * self, PyObject * value )
self->vec[i]= self->vec[i] / (float)dot;
}
- Vector_WriteCallback(self); /* checked alredy */
+ BaseMath_WriteCallback(self); /* checked alredy */
return 0;
}
-static PyObject *Vector_getWrapped( VectorObject * self, void *type )
-{
- if (self->wrapped == Py_WRAP)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
-}
-
-static PyObject *Vector_getOwner( VectorObject * self, void *type )
-{
- if(self->cb_user==NULL) {
- Py_RETURN_NONE;
- }
- else {
- Py_INCREF(self->cb_user);
- return self->cb_user;
- }
-}
-
/* Get a new Vector according to the provided swizzle. This function has little
error checking, as we are in control of the inputs: the closure is set by us
in Vector_createSwizzleGetSeter. */
@@ -1237,7 +1211,7 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure)
float vec[MAX_DIMENSIONS];
unsigned int swizzleClosure;
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
/* Unpack the axes from the closure into an array. */
@@ -1277,7 +1251,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
float vecTemp[MAX_DIMENSIONS];
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return -1;
/* Check that the closure can be used with this vector: even 2D vectors have
@@ -1309,7 +1283,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
axisB++;
}
memcpy(self->vec, vecTemp, axisB * sizeof(float));
- /* continue with Vector_WriteCallback at the end */
+ /* continue with BaseMathObject_WriteCallback at the end */
}
else if (PyList_Check(value))
{
@@ -1335,7 +1309,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
axisB++;
}
memcpy(self->vec, vecTemp, axisB * sizeof(float));
- /* continue with Vector_WriteCallback at the end */
+ /* continue with BaseMathObject_WriteCallback at the end */
}
else if (((scalarVal = (float)PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred())==0)
{
@@ -1348,14 +1322,14 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
}
- /* continue with Vector_WriteCallback at the end */
+ /* continue with BaseMathObject_WriteCallback at the end */
}
else {
PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." );
return -1;
}
- if(!Vector_WriteCallback(vecVal))
+ if(!BaseMath_WriteCallback(vecVal))
return -1;
else
return 0;
@@ -1390,11 +1364,11 @@ static PyGetSetDef Vector_getseters[] = {
"Vector Length",
NULL},
{"wrapped",
- (getter)Vector_getWrapped, (setter)NULL,
+ (getter)BaseMathObject_getWrapped, (setter)NULL,
"True when this wraps blenders internal data",
NULL},
{"__owner__",
- (getter)Vector_getOwner, (setter)NULL,
+ (getter)BaseMathObject_getOwner, (setter)NULL,
"Read only owner for vectors that depend on another object",
NULL},
@@ -1803,7 +1777,7 @@ PyTypeObject vector_Type = {
/* Methods to implement standard operations */
- ( destructor ) Vector_dealloc,/* destructor tp_dealloc; */
+ ( destructor ) BaseMathObject_dealloc,/* destructor tp_dealloc; */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
@@ -1920,7 +1894,7 @@ PyObject *newVectorObject(float *vec, int size, int type)
PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_subtype)
{
float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */
- VectorObject *self= newVectorObject(dummy, size, Py_NEW);
+ VectorObject *self= (VectorObject *)newVectorObject(dummy, size, Py_NEW);
if(self) {
Py_INCREF(cb_user);
self->cb_user= cb_user;
@@ -1928,7 +1902,7 @@ PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_su
self->cb_subtype= (unsigned char)cb_subtype;
}
- return self;
+ return (PyObject *)self;
}
//-----------------row_vector_multiplication (internal)-----------
@@ -1952,7 +1926,7 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat
}
}
- if(!Vector_ReadCallback(vec) || !Matrix_ReadCallback(mat))
+ if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat))
return NULL;
for(x = 0; x < vec_size; x++){
@@ -1975,13 +1949,13 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat
static PyObject *Vector_Negate(VectorObject * self)
{
int i;
- if(!Vector_ReadCallback(self))
+ if(!BaseMath_ReadCallback(self))
return NULL;
for(i = 0; i < self->size; i++)
self->vec[i] = -(self->vec[i]);
- Vector_WriteCallback(self); // alredy checked for error
+ BaseMath_WriteCallback(self); // alredy checked for error
Py_INCREF(self);
return (PyObject*)self;
diff --git a/source/blender/python/generic/vector.h b/source/blender/python/generic/vector.h
index 82dbf13b9aa..f519b2808cb 100644
--- a/source/blender/python/generic/vector.h
+++ b/source/blender/python/generic/vector.h
@@ -37,15 +37,16 @@ extern PyTypeObject vector_Type;
#define VectorObject_Check(v) (((PyObject *)v)->ob_type == &vector_Type)
-typedef struct {
+typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */
PyObject_VAR_HEAD
float *vec; /*1D array of data (alias), wrapped status depends on wrapped status */
PyObject *cb_user; /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
- unsigned char size; /* vec size 2,3 or 4 */
- unsigned char wrapped; /* wrapped data type? */
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */
unsigned char cb_subtype; /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
-
+ unsigned char wrapped; /* wrapped data type? */
+ /* end BaseMathObject */
+
+ unsigned char size; /* vec size 2,3 or 4 */
} VectorObject;
/*prototypes*/
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 3cef6e14861..0b8a7df1ae1 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -44,8 +44,8 @@
#ifdef USE_MATHUTILS
#include "../generic/Mathutils.h" /* so we can have mathutils callbacks */
-/* bpyrna vector callbacks */
-static int mathutils_rna_vector_cb_index= -1; /* index for our callbacks */
+/* bpyrna vector/euler/quat callbacks */
+static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
static int mathutils_rna_generic_check(BPy_PropertyRNA *self)
{
@@ -88,7 +88,7 @@ static int mathutils_rna_vector_set_index(BPy_PropertyRNA *self, int subtype, fl
return 1;
}
-Mathutils_Callback mathutils_rna_vector_cb = {
+Mathutils_Callback mathutils_rna_array_cb = {
mathutils_rna_generic_check,
mathutils_rna_vector_get,
mathutils_rna_vector_set,
@@ -234,26 +234,41 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop);
#ifdef USE_MATHUTILS
+
/* return a mathutils vector where possible */
if(RNA_property_type(prop)==PROP_FLOAT) {
- if(RNA_property_subtype(prop)==PROP_VECTOR) {
+ switch(RNA_property_subtype(prop)) {
+ case PROP_VECTOR:
if(len>=2 && len <= 4) {
- PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_vector_cb_index, 0);
+ PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, 0);
Py_DECREF(ret); /* the vector owns now */
ret= vec_cb; /* return the vector instead */
}
- }
- else if(RNA_property_subtype(prop)==PROP_MATRIX) {
+ break;
+ case PROP_MATRIX:
if(len==16) {
- PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_vector_cb_index, 0);
+ PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret= mat_cb; /* return the matrix instead */
}
else if (len==9) {
- PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_vector_cb_index, 0);
+ PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, 0);
Py_DECREF(ret); /* the matrix owns now */
ret= mat_cb; /* return the matrix instead */
}
+ break;
+ case PROP_ROTATION:
+ if(len==3) { /* euler */
+ PyObject *eul_cb= newEulerObject_cb(ret, mathutils_rna_array_cb_index, 0);
+ Py_DECREF(ret); /* the matrix owns now */
+ ret= eul_cb; /* return the matrix instead */
+ }
+ else if (len==4) {
+ PyObject *quat_cb= newQuaternionObject_cb(ret, mathutils_rna_array_cb_index, 0);
+ Py_DECREF(ret); /* the matrix owns now */
+ ret= quat_cb; /* return the matrix instead */
+ }
+ break;
}
}
@@ -377,12 +392,15 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const char *error_prefi
static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw);
-PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
+PyObject *pyrna_func_to_py(BPy_StructRNA *pyrna, FunctionRNA *func)
{
static PyMethodDef func_meth = {"<generic rna function>", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"};
PyObject *self= PyTuple_New(2);
PyObject *ret;
- PyTuple_SET_ITEM(self, 0, pyrna_struct_CreatePyObject(ptr));
+
+ PyTuple_SET_ITEM(self, 0, (PyObject *)pyrna);
+ Py_INCREF(pyrna);
+
PyTuple_SET_ITEM(self, 1, PyCObject_FromVoidPtr((void *)func, NULL));
ret= PyCFunction_New(&func_meth, self);
@@ -407,23 +425,23 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
#ifdef USE_MATHUTILS
if(MatrixObject_Check(value)) {
MatrixObject *mat = (MatrixObject*)value;
- if(!Matrix_ReadCallback(mat))
+ if(!BaseMath_ReadCallback(mat))
return -1;
py_len = mat->rowSize * mat->colSize;
- } else // continue...
+ } else /* continue... */
#endif
if (PySequence_Check(value)) {
py_len= (int)PySequence_Length(value);
}
else {
- PyErr_SetString(PyExc_TypeError, "expected a python sequence type assigned to an RNA array.");
+ PyErr_Format(PyExc_TypeError, "RNA array assignment expected a sequence instead of %s instance.", Py_TYPE(value)->tp_name);
return -1;
}
/* done getting the length */
if (py_len != len) {
- PyErr_SetString(PyExc_AttributeError, "python sequence length did not match the RNA array.");
+ PyErr_Format(PyExc_AttributeError, "python sequence length %d did not match the RNA array length %d.", py_len, len);
return -1;
}
@@ -493,7 +511,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
if(MatrixObject_Check(value) && RNA_property_subtype(prop) == PROP_MATRIX) {
MatrixObject *mat = (MatrixObject*)value;
memcpy(param_arr, mat->contigPtr, sizeof(float) * len);
- } else // continue...
+ } else /* continue... */
#endif
{
/* collect the variables */
@@ -1036,7 +1054,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
ret = pyrna_prop_to_py(&self->ptr, prop);
}
else if ((func = RNA_struct_find_function(&self->ptr, name))) {
- ret = pyrna_func_to_py(&self->ptr, func);
+ ret = pyrna_func_to_py(self, func);
}
else if (self->ptr.type == &RNA_Context) {
PointerRNA newptr;
@@ -1786,7 +1804,7 @@ PyObject *BPY_rna_module( void )
PointerRNA ptr;
#ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once.
- mathutils_rna_vector_cb_index= Mathutils_RegisterCallback(&mathutils_rna_vector_cb);
+ mathutils_rna_array_cb_index= Mathutils_RegisterCallback(&mathutils_rna_array_cb);
mathutils_rna_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_rna_matrix_cb);
#endif
diff --git a/source/gameengine/Expressions/KX_Python.h b/source/gameengine/Expressions/KX_Python.h
index b8006fdf0ed..61f7ef05042 100644
--- a/source/gameengine/Expressions/KX_Python.h
+++ b/source/gameengine/Expressions/KX_Python.h
@@ -32,6 +32,8 @@
//#define USE_DL_EXPORT
#include "Python.h"
+#define USE_MATHUTILS // Blender 2.5x api will use mathutils, for a while we might want to test without it
+
#ifdef __FreeBSD__
#include <osreldate.h>
#if __FreeBSD_version > 500039
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index defb6853e67..2d4cc612aef 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -331,13 +331,18 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef
}
case KX_PYATTRIBUTE_TYPE_VECTOR:
{
- PyObject* resultlist = PyList_New(3);
MT_Vector3 *val = reinterpret_cast<MT_Vector3*>(ptr);
+#ifdef USE_MATHUTILS
+ float fval[3]= {(*val)[0], (*val)[1], (*val)[2]};
+ return newVectorObject(fval, 3, Py_NEW);
+#else
+ PyObject* resultlist = PyList_New(3);
for (unsigned int i=0; i<3; i++)
{
PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble((*val)[i]));
}
return resultlist;
+#endif
}
case KX_PYATTRIBUTE_TYPE_STRING:
{
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index 96c75b710a3..3b5eebe9893 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -41,13 +41,15 @@
#include "MT_Vector3.h"
#include "SG_QList.h"
-#define USE_MATHUTILS // Blender 2.5x api will use mathutils, for a while we might want to test without it
-
/*------------------------------
* Python defines
------------------------------*/
-
+#ifdef USE_MATHUTILS
+extern "C" {
+#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */
+}
+#endif
#if PY_VERSION_HEX > 0x03000000
#define PyString_FromString PyUnicode_FromString
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index a3b2ba79e11..577f767b475 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -1184,11 +1184,7 @@ CListValue* KX_GameObject::GetChildrenRecursive()
return list;
}
-
#ifdef USE_MATHUTILS
-extern "C" {
-#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */
-}
/* These require an SGNode */
#define MATHUTILS_VEC_CB_POS_LOCAL 1
@@ -1880,12 +1876,7 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT
if (!PyOrientationTo(value, rot, "gameOb.worldOrientation = sequence: KX_GameObject, "))
return PY_SET_ATTR_FAIL;
- if (self->GetSGNode() && self->GetSGNode()->GetSGParent()) {
- self->NodeSetLocalOrientation(self->GetSGNode()->GetSGParent()->GetWorldOrientation().inverse()*rot);
- }
- else {
- self->NodeSetLocalOrientation(rot);
- }
+ self->NodeSetGlobalOrientation(rot);
self->NodeUpdateGS(0.f);
return PY_SET_ATTR_SUCCESS;
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
index eaae04d406d..62e61667c56 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -396,9 +396,14 @@ PyAttributeDef KX_ObjectActuator::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RW("useLocalDLoc", KX_ObjectActuator, m_bitLocalFlag.DLoc),
KX_PYATTRIBUTE_VECTOR_RW_CHECK("dRot", -1000, 1000, false, KX_ObjectActuator, m_drot, PyUpdateFuzzyFlags),
KX_PYATTRIBUTE_BOOL_RW("useLocalDRot", KX_ObjectActuator, m_bitLocalFlag.DRot),
+#ifdef USE_MATHUTILS
+ KX_PYATTRIBUTE_RW_FUNCTION("linV", KX_ObjectActuator, pyattr_get_linV, pyattr_set_linV),
+ KX_PYATTRIBUTE_RW_FUNCTION("angV", KX_ObjectActuator, pyattr_get_angV, pyattr_set_angV),
+#else
KX_PYATTRIBUTE_VECTOR_RW_CHECK("linV", -1000, 1000, false, KX_ObjectActuator, m_linear_velocity, PyUpdateFuzzyFlags),
- KX_PYATTRIBUTE_BOOL_RW("useLocalLinV", KX_ObjectActuator, m_bitLocalFlag.LinearVelocity),
KX_PYATTRIBUTE_VECTOR_RW_CHECK("angV", -1000, 1000, false, KX_ObjectActuator, m_angular_velocity, PyUpdateFuzzyFlags),
+#endif
+ KX_PYATTRIBUTE_BOOL_RW("useLocalLinV", KX_ObjectActuator, m_bitLocalFlag.LinearVelocity),
KX_PYATTRIBUTE_BOOL_RW("useLocalAngV", KX_ObjectActuator, m_bitLocalFlag.AngularVelocity),
KX_PYATTRIBUTE_SHORT_RW("damping", 0, 1000, false, KX_ObjectActuator, m_damping),
KX_PYATTRIBUTE_RW_FUNCTION("forceLimitX", KX_ObjectActuator, pyattr_get_forceLimitX, pyattr_set_forceLimitX),
@@ -425,6 +430,129 @@ int KX_ObjectActuator::py_setattro(PyObject *attr, PyObject *value)
/* Attribute get/set functions */
+#ifdef USE_MATHUTILS
+
+/* These require an SGNode */
+#define MATHUTILS_VEC_CB_LINV 1
+#define MATHUTILS_VEC_CB_ANGV 2
+
+static int mathutils_kxobactu_vector_cb_index= -1; /* index for our callbacks */
+
+static int mathutils_obactu_generic_check(PyObject *self_v)
+{
+ KX_ObjectActuator* self= static_cast<KX_ObjectActuator*>BGE_PROXY_REF(self_v);
+ if(self==NULL)
+ return 0;
+
+ return 1;
+}
+
+static int mathutils_obactu_vector_get(PyObject *self_v, int subtype, float *vec_from)
+{
+ KX_ObjectActuator* self= static_cast<KX_ObjectActuator*>BGE_PROXY_REF(self_v);
+ if(self==NULL)
+ return 0;
+
+ switch(subtype) {
+ case MATHUTILS_VEC_CB_LINV:
+ self->m_linear_velocity.getValue(vec_from);
+ break;
+ case MATHUTILS_VEC_CB_ANGV:
+ self->m_angular_velocity.getValue(vec_from);
+ break;
+ }
+
+ return 1;
+}
+
+static int mathutils_obactu_vector_set(PyObject *self_v, int subtype, float *vec_to)
+{
+ KX_ObjectActuator* self= static_cast<KX_ObjectActuator*>BGE_PROXY_REF(self_v);
+ if(self==NULL)
+ return 0;
+
+ switch(subtype) {
+ case MATHUTILS_VEC_CB_LINV:
+ self->m_linear_velocity.setValue(vec_to);
+ break;
+ case MATHUTILS_VEC_CB_ANGV:
+ self->m_angular_velocity.setValue(vec_to);
+ break;
+ }
+
+ return 1;
+}
+
+static int mathutils_obactu_vector_get_index(PyObject *self_v, int subtype, float *vec_from, int index)
+{
+ float f[4];
+ /* lazy, avoid repeteing the case statement */
+ if(!mathutils_obactu_vector_get(self_v, subtype, f))
+ return 0;
+
+ vec_from[index]= f[index];
+ return 1;
+}
+
+static int mathutils_obactu_vector_set_index(PyObject *self_v, int subtype, float *vec_to, int index)
+{
+ float f= vec_to[index];
+
+ /* lazy, avoid repeteing the case statement */
+ if(!mathutils_obactu_vector_get(self_v, subtype, vec_to))
+ return 0;
+
+ vec_to[index]= f;
+ mathutils_obactu_vector_set(self_v, subtype, vec_to);
+
+ return 1;
+}
+
+Mathutils_Callback mathutils_obactu_vector_cb = {
+ mathutils_obactu_generic_check,
+ mathutils_obactu_vector_get,
+ mathutils_obactu_vector_set,
+ mathutils_obactu_vector_get_index,
+ mathutils_obactu_vector_set_index
+};
+
+PyObject* KX_ObjectActuator::pyattr_get_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_LINV);
+}
+
+int KX_ObjectActuator::pyattr_set_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_ObjectActuator* self= static_cast<KX_ObjectActuator*>(self_v);
+ if (!PyVecTo(value, self->m_linear_velocity))
+ return PY_SET_ATTR_FAIL;
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject* KX_ObjectActuator::pyattr_get_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ return newVectorObject_cb((PyObject *)self_v, 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_ANGV);
+}
+
+int KX_ObjectActuator::pyattr_set_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_ObjectActuator* self= static_cast<KX_ObjectActuator*>(self_v);
+ if (!PyVecTo(value, self->m_angular_velocity))
+ return PY_SET_ATTR_FAIL;
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+
+void KX_ObjectActuator_Mathutils_Callback_Init(void)
+{
+ // register mathutils callbacks, ok to run more then once.
+ mathutils_kxobactu_vector_cb_index= Mathutils_RegisterCallback(&mathutils_obactu_vector_cb);
+}
+
+#endif // USE_MATHUTILS
+
PyObject* KX_ObjectActuator::pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_ObjectActuator* self = reinterpret_cast<KX_ObjectActuator*>(self_v);
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
index f9bd2a0c748..6ca442b2ec2 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -35,6 +35,10 @@
#include "SCA_IActuator.h"
#include "MT_Vector3.h"
+#ifdef USE_MATHUTILS
+void KX_ObjectActuator_Mathutils_Callback_Init(void);
+#endif
+
class KX_GameObject;
//
@@ -197,6 +201,13 @@ public:
static PyObject* pyattr_get_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#ifdef USE_MATHUTILS
+ static PyObject* pyattr_get_linV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_linV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_angV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_angV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+#endif
+
// This lets the attribute macros use UpdateFuzzyFlags()
static int PyUpdateFuzzyFlags(void *self, const PyAttributeDef *attrdef)
{
diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp
index 051d7ae7dba..ee9fed5d30a 100644
--- a/source/gameengine/Ketsji/KX_PyMath.cpp
+++ b/source/gameengine/Ketsji/KX_PyMath.cpp
@@ -46,35 +46,6 @@
#include "KX_Python.h"
#include "KX_PyMath.h"
-bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank)
-{
- if (!pymat)
- return false;
-
- unsigned int y;
- if (PySequence_Check(pymat))
- {
- unsigned int rows = PySequence_Size(pymat);
- if (rows != rank)
- return false;
-
- bool ismatrix = true;
- for (y = 0; y < rank && ismatrix; y++)
- {
- PyObject *pyrow = PySequence_GetItem(pymat, y); /* new ref */
- if (PySequence_Check(pyrow))
- {
- if (((unsigned int)PySequence_Size(pyrow)) != rank)
- ismatrix = false;
- } else
- ismatrix = false;
- Py_DECREF(pyrow);
- }
- return ismatrix;
- }
- return false;
-}
-
bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefix)
{
int size= PySequence_Size(pyval);
@@ -110,12 +81,10 @@ bool PyOrientationTo(PyObject* pyval, MT_Matrix3x3 &rot, const char *error_prefi
PyObject* PyObjectFrom(const MT_Matrix4x4 &mat)
{
-#if 0
- return Py_BuildValue("[[ffff][ffff][ffff][ffff]]",
- mat[0][0], mat[0][1], mat[0][2], mat[0][3],
- mat[1][0], mat[1][1], mat[1][2], mat[1][3],
- mat[2][0], mat[2][1], mat[2][2], mat[2][3],
- mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
+#ifdef USE_MATHUTILS
+ float fmat[16];
+ mat.getValue(fmat);
+ return newMatrixObject(fmat, 4, 4, Py_NEW);
#else
PyObject *list = PyList_New(4);
PyObject *sublist;
@@ -136,11 +105,10 @@ PyObject* PyObjectFrom(const MT_Matrix4x4 &mat)
PyObject* PyObjectFrom(const MT_Matrix3x3 &mat)
{
-#if 0
- return Py_BuildValue("[[fff][fff][fff]]",
- mat[0][0], mat[0][1], mat[0][2],
- mat[1][0], mat[1][1], mat[1][2],
- mat[2][0], mat[2][1], mat[2][2]);
+#ifdef USE_MATHUTILS
+ float fmat[9];
+ mat.getValue3x3(fmat);
+ return newMatrixObject(fmat, 3, 3, Py_NEW);
#else
PyObject *list = PyList_New(3);
PyObject *sublist;
@@ -160,9 +128,9 @@ PyObject* PyObjectFrom(const MT_Matrix3x3 &mat)
PyObject* PyObjectFrom(const MT_Tuple4 &vec)
{
-#if 0
- return Py_BuildValue("[ffff]",
- vec[0], vec[1], vec[2], vec[3]);
+#ifdef USE_MATHUTILS
+ float fvec[4]= {vec[0], vec[1], vec[2], vec[3]};
+ return newVectorObject(fvec, 4, Py_WRAP);
#else
PyObject *list = PyList_New(4);
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
@@ -175,9 +143,9 @@ PyObject* PyObjectFrom(const MT_Tuple4 &vec)
PyObject* PyObjectFrom(const MT_Tuple3 &vec)
{
-#if 0
- return Py_BuildValue("[fff]",
- vec[0], vec[1], vec[2]);
+#ifdef USE_MATHUTILS
+ float fvec[3]= {vec[0], vec[1], vec[2]};
+ return newVectorObject(fvec, 3, Py_WRAP);
#else
PyObject *list = PyList_New(3);
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
@@ -189,9 +157,9 @@ PyObject* PyObjectFrom(const MT_Tuple3 &vec)
PyObject* PyObjectFrom(const MT_Tuple2 &vec)
{
-#if 0
- return Py_BuildValue("[ff]",
- vec[0], vec[1]);
+#ifdef USE_MATHUTILS
+ float fvec[2]= {vec[0], vec[1]};
+ return newVectorObject(fvec, 2, Py_WRAP);
#else
PyObject *list = PyList_New(2);
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h
index a7ce4bc6930..90a13425aa0 100644
--- a/source/gameengine/Ketsji/KX_PyMath.h
+++ b/source/gameengine/Ketsji/KX_PyMath.h
@@ -31,6 +31,12 @@
#ifndef __KX_PYMATH_H__
#define __KX_PYMATH_H__
+#ifdef USE_MATHUTILS
+extern "C" {
+#include "../../blender/python/generic/Mathutils.h" /* so we can have mathutils callbacks */
+}
+#endif
+
#include "MT_Point2.h"
#include "MT_Point3.h"
#include "MT_Vector2.h"
@@ -98,7 +104,28 @@ bool PyMatTo(PyObject* pymat, T& mat)
template<class T>
bool PyVecTo(PyObject* pyval, T& vec)
{
-
+#ifdef USE_MATHUTILS
+ /* no need for BaseMath_ReadCallback() here, reading the sequences will do this */
+
+ if(VectorObject_Check(pyval)) {
+ VectorObject *pyvec= (VectorObject *)pyval;
+ if (pyvec->size != Size(vec)) {
+ PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", pyvec->size, Size(vec));
+ return false;
+ }
+ vec.getValue((float *) pyvec->vec);
+ return true;
+ }
+ else if(EulerObject_Check(pyval)) {
+ EulerObject *pyeul= (EulerObject *)pyval;
+ if (3 != Size(vec)) {
+ PyErr_Format(PyExc_AttributeError, "error setting vector, %d args, should be %d", 3, Size(vec));
+ return false;
+ }
+ vec.getValue((float *) pyeul->eul);
+ return true;
+ } else
+#endif
if(PyTuple_Check(pyval))
{
unsigned int numitems = PyTuple_GET_SIZE(pyval);
@@ -186,10 +213,4 @@ PyObject* PyObjectFrom(const MT_Tuple3 &vec);
*/
PyObject* PyObjectFrom(const MT_Tuple4 &pos);
-/**
- * True if the given PyObject can be converted to an MT_Matrix
- * @param rank = 3 (for MT_Matrix3x3) or 4 (for MT_Matrix4x4)
- */
-bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank);
-
#endif
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
index 05cb818fdd9..d5d0fe3123c 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
@@ -235,7 +235,8 @@ void initPyTypes(void)
#ifdef USE_MATHUTILS
/* Init mathutils callbacks */
KX_GameObject_Mathutils_Callback_Init();
+ KX_ObjectActuator_Mathutils_Callback_Init();
#endif
}
-#endif \ No newline at end of file
+#endif