From ee1c29028d924c1ee7520d547da98b3fd88ece05 Mon Sep 17 00:00:00 2001 From: Benoit Bolsee Date: Mon, 11 May 2009 12:41:48 +0000 Subject: BGE: Add MT_Vector3 support for Py attribute macro system. See KX_PYATTRIBUTE_VECTOR_... --- source/gameengine/Expressions/PyObjectPlus.cpp | 52 +++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'source/gameengine/Expressions/PyObjectPlus.cpp') diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 83c0b25df24..720094b6f98 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -50,6 +50,7 @@ #include "stdlib.h" #include "PyObjectPlus.h" #include "STR_String.h" +#include "MT_Vector3.h" /*------------------------------ * PyObjectPlus Type -- Every class, even the abstract one should have a Type ------------------------------*/ @@ -328,6 +329,16 @@ PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef float *val = reinterpret_cast(ptr); return PyFloat_FromDouble(*val); } + case KX_PYATTRIBUTE_TYPE_VECTOR: + { + PyObject* resultlist = PyList_New(3); + MT_Vector3 *val = reinterpret_cast(ptr); + for (unsigned int i=0; i<3; i++) + { + PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble((*val)[i])); + } + return resultlist; + } case KX_PYATTRIBUTE_TYPE_STRING: { STR_String *val = reinterpret_cast(ptr); @@ -549,7 +560,7 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb } return (*attrdef->m_setFunction)(self, attrdef, value); } - if (attrdef->m_checkFunction != NULL) + if (attrdef->m_checkFunction != NULL || attrdef->m_type == KX_PYATTRIBUTE_TYPE_VECTOR) { // post check function is provided, prepare undo buffer sourceBuffer = ptr; @@ -573,6 +584,9 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb if (sourceBuffer) bufferSize = strlen(reinterpret_cast(sourceBuffer))+1; break; + case KX_PYATTRIBUTE_TYPE_VECTOR: + bufferSize = sizeof(MT_Vector3); + break; default: PyErr_Format(PyExc_AttributeError, "unknown type for attribute \"%s\", report to blender.org", attrdef->m_name); return 1; @@ -693,6 +707,42 @@ int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyOb *var = (float)val; break; } + case KX_PYATTRIBUTE_TYPE_VECTOR: + { + if (!PySequence_Check(value) || PySequence_Size(value) != 3) + { + PyErr_Format(PyExc_TypeError, "expected a sequence of 3 floats for attribute \"%s\"", attrdef->m_name); + return 1; + } + MT_Vector3 *var = reinterpret_cast(ptr); + for (int i=0; i<3; i++) + { + PyObject *item = PySequence_GetItem(value, i); /* new ref */ + // we can decrement the reference immediately, the reference count + // is at least 1 because the item is part of an array + Py_DECREF(item); + double val = PyFloat_AsDouble(item); + if (val == -1.0 && PyErr_Occurred()) + { + PyErr_Format(PyExc_TypeError, "expected a sequence of 3 floats for attribute \"%s\"", attrdef->m_name); + goto RESTORE_AND_ERROR; + } + else if (attrdef->m_clamp) + { + if (val < attrdef->m_fmin) + val = attrdef->m_fmin; + else if (val > attrdef->m_fmax) + val = attrdef->m_fmax; + } + else if (val < attrdef->m_fmin || val > attrdef->m_fmax) + { + PyErr_Format(PyExc_ValueError, "value out of range for attribute \"%s\"", attrdef->m_name); + goto RESTORE_AND_ERROR; + } + (*var)[i] = (MT_Scalar)val; + } + break; + } case KX_PYATTRIBUTE_TYPE_STRING: { STR_String *var = reinterpret_cast(ptr); -- cgit v1.2.3