diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-06-16 23:51:58 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-06-16 23:51:58 +0400 |
commit | ecb39291e97742524ff6b091bbca22a5a915f92c (patch) | |
tree | 360f919c519ce19564064757c8bdf578ab7fa566 | |
parent | 55f1a1dcad5621f323dd76ca3cfcec06677e00be (diff) | |
parent | 2faf20c4b3ae1ca6c82dd2a942d2f2a580685436 (diff) |
small merge needed for testing new animsys in 2.5 BGE, mixing own changes with merge can be a hassle.
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r20928:20937
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 3 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ActionActuator.cpp | 172 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ActionActuator.h | 2 | ||||
-rw-r--r-- | source/gameengine/PyDoc/GameTypes.py | 16 |
4 files changed, 114 insertions, 79 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index d54bc749b71..fb1b2e9cf70 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -800,6 +800,7 @@ void calc_action_range(const bAction *act, float *start, float *end, int incl_hi /* Copy the data from the action-pose (src) into the pose */ /* both args are assumed to be valid */ /* exported to game engine */ +/* Note! this assumes both poses are aligned, this isnt always true when dealing with user poses */ void extract_pose_from_pose(bPose *pose, const bPose *src) { const bPoseChannel *schan; @@ -810,7 +811,7 @@ void extract_pose_from_pose(bPose *pose, const bPose *src) return; } - for (schan=src->chanbase.first; schan; schan=schan->next, pchan= pchan->next) { + for (schan=src->chanbase.first; (schan && pchan); schan=schan->next, pchan= pchan->next) { copy_pose_channel_data(pchan, schan); } } diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index e4dd588f06a..0c7b99df387 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -51,6 +51,7 @@ #include "BKE_utildefines.h" #include "FloatValue.h" #include "PyObjectPlus.h" +#include "KX_PyMath.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -366,8 +367,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame) /* Perform the user override (if any) */ if (m_userpose){ extract_pose_from_pose(m_pose, m_userpose); -// clear_pose(m_userpose); - MEM_freeN(m_userpose); + game_free_pose(m_userpose); //cant use MEM_freeN(m_userpose) because the channels need freeing too. m_userpose = NULL; } #if 1 @@ -767,22 +767,55 @@ PyObject* BL_ActionActuator::PySetFrameProperty(PyObject* args, Py_RETURN_NONE; } -/* -PyObject* BL_ActionActuator::PyGetChannel(PyObject* args, - PyObject* kwds) { - char *string; +PyObject* BL_ActionActuator::PyGetChannel(PyObject* value) { + char *string= PyString_AsString(value); - if (PyArg_ParseTuple(args,"s:getChannel",&string)) - { - m_propname = string; + if (!string) { + PyErr_SetString(PyExc_TypeError, "expected a single string"); + return NULL; } - else { + + bPoseChannel *pchan; + + + // get_pose_channel accounts for NULL pose, run on both incase one exists but + // the channel doesnt + if( !(pchan=get_pose_channel(m_userpose, string)) && + !(pchan=get_pose_channel(m_pose, string)) ) + { + PyErr_SetString(PyExc_ValueError, "channel doesnt exist"); return NULL; } + + PyObject *ret = PyTuple_New(3); - Py_RETURN_NONE; -} + PyObject *list = PyList_New(3); + PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->loc[0])); + PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->loc[1])); + PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->loc[2])); + PyTuple_SET_ITEM(ret, 0, list); + + list = PyList_New(3); + PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->size[0])); + PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->size[1])); + PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->size[2])); + PyTuple_SET_ITEM(ret, 1, list); + + list = PyList_New(4); + PyList_SET_ITEM(list, 0, PyFloat_FromDouble(pchan->quat[0])); + PyList_SET_ITEM(list, 1, PyFloat_FromDouble(pchan->quat[1])); + PyList_SET_ITEM(list, 2, PyFloat_FromDouble(pchan->quat[2])); + PyList_SET_ITEM(list, 3, PyFloat_FromDouble(pchan->quat[3])); + PyTuple_SET_ITEM(ret, 2, list); + + return ret; +/* + return Py_BuildValue("([fff][fff][ffff])", + pchan->loc[0], pchan->loc[1], pchan->loc[2], + pchan->size[0], pchan->size[1], pchan->size[2], + pchan->quat[0], pchan->quat[1], pchan->quat[2], pchan->quat[3] ); */ +} /* getType */ const char BL_ActionActuator::GetType_doc[] = @@ -857,76 +890,69 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel, "\t - matrix : A 4x4 matrix specifying the overriding transformation\n" "\t as an offset from the bone's rest position.\n") { - float matrix[4][4]; + BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent(); char *string; - PyObject* pylist; - bool error = false; - int row,col; - int mode = 0; /* 0 for bone space, 1 for armature/world space */ + PyObject *pymat= NULL; + PyObject *pyloc= NULL, *pysize= NULL, *pyquat= NULL; + bPoseChannel *pchan; - if (!PyArg_ParseTuple(args,"sO|i:setChannel", &string, &pylist, &mode)) - return NULL; - - if (pylist->ob_type == &CListValue::Type) - { - CListValue* listval = (CListValue*) pylist; - if (listval->GetCount() == 4) - { - for (row=0;row<4;row++) // each row has a 4-vector [x,y,z, w] - { - CListValue* vecval = (CListValue*)listval->GetValue(row); - for (col=0;col<4;col++) - { - matrix[row][col] = vecval->GetValue(col)->GetNumber(); - - } - } - } - else - { - error = true; - } + if(PyTuple_Size(args)==2) { + if (!PyArg_ParseTuple(args,"sO:setChannel", &string, &pymat)) // matrix + return NULL; } - else - { - // assert the list is long enough... - int numitems = PyList_Size(pylist); - if (numitems == 4) - { - for (row=0;row<4;row++) // each row has a 4-vector [x,y,z, w] - { - - PyObject* veclist = PyList_GetItem(pylist,row); // here we have a vector4 list - for (col=0;col<4;col++) - { - matrix[row][col] = PyFloat_AsDouble(PyList_GetItem(veclist,col)); - - } - } - } - else - { - error = true; - } + else if(PyTuple_Size(args)==4) { + if (!PyArg_ParseTuple(args,"sOOO:setChannel", &string, &pyloc, &pysize, &pyquat)) // loc/size/quat + return NULL; + } + else { + PyErr_SetString(PyExc_ValueError, "Expected a string and a 4x4 matrix (2 args) or a string and loc/size/quat sequences (4 args)"); + return NULL; } - if (!error) - { - -/* DO IT HERE */ - bPoseChannel *pchan= verify_pose_channel(m_userpose, string); - - Mat4ToQuat(matrix, pchan->quat); - Mat4ToSize(matrix, pchan->size); + if(pymat) { + float matrix[4][4]; + MT_Matrix4x4 mat; + + if(!PyMatTo(pymat, mat)) + return NULL; + + mat.setValue((const float *)matrix); + + BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent(); + obj->GetPose(&m_pose); /* Get the underlying pose from the armature */ + + if (!m_userpose) { + obj->GetPose(&m_pose); /* Get the underlying pose from the armature */ + game_copy_pose(&m_userpose, m_pose); + } + pchan= verify_pose_channel(m_userpose, string); // adds the channel if its not there. + VECCOPY (pchan->loc, matrix[3]); + Mat4ToSize(matrix, pchan->size); + Mat4ToQuat(matrix, pchan->quat); + } + else { + MT_Vector3 loc; + MT_Vector3 size; + MT_Vector4 quat; - pchan->flag |= POSE_ROT|POSE_LOC|POSE_SIZE; - - if (!m_userpose){ - m_userpose = (bPose*)MEM_callocN(sizeof(bPose), "userPose"); + if (!PyVecTo(pyloc, loc) || !PyVecTo(pysize, size) || !PyVecTo(pyquat, quat)) + return NULL; + + // same as above + if (!m_userpose) { + obj->GetPose(&m_pose); /* Get the underlying pose from the armature */ + game_copy_pose(&m_userpose, m_pose); } + pchan= verify_pose_channel(m_userpose, string); + + // for some reason loc.setValue(pchan->loc) fails + pchan->loc[0]= loc[0]; pchan->loc[1]= loc[1]; pchan->loc[2]= loc[2]; + pchan->size[0]= size[0]; pchan->size[1]= size[1]; pchan->size[2]= size[2]; + pchan->quat[0]= quat[0]; pchan->quat[1]= quat[1]; pchan->quat[2]= quat[2]; pchan->quat[3]= quat[3]; } + pchan->flag |= POSE_ROT|POSE_LOC|POSE_SIZE; Py_RETURN_NONE; } @@ -986,7 +1012,7 @@ PyMethodDef BL_ActionActuator::Methods[] = { {"getFrame", (PyCFunction) BL_ActionActuator::sPyGetFrame, METH_VARARGS, (PY_METHODCHAR)GetFrame_doc}, {"getProperty", (PyCFunction) BL_ActionActuator::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc}, {"getFrameProperty", (PyCFunction) BL_ActionActuator::sPyGetFrameProperty, METH_VARARGS, (PY_METHODCHAR)GetFrameProperty_doc}, -// {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_VARARGS}, + {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_O}, {"getType", (PyCFunction) BL_ActionActuator::sPyGetType, METH_VARARGS, (PY_METHODCHAR)GetType_doc}, {"setType", (PyCFunction) BL_ActionActuator::sPySetType, METH_VARARGS, (PY_METHODCHAR)SetType_doc}, {"getContinue", (PyCFunction) BL_ActionActuator::sPyGetContinue, METH_NOARGS, 0}, diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index b3c15c08f50..422b16bb3ec 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -104,7 +104,7 @@ public: KX_PYMETHOD_DOC(BL_ActionActuator,GetFrame); KX_PYMETHOD_DOC(BL_ActionActuator,GetProperty); KX_PYMETHOD_DOC(BL_ActionActuator,GetFrameProperty); -// KX_PYMETHOD(BL_ActionActuator,GetChannel); + KX_PYMETHOD_O(BL_ActionActuator,GetChannel); KX_PYMETHOD_DOC(BL_ActionActuator,GetType); KX_PYMETHOD_DOC(BL_ActionActuator,SetType); KX_PYMETHOD_NOARGS(BL_ActionActuator,GetContinue); diff --git a/source/gameengine/PyDoc/GameTypes.py b/source/gameengine/PyDoc/GameTypes.py index 4ab175a8f6c..63dd1a7fabf 100644 --- a/source/gameengine/PyDoc/GameTypes.py +++ b/source/gameengine/PyDoc/GameTypes.py @@ -336,15 +336,23 @@ class BL_ActionActuator(SCA_IActuator): @ivar framePropName: The name of the property that is set to the current frame number. @type framePropName: string """ - def setChannel(channel, matrix, mode = False): + def setChannel(channel, matrix): """ - @param channel: A string specifying the name of the bone channel. + Alternative to the 2 arguments, 4 arguments (channel, matrix, loc, size, quat) are also supported. + + @param channel: A string specifying the name of the bone channel, created if missing. @type channel: string @param matrix: A 4x4 matrix specifying the overriding transformation as an offset from the bone's rest position. @type matrix: list [[float]] - @param mode: True for armature/world space, False for bone space - @type mode: boolean + """ + + def getChannel(channel): + """ + @param channel: A string specifying the name of the bone channel. error raised if missing. + @type channel: string + @rtype: tuple + @return: (loc, size, quat) """ #{ Deprecated |